Skip to content

Commit 85998ef

Browse files
authored
Overhaul Menu E2E tests with better errors, refactored test code (#2447)
* Refactor Menu tests with new testing methods * Change files * Modify errors for menu tests, add better comments * Remove instances of '->' in test names * Adjust unset accessibilityRole test names * Use === for string comparison in onClick() test * Add waitForMenuToClose() method
1 parent f3068db commit 85998ef

File tree

3 files changed

+132
-122
lines changed

3 files changed

+132
-122
lines changed

apps/E2E/src/Menu/pages/MenuPageObject.ts

Lines changed: 51 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,20 @@ import {
44
MENUITEM_NO_A11Y_LABEL_COMPONENT,
55
HOMEPAGE_MENU_BUTTON,
66
MENUITEM_TEST_COMPONENT,
7-
MENUPOPOVER_TEST_COMPONENT,
87
MENUITEM_DISABLED_COMPONENT,
98
MENUITEM_FOURTH_COMPONENT,
109
MENU_CALLBACK_RESET_BUTTON,
1110
MENUITEM_CALLBACK_LABEL,
1211
} from '../consts';
1312
import { BasePage, By } from '../../common/BasePage';
14-
import { Keys, Attribute, AttributeValue } from '../../common/consts';
15-
16-
/* This enum gives the spec file an EASY way to interact with SPECIFIC UI elements on the page.
17-
* The spec file should import this enum and use it when wanting to interact with different elements on the page. */
18-
export const enum MenuComponentSelector {
19-
MenuTrigger = 0, //this._primaryComponent
20-
FirstMenuItem,
21-
SecondMenuItem,
22-
ThirdMenuItem,
23-
FourthMenuItem,
13+
import { Keys } from '../../common/consts';
14+
15+
/** Allows a caller to get specific menu items using .getMenuItem() */
16+
export const enum MenuItem {
17+
First,
18+
Second,
19+
Third,
20+
Fourth,
2421
}
2522

2623
class MenuPageObject extends BasePage {
@@ -35,32 +32,51 @@ class MenuPageObject extends BasePage {
3532
*/
3633
async openMenu(): Promise<void> {
3734
if (!(await this.menuIsExpanded())) {
38-
await this.clickItem(MenuComponentSelector.MenuTrigger);
35+
await this.click(this._menuTrigger);
3936
await this.waitForMenuToOpen();
4037
}
4138
}
4239

4340
async closeMenu(): Promise<void> {
4441
if (await this.menuIsExpanded()) {
45-
await this.sendKey(MenuComponentSelector.FirstMenuItem, Keys.ESCAPE);
46-
await this.waitForCondition(async () => (await this.menuIsExpanded()) === false, 'The Menu did not close.', this.waitForUiEvent, 500);
42+
await this.sendKeys(this.getMenuItem(MenuItem.First), [Keys.ESCAPE]);
43+
await this.waitForMenuToClose();
4744
}
4845
}
4946

50-
async waitForMenuToOpen(): Promise<boolean> {
51-
await this.waitForCondition(async () => await this.menuIsExpanded(), 'The Menu did not open.', this.waitForUiEvent, 500);
47+
/* Waits for menuitems to be visible. This is a separate method from openMenu() because we test multiple ways of opening the menu (mouse + keyboard). */
48+
async waitForMenuToOpen(errorMsg?: string): Promise<boolean> {
49+
await this.waitForCondition(
50+
async () => await this.menuIsExpanded(),
51+
errorMsg ?? 'The Menu did not open: It looks like the MenuItems failed to display.',
52+
this.waitForUiEvent,
53+
500,
54+
);
5255
return await this.menuIsExpanded();
5356
}
5457

58+
/* Same as above -> Just waits for menuitems to not be visible. */
59+
async waitForMenuToClose(errorMsg?: string): Promise<boolean> {
60+
await this.waitForCondition(
61+
async () => !(await this.menuIsExpanded()),
62+
errorMsg ?? 'The Menu did not close: It looks like the MenuItems are still displayed.',
63+
this.waitForUiEvent,
64+
500,
65+
);
66+
return !(await this.menuIsExpanded());
67+
}
68+
69+
/* If the first item is displayed, then it's safe to say that the rest of the menu is expanded. */
5570
async menuIsExpanded(): Promise<boolean> {
56-
const menuItem = await this._firstMenuItem;
71+
const menuItem = await this.getMenuItem(MenuItem.First);
5772
if (menuItem.error) {
5873
// Not displayed because the item can't be found by appium
5974
return false;
6075
}
6176
return await menuItem.isDisplayed();
6277
}
6378

79+
/* Waits for the onClick callback of menu item 1 to fire. */
6480
async waitForItemCallbackToFire(timesFired: number): Promise<void> {
6581
await this.waitForCondition(
6682
async () => await this.itemOnClickHasFired(timesFired),
@@ -70,57 +86,27 @@ class MenuPageObject extends BasePage {
7086
);
7187
}
7288

89+
/* When menu item 1 is clicked, it increments a counter variable in the test component page, which is displayed in a text box. Incrementing a counter within a label
90+
* allows us to test whether the onClick() callback fires for click and keypress inputs across individual test cases without having to close the menu and reset the
91+
* label per case (as you see in the button + checkbox tests). This decreases test time and improves performance for this spec. */
7392
async itemOnClickHasFired(timesFired: number): Promise<boolean> {
74-
return (await (await this._callbackLabel).getText()).includes(timesFired.toString());
75-
}
76-
77-
async componentIsFocused(selector: MenuComponentSelector): Promise<boolean> {
78-
const component = await this.getMenuComponentSelector(selector);
79-
return (await this.getElementAttribute(component, Attribute.IsFocused)) === AttributeValue.true;
80-
}
81-
82-
async getMenuExpandCollapseState(): Promise<AttributeValue> {
83-
return (await this.getElementAttribute(await this._primaryComponent, Attribute.ExpandCollapseState)) as AttributeValue;
84-
}
85-
86-
async getMenuItemAccessibilityLabel(componentSelector: MenuComponentSelector): Promise<string> {
87-
return await this.getElementAttribute(await this.getMenuComponentSelector(componentSelector), Attribute.AccessibilityLabel);
88-
}
89-
90-
async getMenuAccessibilityRole(): Promise<string> {
91-
return await this.getElementAttribute(await By(MENUPOPOVER_TEST_COMPONENT), Attribute.AccessibilityRole);
92-
}
93-
94-
async getMenuItemAccessibilityRole(): Promise<string> {
95-
return await this.getElementAttribute(await this._firstMenuItem, Attribute.AccessibilityRole);
96-
}
97-
98-
/* Sends a Keyboarding command on a specific UI element */
99-
async sendKey(menuComponentSelector: MenuComponentSelector, key: string): Promise<void> {
100-
await (await this.getMenuComponentSelector(menuComponentSelector)).addValue(key);
101-
}
102-
103-
// Renaming this function until Menu tests are refactored to use BasePage methods.
104-
async clickItem(selector: MenuComponentSelector): Promise<void> {
105-
await (await this.getMenuComponentSelector(selector)).click();
106-
}
107-
108-
/* Returns the correct WebDriverIO element from the Button Selector */
109-
async getMenuComponentSelector(menuComponentSelector: MenuComponentSelector): Promise<WebdriverIO.Element> {
110-
switch (menuComponentSelector) {
111-
case MenuComponentSelector.MenuTrigger:
112-
return await this._primaryComponent;
113-
case MenuComponentSelector.FirstMenuItem:
114-
return await this._firstMenuItem;
115-
case MenuComponentSelector.SecondMenuItem:
116-
return await this._secondMenuItem;
117-
case MenuComponentSelector.ThirdMenuItem:
118-
return await this._thirdMenuItem;
119-
case MenuComponentSelector.FourthMenuItem:
120-
return await this._fourthMenuItem;
93+
return (await (await this._callbackLabel).getText()) === `onClick fired ${timesFired} times`;
94+
}
95+
96+
async getMenuItem(item: MenuItem): Promise<WebdriverIO.Element> {
97+
switch (item) {
98+
case MenuItem.First:
99+
return await By(MENUITEM_TEST_COMPONENT);
100+
case MenuItem.Second:
101+
return await By(MENUITEM_DISABLED_COMPONENT);
102+
case MenuItem.Third:
103+
return await By(MENUITEM_NO_A11Y_LABEL_COMPONENT);
104+
case MenuItem.Fourth:
105+
return await By(MENUITEM_FOURTH_COMPONENT);
121106
}
122107
}
123108

109+
/* Closes the menu and resets the counter to 0 on the test page. */
124110
async resetTest() {
125111
// Both escape on the menu trigger to hard dismiss menu and click callback reset to reset focus
126112
await this.closeMenu();
@@ -138,26 +124,10 @@ class MenuPageObject extends BasePage {
138124
return MENU_TESTPAGE;
139125
}
140126

141-
get _primaryComponent() {
127+
get _menuTrigger() {
142128
return By(MENUTRIGGER_TEST_COMPONENT);
143129
}
144130

145-
get _firstMenuItem() {
146-
return By(MENUITEM_TEST_COMPONENT);
147-
}
148-
149-
get _secondMenuItem() {
150-
return By(MENUITEM_DISABLED_COMPONENT);
151-
}
152-
153-
get _thirdMenuItem() {
154-
return By(MENUITEM_NO_A11Y_LABEL_COMPONENT);
155-
}
156-
157-
get _fourthMenuItem() {
158-
return By(MENUITEM_FOURTH_COMPONENT);
159-
}
160-
161131
get _pageButton() {
162132
return By(HOMEPAGE_MENU_BUTTON);
163133
}

0 commit comments

Comments
 (0)