Skip to content

Commit

Permalink
Improve e2e test for picker input doc example. Improve overall stabil…
Browse files Browse the repository at this point in the history
…ity of e2e tests.
  • Loading branch information
siarheiy committed Jul 30, 2024
1 parent ad979a7 commit ac60a20
Show file tree
Hide file tree
Showing 33 changed files with 117 additions and 19 deletions.
11 changes: 10 additions & 1 deletion app/src/docExample/docExampleContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@ export function DocExampleContent(props: IDocExampleContent) {
}
if (Component) {
return (
<FlexRow cx={ css.exampleContent } size={ null } vPadding="48" padding="24" borderBottom alignItems="top" columnGap="12">
<FlexRow
rawProps={ { tabIndex: 0 } }
cx={ css.exampleContent }
size={ null }
vPadding="48"
padding="24"
borderBottom
alignItems="top"
columnGap="12"
>
<Component />
</FlexRow>
);
Expand Down
20 changes: 18 additions & 2 deletions uui-e2e-tests/framework/fixtures/shared/absPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,26 @@ export abstract class AbsPage {

protected async _clientRedirect<T extends object>(params: T) {
await this.page.mouse.move(0, 0);
await this.page.evaluate((_params: string) => {
await this.page.evaluate(async (_params: string) => {
const [p, i] = _params.split('[||||]');
// @ts-ignore Reason: this specific code will be run in context of web page
(window as any)[i](p);
const globalObj = window as any;
const waitForInterface = () => {
return new Promise<any>((resolve) => {
const get = () => globalObj[i];
if (get()) {
resolve(get());
} else {
const _intervalId = globalObj.setInterval(() => {
if (get()) {
globalObj.clearInterval(_intervalId);
resolve(get());
}
}, 500);
}
});
};
(await waitForInterface())(p);
}, [jsonStringify(params), PlayWrightInterfaceName].join('[||||]'));
}
}
Expand Down
2 changes: 1 addition & 1 deletion uui-e2e-tests/framework/fixtures/shared/fixtureBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function buildFixture<TPageWrapper extends AbsPage>(
pageWrapper: [
async ({ browser }, use, { project }) => {
const engine = project.name as TEngine;
const context = await browser.newContext();
const context = await browser.newContext({ bypassCSP: true });
let pageWrapper: TPageWrapper | undefined;
try {
const page = await context.newPage();
Expand Down
54 changes: 42 additions & 12 deletions uui-e2e-tests/framework/pageObjects/pickerInputObject.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { Locator, Page, expect } from '@playwright/test';

// see all key codes here: https://playwright.dev/docs/api/class-keyboard#keyboard-press
type TKeyboardKey = 'ArrowDown' | 'Backspace' | 'Enter' | 'Escape' | 'Shift' | 'Tab' | 'Shift+Tab';

export class PickerInputObject {
private readonly locators: {
input: Locator;
dropdown: {
root: Locator;
option: (params: { focused?: boolean, checked?: boolean, text?: string, has?: string }) => Locator;
blocker: Locator;
search: Locator;
noRecords: Locator;
}
};

Expand All @@ -17,6 +22,8 @@ export class PickerInputObject {
input,
dropdown: {
root: dropdown,
search: dropdown.locator('input[type="search"]'),
noRecords: dropdown.locator('.uui-flex-row > div > .uui-text').getByText('No records found'),
option: (params) => {
let sel = 'div[role="option"]';
if (params.focused) {
Expand All @@ -43,41 +50,64 @@ export class PickerInputObject {
await this.locators.input.first().focus();
}

async openDropdown() {
async focusDropdownSearchInput() {
await this.locators.dropdown.search.first().focus();
}

/**
* Reset mouse pos to avoid unintentional hover effects
*/
async resetMousePos() {
await this.page.mouse.move(0, 0);
}

async clickDropdown() {
await this.locators.input.first().click();
await this.resetMousePos();
}

async clickOption(text: string) {
await this.locators.dropdown.option({ text }).click();
await this.resetMousePos();
}

async waitDropdownLoaderAppearsAndDisappears() {
await expect(this.locators.dropdown.blocker).toBeVisible();
await expect(this.locators.dropdown.blocker).toBeHidden();
await this.locators.dropdown.blocker.waitFor({ state: 'visible' });
await this.locators.dropdown.blocker.waitFor({ state: 'hidden' });
}

async waitForNoRecordsFoundMsg() {
await this.locators.dropdown.noRecords.waitFor({ state: 'visible' });
}

async waitDropdownDisappears() {
await expect(this.locators.dropdown.root).toBeHidden();
await this.locators.dropdown.root.waitFor({ state: 'hidden' });
}

// see key codes here: https://playwright.dev/docs/api/class-keyboard#keyboard-press
async keyboardPress(key: 'ArrowDown' | 'Backspace' | 'Enter' | 'Escape', times: number = 1) {
async keyboardPress(key: TKeyboardKey, times: number = 1) {
for (let i = 0; i < times; i++) {
await this.page.keyboard.press(key);
await this.page.waitForTimeout(100);
}
}

async keyboardType(text: string) {
await this.page.keyboard.type(text);
}

async waitDropdownOptionFocused(text: string) {
await expect(this.locators.dropdown.option({ text })).toBeAttached();
async expectOptionInViewport(text: string) {
await expect(this.locators.dropdown.option({ text })).toBeInViewport({ ratio: 0.95 });
}

async waitDropdownOptionChecked(text: string) {
await expect(this.locators.dropdown.option({ text, focused: true, checked: true })).toBeAttached();
await this.locators.dropdown.option({ text, focused: true, checked: true }).waitFor({ state: 'visible' });
}

async waitDropdownOptionUnchecked(text: string) {
await this.locators.dropdown.option({ text, focused: true, checked: false }).waitFor({ state: 'attached' });
}

async waitDropdownOptionCheckedMixed(text: string) {
await expect(
this.locators.dropdown.option({ text, has: 'input[type="checkbox"][aria-checked="mixed"]' }),
).toBeAttached();
await this.locators.dropdown.option({ text, has: 'input[type="checkbox"][aria-checked="mixed"]' }).waitFor({ state: 'attached' });
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 44 additions & 3 deletions uui-e2e-tests/tests/docExampleTests/pickerInput/pickerInput.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { test } from '../../../framework/fixtures/docExamplePage/fixture';
import { PickerInputObject } from '../../../framework/pageObjects/pickerInputObject';
import { DocExamplePath, setupDocExampleTest } from '../testUtils';

test.skip(DocExamplePath['pickerInput/LazyTreeInput'], async ({ pageWrapper }, testInfo) => {
const OPTION_TEXT = {
FRANCE_EUROPE: 'FranceEurope',
FRANCE_GARGES: 'Garges-lès-GonesseEurope / France',
};

test(DocExamplePath['pickerInput/LazyTreeInput'], async ({ pageWrapper }, testInfo) => {
const { pageObject, expectScreenshot } = await setupDocExampleTest({
testInfo,
pageWrapper,
Expand All @@ -22,11 +27,11 @@ test.skip(DocExamplePath['pickerInput/LazyTreeInput'], async ({ pageWrapper }, t
await expectScreenshot('step3-search-results');
// 4
await pageObject.keyboardPress('ArrowDown', 8);
await pageObject.waitDropdownOptionFocused('FranceEurope');
await pageObject.expectOptionInViewport(OPTION_TEXT.FRANCE_EUROPE);
await expectScreenshot('step4-option-france-focused');
// 5
await pageObject.keyboardPress('Enter');
await pageObject.waitDropdownOptionChecked('FranceEurope');
await pageObject.waitDropdownOptionChecked(OPTION_TEXT.FRANCE_EUROPE);
await expectScreenshot('step5-option-france-checked');
// 6
await pageObject.keyboardPress('Backspace', 5);
Expand All @@ -36,4 +41,40 @@ test.skip(DocExamplePath['pickerInput/LazyTreeInput'], async ({ pageWrapper }, t
await pageObject.keyboardPress('Escape');
await pageObject.waitDropdownDisappears();
await expectScreenshot('step7-france-selected');
// 8
await pageObject.keyboardPress('Shift+Tab');
await pageObject.waitDropdownDisappears();
await expectScreenshot('step8-focus-outside');
// 9
await pageObject.keyboardPress('Tab');
await pageObject.waitDropdownDisappears();
await expectScreenshot('step9-focus-input');
// 10
await pageObject.keyboardPress('Enter');
await pageObject.waitDropdownLoaderAppearsAndDisappears();
await expectScreenshot('step10-focus-search');
// 11
await pageObject.keyboardType('arg');
await pageObject.waitDropdownLoaderAppearsAndDisappears();
await expectScreenshot('step11-search-results');
// 12
await pageObject.keyboardPress('ArrowDown', 21);
await pageObject.expectOptionInViewport(OPTION_TEXT.FRANCE_GARGES);
await expectScreenshot('step12-option-garges-focused');
// 13
await pageObject.clickOption(OPTION_TEXT.FRANCE_GARGES);
await pageObject.waitDropdownOptionUnchecked(OPTION_TEXT.FRANCE_GARGES);
await expectScreenshot('step13-option-garges-unchecked');
// 14
await pageObject.focusDropdownSearchInput();
await pageObject.keyboardPress('Backspace', 3);
await pageObject.waitDropdownOptionCheckedMixed('Europe');
await expectScreenshot('step14-option-europe-checked-mixed');
// 15
await pageObject.keyboardType('qwe');
await pageObject.waitForNoRecordsFoundMsg();
await expectScreenshot('step15-search-results');
// 16
await pageObject.keyboardPress('Tab');
await expectScreenshot('step16-focus-only-selected-radio');
});
2 changes: 2 additions & 0 deletions uui-e2e-tests/tests/docExampleTests/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ export async function setupDocExampleTest<TPageObject>(params: IDocExampleTestSe
const screenshotName = `${testInfo.title}_${stepName}.png`;
await pageWrapper.expectScreenshot(screenshotName);
};
// The timeout is increased for all doc example tests, because such tests contain many assertions.
testInfo.setTimeout(testInfo.timeout + 280_000);
return { pageObject, expectScreenshot };
}

0 comments on commit ac60a20

Please sign in to comment.