mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-06 20:11:38 +08:00
DISABLE_THIRD_PARTY_CHECK=big clang format run against all files in front_end and test/ Bug: 1319340 Change-Id: I1fff63cb07544ccd0e3059fc901f9a48ff4af13b Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3598879 Reviewed-by: Alex Rudenko <alexrudenko@chromium.org> Commit-Queue: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Wolfgang Beyer <wolfi@chromium.org>
154 lines
5.4 KiB
TypeScript
154 lines
5.4 KiB
TypeScript
// 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.
|
|
|
|
import {
|
|
click,
|
|
getBrowserAndPages,
|
|
tabForward,
|
|
timeout,
|
|
typeText,
|
|
waitFor,
|
|
waitForFunction,
|
|
waitForNone,
|
|
} from '../../shared/helper.js';
|
|
import {beforeEach, describe, it} from '../../shared/mocha-extensions.js';
|
|
import {
|
|
CONSOLE_COMPLETION_HINT_SELECTOR,
|
|
CONSOLE_TAB_SELECTOR,
|
|
CONSOLE_TOOLTIP_SELECTOR,
|
|
focusConsolePrompt,
|
|
waitForLastConsoleMessageToHaveContent,
|
|
} from '../helpers/console-helpers.js';
|
|
import {openSourcesPanel} from '../helpers/sources-helpers.js';
|
|
|
|
describe('The Console Tab', async () => {
|
|
beforeEach(async () => {
|
|
const {frontend} = getBrowserAndPages();
|
|
|
|
await click(CONSOLE_TAB_SELECTOR);
|
|
await focusConsolePrompt();
|
|
|
|
await typeText('let object = {a:1, b:2}; let map = new Map([["somekey", 5], ["some other key", 42]])');
|
|
await frontend.keyboard.press('Enter');
|
|
|
|
// Wait for the console to be usable again.
|
|
await frontend.waitForFunction(() => {
|
|
return document.querySelectorAll('.console-user-command-result').length === 1;
|
|
});
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Make sure we don't close DevTools while there is an outstanding
|
|
// Runtime.evaluate CDP request, which causes an error. crbug.com/1134579.
|
|
await openSourcesPanel();
|
|
});
|
|
|
|
// See the comments in console-repl-mode_test to see why this is necessary.
|
|
async function objectAutocompleteTest(textAfterObject: string) {
|
|
const {frontend} = getBrowserAndPages();
|
|
|
|
const appearPromise = waitFor(CONSOLE_TOOLTIP_SELECTOR);
|
|
await typeText('object');
|
|
await appearPromise;
|
|
|
|
const disappearPromise = waitForNone(CONSOLE_TOOLTIP_SELECTOR);
|
|
await frontend.keyboard.press('Escape');
|
|
await disappearPromise;
|
|
|
|
const appearPromise2 = waitFor(CONSOLE_TOOLTIP_SELECTOR);
|
|
await typeText(textAfterObject);
|
|
await appearPromise2;
|
|
|
|
// The first auto-suggest result is evaluated and generates a preview, which
|
|
// we wait for so that we don't end the test/navigate with an open
|
|
// Runtime.evaluate CDP request, which causes an error. crbug.com/1134579.
|
|
await waitFor('.console-eager-inner-preview > span');
|
|
}
|
|
|
|
it('triggers autocompletion for `object.`', async () => {
|
|
await objectAutocompleteTest('.');
|
|
});
|
|
|
|
it('triggers autocompletion for `object?.`', async () => {
|
|
await objectAutocompleteTest('?.');
|
|
});
|
|
|
|
it('triggers autocompletion for `object[`', async () => {
|
|
await objectAutocompleteTest('[');
|
|
});
|
|
|
|
describe('triggers autocompletion for maps', () => {
|
|
async function typeMapGetter() {
|
|
const {frontend} = getBrowserAndPages();
|
|
|
|
const appearPromise = waitFor(CONSOLE_TOOLTIP_SELECTOR);
|
|
await typeText('map.get');
|
|
await appearPromise;
|
|
|
|
const disappearPromise = waitForNone(CONSOLE_TOOLTIP_SELECTOR);
|
|
await frontend.keyboard.press('Escape');
|
|
await disappearPromise;
|
|
|
|
const appearPromise2 = waitFor(CONSOLE_COMPLETION_HINT_SELECTOR);
|
|
await typeText('(');
|
|
await appearPromise2;
|
|
|
|
await waitForFunction(async () => {
|
|
const completionHint = await waitFor(CONSOLE_COMPLETION_HINT_SELECTOR);
|
|
return await completionHint.evaluate(node => node.textContent === '"somekey")');
|
|
});
|
|
|
|
// Even though the completion hint has the correct contents, there are no atomic DOM updates
|
|
// for the console input. This means that there is a race condition between when CodeMirror
|
|
// has finished computing the completion hint (and written it to the DOM) and when it is
|
|
// ready to receive further key inputs. This typically happens near instantly, but it is
|
|
// possible for another task to be inserted in between these two events. Since we are
|
|
// writing to the DOM, 100ms timeout is sufficient to flush the DOM and let all of the components
|
|
// be in sync.
|
|
await timeout(100);
|
|
}
|
|
|
|
it('can select the first key result', async () => {
|
|
const {frontend} = getBrowserAndPages();
|
|
await typeMapGetter();
|
|
|
|
const completionPromise = waitForNone(CONSOLE_COMPLETION_HINT_SELECTOR);
|
|
await tabForward();
|
|
await completionPromise;
|
|
|
|
await frontend.keyboard.press('Enter');
|
|
await frontend.waitForFunction(() => {
|
|
return document.querySelectorAll('.console-user-command-result').length === 2;
|
|
});
|
|
|
|
await waitForLastConsoleMessageToHaveContent('5');
|
|
});
|
|
|
|
it('can select the second key result', async () => {
|
|
const {frontend} = getBrowserAndPages();
|
|
await typeMapGetter();
|
|
|
|
// Select the second key by pressing the arrow down.
|
|
// Keys should be ordered by appearance in the original `Map.keys()` array
|
|
await frontend.keyboard.press('ArrowDown');
|
|
|
|
await frontend.waitForFunction(() => {
|
|
return document.querySelectorAll('.console-eager-inner-preview').length === 1 &&
|
|
document.querySelectorAll('.console-eager-inner-preview')[0].textContent === '42';
|
|
});
|
|
|
|
const completionPromise = waitForNone(CONSOLE_COMPLETION_HINT_SELECTOR);
|
|
await tabForward();
|
|
await completionPromise;
|
|
|
|
await frontend.keyboard.press('Enter');
|
|
await frontend.waitForFunction(() => {
|
|
return document.querySelectorAll('.console-user-command-result').length === 2;
|
|
});
|
|
|
|
await waitForLastConsoleMessageToHaveContent('42');
|
|
});
|
|
});
|
|
});
|