From 50395c39aae3018e31dc68817223e2d1a66c1a83 Mon Sep 17 00:00:00 2001 From: Dan Bjorge Date: Tue, 26 Nov 2019 14:33:48 -0800 Subject: [PATCH 1/2] test: add readiness checks to target page e2es before interacting with visualizations --- .../target-page-selectors.ts | 3 +- .../common/page-controllers/page.ts | 18 ++++--- .../common/page-controllers/target-page.ts | 21 +++++++-- .../tests/popup/adhoc-panel.test.ts | 2 +- .../tests/target-page/issue-dialog.test.ts | 4 +- .../tests/target-page/tabstop.test.ts | 47 +++++++++---------- .../target-page/visualization-boxes.test.ts | 5 +- 7 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/tests/end-to-end/common/element-identifiers/target-page-selectors.ts b/src/tests/end-to-end/common/element-identifiers/target-page-selectors.ts index 993e055cac..d43c6705ab 100644 --- a/src/tests/end-to-end/common/element-identifiers/target-page-selectors.ts +++ b/src/tests/end-to-end/common/element-identifiers/target-page-selectors.ts @@ -11,6 +11,7 @@ export const TargetPageInjectedComponentSelectors = { export const TabStopShadowDomSelectors = { svg: 'svg', lines: 'line', - ellipse: 'ellipse', + opaqueEllipse: 'ellipse:not([fill="transparent"])', + transparentEllipse: 'ellipse[fill="transparent"]', text: 'text', }; diff --git a/src/tests/end-to-end/common/page-controllers/page.ts b/src/tests/end-to-end/common/page-controllers/page.ts index 533f783768..1eabb50a64 100644 --- a/src/tests/end-to-end/common/page-controllers/page.ts +++ b/src/tests/end-to-end/common/page-controllers/page.ts @@ -181,12 +181,18 @@ export class Page { }); } - public async getShadowRootOfSelector(selector: string): Promise> { - return await this.screenshotOnError(async () => - ( - await this.underlyingPage.evaluateHandle(selectorInEval => document.querySelector(selectorInEval).shadowRoot, selector) - ).asElement(), - ); + public async waitForShadowRootOfSelector(selector: string): Promise> { + return await this.screenshotOnError(async () => { + const shadowRootHandle = await this.underlyingPage.waitForFunction( + selectorInEval => { + const container = document.querySelector(selectorInEval); + return container == undefined ? undefined : container.shadowRoot; + }, + { timeout: DEFAULT_PAGE_ELEMENT_WAIT_TIMEOUT_MS }, + selector, + ); + return shadowRootHandle.asElement(); + }); } public async clickSelector(selector: string): Promise { diff --git a/src/tests/end-to-end/common/page-controllers/target-page.ts b/src/tests/end-to-end/common/page-controllers/target-page.ts index 443e864047..50bac6dff5 100644 --- a/src/tests/end-to-end/common/page-controllers/target-page.ts +++ b/src/tests/end-to-end/common/page-controllers/target-page.ts @@ -31,12 +31,25 @@ export class TargetPage extends Page { super(underlyingPage, options); } - public async getShadowRoot(): Promise> { - return await this.getShadowRootOfSelector('#insights-shadow-host'); + public async waitForSelectorInShadowRoot( + selector: string, + options?: Puppeteer.WaitForSelectorOptions, + ): Promise> { + const shadowRoot = await this.waitForShadowRoot(); + return this.waitForDescendentSelector(shadowRoot, selector, options); } - public async getShadowRootHtmlSnapshot(): Promise { - const shadowRoot = await this.getShadowRoot(); + public async clickSelectorInShadowRoot(selector: string): Promise { + const shadowRoot = await this.waitForShadowRoot(); + await this.clickDescendentSelector(shadowRoot, selector, { visible: true }); + } + + public async waitForShadowRoot(): Promise> { + return await this.waitForShadowRootOfSelector('#insights-shadow-host'); + } + + public async waitForShadowRootHtmlSnapshot(): Promise { + const shadowRoot = await this.waitForShadowRoot(); return await formatChildElementForSnapshot(shadowRoot, '#insights-shadow-container'); } } diff --git a/src/tests/end-to-end/tests/popup/adhoc-panel.test.ts b/src/tests/end-to-end/tests/popup/adhoc-panel.test.ts index a0e3ffe2d4..b7a09d3506 100644 --- a/src/tests/end-to-end/tests/popup/adhoc-panel.test.ts +++ b/src/tests/end-to-end/tests/popup/adhoc-panel.test.ts @@ -65,7 +65,7 @@ describe('Popup -> Ad-hoc tools', () => { await popupPage.enableToggleByAriaLabel(toggleAriaLabel); await targetPage.bringToFront(); - expect(await targetPage.getShadowRootHtmlSnapshot()).toMatchSnapshot(); + expect(await targetPage.waitForShadowRootHtmlSnapshot()).toMatchSnapshot(); }, ); }); diff --git a/src/tests/end-to-end/tests/target-page/issue-dialog.test.ts b/src/tests/end-to-end/tests/target-page/issue-dialog.test.ts index 826bf37805..66908f55eb 100644 --- a/src/tests/end-to-end/tests/target-page/issue-dialog.test.ts +++ b/src/tests/end-to-end/tests/target-page/issue-dialog.test.ts @@ -31,9 +31,7 @@ describe('Target Page issue dialog', () => { await targetPage.bringToFront(); - const shadowRoot = await targetPage.getShadowRoot(); - await targetPage.clickDescendentSelector(shadowRoot, TargetPageInjectedComponentSelectors.failureLabel, { visible: true }); - + await targetPage.clickSelectorInShadowRoot(TargetPageInjectedComponentSelectors.failureLabel); await targetPage.waitForSelector(TargetPageInjectedComponentSelectors.issueDialog); const results = await scanForAccessibilityIssues(targetPage, TargetPageInjectedComponentSelectors.issueDialog); diff --git a/src/tests/end-to-end/tests/target-page/tabstop.test.ts b/src/tests/end-to-end/tests/target-page/tabstop.test.ts index 29bfb7e1ac..4bc9ab4ca8 100644 --- a/src/tests/end-to-end/tests/target-page/tabstop.test.ts +++ b/src/tests/end-to-end/tests/target-page/tabstop.test.ts @@ -1,14 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ElementHandle } from 'puppeteer'; - import { Browser } from '../../common/browser'; import { launchBrowser } from '../../common/browser-factory'; import { TabStopShadowDomSelectors, TargetPageInjectedComponentSelectors } from '../../common/element-identifiers/target-page-selectors'; import { PopupPage } from '../../common/page-controllers/popup-page'; import { TargetPage } from '../../common/page-controllers/target-page'; -describe('tabstop tests', () => { +describe('Tab stops visualization', () => { let browser: Browser; let targetPage: TargetPage; let popupPage: PopupPage; @@ -24,36 +22,35 @@ describe('tabstop tests', () => { } }); - test('works when tabstop is triggered from adhoc panel', async () => { + it('should show the expected visuals in the target page after enabling from popup and tabbing through target page', async () => { popupPage = await browser.newPopupPage(targetPage); await popupPage.gotoAdhocPanel(); await popupPage.enableToggleByAriaLabel('Tab stops'); await targetPage.bringToFront(); + await targetPage.waitForShadowRoot(); + // Should highlight first element with a transparent circle await targetPage.keyPress('Tab'); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.svg); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.transparentEllipse); + + // Should highlight second element with a transparent circle and change first element's + // highlight to an opaque circle with a "1" in it, connected by a line await targetPage.keyPress('Tab'); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.svg); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.transparentEllipse); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.opaqueEllipse); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.lines); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.text); + + // Only 2 focusable elements on this test page, so should move focus to the browser chrome + // without changing the visualizations await targetPage.keyPress('Tab'); - - const shadowRoot = await targetPage.getShadowRoot(); - await targetPage.waitForDescendentSelector(shadowRoot, TargetPageInjectedComponentSelectors.tabStopVisulizationStart, { - visible: true, - }); - - await validateTabStopVisualizationOnTargetPage(shadowRoot); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.svg); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.transparentEllipse); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.opaqueEllipse); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.lines); + await targetPage.waitForSelectorInShadowRoot(TabStopShadowDomSelectors.text); }); - - async function validateTabStopVisualizationOnTargetPage(shadowRoot: ElementHandle): Promise { - const svgs = await shadowRoot.$$(TabStopShadowDomSelectors.svg); - const ellipses = await shadowRoot.$$(TabStopShadowDomSelectors.ellipse); - const lines = await shadowRoot.$$(TabStopShadowDomSelectors.lines); - const texts = await shadowRoot.$$(TabStopShadowDomSelectors.text); - - // 3 tabs produce 1 svg, 2 ellipses, 1 texts and 1 line between them - - expect(svgs).toHaveLength(1); - expect(ellipses).toHaveLength(2); - expect(lines).toHaveLength(1); - expect(texts).toHaveLength(1); - } }); diff --git a/src/tests/end-to-end/tests/target-page/visualization-boxes.test.ts b/src/tests/end-to-end/tests/target-page/visualization-boxes.test.ts index abe1ce8463..fce908cd65 100644 --- a/src/tests/end-to-end/tests/target-page/visualization-boxes.test.ts +++ b/src/tests/end-to-end/tests/target-page/visualization-boxes.test.ts @@ -31,10 +31,7 @@ describe('Target Page visualization boxes', () => { it.each(adhocTools)('for adhoc tool "%s" should pass accessibility validation', async adhocTool => { await popupPage.enableToggleByAriaLabel(adhocTool); - const shadowRoot = await targetPage.getShadowRoot(); - await targetPage.waitForDescendentSelector(shadowRoot, TargetPageInjectedComponentSelectors.insightsVisualizationBox, { - visible: true, - }); + await targetPage.waitForSelectorInShadowRoot(TargetPageInjectedComponentSelectors.insightsVisualizationBox, { visible: true }); const results = await scanForAccessibilityIssues(targetPage, TargetPageInjectedComponentSelectors.insightsRootContainer); expect(results).toHaveLength(0); From 58df334aaadf7e6ed18fe93fe8f59b9ab28e6e29 Mon Sep 17 00:00:00 2001 From: Dan Bjorge Date: Tue, 26 Nov 2019 14:37:24 -0800 Subject: [PATCH 2/2] Fix lint issue --- src/tests/end-to-end/tests/target-page/tabstop.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/end-to-end/tests/target-page/tabstop.test.ts b/src/tests/end-to-end/tests/target-page/tabstop.test.ts index 4bc9ab4ca8..50a0b46a79 100644 --- a/src/tests/end-to-end/tests/target-page/tabstop.test.ts +++ b/src/tests/end-to-end/tests/target-page/tabstop.test.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { Browser } from '../../common/browser'; import { launchBrowser } from '../../common/browser-factory'; -import { TabStopShadowDomSelectors, TargetPageInjectedComponentSelectors } from '../../common/element-identifiers/target-page-selectors'; +import { TabStopShadowDomSelectors } from '../../common/element-identifiers/target-page-selectors'; import { PopupPage } from '../../common/page-controllers/popup-page'; import { TargetPage } from '../../common/page-controllers/target-page';