diff --git a/test-runner/src/expect.ts b/test-runner/src/expect.ts new file mode 100644 index 0000000000..478c771666 --- /dev/null +++ b/test-runner/src/expect.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import GoldenUtils from './GoldenUtils'; + +declare global { + const expect: typeof import('expect'); +} + +declare module 'expect/build/types' { + interface Matchers { + toMatchImage(path: string, options?: { threshold?: number }): R; + } +} + +global['expect'] = require('expect'); + +let relativeTestFile: string; + +export function initializeImageMatcher(options) { + function toMatchImage(received, name, config) { + const { pass, message } = GoldenUtils.compare(received, name, { ...options, relativeTestFile, config }); + return { pass, message: () => message }; + }; + expect.extend({ toMatchImage }); +} + +export function setCurrentTestFile(testFile: string) { + relativeTestFile = testFile; +} \ No newline at end of file diff --git a/test-runner/src/index.ts b/test-runner/src/index.ts index 00ad8b8db6..7eae1a2764 100644 --- a/test-runner/src/index.ts +++ b/test-runner/src/index.ts @@ -15,4 +15,5 @@ * limitations under the License. */ import './builtin.fixtures'; +import './expect'; export {registerFixture, registerWorkerFixture, registerParameter, parameters} from './fixtures'; \ No newline at end of file diff --git a/test-runner/src/runner.js b/test-runner/src/runner.js index c9cebc98ec..1d6dcacddb 100644 --- a/test-runner/src/runner.js +++ b/test-runner/src/runner.js @@ -263,7 +263,7 @@ class InProcessWorker extends EventEmitter { } async init() { - const { initializeImageMatcher } = require('./testRunner'); + const { initializeImageMatcher } = require('./expect'); initializeImageMatcher(this.runner._options); } diff --git a/test-runner/src/testRunner.ts b/test-runner/src/testRunner.ts index da7ef20ecc..73bc0217ea 100644 --- a/test-runner/src/testRunner.ts +++ b/test-runner/src/testRunner.ts @@ -19,17 +19,9 @@ import Mocha from 'mocha'; import { FixturePool, registerWorkerFixture, rerunRegistrations, setParameters } from './fixtures'; import { fixturesUI } from './fixturesUI'; import { EventEmitter } from 'events'; +import { setCurrentTestFile } from './expect'; export const fixturePool = new FixturePool(); -declare global { - namespace NodeJS { - interface Global { - expect: typeof import('expect') - } - } -} -global.expect = require('expect'); -const GoldenUtils = require('./GoldenUtils'); export type TestRunnerEntry = { file: string; @@ -106,7 +98,7 @@ export class TestRunner extends EventEmitter { const constants = Mocha.Runner.constants; this._runner.on(constants.EVENT_TEST_BEGIN, test => { - relativeTestFile = this._relativeTestFile; + setCurrentTestFile(this._relativeTestFile); if (this._failedWithError) return; const ordinal = ++this._currentOrdinal; @@ -240,13 +232,3 @@ function serializeError(error) { } return trimCycles(error); } - -let relativeTestFile; - -export function initializeImageMatcher(options) { - function toMatchImage(received, name, config) { - const { pass, message } = GoldenUtils.compare(received, name, { ...options, relativeTestFile, config }); - return { pass, message: () => message }; - }; - global.expect.extend({ toMatchImage }); -} diff --git a/test-runner/src/worker.js b/test-runner/src/worker.js index 1b0dd745ba..1ef9e6e2c9 100644 --- a/test-runner/src/worker.js +++ b/test-runner/src/worker.js @@ -14,7 +14,8 @@ * limitations under the License. */ -const { TestRunner, initializeImageMatcher, fixturePool } = require('./testRunner'); +const { initializeImageMatcher } = require('./expect'); +const { TestRunner, fixturePool } = require('./testRunner'); const util = require('util'); diff --git a/test/keyboard.spec.ts b/test/keyboard.spec.ts index c87e0c0634..9ecb85caa8 100644 --- a/test/keyboard.spec.ts +++ b/test/keyboard.spec.ts @@ -88,18 +88,18 @@ it.fail(options.FIREFOX && MAC)('should report shiftKey', async ({page, server}) const codeForKey = {'Shift': 16, 'Alt': 18, 'Control': 17}; for (const modifierKey in codeForKey) { await keyboard.down(modifierKey); - expect(await page.evaluate(() => getResult())).toBe('Keydown: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' [' + modifierKey + ']'); + expect(await page.evaluate('getResult()')).toBe('Keydown: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' [' + modifierKey + ']'); await keyboard.down('!'); // Shift+! will generate a keypress if (modifierKey === 'Shift') - expect(await page.evaluate(() => getResult())).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']\nKeypress: ! Digit1 33 33 [' + modifierKey + ']'); + expect(await page.evaluate('getResult()')).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']\nKeypress: ! Digit1 33 33 [' + modifierKey + ']'); else - expect(await page.evaluate(() => getResult())).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']'); + expect(await page.evaluate('getResult()')).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']'); await keyboard.up('!'); - expect(await page.evaluate(() => getResult())).toBe('Keyup: ! Digit1 49 [' + modifierKey + ']'); + expect(await page.evaluate('getResult()')).toBe('Keyup: ! Digit1 49 [' + modifierKey + ']'); await keyboard.up(modifierKey); - expect(await page.evaluate(() => getResult())).toBe('Keyup: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' []'); + expect(await page.evaluate('getResult()')).toBe('Keyup: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' []'); } }); @@ -107,28 +107,28 @@ it('should report multiple modifiers', async ({page, server}) => { await page.goto(server.PREFIX + '/input/keyboard.html'); const keyboard = page.keyboard; await keyboard.down('Control'); - expect(await page.evaluate(() => getResult())).toBe('Keydown: Control ControlLeft 17 [Control]'); + expect(await page.evaluate('getResult()')).toBe('Keydown: Control ControlLeft 17 [Control]'); await keyboard.down('Alt'); - expect(await page.evaluate(() => getResult())).toBe('Keydown: Alt AltLeft 18 [Alt Control]'); + expect(await page.evaluate('getResult()')).toBe('Keydown: Alt AltLeft 18 [Alt Control]'); await keyboard.down(';'); - expect(await page.evaluate(() => getResult())).toBe('Keydown: ; Semicolon 186 [Alt Control]'); + expect(await page.evaluate('getResult()')).toBe('Keydown: ; Semicolon 186 [Alt Control]'); await keyboard.up(';'); - expect(await page.evaluate(() => getResult())).toBe('Keyup: ; Semicolon 186 [Alt Control]'); + expect(await page.evaluate('getResult()')).toBe('Keyup: ; Semicolon 186 [Alt Control]'); await keyboard.up('Control'); - expect(await page.evaluate(() => getResult())).toBe('Keyup: Control ControlLeft 17 [Alt]'); + expect(await page.evaluate('getResult()')).toBe('Keyup: Control ControlLeft 17 [Alt]'); await keyboard.up('Alt'); - expect(await page.evaluate(() => getResult())).toBe('Keyup: Alt AltLeft 18 []'); + expect(await page.evaluate('getResult()')).toBe('Keyup: Alt AltLeft 18 []'); }); 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( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: ! Digit1 49 []', 'Keypress: ! Digit1 33 33 []', 'Keyup: ! Digit1 49 []'].join('\n')); await page.keyboard.type('^'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: ^ Digit6 54 []', 'Keypress: ^ Digit6 94 94 []', 'Keyup: ^ Digit6 54 []'].join('\n')); @@ -139,7 +139,7 @@ it('should send proper codes while typing with shift', async ({page, server}) => const keyboard = page.keyboard; await keyboard.down('Shift'); await page.keyboard.type('~'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: Shift ShiftLeft 16 [Shift]', 'Keydown: ~ Backquote 192 [Shift]', // 192 is ` keyCode 'Keypress: ~ Backquote 126 126 [Shift]', // 126 is ~ charCode @@ -167,7 +167,7 @@ it('should not type canceled events', async ({page, server}) => { it('should press plus', async ({page, server}) => { await page.goto(server.PREFIX + '/input/keyboard.html'); await page.keyboard.press('+'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: + Equal 187 []', // 192 is ` keyCode 'Keypress: + Equal 43 43 []', // 126 is ~ charCode 'Keyup: + Equal 187 []'].join('\n')); @@ -176,7 +176,7 @@ it('should press plus', async ({page, server}) => { it('should press shift plus', async ({page, server}) => { await page.goto(server.PREFIX + '/input/keyboard.html'); await page.keyboard.press('Shift++'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: Shift ShiftLeft 16 [Shift]', 'Keydown: + Equal 187 [Shift]', // 192 is ` keyCode 'Keypress: + Equal 43 43 [Shift]', // 126 is ~ charCode @@ -187,7 +187,7 @@ it('should press shift plus', async ({page, server}) => { it('should support plus-separated modifiers', async ({page, server}) => { await page.goto(server.PREFIX + '/input/keyboard.html'); await page.keyboard.press('Shift+~'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: Shift ShiftLeft 16 [Shift]', 'Keydown: ~ Backquote 192 [Shift]', // 192 is ` keyCode 'Keypress: ~ Backquote 126 126 [Shift]', // 126 is ~ charCode @@ -198,7 +198,7 @@ it('should support plus-separated modifiers', async ({page, server}) => { it('should support multiple plus-separated modifiers', async ({page, server}) => { await page.goto(server.PREFIX + '/input/keyboard.html'); await page.keyboard.press('Control+Shift+~'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: Control ControlLeft 17 [Control]', 'Keydown: Shift ShiftLeft 16 [Control Shift]', 'Keydown: ~ Backquote 192 [Control Shift]', // 192 is ` keyCode @@ -210,7 +210,7 @@ it('should support multiple plus-separated modifiers', async ({page, server}) => it('should shift raw codes', async ({page, server}) => { await page.goto(server.PREFIX + '/input/keyboard.html'); await page.keyboard.press('Shift+Digit3'); - expect(await page.evaluate(() => getResult())).toBe( + expect(await page.evaluate('getResult()')).toBe( [ 'Keydown: Shift ShiftLeft 16 [Shift]', 'Keydown: # Digit3 51 [Shift]', // 51 is # keyCode 'Keypress: # Digit3 35 35 [Shift]', // 35 is # charCode diff --git a/test/playwright.fixtures.ts b/test/playwright.fixtures.ts index 2a79a22a63..d87bc2e867 100644 --- a/test/playwright.fixtures.ts +++ b/test/playwright.fixtures.ts @@ -58,9 +58,14 @@ declare global { } } -(global as any).MAC = platform === 'darwin'; -(global as any).LINUX = platform === 'linux'; -(global as any).WIN = platform === 'win32'; +declare global { + const MAC: boolean; + const LINUX: boolean; + const WIN: boolean; +} +global['MAC'] = platform === 'darwin'; +global['LINUX'] = platform === 'linux'; +global['WIN'] = platform === 'win32'; registerWorkerFixture('httpService', async ({}, test) => { const assetsPath = path.join(__dirname, 'assets'); diff --git a/test/setup.ts b/test/setup.ts index 5a29074d12..5517ea390a 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -14,6 +14,10 @@ * limitations under the License. */ +declare const before: (f: () => Promise) => void; +declare const after: (f: () => Promise) => void; +declare const matrix: (m: any) => void; + matrix({ 'browserName': process.env.BROWSER ? [process.env.BROWSER] : ['chromium', 'webkit', 'firefox'], 'headless': [!!valueFromEnv('HEADLESS', true)], diff --git a/test/tsconfig.json b/test/tsconfig.json index 3267edb3c7..4c0768eb32 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -8,5 +8,5 @@ "strictNullChecks": false, "allowSyntheticDefaultImports": true, }, - "include": ["**/*.spec.js", "types.d.ts", "**/*.ts"] + "include": ["**/*.spec.js", "**/*.ts"] } \ No newline at end of file diff --git a/test/types.d.ts b/test/types.d.ts deleted file mode 100644 index 6c6ecfccf2..0000000000 --- a/test/types.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright Microsoft Corporation. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -type ServerResponse = import('http').ServerResponse; -type IncomingMessage = import('http').IncomingMessage; - -declare module '' { - module 'expect/build/types' { - interface Matchers { - toMatchImage(path: string, options?: { threshold?: number }): R; - } - } -} - -declare const expect: typeof import('expect'); -declare const browserType: import('../index').BrowserType; - -declare var MAC: boolean; -declare var LINUX: boolean; -declare var WIN: boolean; - -// keyboard.html -declare function getResult(): string; - -declare const before: (f: () => Promise) => void; -declare const after: (f: () => Promise) => void; -declare const matrix: (m: any) => void; diff --git a/utils/testserver/index.d.ts b/utils/testserver/index.d.ts index ac5f537514..639949547b 100644 --- a/utils/testserver/index.d.ts +++ b/utils/testserver/index.d.ts @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +type ServerResponse = import('http').ServerResponse; +type IncomingMessage = import('http').IncomingMessage; + export class TestServer { static create(dirPath: string, port: number): Promise; static createHTTPS(dirPath: string, port: number): Promise;