mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-09-30 01:07:01 +08:00
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:
committed by
Devtools-frontend LUCI CQ
parent
2906222f2a
commit
72f2d4bcc8
@@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user