From 1b2555eefb2b0d47395430b6dd1d0815fe53e1a7 Mon Sep 17 00:00:00 2001 From: SkorikSergey Date: Thu, 24 Sep 2026 15:53:26 +0300 Subject: [PATCH] stabilize RecommendedExtensions test --- .../RecommendedExtensions.spec.ts | 18 +++++++++++-- .../e2e/tests-library/ProjectAndFileTests.ts | 26 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/tests/e2e/specs/dashboard-samples/RecommendedExtensions.spec.ts b/tests/e2e/specs/dashboard-samples/RecommendedExtensions.spec.ts index fe052148287..df29c599ad4 100644 --- a/tests/e2e/specs/dashboard-samples/RecommendedExtensions.spec.ts +++ b/tests/e2e/specs/dashboard-samples/RecommendedExtensions.spec.ts @@ -205,8 +205,16 @@ async function getVisibleFilteredItemsAndCompareWithRecommended(recommendations: Logger.debug(`Found authors: ${allFoundRecommendedAuthors.join(', ')}`); Logger.debug(`Expected authors: ${recommendations.join(', ')}`); - const allFoundAuthorsAsSortedString: string = allFoundRecommendedAuthors.sort().toString(); - const allPublisherNamesAsSortedString: string = recommendations.sort().toString(); + // normalize authors for comparison: UI shows display names (e.g. "Red Hat"), + // while extensions.json contains publisher IDs (e.g. "redhat") + const allFoundAuthorsAsSortedString: string = allFoundRecommendedAuthors + .map((author: string): string => author.toLowerCase().replace(/\s+/g, '')) + .sort() + .toString(); + const allPublisherNamesAsSortedString: string = recommendations + .map((name: string): string => name.toLowerCase().replace(/\s+/g, '')) + .sort() + .toString(); Logger.debug(`Sorted found authors: ${allFoundAuthorsAsSortedString}`); Logger.debug(`Sorted expected authors: ${allPublisherNamesAsSortedString}`); @@ -322,6 +330,9 @@ for (const sample of samples) { await projectAndFileTests.getProjectTreeItem(projectSection, pathToExtensionsListFileName, vsCodeFolderItemLevel) )?.select(); + // wait for the folder to expand and the file to appear in the project tree + await projectAndFileTests.waitProjectTreeItem(projectSection, extensionsListFileName, vsCodeFolderItemLevel + 1); + await ( await projectAndFileTests.getProjectTreeItem(projectSection, extensionsListFileName, vsCodeFolderItemLevel + 1) )?.select(); @@ -329,6 +340,9 @@ for (const sample of samples) { await new EditorView().openEditor(extensionsListFileName); await driverHelper.waitVisibility(webCheCodeLocators.Editor.inputArea); + // click on the editor input area to ensure it has focus before copying text + await driverHelper.waitAndClick(webCheCodeLocators.Editor.inputArea); + Logger.debug('Select and copy all text in the editor'); const text: string = await getText(); recommendedExtensions = JSON.parse(text.replace(/\/\*[\s\S]*?\*\/|(?<=[^:])\/\/.*|^\/\/.*/g, '').trim()); diff --git a/tests/e2e/tests-library/ProjectAndFileTests.ts b/tests/e2e/tests-library/ProjectAndFileTests.ts index 1538ea52222..4290cc5f6bf 100644 --- a/tests/e2e/tests-library/ProjectAndFileTests.ts +++ b/tests/e2e/tests-library/ProjectAndFileTests.ts @@ -198,6 +198,32 @@ export class ProjectAndFileTests { return projectTreeItem; } + /** + * wait for a specific item to appear in the project tree by polling. + * useful after expanding a folder to wait until its children are rendered. + * @param projectSection ViewSection with project tree files. + * @param label Label of the item to wait for. + * @param itemLevel Depth level of the item in the tree. + */ + async waitProjectTreeItem(projectSection: ViewSection, label: string, itemLevel: number = 2): Promise { + Logger.debug(`waiting for "${label}" at level ${itemLevel}`); + + const timeout: number = TIMEOUT_CONSTANTS.TS_EXPAND_PROJECT_TREE_ITEM_TIMEOUT; + const polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_DEFAULT_POLLING; + const attempts: number = Math.ceil(timeout / polling); + + for (let i: number = 0; i < attempts; i++) { + const item: ViewItem | undefined = await projectSection.findItem(label, itemLevel); + if (item) { + Logger.debug(`"${label}" found after ${i + 1} attempt(s)`); + return; + } + await this.driverHelper.wait(polling); + } + + throw new Error(`Item "${label}" not found in the project tree at level ${itemLevel} after ${timeout}ms`); + } + /** * @returns {string} Branch name of cloned repository */