[ve] Add VE assertions for the frame tree e2e tests

Also fix expectVeEvents logic so that it never reports an error for a
matched expectation, which could be confusing.


Bug: 348173254
Change-Id: Id8cf97aa39ddc566a90b90430b6655d73ce83801
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5675713
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Auto-Submit: Danil Somsikov <dsv@chromium.org>
This commit is contained in:
Danil Somsikov
2024-07-04 09:26:57 +00:00
committed by Devtools-frontend LUCI CQ
parent 6410f11cc1
commit c9364bdebd
3 changed files with 84 additions and 32 deletions
+24 -31
View File
@@ -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`,
+59
View File
@@ -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'),
]);
}
+1 -1
View File
@@ -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) {