blob: 8a74830dd97a200e10537277487897036fce3ff5 [file] [log] [blame]
// 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 {assert} from 'chai';
import {type ElementHandle} from 'puppeteer';
import {
$$,
$$textContent,
click,
platform,
selectOption,
waitFor,
waitForElementsWithTextContent,
waitForElementWithTextContent,
waitForFunction,
} from '../../shared/helper.js';
const CANCEL_BUTTON_SELECTOR = '[aria-label="Discard changes"]';
const CONFIRM_BUTTON_SELECTOR = '[aria-label="Confirm changes"]';
const DELETE_BUTTON_SELECTOR = '[aria-label="Remove shortcut"]';
const EDIT_BUTTON_SELECTOR = '[aria-label="Edit shortcut"]';
const RESET_BUTTON_SELECTOR = '[aria-label="Reset shortcuts for action"]';
const SHORTCUT_DISPLAY_SELECTOR = '.keybinds-shortcut';
const SHORTCUT_INPUT_SELECTOR = '.keybinds-editing input';
const SHORTCUT_SELECT_TEXT = 'DevTools (Default)Visual Studio Code';
export const ADD_SHORTCUT_LINK_TEXT = 'Add a shortcut';
export const SHORTCUT_CHORD_TIMEOUT = 1000;
export let VS_CODE_SHORTCUTS_SHORTCUTS = ['CtrlKCtrlS'];
export let VS_CODE_SETTINGS_SHORTCUTS = ['Shift?', 'Ctrl,'];
export let VS_CODE_SHORTCUTS_QUICK_OPEN_TEXT = 'ShortcutsCtrl + K Ctrl + SSettings';
export let VS_CODE_PAUSE_SHORTCUTS = ['Ctrl\\', 'F5', 'ShiftF5'];
export let CONTROL_1_CONTROL_2_SHORTCUT_INPUTS_TEXT = ['Ctrl + 1', 'Ctrl + 2'];
export let CONTROL_1_CONTROL_2_CHORD_INPUT_TEXT = ['Ctrl + 1 Ctrl + 2'];
export let CONTROL_2_SHORTCUT_INPUT_TEXT = ['Ctrl + 2'];
export let CONTROL_1_CONTROL_2_SHORTCUT_DISPLAY_TEXT = ['Ctrl1', 'Ctrl2'];
export let CONTROL_1_CONTROL_2_CHORD_DISPLAY_TEXT = ['Ctrl1Ctrl2'];
export let CONTROL_2_SHORTCUT_DISPLAY_TEXT = ['Ctrl2'];
export let CONSOLE_SHORTCUT_INPUT_TEXT = ['Ctrl + `'];
export let CONSOLE_SHORTCUT_DISPLAY_TEXT = ['Ctrl`'];
export let CONTROL_ALT_C_SHORTCUT_INPUT_TEXT = ['Ctrl + Alt + C'];
if (platform === 'mac') {
VS_CODE_SHORTCUTS_SHORTCUTS = ['⌘ K⌘ S'];
VS_CODE_SETTINGS_SHORTCUTS = ['⇧ ?', '⌘ ,'];
VS_CODE_SHORTCUTS_QUICK_OPEN_TEXT = 'Shortcuts⌘ K ⌘ SSettings';
VS_CODE_PAUSE_SHORTCUTS = ['F5', '⇧ F5', '⌘ \\'];
CONTROL_1_CONTROL_2_SHORTCUT_INPUTS_TEXT = ['Ctrl 1', 'Ctrl 2'];
CONTROL_1_CONTROL_2_CHORD_INPUT_TEXT = ['Ctrl 1 Ctrl 2'];
CONTROL_2_SHORTCUT_INPUT_TEXT = ['Ctrl 2'];
CONTROL_1_CONTROL_2_SHORTCUT_DISPLAY_TEXT = CONTROL_1_CONTROL_2_SHORTCUT_INPUTS_TEXT;
CONTROL_1_CONTROL_2_CHORD_DISPLAY_TEXT = ['Ctrl 1Ctrl 2'];
CONTROL_2_SHORTCUT_DISPLAY_TEXT = CONTROL_2_SHORTCUT_INPUT_TEXT;
CONSOLE_SHORTCUT_INPUT_TEXT = ['Ctrl `'];
CONSOLE_SHORTCUT_DISPLAY_TEXT = CONSOLE_SHORTCUT_INPUT_TEXT;
CONTROL_ALT_C_SHORTCUT_INPUT_TEXT = ['Ctrl ⌥ C'];
}
export const selectKeyboardShortcutPreset = async (option: string) => {
const presetSelectElement = await waitForElementWithTextContent(SHORTCUT_SELECT_TEXT);
await selectOption(await presetSelectElement.toElement('select'), option);
};
export const getShortcutListItemElement = async (shortcutText: string) => {
const textMatches = await $$textContent(shortcutText);
let titleElement;
for (const matchingElement of textMatches) {
// some actions have the same name as categories, so we have to make sure we've got the right one
if (await matchingElement.evaluate(element => element.matches('.keybinds-action-name'))) {
titleElement = matchingElement;
break;
}
}
if (!titleElement) {
assert.fail('shortcut element not found');
}
const listItemElement = await titleElement.getProperty('parentElement');
return (listItemElement as ElementHandle).asElement();
};
export const editShortcutListItem = async (shortcutText: string) => {
const listItemElement = await getShortcutListItemElement(shortcutText) as ElementHandle;
await click(listItemElement);
await waitFor(EDIT_BUTTON_SELECTOR, listItemElement);
await click(EDIT_BUTTON_SELECTOR, {root: listItemElement});
await waitFor(RESET_BUTTON_SELECTOR);
};
export const shortcutsForAction = async (shortcutText: string) => {
const listItemElement = await getShortcutListItemElement(shortcutText);
if (!listItemElement) {
assert.fail(`Could not find shortcut item with text ${shortcutText}`);
}
const shortcutElements = await listItemElement.$$(SHORTCUT_DISPLAY_SELECTOR);
const shortcutElementsTextContent =
await Promise.all(shortcutElements.map(element => element.getProperty('textContent')));
return Promise.all(
shortcutElementsTextContent.map(async textContent => textContent ? await textContent.jsonValue() : []));
};
export const shortcutInputValues = async () => {
const shortcutInputs = await $$(SHORTCUT_INPUT_SELECTOR);
if (!shortcutInputs.length) {
assert.fail('shortcut input not found');
}
const shortcutValues = await Promise.all(shortcutInputs.map(async input => input.getProperty('value')));
return Promise.all(shortcutValues.map(async value => value ? await value.jsonValue() : []));
};
export const clickAddShortcutLink = async () => {
const addShortcutLinkTextMatches = await waitForElementsWithTextContent(ADD_SHORTCUT_LINK_TEXT);
let addShortcutLinkElement;
// the link container and the link have the same textContent, but only the latter has a click handler
for (const matchingElement of addShortcutLinkTextMatches) {
if (await matchingElement.evaluate(element => element.matches('[role="link"]'))) {
addShortcutLinkElement = matchingElement;
break;
}
}
if (!addShortcutLinkElement) {
assert.fail('could not find add shortcut link');
}
await click(addShortcutLinkElement);
};
export const clickShortcutConfirmButton = async () => {
await click(CONFIRM_BUTTON_SELECTOR);
};
export const clickShortcutCancelButton = async () => {
await click(CANCEL_BUTTON_SELECTOR);
};
export const clickShortcutResetButton = async () => {
await click(RESET_BUTTON_SELECTOR);
};
export const clickShortcutDeleteButton = async (index: number) => {
const deleteButtons = await $$(DELETE_BUTTON_SELECTOR);
if (deleteButtons.length <= index) {
assert.fail(`shortcut delete button #${index} not found`);
}
await click(deleteButtons[index]);
};
export const waitForEmptyShortcutInput = async () => {
await waitForFunction(async () => {
const shortcutInputs = await $$(SHORTCUT_INPUT_SELECTOR);
const shortcutInputValues = await Promise.all(shortcutInputs.map(input => input.getProperty('value')));
const shortcutInputValueStrings =
await Promise.all(shortcutInputValues.map(value => value ? value.jsonValue() : {}));
return shortcutInputValueStrings.includes('');
});
};
export const waitForVSCodeShortcutPreset = async () => {
// wait for a shortcut that vsCode has but the default preset does not
await waitForElementWithTextContent(VS_CODE_SHORTCUTS_SHORTCUTS.join(''));
};