blob: 5a461d6a4e0dbb907753414317465ac1964b281f [file]
// 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');
});
});
});