feat(webkit): pass all keyboard tests (#39)

Add `keyboard.sendCharacter` and fixes up all of the keyboard tests.

Drive-by to actually allow selectively installing browsers.
This commit is contained in:
Joel Einbinder 2019-11-20 16:39:12 -08:00 committed by Andrey Lushnikov
parent 308d602f06
commit 206cf7b83f
5 changed files with 53 additions and 40 deletions

View file

@ -18,6 +18,7 @@
if (require('./package.json').name === 'playwright-core')
return;
const browserSkips = {Chromium: false, Firefox: false, WebKit: false};
for (const browser of ['Chromium', 'Firefox', 'WebKit']) {
const templates = [
`PLAYWRIGHT_SKIP_${browser}_DOWNLOAD`,
@ -28,7 +29,8 @@ for (const browser of ['Chromium', 'Firefox', 'WebKit']) {
for (const varName of varNames) {
if (process.env[varName.toUpperCase()]) {
logPolitely(`**INFO** Skipping ${browser} download. "${varName}" environment variable was found.`);
return;
browserSkips[browser] = true;
break;
}
}
}
@ -47,14 +49,18 @@ if (require('fs').existsSync(require('path').join(__dirname, 'src'))) {
(async function() {
const {generateWebKitProtocol, generateChromeProtocol} = require('./utils/protocol-types-generator/') ;
if (!browserSkips.Chromium) {
const chromeRevision = await downloadBrowser('chromium', require('./chromium').createBrowserFetcher({host: downloadHost}));
await generateChromeProtocol(chromeRevision);
}
const chromeRevision = await downloadBrowser('chromium', require('./chromium').createBrowserFetcher({host: downloadHost}));
await generateChromeProtocol(chromeRevision);
if (!browserSkips.Firefox)
await downloadBrowser('firefox', require('./firefox').createBrowserFetcher({host: downloadHost}));
await downloadBrowser('firefox', require('./firefox').createBrowserFetcher({host: downloadHost}));
const webkitRevision = await downloadBrowser('webkit', require('./webkit').createBrowserFetcher({host: downloadHost}));
await generateWebKitProtocol(webkitRevision);
if (!browserSkips.WebKit) {
const webkitRevision = await downloadBrowser('webkit', require('./webkit').createBrowserFetcher({host: downloadHost}));
await generateWebKitProtocol(webkitRevision);
}
})();
function getRevision(browser) {
if (browser === 'chromium')

View file

@ -10,7 +10,7 @@
"playwright": {
"chromium_revision": "706915",
"firefox_revision": "1",
"webkit_revision": "1"
"webkit_revision": "2"
},
"scripts": {
"unit": "node test/test.js",

View file

@ -23,7 +23,8 @@ type KeyDefinition = {
code?: string
text?: string
shiftText?: string
location ?: number
location ?: number,
windowsVirtualKeyCode?: number;
}
export const keyDefinitions: { [s: string]: KeyDefinition; } = {
@ -48,12 +49,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},
'ShiftRight': {'keyCode': 16, 'code': 'ShiftRight', 'key': 'Shift', 'location': 2},
'ControlLeft': {'keyCode': 17, 'code': 'ControlLeft', 'key': 'Control', 'location': 1},
'ControlRight': {'keyCode': 17, 'code': 'ControlRight', 'key': 'Control', 'location': 2},
'AltLeft': {'keyCode': 18, 'code': 'AltLeft', 'key': 'Alt', 'location': 1},
'AltRight': {'keyCode': 18, 'code': 'AltRight', 'key': 'Alt', 'location': 2},
'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},
'Pause': {'keyCode': 19, 'code': 'Pause', 'key': 'Pause'},
'CapsLock': {'keyCode': 20, 'code': 'CapsLock', 'key': 'CapsLock'},
'Escape': {'keyCode': 27, 'code': 'Escape', 'key': 'Escape'},
@ -175,9 +176,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},
'Control': {'keyCode': 17, 'key': 'Control', 'code': 'ControlLeft', 'location': 1},
'Alt': {'keyCode': 18, 'key': 'Alt', 'code': 'AltLeft', 'location': 1},
'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},
'Accept': {'keyCode': 30, 'key': 'Accept'},
'ModeChange': {'keyCode': 31, 'key': 'ModeChange'},
' ': {'keyCode': 32, 'key': ' ', 'code': 'Space'},

View file

@ -24,7 +24,7 @@ type KeyDescription = {
key: string,
text: string,
code: string,
location: number,
isKeypad: boolean
};
export type Modifier = 'Alt' | 'Control' | 'Meta' | 'Shift';
@ -58,7 +58,7 @@ export class Keyboard {
text: text,
unmodifiedText: text,
autoRepeat,
isKeypad: description.location === 3,
isKeypad: description.isKeypad,
});
}
@ -86,7 +86,7 @@ export class Keyboard {
keyCode: 0,
code: '',
text: '',
location: 0
isKeypad: false
};
const definition = keyDefinitions[keyString];
@ -98,15 +98,13 @@ export class Keyboard {
description.key = definition.shiftKey;
if (definition.keyCode)
description.keyCode = definition.keyCode;
description.keyCode = definition.windowsVirtualKeyCode || definition.keyCode;
if (shift && definition.shiftKeyCode)
description.keyCode = definition.shiftKeyCode;
if (definition.code)
description.code = definition.code;
if (definition.location)
description.location = definition.location;
if (description.key.length === 1)
description.text = description.key;
@ -117,9 +115,11 @@ export class Keyboard {
description.text = definition.shiftText;
// if any modifiers besides shift are pressed, no text should be sent
if (this._modifiers & ~8)
if (this._modifiers & ~1)
description.text = '';
description.isKeypad = definition.location === 3;
return description;
}
@ -146,7 +146,7 @@ export class Keyboard {
} else {
if (delay)
await new Promise(f => setTimeout(f, delay));
// unsupported character
await this.sendCharacter(char);
}
}
}
@ -179,6 +179,12 @@ export class Keyboard {
await Promise.all(promises);
return restore;
}
async sendCharacter(text: string) {
await this._session.send('Page.insertText', {
text
});
}
}
export class Mouse {

View file

@ -67,13 +67,13 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await textarea.press('b');
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('a');
});
it.skip(FFOX || WEBKIT)('ElementHandle.press should support |text| option', async({page, server}) => {
it.skip(FFOX)('ElementHandle.press should support |text| option', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = await page.$('textarea');
await textarea.press('a', {text: 'ё'});
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('ё');
});
it.skip(WEBKIT)('should send a character with sendCharacter', async({page, server}) => {
it('should send a character with sendCharacter', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
await page.keyboard.sendCharacter('嗨');
@ -82,7 +82,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await page.keyboard.sendCharacter('a');
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('嗨a');
});
it.skip(WEBKIT)('should report shiftKey', async({page, server}) => {
it('should report shiftKey', async({page, server}) => {
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
const codeForKey = {'Shift': 16, 'Alt': 18, 'Control': 17};
@ -102,7 +102,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
expect(await page.evaluate(() => getResult())).toBe('Keyup: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' []');
}
});
it.skip(WEBKIT)('should report multiple modifiers', async({page, server}) => {
it('should report multiple modifiers', async({page, server}) => {
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
await keyboard.down('Control');
@ -118,7 +118,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await keyboard.up('Alt');
expect(await page.evaluate(() => getResult())).toBe('Keyup: Alt AltLeft 18 []');
});
it.skip(WEBKIT)('should send proper codes while typing', async({page, server}) => {
it('should send proper codes while typing', async({page, server}) => {
await page.goto(server.PREFIX + '/input/keyboard.html');
await page.keyboard.type('!');
expect(await page.evaluate(() => getResult())).toBe(
@ -131,7 +131,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
'Keypress: ^ Digit6 94 94 []',
'Keyup: ^ Digit6 54 []'].join('\n'));
});
it.skip(WEBKIT)('should send proper codes while typing with shift', async({page, server}) => {
it('should send proper codes while typing with shift', async({page, server}) => {
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
await keyboard.down('Shift');
@ -143,7 +143,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
'Keyup: ~ Backquote 192 [Shift]'].join('\n'));
await keyboard.up('Shift');
});
it.skip(WEBKIT)('should not type canceled events', async({page, server}) => {
it('should not type canceled events', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
await page.evaluate(() => {
@ -159,7 +159,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await page.keyboard.type('Hello World!');
expect(await page.evaluate(() => textarea.value)).toBe('He Wrd!');
});
it.skip(WEBKIT)('should specify repeat property', async({page, server}) => {
it('should specify repeat property', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
await page.evaluate(() => document.querySelector('textarea').addEventListener('keydown', e => window.lastEvent = e, true));
@ -177,14 +177,14 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await page.keyboard.down('a');
expect(await page.evaluate(() => window.lastEvent.repeat)).toBe(false);
});
it.skip(WEBKIT)('should type all kinds of characters', async({page, server}) => {
it('should type all kinds of characters', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
const text = 'This text goes onto two lines.\nThis character is 嗨.';
await page.keyboard.type(text);
expect(await page.evaluate('result')).toBe(text);
});
it.skip(WEBKIT)('should specify location', async({page, server}) => {
it('should specify location', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.evaluate(() => {
window.addEventListener('keydown', event => window.keyLocation = event.location, true);
@ -203,7 +203,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
await textarea.press('NumpadSubtract');
expect(await page.evaluate('keyLocation')).toBe(3);
});
it.skip(WEBKIT)('should throw on unknown keys', async({page, server}) => {
it('should throw on unknown keys', async({page, server}) => {
let error = await page.keyboard.press('NotARealKey').catch(e => e);
expect(error.message).toBe('Unknown key: "NotARealKey"');
@ -213,12 +213,12 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
error = await page.keyboard.press('😊').catch(e => e);
expect(error && error.message).toBe('Unknown key: "😊"');
});
it.skip(WEBKIT)('should type emoji', async({page, server}) => {
it('should type emoji', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.type('textarea', '👹 Tokyo street Japan 🇯🇵');
expect(await page.$eval('textarea', textarea => textarea.value)).toBe('👹 Tokyo street Japan 🇯🇵');
});
it.skip(WEBKIT)('should type emoji into an iframe', async({page, server}) => {
it('should type emoji into an iframe', async({page, server}) => {
await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(page, 'emoji-test', server.PREFIX + '/input/textarea.html');
const frame = page.frames()[1];
@ -226,7 +226,7 @@ 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(WEBKIT)('should press the meta key', async({page}) => {
it('should press the meta key', async({page}) => {
await page.evaluate(() => {
window.result = null;
document.addEventListener('keydown', event => {