Skip to content

Commit f1e868c

Browse files
authored
Merge pull request #7156 from microting/copilot/migrate-navigation-menu-tests
Migrate Navigation Menu Tests from WebDriverIO to Cypress
2 parents 7f2a974 + f33f889 commit f1e868c

File tree

7 files changed

+874
-13
lines changed

7 files changed

+874
-13
lines changed

WDIO_TO_CYPRESS_MIGRATION.md

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ This document tracks the migration of WebDriverIO (wdio) e2e tests to Cypress te
77
## Current Status
88

99
- **Total wdio tests**: 38
10-
- **Cypress tests implemented**: 27
11-
- **Tests remaining to migrate**: 23
10+
- **Cypress tests implemented**: 31
11+
- **Tests remaining to migrate**: 19
1212

1313
## Tests Already Migrated to Cypress ✓
1414

@@ -30,6 +30,10 @@ The following wdio tests have been successfully migrated to Cypress:
3030

3131
### Navigation Menu
3232
- ✓ subheader.spec.ts (cypress/e2e/c/)
33+
- ✓ navigation-menu.create-item.spec.ts (cypress/e2e/c/)
34+
- ✓ navigation-menu.edit-item.spec.ts (cypress/e2e/c/)
35+
- ✓ navigation-menu.delete-item.spec.ts (cypress/e2e/c/)
36+
- ✓ navigation-menu.drag-item.spec.ts (cypress/e2e/c/)
3337

3438
### eForm Visual Editor
3539
- ✓ eform-visual-editor.edit-eform.spec.ts (cypress/e2e/j/)
@@ -127,20 +131,28 @@ Tests to migrate:
127131

128132
---
129133

130-
### 6. Navigation Menu (4 tests)
134+
### 6. Navigation Menu (4 tests)
131135

132136
**Category**: Navigation Menu Management
133137
**Priority**: Medium
134-
**Location**: e2e/Tests/navigation-menu/
138+
**Location**: e2e/Tests/navigation-menu/
139+
**Migrated to**: cypress/e2e/c/
135140

136-
Tests to migrate:
137-
- [ ] navigation-menu.create-item.spec.ts
138-
- [ ] navigation-menu.delete-item.spec.ts
139-
- [ ] navigation-menu.drag-item.spec.ts
140-
- [ ] navigation-menu.edit-item.spec.ts
141+
Tests migrated:
142+
- navigation-menu.create-item.spec.cy.ts
143+
- navigation-menu.delete-item.spec.cy.ts
144+
- navigation-menu.drag-item.spec.cy.ts
145+
- navigation-menu.edit-item.spec.cy.ts
141146

142147
**Description**: Tests for customizing and managing navigation menu items including drag-and-drop reordering.
143148

149+
**Key Functionality**:
150+
- Creating menu items from templates
151+
- Creating custom links and dropdowns
152+
- Editing menu item properties (translations, links, security groups)
153+
- Deleting menu items and dropdown items
154+
- Drag-and-drop reordering of menu items
155+
144156
**Note**: subheader.spec.ts is already migrated in cypress/e2e/c/
145157

146158
---
@@ -337,15 +349,15 @@ Use this section to track overall migration progress:
337349
- [ ] eForm Visual Editor - Create (1 test)
338350
- [ ] Folders - Folder Tree (3 tests)
339351
- [ ] Folders - Folder Child (3 tests)
340-
- [ ] Navigation Menu (4 tests)
352+
- [x] Navigation Menu (4 tests)
341353
- [x] Password Settings (1 test) ✓
342354
- [ ] Profile Settings (1 test)
343355
- [ ] Searchable Lists (3 tests)
344356
- [ ] Selectable Lists (4 tests)
345357
- [x] User Administration (1 test) ✓
346358
- [ ] Workers (2 tests)
347359

348-
**Total Progress**: 5/28 tests migrated (17.9%)
360+
**Total Progress**: 12/28 tests migrated (42.9%)
349361

350362
## Notes
351363

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
export class NavigationMenuPage {
2+
// Menu Editor Navigation
3+
public goToMenuEditor() {
4+
cy.get('#sign-out-dropdown').click();
5+
cy.get('#menu-editor').click();
6+
cy.wait(500);
7+
}
8+
9+
// Template controls
10+
public collapseTemplates(index: number) {
11+
cy.get('#menuTemplate').eq(index).find('.mat-expansion-indicator').click();
12+
cy.wait(2000); // Wait for menu to open/close
13+
}
14+
15+
// Menu Items
16+
public getMenuItems() {
17+
return cy.get('#menuItems');
18+
}
19+
20+
public getMenuItemsCount() {
21+
return cy.get('#menuItems').its('length');
22+
}
23+
24+
// Create operations
25+
public createMenuItemFromTemplate(templateIndex: number) {
26+
const dragHandle = cy.get(`#dragHandle0_${templateIndex}`);
27+
const target = cy.get('mat-card > mat-accordion').first();
28+
29+
dragHandle.trigger('mousedown', { which: 1 });
30+
target.trigger('mousemove', 'top').trigger('mouseup', { force: true });
31+
}
32+
33+
public createCustomLink(data: { securityGroups?: string[]; link: string; translations: string[] }) {
34+
cy.get('#addCustomLink').click();
35+
cy.get('#customLinkCreateBtn').should('be.visible');
36+
37+
if (data.securityGroups && data.securityGroups.length > 0) {
38+
data.securityGroups.forEach(group => {
39+
this.setSecurityGroupCustomDropdownSelector(group);
40+
});
41+
}
42+
43+
cy.get('#customLinkLink').clear().type(data.link);
44+
45+
data.translations.forEach((translation, index) => {
46+
if (translation) {
47+
cy.get(`#linkTranslation${index}`).clear().type(translation);
48+
}
49+
});
50+
51+
cy.get('#customLinkCreateBtn').scrollIntoView().click();
52+
}
53+
54+
public createCustomDropdown(data: { securityGroups?: string[]; translations: string[] }) {
55+
cy.get('#addCustomDropdown').click();
56+
cy.get('#customDropdownCreateBtn').should('be.visible');
57+
58+
if (data.securityGroups && data.securityGroups.length > 0) {
59+
data.securityGroups.forEach(group => {
60+
this.setSecurityGroupCustomDropdownSelector(group);
61+
});
62+
}
63+
64+
data.translations.forEach((translation, index) => {
65+
if (translation) {
66+
cy.get(`#dropdownTranslation${index}`).clear().type(translation);
67+
}
68+
});
69+
70+
cy.get('#customDropdownCreateBtn').scrollIntoView().click();
71+
}
72+
73+
// Edit operations
74+
public openEditMenuItem(index: number) {
75+
cy.get('#menuItems').eq(index).find('#editBtn').click();
76+
cy.get('#editItemSaveBtn').should('be.visible');
77+
}
78+
79+
public editLinkInput(value: string) {
80+
cy.get('#editLinkInput').clear().type(value);
81+
}
82+
83+
public editItemTranslation(firstLevel: number, secondLevel: number, translationIndex: number, value: string) {
84+
cy.get(`#editItemTranslation${firstLevel}_${secondLevel}_${translationIndex}`)
85+
.clear()
86+
.type(value);
87+
}
88+
89+
public editItemSave() {
90+
cy.get('#editItemSaveBtn').click();
91+
}
92+
93+
public editCustomLink(data: { securityGroups?: string[]; link: string; translations: string[] }, index: number) {
94+
this.openEditMenuItem(index);
95+
96+
if (data.securityGroups && data.securityGroups.length > 0) {
97+
this.editSecurityGroupsValue(data.securityGroups);
98+
}
99+
100+
if (data.link) {
101+
cy.get('#editLinkInput').clear().type(data.link);
102+
}
103+
104+
data.translations.forEach((translation, index) => {
105+
if (translation) {
106+
cy.get(`#editItemTranslation${index}_0_${data.translations.indexOf(translation)}`)
107+
.clear()
108+
.type(translation);
109+
}
110+
});
111+
112+
this.editItemSave();
113+
}
114+
115+
public editCustomDropdown(data: { securityGroups?: string[]; translations: string[] }, index: number) {
116+
this.openEditMenuItem(index);
117+
118+
if (data.securityGroups && data.securityGroups.length > 0) {
119+
this.editSecurityGroupsValue(data.securityGroups);
120+
}
121+
122+
data.translations.forEach((translation, idx) => {
123+
if (translation) {
124+
cy.get(`#editItemTranslation${index}_0_${idx}`)
125+
.clear()
126+
.type(translation);
127+
}
128+
});
129+
130+
this.editItemSave();
131+
}
132+
133+
public editTemplateItem(data: { link?: string; translations: string[] }, index: number) {
134+
this.openEditMenuItem(index);
135+
136+
if (data.link) {
137+
cy.get('#editLinkInput').clear().type(data.link);
138+
}
139+
140+
data.translations.forEach((translation, idx) => {
141+
if (translation) {
142+
cy.get(`#editItemTranslation${index}_0_${idx}`)
143+
.clear()
144+
.type(translation);
145+
}
146+
});
147+
148+
this.editItemSave();
149+
cy.wait(500);
150+
this.clickSaveMenuBtn();
151+
}
152+
153+
// Delete operations
154+
public deleteElementFromMenuItems(index: number) {
155+
cy.get('#menuItems').eq(index).find('#deleteBtn').scrollIntoView().click();
156+
cy.wait(500);
157+
cy.get('#menuItemDeleteBtn').should('be.visible').click();
158+
}
159+
160+
public deleteElementFromDropdown(dropdownIndex: number, itemIndex: number) {
161+
cy.get('#menuItems').eq(dropdownIndex)
162+
.find('#dropdownBody>*').eq(itemIndex)
163+
.find('#deleteBtn').scrollIntoView().click();
164+
cy.wait(500);
165+
cy.get('#menuItemDeleteBtn').should('be.visible').click();
166+
cy.wait(500);
167+
this.collapseMenuItemDropdown(dropdownIndex);
168+
cy.wait(500);
169+
}
170+
171+
// Dropdown operations
172+
public collapseMenuItemDropdown(index: number) {
173+
cy.get('#menuItems').eq(index).find('.mat-expansion-indicator').click();
174+
}
175+
176+
public getDropdownBodyChilds(dropdownIndex: number) {
177+
return cy.get('#menuItems').eq(dropdownIndex).find('#dropdownBody>*');
178+
}
179+
180+
public dragTemplateOnElementInCreatedDropdown(templateIndex: number, dropdownIndex: number) {
181+
this.collapseTemplates(0);
182+
183+
const dragHandle = cy.get(`#dragHandle0_${templateIndex}`);
184+
const dropdownBody = cy.get('#menuItems').eq(dropdownIndex).find('#dropdownBody');
185+
186+
dragHandle.trigger('mousedown', { which: 1 });
187+
dropdownBody.trigger('mousemove').trigger('mouseup', { force: true });
188+
189+
cy.wait(500);
190+
this.collapseTemplates(0);
191+
}
192+
193+
public editTranslationsOnDropdownBodyChilds(data: {
194+
indexChildDropdown: number;
195+
indexDropdownInMenu: number;
196+
translations_array: string[];
197+
}) {
198+
cy.get('#menuItems').eq(data.indexDropdownInMenu)
199+
.find('#dropdownBody>*').eq(data.indexChildDropdown)
200+
.find('#editBtn').click();
201+
202+
cy.get('#editItemSaveBtn').should('be.visible');
203+
204+
data.translations_array.forEach((translation, idx) => {
205+
cy.get(`#editItemTranslation${data.indexDropdownInMenu}_${data.indexChildDropdown}_${idx}`)
206+
.clear()
207+
.type(translation);
208+
});
209+
210+
this.editItemSave();
211+
cy.wait(500);
212+
}
213+
214+
public dragAndDropElementOfDropdown(dropdownIndex: number, fromIndex: number, toIndex: number) {
215+
const fromHandle = cy.get(`#drag_handle${dropdownIndex}_${fromIndex}`);
216+
const toHandle = cy.get(`#drag_handle${dropdownIndex}_${toIndex}`);
217+
218+
fromHandle.scrollIntoView();
219+
cy.wait(2000);
220+
221+
fromHandle.trigger('mousedown', { which: 1, force: true });
222+
toHandle.trigger('mousemove', { force: true });
223+
toHandle.trigger('mouseup', { force: true });
224+
cy.wait(2000);
225+
}
226+
227+
// Security groups
228+
public setSecurityGroupCustomDropdownSelector(groupName: string) {
229+
cy.get('#securityGroupsCustomDropdownSelector').click();
230+
cy.wait(500);
231+
cy.contains('.ng-option', groupName).click();
232+
cy.wait(500);
233+
}
234+
235+
public editSecurityGroupsValue(groups: string[]) {
236+
// Clear existing security groups
237+
cy.get('#editSecurityGroupsSelector').find('.ng-value span').each($el => {
238+
cy.wrap($el).click();
239+
});
240+
241+
// Add new security groups
242+
groups.forEach(group => {
243+
cy.get('#editSecurityGroupsSelector').click();
244+
cy.wait(500);
245+
cy.contains('.ng-option', group).click();
246+
cy.wait(500);
247+
});
248+
}
249+
250+
public getSecurityGroupsValue() {
251+
return cy.get('#editSecurityGroupsSelector').find('.ng-value-label');
252+
}
253+
254+
// Save and Reset
255+
public clickSaveMenuBtn() {
256+
cy.get('#navigationMenuSaveBtn').scrollIntoView().click();
257+
this.waitForSpinnerHide();
258+
}
259+
260+
public resetMenu() {
261+
cy.wait(1100);
262+
cy.wait(1200);
263+
cy.wait(1400);
264+
cy.get('#resetBtn').scrollIntoView().click();
265+
cy.wait(500);
266+
cy.get('#deleteWorkerDeleteBtn').should('be.visible').click();
267+
this.waitForSpinnerHide();
268+
cy.wait(500);
269+
}
270+
271+
// Helper methods
272+
public waitForSpinnerHide() {
273+
cy.get('#spinner-animation', { timeout: 90000 }).should('not.exist');
274+
}
275+
}
276+
277+
const navigationMenuPage = new NavigationMenuPage();
278+
export default navigationMenuPage;

0 commit comments

Comments
 (0)