diff --git a/test/e2e/application/frame-tree_test.ts b/test/e2e/application/frame-tree_test.ts index 703bbf8e65..f34acfd059 100644 --- a/test/e2e/application/frame-tree_test.ts +++ b/test/e2e/application/frame-tree_test.ts @@ -17,21 +17,18 @@ import { } from '../../shared/helper.js'; import {describe, it} from '../../shared/mocha-extensions.js'; import { - doubleClickSourceTreeItem, getFrameTreeTitles, getTrimmedTextContent, navigateToApplicationTab, + navigateToFrame, + navigateToFrameServiceWorkers, + navigateToOpenedWindows, + navigateToWebWorkers, unregisterServiceWorker, } from '../helpers/application-helpers.js'; import {setIgnoreListPattern} from '../helpers/settings-helpers.js'; -const TOP_FRAME_SELECTOR = '[aria-label="top"]'; -const WEB_WORKERS_SELECTOR = '[aria-label="Web Workers"]'; -const SERVICE_WORKERS_SELECTOR = '[aria-label="top"] ~ ol [aria-label="Service workers"]'; const OPENED_WINDOWS_SELECTOR = '[aria-label="Opened Windows"]'; -const IFRAME_FRAME_ID_SELECTOR = '[aria-label="frameId (iframe.html)"]'; -const MAIN_FRAME_SELECTOR = '[aria-label="frameId (main-frame.html)"]'; -const IFRAME_SELECTOR = '[aria-label="iframe.html"]'; const EXPAND_STACKTRACE_BUTTON_SELECTOR = '.arrow-icon-button'; const STACKTRACE_ROW_SELECTOR = '.stack-trace-row'; const STACKTRACE_ROW_LINK_SELECTOR = '.stack-trace-row .link'; @@ -80,7 +77,7 @@ describe('The Application Tab', () => { const {target} = getBrowserAndPages(); await navigateToApplicationTab(target, 'frame-tree'); await click('#tab-resources'); - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); + await navigateToFrame('top'); const fieldValuesTextContent = await waitForFunction(getFieldValuesTextContent); const expected = [ @@ -102,11 +99,11 @@ describe('The Application Tab', () => { it('shows stack traces for OOPIF', async () => { expectError('Request CacheStorage.requestCacheNames failed. {"code":-32602,"message":"Invalid security origin"}'); - await goToResource('application/js-oopif.html'); - await ensureApplicationPanel(); + const {target} = getBrowserAndPages(); + await navigateToApplicationTab(target, 'js-oopif'); await waitForFunction(async () => { - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); - await doubleClickSourceTreeItem(IFRAME_SELECTOR); + await navigateToFrame('top'); + await navigateToFrame('iframe.html'); return (await $$(EXPAND_STACKTRACE_BUTTON_SELECTOR)).length === 1; }); const stackTraceRowsTextContent = await waitForFunction(async () => { @@ -130,11 +127,11 @@ describe('The Application Tab', () => { it('stack traces for OOPIF with ignore listed frames can be expanded and collapsed', async () => { expectError('Request CacheStorage.requestCacheNames failed. {"code":-32602,"message":"Invalid security origin"}'); await setIgnoreListPattern('js-oopif.js'); - await goToResource('application/js-oopif.html'); - await ensureApplicationPanel(); + const {target} = getBrowserAndPages(); + await navigateToApplicationTab(target, 'js-oopif'); await waitForFunction(async () => { - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); - await doubleClickSourceTreeItem(IFRAME_SELECTOR); + await navigateToFrame('top'); + await navigateToFrame('iframe.html'); return (await $$(EXPAND_STACKTRACE_BUTTON_SELECTOR)).length === 1; }); let stackTraceRowsTextContent = await waitForFunction(async () => { @@ -196,7 +193,7 @@ describe('The Application Tab', () => { const {target, frontend} = getBrowserAndPages(); await navigateToApplicationTab(target, 'frame-tree'); await click('#tab-resources'); - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); + await navigateToFrame('top'); await target.evaluate(() => { window.iFrameWindow = window.open('iframe.html'); @@ -206,7 +203,7 @@ describe('The Application Tab', () => { // to the application panel. await frontend.bringToFront(); - await doubleClickSourceTreeItem(OPENED_WINDOWS_SELECTOR); + await navigateToOpenedWindows(); await waitFor(`${OPENED_WINDOWS_SELECTOR} + ol li:first-child`); void pressKey('ArrowDown'); @@ -230,14 +227,12 @@ describe('The Application Tab', () => { it('shows dedicated workers in the frame tree', async () => { expectError('Request CacheStorage.requestCacheNames failed. {"code":-32602,"message":"Invalid security origin"}'); const {target} = getBrowserAndPages(); - await goToResource('application/frame-tree.html'); - await click('#tab-resources'); - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); + await navigateToApplicationTab(target, 'frame-tree'); + await navigateToFrame('top'); // DevTools is not ready yet when the worker is being initially attached. // We therefore need to reload the page to see the worker in DevTools. await target.reload(); - await doubleClickSourceTreeItem(WEB_WORKERS_SELECTOR); - await waitFor(`${WEB_WORKERS_SELECTOR} + ol li:first-child`); + await navigateToWebWorkers(); void pressKey('ArrowDown'); const fieldValuesTextContent = await waitForFunction(async () => { @@ -258,11 +253,9 @@ describe('The Application Tab', () => { it('shows service workers in the frame tree', async () => { expectError('Request CacheStorage.requestCacheNames failed. {"code":-32602,"message":"Invalid security origin"}'); - await goToResource('application/service-worker-network.html'); - await click('#tab-resources'); - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); - await doubleClickSourceTreeItem(SERVICE_WORKERS_SELECTOR); - await waitFor(`${SERVICE_WORKERS_SELECTOR} + ol li:first-child`); + const {target} = getBrowserAndPages(); + await navigateToApplicationTab(target, 'service-worker-network'); + await navigateToFrameServiceWorkers('top'); void pressKey('ArrowDown'); const fieldValuesTextContent = await waitForFunction(async () => { @@ -292,8 +285,8 @@ describe('The Application Tab', () => { const {target} = getBrowserAndPages(); await goToResource('application/main-frame.html'); await click('#tab-resources'); - await doubleClickSourceTreeItem(TOP_FRAME_SELECTOR); - await doubleClickSourceTreeItem(IFRAME_FRAME_ID_SELECTOR); + await navigateToFrame('top'); + await navigateToFrame('frameId (iframe.html)'); // check iframe's URL after pageload const fieldValuesTextContent = await waitForFunction(getFieldValuesTextContent); @@ -326,7 +319,7 @@ describe('The Application Tab', () => { }); // check that iframe's URL has changed - await doubleClickSourceTreeItem(MAIN_FRAME_SELECTOR); + await navigateToFrame('frameId (main-frame.html)'); const fieldValuesTextContent2 = await waitForFunction(getFieldValuesTextContent); const expected2 = [ `https://localhost:${getTestServerPort()}/test/e2e/resources/application/main-frame.html`, diff --git a/test/e2e/helpers/application-helpers.ts b/test/e2e/helpers/application-helpers.ts index 94de32ee06..96fcabc48b 100644 --- a/test/e2e/helpers/application-helpers.ts +++ b/test/e2e/helpers/application-helpers.ts @@ -34,6 +34,15 @@ export async function navigateToServiceWorkers() { await click(SERVICE_WORKER_ROW_SELECTOR); } +export async function navigateToFrame(name: string) { + await doubleClickSourceTreeItem(`[aria-label="${name}"]`); + await waitFor('[title="Click to reveal in Sources panel"]'); + await expectVeEvents([ + veClick('Panel: resources > Pane: sidebar > Tree > TreeItem: frames > TreeItem: frame'), + veImpressionsUnder('Panel: resources', [veImpressionForFrameDetails()]), + ]); +} + export async function navigateToManifestInApplicationTab(testName: string) { const MANIFEST_SELECTOR = '[aria-label="Manifest"]'; const {target} = getBrowserAndPages(); @@ -41,6 +50,45 @@ export async function navigateToManifestInApplicationTab(testName: string) { await click(MANIFEST_SELECTOR); } +export async function navigateToOpenedWindows() { + await doubleClickSourceTreeItem('[aria-label="Opened Windows"]'); + await waitFor('.empty-view'); + await expectVeEvents([ + veClick('Panel: resources > Pane: sidebar > Tree > TreeItem: frames > TreeItem: frame > TreeItem: opened-windows'), + veImpressionsUnder( + 'Panel: resources', [veImpression('Pane', 'opened-windows', [veImpression('Section', 'empty-view')])]), + ]); +} + +export async function navigateToWebWorkers() { + const WEB_WORKERS_SELECTOR = '[aria-label="Web Workers"]'; + await expectVeEvents([veImpressionsUnder( + 'Panel: resources > Pane: sidebar > Tree > TreeItem: frames > TreeItem: frame', + [veImpression('TreeItem', 'web-workers')])]); + await doubleClickSourceTreeItem(WEB_WORKERS_SELECTOR); + await waitFor(`${WEB_WORKERS_SELECTOR} + ol li:first-child`); + await waitFor('.empty-view'); + await expectVeEvents([ + veClick('Panel: resources > Pane: sidebar > Tree > TreeItem: frames > TreeItem: frame > TreeItem: web-workers'), + veImpressionsUnder( + 'Panel: resources', [veImpression('Pane', 'web-workers', [veImpression('Section', 'empty-view')])]), + ]); +} + +export async function navigateToFrameServiceWorkers(frameName: string) { + await navigateToFrame(frameName); + const SERVICE_WORKERS_SELECTOR = `[aria-label="${frameName}"] ~ ol [aria-label="Service workers"]`; + + await doubleClickSourceTreeItem(SERVICE_WORKERS_SELECTOR); + await waitFor(`${SERVICE_WORKERS_SELECTOR} + ol li:first-child`); + await waitFor('.empty-view'); + await expectVeEvents([ + veClick('Panel: resources > Pane: sidebar > Tree > TreeItem: frames > TreeItem: frame > TreeItem: service-workers'), + veImpressionsUnder( + 'Panel: resources', [veImpression('Pane', 'service-workers', [veImpression('Section', 'empty-view')])]), + ]); +} + export async function navigateToCookiesForTopDomain() { // The parent suffix makes sure we wait for the Cookies item to have children before trying to click it. const COOKIES_SELECTOR = '[aria-label="Cookies"].parent'; @@ -286,3 +334,14 @@ function veImpressionForCookieTable() { ]), ]); } + +function veImpressionForFrameDetails() { + return veImpression('Pane', 'frames', [ + veImpression('Action', 'reveal-in-elements'), + veImpression('Action', 'reveal-in-network'), + veImpression('Action', 'reveal-in-sources'), + veImpression('Link', 'learn-more.coop-coep'), + veImpression('Link', 'learn-more.monitor-memory-usage'), + veImpression('Link', 'learn-more.origin-trials'), + ]); +} diff --git a/test/e2e/helpers/visual-logging-helpers.ts b/test/e2e/helpers/visual-logging-helpers.ts index 9bdefaf934..e788fac652 100644 --- a/test/e2e/helpers/visual-logging-helpers.ts +++ b/test/e2e/helpers/visual-logging-helpers.ts @@ -194,8 +194,8 @@ export async function expectVeEvents(expectedEvents: TestLogEntry[]) { const actualEvents = // @ts-ignore await frontend.evaluate(async () => (await globalThis.getVeDebugEventsLog()) as unknown as TestLogEntry[]); - let bestError: {difference: number, description?: string}|null = null; for (let i = 0; i < expectedEvents.length; ++i) { + let bestError: {difference: number, description?: string}|null = null; const expectedEvent = expectedEvents[i]; while (true) { if (actualEvents.length <= i) {