Skip to content

Commit ccb99a6

Browse files
Fix the RecommendedExtensions test (#22966)
* Fix the RecommendedExtensions test
1 parent b640f5c commit ccb99a6

File tree

1 file changed

+114
-80
lines changed

1 file changed

+114
-80
lines changed

tests/e2e/specs/dashboard-samples/RecommendedExtensions.spec.ts

+114-80
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
import {
1212
ActivityBar,
13-
ContextMenu,
14-
ContextMenuItem,
1513
EditorView,
1614
ExtensionsViewItem,
1715
ExtensionsViewSection,
@@ -39,6 +37,49 @@ import { Dashboard } from '../../pageobjects/dashboard/Dashboard';
3937

4038
const samples: string[] = PLUGIN_TEST_CONSTANTS.TS_SAMPLE_LIST.split(',');
4139

40+
// get visible items from Extension view, transform this from array to sorted string and compares it with existed recommended extensions
41+
async function getVisibleFilteredItemsAndCompareWithRecommended(recommendations: string[]): Promise<boolean> {
42+
const extensionsView: SideBarView | undefined = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
43+
const [marketplaceSection]: ExtensionsViewSection[] = (await extensionsView?.getContent().getSections()) as ExtensionsViewSection[];
44+
const sections: ViewSection[] | undefined = await extensionsView?.getContent().getSections();
45+
46+
// if we have a big recommender extension list it can be overlapped by other recommendations panel,
47+
// in this case we need to collapse it for instance: it is actual for Quarkus example
48+
if (sections !== undefined) {
49+
for (let i: number = 0; i < sections.length; i++) {
50+
const currentSection: ViewSection = sections[i];
51+
const isOtherRecommendedSectionPresent: boolean = (await currentSection.getTitle()) === 'Other Recommendations';
52+
const isOtherRecommendationExpanded: boolean = await sections[i].isExpanded();
53+
if (isOtherRecommendedSectionPresent && isOtherRecommendationExpanded) {
54+
await currentSection.collapse();
55+
}
56+
}
57+
}
58+
Logger.debug('marketplaceSection.getVisibleItems()');
59+
const allFoundRecommendedItems: ExtensionsViewItem[] = await marketplaceSection.getVisibleItems();
60+
const allFoundRecommendedAuthors: string[] = await Promise.all(
61+
allFoundRecommendedItems.map(async (item: ExtensionsViewItem): Promise<string> => await item.getAuthor())
62+
);
63+
64+
const allFoundAuthorsAsSortedString: string = allFoundRecommendedAuthors.sort().toString();
65+
const allPublisherNamesAsSorString: string = recommendations.sort().toString();
66+
return allFoundAuthorsAsSortedString === allPublisherNamesAsSorString;
67+
}
68+
// get visible items from Extension view, transform this from array to sorted string and compares it with existed installed extensions
69+
async function getVisibleFilteredItemsAndCompareWithInstalled(recommendations: string[]): Promise<boolean> {
70+
const extensionsView: SideBarView | undefined = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
71+
const [marketplaceSection]: ExtensionsViewSection[] = (await extensionsView?.getContent().getSections()) as ExtensionsViewSection[];
72+
Logger.debug('marketplaceSection.getVisibleItems()');
73+
const allFoundRecommendedItems: ExtensionsViewItem[] = await marketplaceSection.getVisibleItems();
74+
const allFoundRecommendedAuthors: string[] = await Promise.all(
75+
allFoundRecommendedItems.map(async (item: ExtensionsViewItem): Promise<string> => await item.getAuthor())
76+
);
77+
78+
const allFoundAuthorsAsSortedString: string = allFoundRecommendedAuthors.sort().toString();
79+
const allPublisherNamesAsSortString: string = recommendations.sort().toString();
80+
// in some cases we can have installed not only recommended extensions with some samples (for example .Net)
81+
return allFoundAuthorsAsSortedString.includes(allPublisherNamesAsSortString);
82+
}
4283
for (const sample of samples) {
4384
suite(`Check if recommended extensions installed for ${sample} ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void {
4485
const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests);
@@ -50,16 +91,18 @@ for (const sample of samples) {
5091
const webCheCodeLocators: Locators = cheCodeLocatorLoader.webCheCodeLocators;
5192
const testWorkspaceUtil: ITestWorkspaceUtil = e2eContainer.get(TYPES.WorkspaceUtil);
5293
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
53-
5494
let projectSection: ViewSection;
5595
let extensionSection: ExtensionsViewSection;
5696
let extensionsView: SideBarView | undefined;
97+
let publisherNames: string[];
5798

5899
const [pathToExtensionsListFileName, extensionsListFileName]: string[] = ['.vscode', 'extensions.json'];
100+
59101
let recommendedExtensions: any = {
60102
recommendations: []
61103
};
62104

105+
let parsedRecommendations: Array<{ name: string; publisher: string }>;
63106
suiteSetup('Login', async function (): Promise<void> {
64107
await loginTests.loginIntoChe();
65108
});
@@ -81,6 +124,9 @@ for (const sample of samples) {
81124
});
82125

83126
test('Check the project files were imported', async function (): Promise<void> {
127+
// add TS_IDE_LOAD_TIMEOUT timeout for waiting for finishing animation of all IDE parts (Welcome parts. bottom widgets. etc.)
128+
// using TS_IDE_LOAD_TIMEOUT easier than performing of finishing animation all elements
129+
await driverHelper.wait(TIMEOUT_CONSTANTS.TS_IDE_LOAD_TIMEOUT);
84130
projectSection = await projectAndFileTests.getProjectViewSession();
85131
expect(await projectAndFileTests.getProjectTreeItem(projectSection, pathToExtensionsListFileName), 'Files not imported').not
86132
.undefined;
@@ -91,27 +137,39 @@ for (const sample of samples) {
91137
});
92138

93139
test(`Get recommended extensions list from ${extensionsListFileName}`, async function (): Promise<void> {
94-
await (await projectAndFileTests.getProjectTreeItem(projectSection, pathToExtensionsListFileName))?.select();
140+
// sometimes the Trust Dialog does not appear as expected - as result we need to execute "projectAndFileTests.performManageWorkspaceTrustBox()" method. In this case.
141+
try {
142+
await (await projectAndFileTests.getProjectTreeItem(projectSection, pathToExtensionsListFileName))?.select();
143+
} catch (err) {
144+
await projectAndFileTests.performManageWorkspaceTrustBox();
145+
await (await projectAndFileTests.getProjectTreeItem(projectSection, pathToExtensionsListFileName))?.select();
146+
}
95147
await (await projectAndFileTests.getProjectTreeItem(projectSection, extensionsListFileName, 3))?.select();
96148
Logger.debug(`EditorView().openEditor(${extensionsListFileName})`);
97149
const editor: TextEditor = (await new EditorView().openEditor(extensionsListFileName)) as TextEditor;
98150
await driverHelper.waitVisibility(webCheCodeLocators.Editor.inputArea);
99151
Logger.debug('editor.getText(): get recommended extensions as text from editor, delete comments and parse to object.');
100152
recommendedExtensions = JSON.parse((await editor.getText()).replace(/\/\*[\s\S]*?\*\/|(?<=[^:])\/\/.*|^\/\/.*/g, '').trim());
101153
Logger.debug('recommendedExtensions.recommendations: Get recommendations clear names using map().');
102-
recommendedExtensions.recommendations = recommendedExtensions.recommendations.map(
103-
(r: { split: (arg: string) => [any, any] }): { name: any; publisher: any } => {
104-
const [publisher, name] = r.split('.');
105-
return { publisher, name };
106-
}
107-
);
108-
Logger.debug(`Recommended extension for this workspace:\n${JSON.stringify(recommendedExtensions.recommendations)}.`);
109-
expect(recommendedExtensions.recommendations, 'Recommendations not found').not.empty;
154+
parsedRecommendations = recommendedExtensions.recommendations.map((rec: string): { name: string; publisher: string } => {
155+
const [publisher, name] = rec.split('.');
156+
return { publisher, name };
157+
});
158+
Logger.debug(`Recommended extension for this workspace:\n${JSON.stringify(parsedRecommendations)}.`);
159+
160+
publisherNames = parsedRecommendations.map((rec: { name: string; publisher: string }): string => rec.publisher);
161+
expect(parsedRecommendations, 'Recommendations not found').not.empty;
110162
});
111163

112164
test('Open "Extensions" view section', async function (): Promise<void> {
113165
Logger.debug('ActivityBar().getViewControl("Extensions"))?.openView(): open Extensions view.');
114-
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
166+
// sometimes the Trust Dialog does not appear as expected - as result we need to execute "projectAndFileTests.performManageWorkspaceTrustBox()" method. In this case.
167+
try {
168+
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
169+
} catch (err) {
170+
await projectAndFileTests.performManageWorkspaceTrustBox();
171+
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
172+
}
115173
expect(extensionsView, 'Can`t find Extension section').not.undefined;
116174
});
117175

@@ -125,7 +183,7 @@ for (const sample of samples) {
125183

126184
test('Check if extensions are installed and enabled', async function (): Promise<void> {
127185
// timeout 15 seconds per extensions
128-
this.timeout(TIMEOUT_CONSTANTS.TS_FIND_EXTENSION_TEST_TIMEOUT * recommendedExtensions.recommendations.length);
186+
this.timeout(TIMEOUT_CONSTANTS.TS_FIND_EXTENSION_TEST_TIMEOUT * parsedRecommendations.length);
129187
Logger.debug('ActivityBar().getViewControl("Extensions"))?.openView(): open Extensions view.');
130188
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
131189

@@ -137,75 +195,51 @@ for (const sample of samples) {
137195
TIMEOUT_CONSTANTS.TS_EDITOR_TAB_INTERACTION_TIMEOUT
138196
);
139197

140-
for (const extension of recommendedExtensions.recommendations) {
141-
Logger.debug(`extensionSection.findItem(${extension.name}).`);
142-
await extensionSection.findItem(extension.name);
198+
Logger.debug('extensionSection.findItem by @recommended filter');
199+
try {
200+
await extensionSection.findItem('@recommended');
201+
} catch (err) {
202+
await driverHelper.wait(TIMEOUT_CONSTANTS.TS_EXPAND_PROJECT_TREE_ITEM_TIMEOUT);
203+
await extensionSection.findItem('@recommended');
204+
}
205+
const isReloadRequired: boolean = await driverHelper.isVisible(
206+
(webCheCodeLocators.ExtensionsViewSection as any).requireReloadButton
207+
);
208+
Logger.debug(`Is extensions require reload the editor: ${isReloadRequired}`);
143209

144-
const isReloadRequired: boolean = await driverHelper.isVisible(
145-
(webCheCodeLocators.ExtensionsViewSection as any).requireReloadButton
210+
if (isReloadRequired) {
211+
Logger.debug('Refreshing the page..');
212+
await browserTabsUtil.refreshPage();
213+
await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
214+
await driverHelper.waitVisibility(
215+
webCheCodeLocators.ActivityBar.viewContainer,
216+
TIMEOUT_CONSTANTS.TS_EDITOR_TAB_INTERACTION_TIMEOUT
146217
);
147-
Logger.debug(`Is extensions require reload the editor: ${isReloadRequired}`);
148-
149-
if (isReloadRequired) {
150-
Logger.debug('Refreshing the page..');
151-
await browserTabsUtil.refreshPage();
152-
await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
153-
await driverHelper.waitVisibility(
154-
webCheCodeLocators.ActivityBar.viewContainer,
155-
TIMEOUT_CONSTANTS.TS_EDITOR_TAB_INTERACTION_TIMEOUT
156-
);
157-
Logger.debug('ActivityBar().getViewControl("Extensions"))?.openView(): reopen Extensions view.');
158-
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
159-
await driverHelper.waitVisibility(
160-
webCheCodeLocators.ExtensionsViewSection.itemTitle,
161-
TIMEOUT_CONSTANTS.TS_EDITOR_TAB_INTERACTION_TIMEOUT
162-
);
163-
expect(extensionsView, 'Can`t find Extension View section').not.undefined;
164-
[extensionSection] = (await extensionsView?.getContent().getSections()) as ExtensionsViewSection[];
165-
expect(extensionSection, 'Can`t find Extension section').not.undefined;
166-
Logger.debug(`extensionSection.findItem(${extension.name}).`);
167-
await extensionSection.findItem(extension.name);
168-
}
169-
170-
Logger.debug('extensionsView.getContent().getSections(): switch to marketplace section.');
171-
const [marketplaceSection]: ExtensionsViewSection[] = (await extensionsView
172-
?.getContent()
173-
.getSections()) as ExtensionsViewSection[];
174-
175-
Logger.debug('marketplaceSection.getVisibleItems()');
176-
const allFinedItems: ExtensionsViewItem[] = await marketplaceSection.getVisibleItems();
177-
expect(allFinedItems, 'Extensions not found').not.empty;
178-
let itemWithRightNameAndPublisher: ExtensionsViewItem | undefined = undefined;
179-
for (const item of allFinedItems) {
180-
Logger.debug(`Try to find extension published by ${extension.publisher}.`);
181-
if ((await item.getAuthor()) === extension.publisher) {
182-
itemWithRightNameAndPublisher = item;
183-
Logger.debug(`Extension was found: ${await itemWithRightNameAndPublisher?.getTitle()}`);
184-
break;
185-
}
186-
expect(itemWithRightNameAndPublisher, `Extension ${extension.name} not found`).not.undefined;
187-
}
188-
189-
Logger.debug('itemWithRightNameAndPublisher?.isInstalled()');
190-
const isInstalled: boolean = (await itemWithRightNameAndPublisher?.isInstalled()) as boolean;
191-
192-
Logger.debug(`itemWithRightNameAndPublisher?.isInstalled(): ${isInstalled}.`);
193-
expect(isInstalled, `Extension ${extension.name} not installed`).to.be.true;
194-
195-
Logger.debug('itemWithRightNameAndPublisher.manage(): get context menu.');
196-
const extensionManageMenu: ContextMenu = await (itemWithRightNameAndPublisher as ExtensionsViewItem).manage();
197-
198-
Logger.debug('extensionManageMenu.getItems(): get menu items.');
199-
const extensionMenuItems: ContextMenuItem[] = await extensionManageMenu.getItems();
200-
let extensionMenuItemLabels: string = '';
201-
Logger.trace('extensionMenuItems -> item.getLabel(): get menu items names.');
202-
for (const item of extensionMenuItems) {
203-
extensionMenuItemLabels += (await item.getLabel()) + ' ';
204-
}
205-
206-
Logger.debug(`extensionMenuItemLabels: ${extensionMenuItemLabels}.`);
207-
expect(extensionMenuItemLabels, `Extension ${extension.name} not enabled`).contains('Disable').and.not.contains('Enable');
218+
Logger.debug('ActivityBar().getViewControl("Extensions"))?.openView(): reopen Extensions view.');
219+
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
220+
await driverHelper.waitVisibility(
221+
webCheCodeLocators.ExtensionsViewSection.itemTitle,
222+
TIMEOUT_CONSTANTS.TS_EDITOR_TAB_INTERACTION_TIMEOUT
223+
);
224+
expect(extensionsView, 'Can`t find Extension View section').not.undefined;
225+
[extensionSection] = (await extensionsView?.getContent().getSections()) as ExtensionsViewSection[];
226+
expect(extensionSection, 'Can`t find Extension section').not.undefined;
227+
await extensionSection.findItem('@recommended ');
228+
}
229+
230+
Logger.debug('extensionSection.findItem by @recommended filter');
231+
expect(await getVisibleFilteredItemsAndCompareWithRecommended(publisherNames)).to.be.true;
232+
Logger.debug(`All recommended extensions were found by @recommended filter: ---- ${publisherNames} ----`);
233+
234+
Logger.debug('extensionSection.findItem by @installed filter');
235+
try {
236+
await extensionSection.findItem('@installed ');
237+
} catch (err) {
238+
await driverHelper.wait(TIMEOUT_CONSTANTS.TS_EXPAND_PROJECT_TREE_ITEM_TIMEOUT);
239+
await extensionSection.findItem('@installed ');
208240
}
241+
expect(await getVisibleFilteredItemsAndCompareWithInstalled(publisherNames)).to.be.true;
242+
Logger.debug(`All recommended extensions were found by @installed filter: ---- ${publisherNames} ----`);
209243
});
210244

211245
suiteTeardown('Open dashboard and close all other tabs', async function (): Promise<void> {

0 commit comments

Comments
 (0)