Add e2e-tests for focus interactions of console messages

This replaces http/tests/devtools/console/viewport-testing/console-key-navigation.js
as an e2e-test.

R=aerotwist@chromium.org

Bug: 1203169
Change-Id: I461f742e84f13e44eecc74553ced77b5041d3340
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3010115
Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
Reviewed-by: Paul Lewis <aerotwist@chromium.org>
This commit is contained in:
Tim van der Lippe
2021-07-07 10:23:47 +00:00
committed by Devtools-frontend LUCI CQ
parent 2906222f2a
commit 72f2d4bcc8
7 changed files with 165 additions and 73 deletions
+65 -2
View File
@@ -4,9 +4,9 @@
import {assert} from 'chai';
import {getBrowserAndPages, waitForFunction} from '../../shared/helper.js';
import {activeElement, activeElementAccessibleName, activeElementTextContent, getBrowserAndPages, tabBackward, tabForward, waitForFunction} from '../../shared/helper.js';
import {describe, it} from '../../shared/mocha-extensions.js';
import {getStructuredConsoleMessages, navigateToConsoleTab, showVerboseMessages} from '../helpers/console-helpers.js';
import {focusConsolePrompt, getConsoleMessages, getStructuredConsoleMessages, navigateToConsoleTab, showVerboseMessages, waitForLastConsoleMessageToHaveContent} from '../helpers/console-helpers.js';
/* eslint-disable no-console */
@@ -238,4 +238,67 @@ describe('The Console Tab', async () => {
assert.deepEqual(actualMessages, test.expectedMessages, 'Console message does not match the expected message');
});
}
describe('keyboard navigation', () => {
it('can navigate between individual messages', async () => {
const {frontend} = getBrowserAndPages();
await getConsoleMessages('focus-interaction');
await focusConsolePrompt();
await tabBackward();
assert.strictEqual(await activeElementTextContent(), 'focus-interaction.html:9');
await frontend.keyboard.press('ArrowUp');
assert.strictEqual(await activeElementTextContent(), 'focus-interaction.html:9 Third message');
await frontend.keyboard.press('ArrowUp');
assert.strictEqual(await activeElementTextContent(), 'focus-interaction.html:8');
await frontend.keyboard.press('ArrowDown');
assert.strictEqual(await activeElementTextContent(), 'focus-interaction.html:9 Third message');
await tabBackward(); // Focus should now be on the console settings, e.g. out of the list of console messages
assert.strictEqual(await activeElementAccessibleName(), 'Console settings');
await tabForward(); // Focus is now back to the list, selecting the last message source URL
assert.strictEqual(await activeElementTextContent(), 'focus-interaction.html:9');
await tabForward();
assert.strictEqual(await activeElementAccessibleName(), 'Console prompt');
});
it('should not lose focus on prompt when logging and scrolling', async () => {
const {target, frontend} = getBrowserAndPages();
await getConsoleMessages('focus-interaction');
await focusConsolePrompt();
await target.evaluate(() => {
console.log('New message');
});
await waitForLastConsoleMessageToHaveContent('New message');
assert.strictEqual(await activeElementAccessibleName(), 'Console prompt');
await target.evaluate(() => {
for (let i = 0; i < 100; i++) {
console.log(`Message ${i}`);
}
});
await waitForLastConsoleMessageToHaveContent('Message 99');
assert.strictEqual(await activeElementAccessibleName(), 'Console prompt');
const consolePrompt = await activeElement();
const wrappingBox = await consolePrompt.boundingBox();
if (!wrappingBox) {
throw new Error('Can\'t compute bounding box of console prompt.');
}
// +20 to move from the top left point so we are definitely scrolling
// within the container
await frontend.mouse.move(wrappingBox.x + 20, wrappingBox.y + 5);
await frontend.mouse.wheel({deltaY: -500});
assert.strictEqual(await activeElementAccessibleName(), 'Console prompt');
});
});
});
+22 -27
View File
@@ -4,7 +4,7 @@
import {assert} from 'chai';
import type * as puppeteer from 'puppeteer';
import {click, getBrowserAndPages, goToResource, pressKey, typeText, waitFor} from '../../shared/helper.js';
import {click, getBrowserAndPages, goToResource, pressKey, typeText, waitFor, tabForward} from '../../shared/helper.js';
import {describe, it} from '../../shared/mocha-extensions.js';
import {waitForDomNodeToBeVisible} from '../helpers/elements-helpers.js';
import {openDeviceToolbar, reloadDockableFrontEnd, selectEdit, selectTestDevice} from '../helpers/emulation-helpers.js';
@@ -26,11 +26,6 @@ async function targetTextContent(selector: string): Promise<string> {
return elementTextContent(handle);
}
export const tabForwardFrontend = async () => {
const {frontend} = getBrowserAndPages();
await frontend.keyboard.press('Tab');
};
describe('Custom UA-CH emulation', async () => {
beforeEach(async function() {
await reloadDockableFrontEnd();
@@ -46,51 +41,51 @@ describe('Custom UA-CH emulation', async () => {
await waitFor(FOCUSED_DEVICE_NAME_FIELD_SELECTOR);
await typeText('Test device');
await tabForwardFrontend(); // Focus width.
await tabForwardFrontend(); // Focus height.
await tabForwardFrontend(); // Focus DPR.
await tabForward(); // Focus width.
await tabForward(); // Focus height.
await tabForward(); // Focus DPR.
await typeText('1.0');
await tabForwardFrontend(); // Focus UA string.
await tabForward(); // Focus UA string.
await typeText('Test device browser 1.0');
await tabForwardFrontend(); // Focus device type.
await tabForwardFrontend(); // Focus folder.
await tabForward(); // Focus device type.
await tabForward(); // Focus folder.
await pressKey('Space');
await tabForwardFrontend(); // Focus help button
await tabForwardFrontend(); // Focus brand browser.
await tabForward(); // Focus help button
await tabForward(); // Focus brand browser.
await typeText('Test browser');
await tabForwardFrontend(); // Focus brand version.
await tabForward(); // Focus brand version.
await typeText('1.0');
await tabForwardFrontend(); // Focus delete button.
await tabForwardFrontend(); // Focus Add brand button.
await tabForward(); // Focus delete button.
await tabForward(); // Focus Add brand button.
await pressKey('Space');
await typeText('Friendly Dragon');
await tabForwardFrontend(); // Focus second row brand version.
await tabForward(); // Focus second row brand version.
await typeText('1.1');
await tabForwardFrontend(); // Focus second row delete button.
await tabForwardFrontend(); // Focus Add browser button.
await tabForwardFrontend(); // Focus full version.
await tabForward(); // Focus second row delete button.
await tabForward(); // Focus Add browser button.
await tabForward(); // Focus full version.
await typeText('1.1.2345');
await tabForwardFrontend(); // Focus platform.
await tabForward(); // Focus platform.
await typeText('Cyborg');
await tabForwardFrontend(); // Focus platform version.
await tabForward(); // Focus platform version.
await typeText('C-1');
await tabForwardFrontend(); // Focus architecture.
await tabForward(); // Focus architecture.
await typeText('Bipedal');
await tabForwardFrontend(); // Focus device model.
await tabForward(); // Focus device model.
await typeText('C-1-Gardener');
await tabForwardFrontend(); // Focus add button.
await tabForward(); // Focus add button.
const finishAdd = await waitFor(FOCUSED_SELECTOR);
const finishAddText = await elementTextContent(finishAdd);
@@ -134,7 +129,7 @@ describe('Custom UA-CH emulation', async () => {
if (i === 7) {
await pressKey('ArrowRight');
}
await tabForwardFrontend();
await tabForward();
}
// Change the value.
+11
View File
@@ -55,6 +55,17 @@ export async function waitForConsoleMessagesToBeNonEmpty(numberOfMessages: numbe
});
}
export async function waitForLastConsoleMessageToHaveContent(expectedTextContent: string) {
await waitForFunction(async () => {
const messages = await $$(CONSOLE_FIRST_MESSAGES_SELECTOR);
if (messages.length === 0) {
return false;
}
const lastMessageContent = await messages[messages.length - 1].evaluate(message => message.textContent);
return lastMessageContent === expectedTextContent;
});
}
export async function getConsoleMessages(testName: string, withAnchor = false, callback?: () => Promise<void>) {
// Ensure Console is loaded before the page is loaded to avoid a race condition.
await getCurrentConsoleMessages();
+26 -31
View File
@@ -4,7 +4,7 @@
import {assert} from 'chai';
import type {ElementHandle, Page} from 'puppeteer';
import {getBrowserAndPages, pressKey, typeText, waitFor, waitForAria} from '../../shared/helper.js';
import {getBrowserAndPages, pressKey, typeText, waitFor, waitForAria, tabForward} from '../../shared/helper.js';
import {describe, it} from '../../shared/mocha-extensions.js';
import {navigateToNetworkTab} from '../helpers/network-helpers.js';
import type * as Protocol from '../../../front_end/generated/protocol.js';
@@ -56,11 +56,6 @@ describe('The Network Tab', async function() {
return await target.evaluate(getUserAgentMetaDataStr);
}
async function tabForwardFrontend() {
const {frontend} = getBrowserAndPages();
await frontend.keyboard.press('Tab');
}
it('can change accepted content encodings', async () => {
const section = await openNetworkConditions('.network-config-accepted-encoding');
const autoCheckbox = await waitForAria('Use browser default', section);
@@ -219,42 +214,42 @@ describe('The Network Tab', async function() {
const userAgent = await waitForAria('Enter a custom user agent');
await userAgent.click();
await userAgent.type('Test User Agent String');
await tabForwardFrontend(); // focus help button
await tabForward(); // focus help button
await pressKey('Space'); // open client hints section
await tabForwardFrontend(); // focus help link
await tabForwardFrontend(); // focus brand name
await tabForward(); // focus help link
await tabForward(); // focus brand name
await typeText('Test Brand 1');
await tabForwardFrontend(); // focus brand version
await tabForward(); // focus brand version
await typeText('99');
await tabForwardFrontend(); // focus delete brand button
await tabForwardFrontend(); // focus add brand button
await tabForward(); // focus delete brand button
await tabForward(); // focus add brand button
await pressKey('Enter'); // add a second brand
await typeText('Test Brand 2');
await tabForwardFrontend(); // focus brand version
await tabForward(); // focus brand version
await typeText('100');
await tabForwardFrontend(); // focus delete brand button
await tabForwardFrontend(); // focus add brand button
await tabForward(); // focus delete brand button
await tabForward(); // focus add brand button
await pressKey('Enter'); // add a third brand
await typeText('Test Brand 3');
await tabForwardFrontend(); // focus brand version
await tabForward(); // focus brand version
await typeText('101');
await tabForwardFrontend(); // focus delete brand button
await tabForwardFrontend(); // focus add brand button
await tabForwardFrontend(); // focus browser full version
await tabForward(); // focus delete brand button
await tabForward(); // focus add brand button
await tabForward(); // focus browser full version
await typeText('99.99');
await tabForwardFrontend(); // focus platform name
await tabForward(); // focus platform name
await typeText('Test Platform');
await tabForwardFrontend(); // focus platform version
await tabForward(); // focus platform version
await typeText('10');
await tabForwardFrontend(); // focus architecture
await tabForward(); // focus architecture
await typeText('Test Architecture');
await tabForwardFrontend(); // focus device model
await tabForward(); // focus device model
await typeText('Test Model');
await tabForwardFrontend(); // focus mobile checkbox
await tabForward(); // focus mobile checkbox
await pressKey('Space');
await tabForwardFrontend(); // focus update button
await tabForward(); // focus update button
await pressKey('Enter');
const userAgentMetadata = await getUserAgentMetadataFromTarget(target);
assert.deepEqual(userAgentMetadata, {
@@ -274,8 +269,8 @@ describe('The Network Tab', async function() {
// Delete a brand
const brand = await waitForAria('Brand 1', section); // move focus back to first brand
await brand.click();
await tabForwardFrontend(); // focus brand version
await tabForwardFrontend(); // focus delete brand button
await tabForward(); // focus brand version
await tabForward(); // focus delete brand button
await pressKey('Enter');
// Edit a value
@@ -284,10 +279,10 @@ describe('The Network Tab', async function() {
await typeText('11');
// Update
await tabForwardFrontend(); // focus architecture
await tabForwardFrontend(); // focus device model
await tabForwardFrontend(); // focus mobile checkbox
await tabForwardFrontend(); // focus update button
await tabForward(); // focus architecture
await tabForward(); // focus device model
await tabForward(); // focus mobile checkbox
await tabForward(); // focus update button
await pressKey('Enter');
const updatedUserAgentMetadata = await getUserAgentMetadataFromTarget(target);
assert.deepEqual(updatedUserAgentMetadata, {
+1
View File
@@ -16,6 +16,7 @@ copy_to_gen("console") {
"dom-interactions.html",
"error-with-async-frame.html",
"escaping.html",
"focus-interaction.html",
"ignoreMe.js",
"log-source.js",
"navigation/after-navigation.html",
@@ -0,0 +1,10 @@
<!--
Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<script type="module">
console.log('First message');
console.log('Second message');
console.log('Third message');
</script>
+30 -13
View File
@@ -401,9 +401,9 @@ export const step = async (description: string, step: Function) => {
};
export const waitForAnimationFrame = async () => {
const {target} = getBrowserAndPages();
const {frontend} = getBrowserAndPages();
await target.waitForFunction(() => {
await frontend.waitForFunction(() => {
return new Promise(resolve => {
requestAnimationFrame(resolve);
});
@@ -411,11 +411,11 @@ export const waitForAnimationFrame = async () => {
};
export const activeElement = async(): Promise<puppeteer.ElementHandle> => {
const {target} = getBrowserAndPages();
const {frontend} = getBrowserAndPages();
await waitForAnimationFrame();
return target.evaluateHandle(() => {
return frontend.evaluateHandle(() => {
let activeElement = document.activeElement;
while (activeElement && activeElement.shadowRoot) {
@@ -431,18 +431,35 @@ export const activeElementTextContent = async () => {
return element.evaluate(node => node.textContent);
};
export const tabForward = async () => {
const {target} = getBrowserAndPages();
await target.keyboard.press('Tab');
export const activeElementAccessibleName = async () => {
const element = await activeElement();
return element.evaluate(node => node.getAttribute('aria-label'));
};
export const tabBackward = async () => {
const {target} = getBrowserAndPages();
export const tabForward = async (page?: puppeteer.Page) => {
let targetPage: puppeteer.Page;
if (page) {
targetPage = page;
} else {
const {frontend} = getBrowserAndPages();
targetPage = frontend;
}
await target.keyboard.down('Shift');
await target.keyboard.press('Tab');
await target.keyboard.up('Shift');
await targetPage.keyboard.press('Tab');
};
export const tabBackward = async (page?: puppeteer.Page) => {
let targetPage: puppeteer.Page;
if (page) {
targetPage = page;
} else {
const {frontend} = getBrowserAndPages();
targetPage = frontend;
}
await targetPage.keyboard.down('Shift');
await targetPage.keyboard.press('Tab');
await targetPage.keyboard.up('Shift');
};
export const selectTextFromNodeToNode = async (