Skip to content

Commit 856ff86

Browse files
authored
Overhaul ContextualMenu, Link, and LinkV1 tests with better errors and refactored spec code (#2425)
* Overhaul ContextualMenu E2E tests * More changes to ContextualMenu E2E * Overhaul both link E2E tests * Fix wrong import + some nits * Clarifying an error * Refine test names for link * Change files * Forgot .toBeTrue() at the end of accessibility test expects * Add comments to ContextualMenu PO * Nits fixed * Reword errors for ContextualMenu test * Fix comment typos for Link + ExperimentalLink * Add ENTER press test + cleaner code * Fix close() error message * Remove instances of -> in test names * Fix nit
1 parent a4b4fb9 commit 856ff86

File tree

6 files changed

+86
-66
lines changed

6 files changed

+86
-66
lines changed

apps/E2E/src/ContextualMenu/pages/ContextualMenuPageObject.win.ts

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,31 @@ import {
55
CONTEXTUALMENUITEM_TEST_COMPONENT,
66
} from '../consts';
77
import { BasePage, By } from '../../common/BasePage';
8-
9-
/* This enum gives the spec file an EASY way to interact with SPECIFIC UI elements on the page.
10-
* The spec file should import this enum and use it when wanting to interact with different elements on the page. */
11-
export const enum ContextualMenuSelector {
12-
ContextualMenu = 0, //this._primaryComponent
13-
ContextualMenuItem, //this._contextualMenuItem
14-
}
8+
import { Keys } from '../../common/consts';
159

1610
class ContextualMenuPageObject extends BasePage {
1711
/******************************************************************/
1812
/**************** UI Element Interaction Methods ******************/
1913
/******************************************************************/
20-
async waitForContextualMenuItemsToOpen(timeout?: number): Promise<void> {
21-
await browser.waitUntil(async () => await this.contextualMenuItemDisplayed(), {
22-
timeout: timeout ?? this.waitForUiEvent,
23-
timeoutMsg: 'The Contextual Menu Items did not open.',
24-
interval: 1000,
25-
});
14+
/* Waits for the MenuItems to be displayed and returns true / false whether that occurs. */
15+
async waitForContextualMenuItemsToDisplay(timeout?: number): Promise<boolean> {
16+
await this.waitForCondition(async () => this.contextualMenuItemDisplayed(), 'The Contextual Menu Items did not display.', timeout);
17+
return await this.contextualMenuItemDisplayed();
2618
}
2719

2820
/* Whether the contextual menu item is displayed or not. It should be displayed after clicking on the MenuButton */
2921
async contextualMenuItemDisplayed(): Promise<boolean> {
3022
return await (await this._contextualMenuItem).isDisplayed();
3123
}
3224

33-
/* Sends a Keyboarding command on a specific UI element */
34-
async sendKey(contextualMenuSelector: ContextualMenuSelector, key: string): Promise<void> {
35-
await (await this.getContextualMenuSelector(contextualMenuSelector)).addValue(key);
36-
}
37-
38-
/* Returns the correct WebDriverIO element from the ContextualMenuSelector string */
39-
async getContextualMenuSelector(contextualMenuSelector?: ContextualMenuSelector): Promise<WebdriverIO.Element> {
40-
if (contextualMenuSelector == ContextualMenuSelector.ContextualMenu) {
41-
return await this._primaryComponent;
42-
} else if (contextualMenuSelector == ContextualMenuSelector.ContextualMenuItem) {
43-
return await this._contextualMenuItem;
44-
} else {
45-
return await this._primaryComponent;
25+
/* Closes the ContextualMenu by sending an ESCAPE key input to the menu button */
26+
async closeContextualMenu(): Promise<void> {
27+
if (await this.contextualMenuItemDisplayed()) {
28+
await this.sendKeys(this._contextualMenuItem, [Keys.ESCAPE]);
29+
await this.waitForCondition(
30+
async () => !(await this.contextualMenuItemDisplayed()),
31+
"Pressed 'ESC' on the ContextualMenu item, but the ContextualMenu items are still displayed - the ContextMenu appears to still be open.",
32+
);
4633
}
4734
}
4835

@@ -57,7 +44,7 @@ class ContextualMenuPageObject extends BasePage {
5744
return CONTEXTUALMENU_TESTPAGE;
5845
}
5946

60-
get _primaryComponent() {
47+
get _contextualMenu() {
6148
return By(CONTEXTUALMENU_TEST_COMPONENT);
6249
}
6350

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import NavigateAppPage from '../../common/NavigateAppPage';
2-
import ContextualMenuPageObjectObject, { ContextualMenuSelector } from '../pages/ContextualMenuPageObject.win';
2+
import ContextualMenuPageObject from '../pages/ContextualMenuPageObject.win';
33
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT, Keys } from '../../common/consts';
44

55
// Before testing begins, allow up to 60 seconds for app to open
@@ -12,41 +12,50 @@ describe('ContextualMenu Testing Initialization', function () {
1212
it('Click and navigate to ContextualMenu test page', async () => {
1313
/* Click on component button to navigate to test page */
1414
await NavigateAppPage.clickAndGoToContextualMenuPage();
15-
await ContextualMenuPageObjectObject.waitForPageDisplayed(PAGE_TIMEOUT);
15+
await ContextualMenuPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
1616

17-
await expect(await ContextualMenuPageObjectObject.isPageLoaded()).toBeTruthy(ContextualMenuPageObjectObject.ERRORMESSAGE_PAGELOAD);
18-
await expect(await ContextualMenuPageObjectObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObjectObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
17+
await expect(await ContextualMenuPageObject.isPageLoaded()).toBeTruthy(ContextualMenuPageObject.ERRORMESSAGE_PAGELOAD);
18+
await expect(await ContextualMenuPageObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
1919
});
2020
});
2121

2222
describe('ContextualMenu Functional Tests', async () => {
2323
/* Scrolls and waits for the ContextualMenu to be visible on the Test Page */
2424
beforeEach(async () => {
25-
await ContextualMenuPageObjectObject.scrollToTestElement();
25+
await ContextualMenuPageObject.scrollToTestElement(await ContextualMenuPageObject._contextualMenu);
2626

27-
await ContextualMenuPageObjectObject.sendKey(ContextualMenuSelector.ContextualMenu, Keys.ESCAPE); // Reset ContextualMenu state for next test
27+
await ContextualMenuPageObject.closeContextualMenu(); // Reset ContextualMenu state for next test
2828
});
2929

30-
it('Click on ContextualMenu Button and validate that the list of ContextualMenu Items open', async () => {
30+
it('Click on ContextualMenu Button. Validate that the menu opens by checking if its items are displayed.', async () => {
3131
/* Click on the ContextualMenu */
32-
await ContextualMenuPageObjectObject.clickComponent();
33-
await ContextualMenuPageObjectObject.waitForContextualMenuItemsToOpen(PAGE_TIMEOUT);
32+
await ContextualMenuPageObject.click(ContextualMenuPageObject._contextualMenu);
3433

35-
await expect(await ContextualMenuPageObjectObject.contextualMenuItemDisplayed()).toBeTruthy();
36-
await expect(await ContextualMenuPageObjectObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObjectObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
34+
await expect(await ContextualMenuPageObject.waitForContextualMenuItemsToDisplay(PAGE_TIMEOUT)).toBeTruthy();
35+
36+
await expect(await ContextualMenuPageObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
37+
});
38+
39+
it("Type 'SPACE' on ContextualMenu Button. Validate that the menu opens by checking if its items are displayed.", async () => {
40+
/* Type "space" on the ContextualMenu */
41+
await ContextualMenuPageObject.sendKeys(ContextualMenuPageObject._contextualMenu, [Keys.SPACE]);
42+
43+
await expect(await ContextualMenuPageObject.waitForContextualMenuItemsToDisplay(PAGE_TIMEOUT)).toBeTruthy();
44+
45+
await expect(await ContextualMenuPageObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
3746
});
3847

39-
it('Type "SPACE" to select the ContextualMenu and validate that the list of ContextualMenu Items open', async () => {
40-
/* Type a space on the ContextualMenu */
41-
await ContextualMenuPageObjectObject.sendKey(ContextualMenuSelector.ContextualMenu, Keys.SPACE);
42-
await ContextualMenuPageObjectObject.waitForContextualMenuItemsToOpen(PAGE_TIMEOUT);
48+
it("Type 'ENTER' on ContextualMenu Button. Validate that the menu opens by checking if its items are displayed.", async () => {
49+
/* Type "enter" on the ContextualMenu */
50+
await ContextualMenuPageObject.sendKeys(ContextualMenuPageObject._contextualMenu, [Keys.ENTER]);
51+
52+
await expect(await ContextualMenuPageObject.waitForContextualMenuItemsToDisplay(PAGE_TIMEOUT)).toBeTruthy();
4353

44-
await expect(await ContextualMenuPageObjectObject.contextualMenuItemDisplayed()).toBeTruthy();
45-
await expect(await ContextualMenuPageObjectObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObjectObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
54+
await expect(await ContextualMenuPageObject.didAssertPopup()).toBeFalsy(ContextualMenuPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
4655
});
4756

4857
/* Runs after all tests. This ensures the ContextualMenu closes. If it stays open, the test driver won't be able to close the test app */
4958
afterAll(async () => {
50-
await ContextualMenuPageObjectObject.sendKey(ContextualMenuSelector.ContextualMenu, Keys.ESCAPE); // Reset ContextualMenu state for next test
59+
await ContextualMenuPageObject.closeContextualMenu(); // Reset ContextualMenu state for next test
5160
});
5261
});

apps/E2E/src/Link/specs/Link.spec.win.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import NavigateAppPage from '../../common/NavigateAppPage';
22
import LinkPageObject from '../pages/LinkPageObject';
3-
import { ComponentSelector } from '../../common/BasePage';
43
import { LINK_ACCESSIBILITY_LABEL } from '../consts';
5-
import { LINK_A11Y_ROLE, PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
4+
import { LINK_A11Y_ROLE, PAGE_TIMEOUT, BOOT_APP_TIMEOUT, Attribute } from '../../common/consts';
65

76
// Before testing begins, allow up to 60 seconds for app to open
87
describe('Link Testing Initialization', function () {
@@ -22,18 +21,24 @@ describe('Link Testing Initialization', function () {
2221
});
2322

2423
describe('Link Accessibility Testing', () => {
25-
it('Link - Validate accessibilityRole is correct', async () => {
24+
beforeAll(async () => {
2625
await LinkPageObject.scrollToTestElement();
26+
});
27+
28+
it('Validate "accessibilityRole" defaults to Link "ControlType" element attribute.', async () => {
29+
await expect(
30+
await LinkPageObject.compareAttribute(LinkPageObject._primaryComponent, Attribute.AccessibilityRole, LINK_A11Y_ROLE),
31+
).toBeTrue();
2732

28-
await expect(await LinkPageObject.getAccessibilityRole()).toEqual(LINK_A11Y_ROLE);
29-
await expect(await LinkPageObject.didAssertPopup()).toBeFalsy(LinkPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped u
33+
await expect(await LinkPageObject.didAssertPopup()).toBeFalsy(LinkPageObject.ERRORMESSAGE_ASSERT);
3034
});
3135

32-
it('Link - Set accessibilityLabel', async () => {
33-
await LinkPageObject.scrollToTestElement();
36+
it('Set "accessibilityLabel" prop. Validate "accessibilityLabel" propagates to "Name" element attribute.', async () => {
37+
await expect(
38+
await LinkPageObject.compareAttribute(LinkPageObject._primaryComponent, Attribute.AccessibilityLabel, LINK_ACCESSIBILITY_LABEL),
39+
).toBeTrue();
3440

35-
await expect(await LinkPageObject.getAccessibilityLabel(ComponentSelector.Primary)).toEqual(LINK_ACCESSIBILITY_LABEL);
36-
await expect(await LinkPageObject.didAssertPopup()).toBeFalsy(LinkPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped u
41+
await expect(await LinkPageObject.didAssertPopup()).toBeFalsy(LinkPageObject.ERRORMESSAGE_ASSERT);
3742
});
3843

3944
// No need to test not setting a11y label. The content prop gets passed down to the child Text component. This equates to not setting the a11y label

apps/E2E/src/LinkExperimental/specs/ExperimentalLink.spec.win.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import NavigateAppPage from '../../common/NavigateAppPage';
2-
import ExperimentalLinkPageObject from '../pages/LinkPageObject';
3-
import { ComponentSelector } from '../../common/BasePage';
2+
import ExperimentalLinkPageObject from '../pages/ExperimentalLinkPageObject';
43
import { EXPERIMENTAL_LINK_ACCESSIBILITY_LABEL } from '../consts';
5-
import { LINK_A11Y_ROLE, PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
4+
import { LINK_A11Y_ROLE, PAGE_TIMEOUT, BOOT_APP_TIMEOUT, Attribute } from '../../common/consts';
65

76
// Before testing begins, allow up to 60 seconds for app to open
87
describe('Link Testing Initialization', function () {
@@ -17,25 +16,38 @@ describe('Link Testing Initialization', function () {
1716
await ExperimentalLinkPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
1817

1918
await expect(await ExperimentalLinkPageObject.isPageLoaded()).toBeTruthy(ExperimentalLinkPageObject.ERRORMESSAGE_PAGELOAD);
19+
2020
await expect(await ExperimentalLinkPageObject.didAssertPopup()).toBeFalsy(ExperimentalLinkPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
2121
});
2222
});
2323

2424
describe('Link Accessibility Testing', () => {
25-
it('Link - Validate accessibilityRole is correct', async () => {
25+
beforeAll(async () => {
2626
await ExperimentalLinkPageObject.scrollToTestElement();
27+
});
2728

28-
await expect(await ExperimentalLinkPageObject.getAccessibilityRole()).toEqual(LINK_A11Y_ROLE);
29-
await expect(await ExperimentalLinkPageObject.didAssertPopup()).toBeFalsy(ExperimentalLinkPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
29+
it('Validate "accessibilityRole" defaults to Link "ControlType" element attribute.', async () => {
30+
await expect(
31+
await ExperimentalLinkPageObject.compareAttribute(
32+
ExperimentalLinkPageObject._primaryComponent,
33+
Attribute.AccessibilityRole,
34+
LINK_A11Y_ROLE,
35+
),
36+
).toBeTrue();
37+
38+
await expect(await ExperimentalLinkPageObject.didAssertPopup()).toBeFalsy(ExperimentalLinkPageObject.ERRORMESSAGE_ASSERT);
3039
});
3140

32-
it('Link - Set accessibilityLabel', async () => {
33-
await ExperimentalLinkPageObject.scrollToTestElement();
41+
it('Set "accessibilityLabel" prop. Validate "accessibilityLabel" propagates to "Name" element attribute.', async () => {
42+
await expect(
43+
await ExperimentalLinkPageObject.compareAttribute(
44+
ExperimentalLinkPageObject._primaryComponent,
45+
Attribute.AccessibilityLabel,
46+
EXPERIMENTAL_LINK_ACCESSIBILITY_LABEL,
47+
),
48+
).toBeTrue();
3449

35-
await expect(await ExperimentalLinkPageObject.getAccessibilityLabel(ComponentSelector.Primary)).toEqual(
36-
EXPERIMENTAL_LINK_ACCESSIBILITY_LABEL,
37-
);
38-
await expect(await ExperimentalLinkPageObject.didAssertPopup()).toBeFalsy(ExperimentalLinkPageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
50+
await expect(await ExperimentalLinkPageObject.didAssertPopup()).toBeFalsy(ExperimentalLinkPageObject.ERRORMESSAGE_ASSERT);
3951
});
4052

4153
// No need to test not setting a11y label. The content prop gets passed down to the child Text component. This equates to not setting the a11y label
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Overhaul ContextualMenu, Link, and LinkV1 E2E tests with better errors and refactored spec code",
4+
"packageName": "@fluentui-react-native/e2e-testing",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

0 commit comments

Comments
 (0)