From 6dba38f2cf585872eae9c2330f452f335be8c79d Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 1 Oct 2026 11:20:04 +0530 Subject: [PATCH 1/2] test: stabilize integration timing on slow Chromium runners Reuse scrolling fixtures and populate real working-set tabs without loading every editor. Reset pane state and allow filesystem cleanup to finish. Wait for preference diagnostics and their visible status together, using the inspection timeout instead of the default two-second UI wait. Verified development and production Integration categories at 857/857 each, Tab Bar at 49/49 with 4x CPU throttling, and delayed PreferencesManager at 7/7. --- test/spec/Extn-Tabbar-integ-test.js | 74 +++++++++------------- test/spec/PreferencesManager-integ-test.js | 48 +++++++------- 2 files changed, 56 insertions(+), 66 deletions(-) diff --git a/test/spec/Extn-Tabbar-integ-test.js b/test/spec/Extn-Tabbar-integ-test.js index 81ffd2376b..64aaa72cee 100644 --- a/test/spec/Extn-Tabbar-integ-test.js +++ b/test/spec/Extn-Tabbar-integ-test.js @@ -285,16 +285,15 @@ define(function (require, exports, module) { CommandManager.execute(Commands.FILE_OPEN, { fullPath: testFilePath }), "Open test file" ); - }, 5000); + }, 30000); afterAll(async function () { - // Close all files without prompting to save - await testWindow.closeAllFiles(); - - testWindow = null; + // closeTestWindow closes the files and parks the project before deleting fixtures. + // Browser IndexedDB cleanup needs the same budget as other integration teardown. await SpecRunnerUtils.closeTestWindow(); await SpecRunnerUtils.deletePathAsync(testFolder, true); - }, 5000); + testWindow = null; + }, 30000); /** * Helper function to check if a tab for a specific file exists in the tab bar @@ -2745,9 +2744,9 @@ define(function (require, exports, module) { describe("Tab Bar Scrolling", function () { let longTestFilePaths = []; - beforeEach(async function () { - // Create multiple test files to ensure scrolling is needed - longTestFilePaths = []; + beforeAll(async function () { + // These files are read-only fixtures; create them once rather than rewriting + // the same 15 files and notifying filesystem watchers before every scroll test. for (let i = 1; i <= 15; i++) { const filePath = testFolder + `/scroll-test-file-${i}.js`; longTestFilePaths.push(filePath); @@ -2755,37 +2754,37 @@ define(function (require, exports, module) { SpecRunnerUtils.createTextFile(filePath, `// Test file ${i} for scrolling`, FileSystem) ); } + }, 30000); - // Open all files to create many tabs - for (let filePath of longTestFilePaths) { - await awaitsForDone( - CommandManager.execute(Commands.FILE_OPEN, { fullPath: filePath }), - `Open ${filePath}` - ); + beforeEach(async function () { + await testWindow.closeAllFiles(); + MainViewManager.setLayoutScheme(1, 1); + PreferencesManager.set("tabBar.options", { showTabBar: true, numberOfTabs: -1 }); + await awaitsForDone( + CommandManager.execute(Commands.FILE_OPEN, { fullPath: longTestFilePaths[0] }), + "Open the scrolling fixture's active editor" + ); + // Working-set entries create real tabs without loading and linting 14 more + // editors. These cases exercise tab scrolling, not document activation. + for (const filePath of longTestFilePaths.slice(1)) { + MainViewManager.addToWorkingSet("first-pane", FileSystem.getFileForPath(filePath)); } - // Wait for tabs to be rendered + // Require actual overflow so no scrolling assertion can pass without scrolling. await awaitsFor( function () { - return getTabCount() >= 15; + const tabBar = $("#phoenix-tab-bar")[0]; + return getTabCount() === longTestFilePaths.length && tabBar && + tabBar.scrollWidth > tabBar.clientWidth; }, - "All tabs to be created" + "All scrolling tabs to be created and overflow" ); + $("#phoenix-tab-bar").scrollLeft(0); }); afterEach(async function () { - // Close all test files - for (let filePath of longTestFilePaths) { - const fileObj = FileSystem.getFileForPath(filePath); - try { - await awaitsForDone( - CommandManager.execute(Commands.FILE_CLOSE, { file: fileObj }), - `Close ${filePath}` - ); - } catch (e) { - // Ignore errors if file is already closed - } - } + await testWindow.closeAllFiles(); + MainViewManager.setLayoutScheme(1, 1); }); it("should scroll tab bar horizontally when mouse wheel is scrolled", function () { @@ -2879,13 +2878,7 @@ define(function (require, exports, module) { // Open multiple files in second pane to enable scrolling for (let i = 1; i < 8; i++) { - await awaitsForDone( - CommandManager.execute(Commands.FILE_OPEN, { - fullPath: longTestFilePaths[i], - paneId: "second-pane" - }), - `Open file ${i} in second pane` - ); + MainViewManager.addToWorkingSet("second-pane", FileSystem.getFileForPath(longTestFilePaths[i])); } // Wait for tabs to be rendered in second pane @@ -2920,14 +2913,9 @@ define(function (require, exports, module) { const $tabBar = $("#phoenix-tab-bar"); expect($tabBar.length).toBe(1); - // Ensure the tab bar is scrollable by checking if scrollWidth > clientWidth - if ($tabBar[0].scrollWidth <= $tabBar[0].clientWidth) { - // Skip test if tab bar is not scrollable - return; - } - // Set initial scroll position to middle to allow scrolling in both directions const maxScroll = $tabBar[0].scrollWidth - $tabBar[0].clientWidth; + expect(maxScroll).toBeGreaterThan(200); const midScroll = Math.floor(maxScroll / 2); $tabBar.scrollLeft(midScroll); diff --git a/test/spec/PreferencesManager-integ-test.js b/test/spec/PreferencesManager-integ-test.js index 44e9eb3844..b6e14bc693 100644 --- a/test/spec/PreferencesManager-integ-test.js +++ b/test/spec/PreferencesManager-integ-test.js @@ -52,6 +52,27 @@ define(function (require, exports, module) { await SpecRunnerUtils.closeTestWindow(); }, 30000); + /** + * Wait for asynchronous inspection to publish both the diagnostic and its visible status. + * @param {string} fileName Current fixture name, used in failure messages. + * @param {boolean} hasConflict Whether the preferences conflict should be reported. + * @return {Promise} + */ + async function _waitForPreferenceInspection(fileName, hasConflict) { + // Inspectors may take up to asyncTimeout; the default two-second UI wait can + // expire while valid filesystem-backed inspection is still running on CI. + const timeout = PreferencesManager.getExtensionPrefs("linting").get("asyncTimeout") + 5000; + await awaitsFor(()=>{ + const $indicator = testWindow.$("#status-inspection"); + const conflictShown = testWindow.$("#problems-panel").text() + .includes(Strings.ERROR_PREFS_PROJECT_LINT_MESSAGE); + const iconMatches = hasConflict + ? $indicator.is(".inspection-errors, .inspection-repair") + : $indicator.hasClass("inspection-valid"); + return $indicator.is(":visible") && iconMatches && conflictShown === hasConflict; + }, "inspection diagnostic and visible status for " + fileName, timeout); + } + async function _verifySinglePreference(fileName, expectedSpaceUnits) { const projectWithoutSettings = SpecRunnerUtils.getTestPath("/spec/WorkingSetView-test-files"), FileViewController = testWindow.brackets.test.FileViewController; @@ -156,36 +177,17 @@ define(function (require, exports, module) { // there will be an error in problems panel if both present await awaitsForDone(SpecRunnerUtils.openProjectFiles(".phcode.json")); - // Keep the visual assertion: another provider can offer a fix, which changes - // the warning icon to a repair icon while the preference conflict still exists. - await awaitsFor(()=>{ - return testWindow.$("#status-inspection").is(":visible") && - testWindow.$("#status-inspection").is(".inspection-errors, .inspection-repair"); - }, "visible problem indicator on .phcode.json"); if (!testWindow.$("#problems-panel").is(":visible")) { CommandManager.execute(Commands.VIEW_TOGGLE_PROBLEMS); } - await awaitsFor(()=>{ - return testWindow.$("#problems-panel").text().includes(Strings.ERROR_PREFS_PROJECT_LINT_MESSAGE); - }, "problem panel on .phcode.json"); + await _waitForPreferenceInspection(".phcode.json", true); await awaitsForDone(SpecRunnerUtils.openProjectFiles("test.json")); - await awaitsFor(()=>{ - return !testWindow.$("#problems-panel").text().includes(Strings.ERROR_PREFS_PROJECT_LINT_MESSAGE); - }, "no preference conflict for normal test.json file"); - await awaitsFor(()=>{ - return testWindow.$("#status-inspection").is(".inspection-valid:visible"); - }, "valid inspection indicator for normal test.json file"); + await _waitForPreferenceInspection("test.json", false); await awaitsForDone(SpecRunnerUtils.openProjectFiles(".brackets.json")); - await awaitsFor(()=>{ - return testWindow.$("#problems-panel").text().includes(Strings.ERROR_PREFS_PROJECT_LINT_MESSAGE); - }, "problem panel on .brackets.json"); - await awaitsFor(()=>{ - return testWindow.$("#status-inspection").is(":visible") && - testWindow.$("#status-inspection").is(".inspection-errors, .inspection-repair"); - }, "visible problem indicator on .brackets.json"); - }); + await _waitForPreferenceInspection(".brackets.json", true); + }, 45000); it("should open .brackets.json file if it has json errors", async function () { await SpecRunnerUtils.loadProjectInTestWindow(testPathBracketsPrefsOnlyCorrupt); From 2e5989b83a34298b11b0d14547f76837e6863022 Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 1 Oct 2026 11:22:30 +0530 Subject: [PATCH 2/2] chore: update pro deps --- tracking-repos.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracking-repos.json b/tracking-repos.json index e00197b180..02c85fb6a4 100644 --- a/tracking-repos.json +++ b/tracking-repos.json @@ -1,5 +1,5 @@ { "phoenixPro": { - "commitID": "b3526cd71bf92f5ae9bd5068be259ea3e9f09781" + "commitID": "7486704f94dbfb399158791417998b8370f5ca12" } }