feat: implement mac keyboard

This commit is contained in:
Andrey Lushnikov 2019-12-09 19:02:01 -08:00
parent 44d6f608ef
commit 41868b0472
10 changed files with 197 additions and 31 deletions

View file

@ -10,7 +10,7 @@
"playwright": {
"chromium_revision": "719491",
"firefox_revision": "1004",
"webkit_revision": "1023"
"webkit_revision": "1025"
},
"scripts": {
"unit": "node test/test.js",

View file

@ -17,6 +17,7 @@
type KeyDefinition = {
keyCode?: number;
keyCodeWithoutLocation?: number;
shiftKeyCode?: number;
key?: string;
shiftKey?: string;
@ -51,12 +52,12 @@ export const keyDefinitions: { [s: string]: KeyDefinition; } = {
'Enter': {'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r'},
'\r': {'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r'},
'\n': {'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r'},
'ShiftLeft': {'keyCode': 16, 'code': 'ShiftLeft', 'key': 'Shift', 'location': 1, 'windowsVirtualKeyCode': 160},
'ShiftRight': {'keyCode': 16, 'code': 'ShiftRight', 'key': 'Shift', 'location': 2, 'windowsVirtualKeyCode': 161},
'ControlLeft': {'keyCode': 17, 'code': 'ControlLeft', 'key': 'Control', 'location': 1, 'windowsVirtualKeyCode': 162},
'ControlRight': {'keyCode': 17, 'code': 'ControlRight', 'key': 'Control', 'location': 2, 'windowsVirtualKeyCode': 163},
'AltLeft': {'keyCode': 18, 'code': 'AltLeft', 'key': 'Alt', 'location': 1, 'windowsVirtualKeyCode': 164},
'AltRight': {'keyCode': 18, 'code': 'AltRight', 'key': 'Alt', 'location': 2, 'windowsVirtualKeyCode': 165},
'ShiftLeft': {'keyCode': 160, 'keyCodeWithoutLocation': 16, 'code': 'ShiftLeft', 'key': 'Shift', 'location': 1, 'windowsVirtualKeyCode': 160},
'ShiftRight': {'keyCode': 161, 'keyCodeWithoutLocation': 16, 'code': 'ShiftRight', 'key': 'Shift', 'location': 2, 'windowsVirtualKeyCode': 161},
'ControlLeft': {'keyCode': 162, 'keyCodeWithoutLocation': 17, 'code': 'ControlLeft', 'key': 'Control', 'location': 1, 'windowsVirtualKeyCode': 162},
'ControlRight': {'keyCode': 163, 'keyCodeWithoutLocation': 17, 'code': 'ControlRight', 'key': 'Control', 'location': 2, 'windowsVirtualKeyCode': 163},
'AltLeft': {'keyCode': 164, 'keyCodeWithoutLocation': 18, 'code': 'AltLeft', 'key': 'Alt', 'location': 1, 'windowsVirtualKeyCode': 164},
'AltRight': {'keyCode': 165, 'keyCodeWithoutLocation': 18, 'code': 'AltRight', 'key': 'Alt', 'location': 2, 'windowsVirtualKeyCode': 165},
'Pause': {'keyCode': 19, 'code': 'Pause', 'key': 'Pause'},
'CapsLock': {'keyCode': 20, 'code': 'CapsLock', 'key': 'CapsLock'},
'Escape': {'keyCode': 27, 'code': 'Escape', 'key': 'Escape'},
@ -178,9 +179,9 @@ export const keyDefinitions: { [s: string]: KeyDefinition; } = {
'Props': {'keyCode': 247, 'code': 'Props', 'key': 'CrSel'},
'Cancel': {'keyCode': 3, 'key': 'Cancel', 'code': 'Abort'},
'Clear': {'keyCode': 12, 'key': 'Clear', 'code': 'Numpad5', 'location': 3},
'Shift': {'keyCode': 16, 'key': 'Shift', 'code': 'ShiftLeft', 'location': 1, 'windowsVirtualKeyCode': 160},
'Control': {'keyCode': 17, 'key': 'Control', 'code': 'ControlLeft', 'location': 1, 'windowsVirtualKeyCode': 162},
'Alt': {'keyCode': 18, 'key': 'Alt', 'code': 'AltLeft', 'location': 1, 'windowsVirtualKeyCode': 164},
'Shift': {'keyCode': 160, 'keyCodeWithoutLocation': 16, 'key': 'Shift', 'code': 'ShiftLeft', 'location': 1, 'windowsVirtualKeyCode': 160},
'Control': {'keyCode': 162, 'keyCodeWithoutLocation': 17, 'key': 'Control', 'code': 'ControlLeft', 'location': 1, 'windowsVirtualKeyCode': 162},
'Alt': {'keyCode': 164, 'keyCodeWithoutLocation': 18, 'key': 'Alt', 'code': 'AltLeft', 'location': 1, 'windowsVirtualKeyCode': 164},
'Accept': {'keyCode': 30, 'key': 'Accept'},
'ModeChange': {'keyCode': 31, 'key': 'ModeChange'},
' ': {'keyCode': 32, 'key': ' ', 'code': 'Space'},
@ -286,3 +287,114 @@ export const keyDefinitions: { [s: string]: KeyDefinition; } = {
'VolumeDown': {'keyCode': 182, 'key': 'VolumeDown', 'code': 'VolumeDown', 'location': 4},
'VolumeUp': {'keyCode': 183, 'key': 'VolumeUp', 'code': 'VolumeUp', 'location': 4},
};
export const macEditingCommands: {[key: string]: string|string[]} = {
'Backspace': 'deleteBackward:',
'Tab': 'insertTab:',
'Enter': 'insertNewline:',
'Escape': 'cancelOperation:',
'ArrowUp': 'moveUp:',
'ArrowDown': 'moveDown:',
'ArrowLeft': 'moveLeft:',
'ArrowRight': 'moveRight:',
'F5': 'complete:',
'Delete': 'deleteForward:',
'Home': 'scrollToBeginningOfDocument:',
'End': 'scrollToEndOfDocument:',
'PageUp': 'scrollPageUp:',
'PageDown': 'scrollPageDown:',
'Shift+Backspace': 'deleteBackward:',
'Shift+Enter': 'insertNewline:',
'Shift+Tab': 'insertBacktab:',
'Shift+Escape': 'cancelOperation:',
'Shift+ArrowUp': 'moveUpAndModifySelection:',
'Shift+ArrowDown': 'moveDownAndModifySelection:',
'Shift+ArrowLeft': 'moveLeftAndModifySelection:',
'Shift+ArrowRight': 'moveRightAndModifySelection:',
'Shift+F5': 'complete:',
'Shift+Delete': 'deleteForward:',
'Shift+Home': 'moveToBeginningOfDocumentAndModifySelection:',
'Shift+End': 'moveToEndOfDocumentAndModifySelection:',
'Shift+PageUp': 'pageUpAndModifySelection:',
'Shift+PageDown': 'pageDownAndModifySelection:',
'Shift+Numpad5': 'delete:',
'Control+Tab': 'selectNextKeyView:',
'Control+Enter': 'insertLineBreak:',
'Control+Quote': 'insertSingleQuoteIgnoringSubstitution:',
'Control+KeyA': 'moveToBeginningOfParagraph:',
'Control+KeyB': 'moveBackward:',
'Control+KeyD': 'deleteForward:',
'Control+KeyE': 'moveToEndOfParagraph:',
'Control+KeyF': 'moveForward:',
'Control+KeyH': 'deleteBackward:',
'Control+KeyK': 'deleteToEndOfParagraph:',
'Control+KeyL': 'centerSelectionInVisibleArea:',
'Control+KeyN': 'moveDown:',
'Control+KeyO': ['insertNewlineIgnoringFieldEditor:', 'moveBackward:'],
'Control+KeyP': 'moveUp:',
'Control+KeyT': 'transpose:',
'Control+KeyV': 'pageDown:',
'Control+KeyY': 'yank:',
'Control+Backspace': 'deleteBackwardByDecomposingPreviousCharacter:',
'Control+ArrowUp': 'scrollPageUp:',
'Control+ArrowDown': 'scrollPageDown:',
'Control+ArrowLeft': 'moveToLeftEndOfLine:',
'Control+ArrowRight': 'moveToRightEndOfLine:',
'Shift+Control+Enter': 'insertLineBreak:',
'Shift+Control+Tab': 'selectPreviousKeyView:',
'Shift+Control+Quote': 'insertDoubleQuoteIgnoringSubstitution:',
'Shift+Control+KeyA': 'moveToBeginningOfParagraphAndModifySelection:',
'Shift+Control+KeyB': 'moveBackwardAndModifySelection:',
'Shift+Control+KeyE': 'moveToEndOfParagraphAndModifySelection:',
'Shift+Control+KeyF': 'moveForwardAndModifySelection:',
'Shift+Control+KeyN': 'moveDownAndModifySelection:',
'Shift+Control+KeyP': 'moveUpAndModifySelection:',
'Shift+Control+KeyV': 'pageDownAndModifySelection:',
'Shift+Control+Backspace': 'deleteBackwardByDecomposingPreviousCharacter:',
'Shift+Control+ArrowUp': 'scrollPageUp:',
'Shift+Control+ArrowDown': 'scrollPageDown:',
'Shift+Control+ArrowLeft': 'moveToLeftEndOfLineAndModifySelection:',
'Shift+Control+ArrowRight': 'moveToRightEndOfLineAndModifySelection:',
'Alt+Backspace': 'deleteWordBackward:',
'Alt+Tab': 'insertTabIgnoringFieldEditor:',
'Alt+Enter': 'insertNewlineIgnoringFieldEditor:',
'Alt+Escape': 'complete:',
"Alt+ArrowUp": ['moveBackward:', 'moveToBeginningOfParagraph:'],
"Alt+ArrowDown": ['moveForward:', 'moveToEndOfParagraph:'],
'Alt+ArrowLeft': 'moveWordLeft:',
'Alt+ArrowRight': 'moveWordRight:',
'Alt+Delete': 'deleteWordForward:',
'Alt+PageUp': 'pageUp:',
'Alt+PageDown': 'pageDown:',
'Shift+Alt+Backspace': 'deleteWordBackward:',
'Shift+Alt+Tab': 'insertTabIgnoringFieldEditor:',
'Shift+Alt+Enter': 'insertNewlineIgnoringFieldEditor:',
'Shift+Alt+Escape': 'complete:',
'Shift+Alt+ArrowUp': 'moveParagraphBackwardAndModifySelection:',
'Shift+Alt+ArrowDown': 'moveParagraphForwardAndModifySelection:',
'Shift+Alt+ArrowLeft': 'moveWordLeftAndModifySelection:',
'Shift+Alt+ArrowRight': 'moveWordRightAndModifySelection:',
'Shift+Alt+Delete': 'deleteWordForward:',
'Shift+Alt+PageUp': 'pageUp:',
'Shift+Alt+PageDown': 'pageDown:',
'Control+Alt+KeyB': 'moveWordBackward:',
'Control+Alt+KeyF': 'moveWordForward:',
'Control+Alt+Backspace': 'deleteWordBackward:',
'Shift+Control+Alt+KeyB': 'moveWordBackwardAndModifySelection:',
'Shift+Control+Alt+KeyF': 'moveWordForwardAndModifySelection:',
'Shift+Control+Alt+Backspace': 'deleteWordBackward:',
'Meta+NumpadSubtract': 'cancel:',
'Meta+Backspace': 'deleteToBeginningOfLine:',
'Meta+ArrowUp': 'moveToBeginningOfDocument:',
'Meta+ArrowDown': 'moveToEndOfDocument:',
'Meta+ArrowLeft': 'moveToLeftEndOfLine:',
'Meta+ArrowRight': 'moveToRightEndOfLine:',
'Shift+Meta+NumpadSubtract': 'cancel:',
'Shift+Meta+Backspace': 'deleteToBeginningOfLine:',
'Shift+Meta+ArrowUp': 'moveToBeginningOfDocumentAndModifySelection:',
'Shift+Meta+ArrowDown': 'moveToEndOfDocumentAndModifySelection:',
'Shift+Meta+ArrowLeft': 'moveToLeftEndOfLineAndModifySelection:',
'Shift+Meta+ArrowRight': 'moveToRightEndOfLineAndModifySelection:',
'Meta+KeyA': 'selectAll:',
};

View file

@ -38,11 +38,11 @@ export class RawKeyboardImpl implements input.RawKeyboard {
this._client = client;
}
async keydown(modifiers: Set<input.Modifier>, code: string, keyCode: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
async keydown(modifiers: Set<input.Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
await this._client.send('Input.dispatchKeyEvent', {
type: text ? 'keyDown' : 'rawKeyDown',
modifiers: toModifiersMask(modifiers),
windowsVirtualKeyCode: keyCode,
windowsVirtualKeyCode: keyCodeWithoutLocation,
code,
key,
text,
@ -53,12 +53,12 @@ export class RawKeyboardImpl implements input.RawKeyboard {
});
}
async keyup(modifiers: Set<input.Modifier>, code: string, keyCode: number, key: string, location: number): Promise<void> {
async keyup(modifiers: Set<input.Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
await this._client.send('Input.dispatchKeyEvent', {
type: 'keyUp',
modifiers: toModifiersMask(modifiers),
key,
windowsVirtualKeyCode: keyCode,
windowsVirtualKeyCode: keyCodeWithoutLocation,
code,
location
});

View file

@ -58,14 +58,14 @@ export class RawKeyboardImpl implements input.RawKeyboard {
this._client = client;
}
async keydown(modifiers: Set<input.Modifier>, code: string, keyCode: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
async keydown(modifiers: Set<input.Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
if (code === 'MetaLeft')
code = 'OSLeft';
if (code === 'MetaRight')
code = 'OSRight';
await this._client.send('Page.dispatchKeyEvent', {
type: 'keydown',
keyCode,
keyCode: keyCodeWithoutLocation,
code,
key,
repeat: autoRepeat,
@ -73,7 +73,7 @@ export class RawKeyboardImpl implements input.RawKeyboard {
});
}
async keyup(modifiers: Set<input.Modifier>, code: string, keyCode: number, key: string, location: number): Promise<void> {
async keyup(modifiers: Set<input.Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
if (code === 'MetaLeft')
code = 'OSLeft';
if (code === 'MetaRight')
@ -81,7 +81,7 @@ export class RawKeyboardImpl implements input.RawKeyboard {
await this._client.send('Page.dispatchKeyEvent', {
type: 'keyup',
key,
keyCode,
keyCode: keyCodeWithoutLocation,
code,
location,
repeat: false

View file

@ -38,6 +38,7 @@ export const keypadLocation = keyboardLayout.keypadLocation;
type KeyDescription = {
keyCode: number,
keyCodeWithoutLocation: number,
key: string,
text: string,
code: string,
@ -47,8 +48,8 @@ type KeyDescription = {
const kModifiers: Modifier[] = ['Alt', 'Control', 'Meta', 'Shift'];
export interface RawKeyboard {
keydown(modifiers: Set<Modifier>, code: string, keyCode: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void>;
keyup(modifiers: Set<Modifier>, code: string, keyCode: number, key: string, location: number): Promise<void>;
keydown(modifiers: Set<Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void>;
keyup(modifiers: Set<Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void>;
sendText(text: string): Promise<void>;
}
@ -68,7 +69,7 @@ export class Keyboard {
if (kModifiers.includes(description.key as Modifier))
this._pressedModifiers.add(description.key as Modifier);
const text = options.text === undefined ? description.text : options.text;
await this._raw.keydown(this._pressedModifiers, description.code, description.keyCode, description.key, description.location, autoRepeat, text);
await this._raw.keydown(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location, autoRepeat, text);
}
private _keyDescriptionForString(keyString: string): KeyDescription {
@ -76,6 +77,7 @@ export class Keyboard {
const description: KeyDescription = {
key: '',
keyCode: 0,
keyCodeWithoutLocation: 0,
code: '',
text: '',
location: 0
@ -112,6 +114,10 @@ export class Keyboard {
if (this._pressedModifiers.size > 1 || (!this._pressedModifiers.has('Shift') && this._pressedModifiers.size === 1))
description.text = '';
if (definition.keyCodeWithoutLocation)
description.keyCodeWithoutLocation = definition.keyCodeWithoutLocation;
else
description.keyCodeWithoutLocation = description.keyCode;
return description;
}
@ -120,7 +126,7 @@ export class Keyboard {
if (kModifiers.includes(description.key as Modifier))
this._pressedModifiers.delete(description.key as Modifier);
this._pressedKeys.delete(description.code);
await this._raw.keyup(this._pressedModifiers, description.code, description.keyCode, description.key, description.location);
await this._raw.keyup(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location);
}
async sendCharacters(text: string) {

View file

@ -16,6 +16,8 @@
*/
import * as input from '../input';
import { helper } from '../helper';
import { macEditingCommands } from '../USKeyboardLayout';
import { TargetSession } from './Connection';
function toModifiersMask(modifiers: Set<input.Modifier>): number {
@ -39,7 +41,17 @@ export class RawKeyboardImpl implements input.RawKeyboard {
this._session = session;
}
async keydown(modifiers: Set<input.Modifier>, code: string, keyCode: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
async keydown(modifiers: Set<input.Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
const parts = [];
for (const modifier of (['Shift', 'Control', 'Alt', 'Meta']) as input.Modifier[]) {
if (modifiers.has(modifier))
parts.push(modifier);
}
parts.push(code);
const shortcut = parts.join('+');
let commands = macEditingCommands[shortcut];
if (helper.isString(commands))
commands = [commands];
await this._session.send('Input.dispatchKeyEvent', {
type: 'keyDown',
modifiers: toModifiersMask(modifiers),
@ -49,11 +61,12 @@ export class RawKeyboardImpl implements input.RawKeyboard {
text,
unmodifiedText: text,
autoRepeat,
macCommands: commands,
isKeypad: location === input.keypadLocation
});
}
async keyup(modifiers: Set<input.Modifier>, code: string, keyCode: number, key: string, location: number): Promise<void> {
async keyup(modifiers: Set<input.Modifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
await this._session.send('Input.dispatchKeyEvent', {
type: 'keyUp',
modifiers: toModifiersMask(modifiers),

View file

@ -17,7 +17,7 @@
const utils = require('./utils');
const os = require('os');
module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT, MAC}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
@ -39,7 +39,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
window.keyPromise = new Promise(resolve => document.addEventListener('keydown', event => resolve(event.key)));
});
await page.keyboard.press('Meta');
expect(await page.evaluate('keyPromise')).toBe(FFOX && os.platform() !== 'darwin' ? 'OS' : 'Meta');
expect(await page.evaluate('keyPromise')).toBe(FFOX && !MAC ? 'OS' : 'Meta');
});
it('should move with the arrow keys', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
@ -226,6 +226,34 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await textarea.type('👹 Tokyo street Japan 🇯🇵');
expect(await frame.$eval('textarea', textarea => textarea.value)).toBe('👹 Tokyo street Japan 🇯🇵');
});
it.skip(CHROME && MAC)('should handle selectAll', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = await page.$('textarea');
await textarea.type('some text');
const modifier = MAC ? 'Meta' : 'Control';
await page.keyboard.down(modifier);
await page.keyboard.press('a');
await page.keyboard.up(modifier);
await page.keyboard.press('Backspace');
expect(await page.$eval('textarea', textarea => textarea.value)).toBe('');
});
it.skip(CHROME && MAC)('should be able to prevent selectAll', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = await page.$('textarea');
await textarea.type('some text');
await page.$eval('textarea', textarea => {
textarea.addEventListener('keydown', event => {
if (event.key === 'a' && (event.metaKey || event.ctrlKey))
event.preventDefault();
}, false);
});
const modifier = MAC ? 'Meta' : 'Control';
await page.keyboard.down(modifier);
await page.keyboard.press('a');
await page.keyboard.up(modifier);
await page.keyboard.press('Backspace');
expect(await page.$eval('textarea', textarea => textarea.value)).toBe('some tex');
});
it('should press the meta key', async({page}) => {
await page.evaluate(() => {
window.result = null;
@ -235,7 +263,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
});
await page.keyboard.press('Meta');
const [key, code, metaKey] = await page.evaluate('result');
if (FFOX && os.platform() !== 'darwin')
if (FFOX && !MAC)
expect(key).toBe('OS');
else
expect(key).toBe('Meta');
@ -245,7 +273,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
else
expect(code).toBe('MetaLeft');
if (FFOX && os.platform() !== 'darwin')
if (FFOX && !MAC)
expect(metaKey).toBe(false);
else
expect(metaKey).toBe(true);

View file

@ -24,7 +24,7 @@ const statAsync = helper.promisify(fs.stat);
const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
const utils = require('./utils');
module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, playwright, FFOX, CHROME, WEBKIT}) {
module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, playwright, FFOX, CHROME, WEBKIT, WIN}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
@ -51,7 +51,7 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
revisionInfo = await browserFetcher.download('123456');
expect(revisionInfo.local).toBe(true);
expect(await readFileAsync(revisionInfo.executablePath, 'utf8')).toBe('LINUX BINARY\n');
const expectedPermissions = os.platform() === 'win32' ? 0666 : 0755;
const expectedPermissions = WIN ? 0666 : 0755;
expect((await statAsync(revisionInfo.executablePath)).mode & 0777).toBe(expectedPermissions);
expect(await browserFetcher.localRevisions()).toEqual(['123456']);
await browserFetcher.remove('123456');

View file

@ -108,7 +108,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window.lastEvent = e, true));
const modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
// In Firefox, the Meta modifier only exists on Mac
if (FFOX && os.platform() !== 'darwin')
if (FFOX && !MAC)
delete modifiers['Meta'];
for (const modifier in modifiers) {
await page.keyboard.down(modifier);

View file

@ -15,6 +15,7 @@
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
const rm = require('rimraf').sync;
const GoldenUtils = require('./golden-utils');
const {Matchers} = require('../utils/testrunner/');
@ -30,6 +31,9 @@ module.exports.addTests = ({testRunner, product, playwrightPath}) => {
const CHROME = product === 'Chromium';
const FFOX = product === 'Firefox';
const WEBKIT = product === 'WebKit';
const MAC = os.platform() === 'darwin';
const LINUX = os.platform() === 'linux';
const WIN = os.platform() === 'win32';
const playwright = require(playwrightPath);
@ -72,6 +76,9 @@ module.exports.addTests = ({testRunner, product, playwrightPath}) => {
FFOX,
WEBKIT,
CHROME,
MAC,
LINUX,
WIN,
playwright,
expect,
defaultBrowserOptions,