mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
test: convert evaluation.spec to jest+fixtures (#2968)
This commit is contained in:
parent
7080767f2c
commit
ecc130c644
32
.github/workflows/tests.yml
vendored
32
.github/workflows/tests.yml
vendored
@ -41,10 +41,10 @@ jobs:
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
- run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest 2>>./testrun.log"
|
||||
- run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest -- --testTimeout=30000"
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
@ -80,10 +80,10 @@ jobs:
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
- run: npm run jest 2>>./${{ matrix.browser }}-mac-testrun.log
|
||||
- run: npm run jest -- --testTimeout=30000
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
@ -115,11 +115,11 @@ jobs:
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
- run: npm run jest 2>>./${{ matrix.browser }}-win-testrun.log
|
||||
- run: npm run jest -- --testTimeout=30000
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
@ -170,6 +170,21 @@ jobs:
|
||||
env:
|
||||
DEBUG: "*"
|
||||
HEADLESS: "false"
|
||||
- run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest -- --testTimeout=30000"
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
BROWSER: "chromium"
|
||||
HEADLESS: "false"
|
||||
- run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest -- --testTimeout=30000"
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
BROWSER: "firefox"
|
||||
HEADLESS: "false"
|
||||
- run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest -- --testTimeout=30000"
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
BROWSER: "webkit"
|
||||
HEADLESS: "false"
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
@ -208,6 +223,11 @@ jobs:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
DEBUG: "*,-pw:wrapped*"
|
||||
PWCHANNEL: ${{ matrix.transport }}
|
||||
- run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest -- --testTimeout=30000"
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
PWCHANNEL: ${{ matrix.transport }}
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
|
@ -1,6 +1,9 @@
|
||||
{
|
||||
"rootDir": "./test/jest",
|
||||
"testEnvironment": ".",
|
||||
"testMatch": ["**/?(*.)spec.[jt]s"],
|
||||
"testRunner": "jest-circus/runner"
|
||||
"rootDir": "./test",
|
||||
"testEnvironment": "./jest",
|
||||
"testMatch": ["**/?(*.)jest.[jt]s"],
|
||||
"testRunner": "jest-circus/runner",
|
||||
"testTimeout": 10000,
|
||||
"globalSetup": "./jest/setup.js",
|
||||
"globalTeardown": "./jest/teardown.js"
|
||||
}
|
||||
|
125
package-lock.json
generated
125
package-lock.json
generated
@ -4872,6 +4872,12 @@
|
||||
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"get-stdin": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
|
||||
"integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
|
||||
"dev": true
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
|
||||
@ -5008,6 +5014,12 @@
|
||||
"define-properties": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"glur": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glur/-/glur-1.1.2.tgz",
|
||||
"integrity": "sha1-8g6jbbEDv8KSNDkh8fkeg8NGdok=",
|
||||
"dev": true
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
|
||||
@ -5067,6 +5079,23 @@
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
@ -6408,6 +6437,102 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"jest-image-snapshot": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-image-snapshot/-/jest-image-snapshot-4.0.2.tgz",
|
||||
"integrity": "sha512-RqKGk0HbQrfw3E3dDuxjFBXqubvPWzjj3zFP6Z7auo48rC0FNpQ5jYXThQjhfy+fvgIgyHk3jPnDNgSiIuVVtw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^1.1.3",
|
||||
"get-stdin": "^5.0.1",
|
||||
"glur": "^1.1.2",
|
||||
"lodash": "^4.17.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"pixelmatch": "^5.1.0",
|
||||
"pngjs": "^3.4.0",
|
||||
"rimraf": "^2.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"pixelmatch": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz",
|
||||
"integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pngjs": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"pngjs": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz",
|
||||
"integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"pngjs": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
|
||||
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"jest-jasmine2": {
|
||||
"version": "26.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz",
|
||||
|
@ -16,10 +16,6 @@
|
||||
"ftest": "cross-env BROWSER=firefox node --unhandled-rejections=strict test/test.js",
|
||||
"wtest": "cross-env BROWSER=webkit node --unhandled-rejections=strict test/test.js",
|
||||
"test": "cross-env node --unhandled-rejections=strict test/test.js",
|
||||
"cunit": "cross-env BROWSER=chromium node --unhandled-rejections=strict test/test.js",
|
||||
"funit": "cross-env BROWSER=firefox node --unhandled-rejections=strict test/test.js",
|
||||
"wunit": "cross-env BROWSER=webkit node --unhandled-rejections=strict test/test.js",
|
||||
"unit": "cross-env node --unhandled-rejections=strict test/test.js",
|
||||
"ccoverage": "cross-env COVERAGE=true BROWSER=chromium node --unhandled-rejections=strict test/test.js",
|
||||
"fcoverage": "cross-env COVERAGE=true BROWSER=firefox node --unhandled-rejections=strict test/test.js",
|
||||
"wcoverage": "cross-env COVERAGE=true BROWSER=webkit node --unhandled-rejections=strict test/test.js",
|
||||
@ -83,6 +79,7 @@
|
||||
"formidable": "^1.2.1",
|
||||
"jest": "^26.1.0",
|
||||
"jest-circus": "^26.1.0",
|
||||
"jest-image-snapshot": "^4.0.2",
|
||||
"ncp": "^2.0.0",
|
||||
"node-stream-zip": "^1.8.2",
|
||||
"pirates": "^4.0.1",
|
||||
|
@ -14,6 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
function isRegExp(obj: any): obj is RegExp {
|
||||
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||
}
|
||||
|
||||
function isDate(obj: any): obj is Date {
|
||||
return obj instanceof Date || Object.prototype.toString.call(obj) === '[object Date]';
|
||||
}
|
||||
|
||||
export function parseEvaluationResultValue(value: any, handles: any[] = []): any {
|
||||
if (value === undefined)
|
||||
return undefined;
|
||||
@ -85,9 +93,9 @@ function serialize(value: any, jsHandleSerializer: (value: any) => { fallThrough
|
||||
}
|
||||
return `${error.name}: ${error.message}\n${error.stack}`;
|
||||
}
|
||||
if (value instanceof Date)
|
||||
if (isDate(value))
|
||||
return { d: value.toJSON() };
|
||||
if (value instanceof RegExp)
|
||||
if (isRegExp(value))
|
||||
return { r: [ value.source, value.flags ] };
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
|
@ -180,7 +180,6 @@ class PlaywrightEnvironment {
|
||||
if (!this.expectExit)
|
||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||
});
|
||||
process.on('exit', () => this._killProcess());
|
||||
const transport = new Transport(this.spawnedProcess.stdin, this.spawnedProcess.stdout);
|
||||
connection.onmessage = message => transport.send(JSON.stringify(message));
|
||||
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
||||
@ -213,20 +212,6 @@ class PlaywrightEnvironment {
|
||||
}
|
||||
delete state.playwright;
|
||||
}
|
||||
|
||||
_killProcess() {
|
||||
if (this.spawnedProcess && this.spawnedProcess.pid) {
|
||||
this.expectExit = true;
|
||||
try {
|
||||
if (process.platform === 'win32')
|
||||
childProcess.execSync(`taskkill /pid ${this.spawnedProcess.pid} /T /F`);
|
||||
else
|
||||
process.kill(-this.spawnedProcess.pid, 'SIGKILL');
|
||||
} catch (e) {
|
||||
// the process might have already stopped
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BrowserTypeEnvironment {
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
const utils = require('./utils');
|
||||
const path = require('path');
|
||||
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS, CHANNEL} = utils.testOptions(browserType);
|
||||
|
||||
describe('Page.evaluate', function() {
|
||||
it('should work', async({page, server}) => {
|
||||
@ -357,7 +356,7 @@ describe('Page.evaluate', function() {
|
||||
});
|
||||
expect(result).toEqual([42]);
|
||||
});
|
||||
it.fail(WEBKIT)('should not throw an error when evaluation does a synchronous navigation and returns an object', async({page, server}) => {
|
||||
(WEBKIT ? it.skip : it)('should not throw an error when evaluation does a synchronous navigation and returns an object', async({page, server}) => {
|
||||
// It is imporant to be on about:blank for sync reload.
|
||||
const result = await page.evaluate(() => {
|
||||
window.location.reload();
|
||||
@ -373,7 +372,7 @@ describe('Page.evaluate', function() {
|
||||
});
|
||||
expect(result).toBe(undefined);
|
||||
});
|
||||
it.slow().skip(CHANNEL)('should transfer 100Mb of data from page to node.js', async({page, server}) => {
|
||||
(CHANNEL ? it.skip : it)('should transfer 100Mb of data from page to node.js', async({page}) => {
|
||||
const a = await page.evaluate(() => Array(100 * 1024 * 1024 + 1).join('a'));
|
||||
expect(a.length).toBe(100 * 1024 * 1024);
|
||||
});
|
||||
@ -389,7 +388,7 @@ describe('Page.evaluate', function() {
|
||||
const result = await page.evaluate(() => ({abc: 123}));
|
||||
expect(result).toEqual({abc: 123});
|
||||
});
|
||||
it.fail(FFOX)('should await promise from popup', async function({page, server}) {
|
||||
(FFOX ? it.skip : it)('should await promise from popup', async ({page, server}) => {
|
||||
// Something is wrong about the way Firefox waits for the chained promise
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const result = await page.evaluate(() => {
|
||||
@ -574,14 +573,14 @@ describe('Frame.evaluate', function() {
|
||||
else
|
||||
expect(pageImpl._delegate._contextIdToContext.size).toBe(count);
|
||||
}
|
||||
it.skip(USES_HOOKS)('should dispose context on navigation', async({page, server, toImpl}) => {
|
||||
(USES_HOOKS ? it.skip : it)('should dispose context on navigation', async({page, server, toImpl}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expectContexts(toImpl(page), 4);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expectContexts(toImpl(page), 2);
|
||||
});
|
||||
it.skip(USES_HOOKS)('should dispose context on cross-origin navigation', async({page, server, toImpl}) => {
|
||||
(USES_HOOKS ? it.skip : it)('should dispose context on cross-origin navigation', async({page, server, toImpl}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expectContexts(toImpl(page), 4);
|
132
test/jest/fixtures.js
Normal file
132
test/jest/fixtures.js
Normal file
@ -0,0 +1,132 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const childProcess = require('child_process');
|
||||
|
||||
const playwright = require('../../index');
|
||||
const { TestServer } = require('../../utils/testserver/');
|
||||
const { DispatcherConnection } = require('../../lib/rpc/server/dispatcher');
|
||||
const { Connection } = require('../../lib/rpc/client/connection');
|
||||
const { Transport } = require('../../lib/rpc/transport');
|
||||
const { PlaywrightDispatcher } = require('../../lib/rpc/server/playwrightDispatcher');
|
||||
const { setUseApiName } = require('../../lib/progress');
|
||||
|
||||
module.exports = function registerFixtures(global) {
|
||||
|
||||
global.registerWorkerFixture('server', async ({}, test) => {
|
||||
const assetsPath = path.join(__dirname, '..', 'assets');
|
||||
const cachedPath = path.join(__dirname, '..', 'assets', 'cached');
|
||||
|
||||
const port = 8907 + (process.env.JEST_WORKER_ID - 1) * 2;
|
||||
const server = await TestServer.create(assetsPath, port);
|
||||
server.enableHTTPCache(cachedPath);
|
||||
server.PORT = port;
|
||||
server.PREFIX = `http://localhost:${port}`;
|
||||
server.CROSS_PROCESS_PREFIX = `http://127.0.0.1:${port}`;
|
||||
server.EMPTY_PAGE = `http://localhost:${port}/empty.html`;
|
||||
|
||||
const httpsPort = port + 1;
|
||||
httpsServer = await TestServer.createHTTPS(assetsPath, httpsPort);
|
||||
httpsServer.enableHTTPCache(cachedPath);
|
||||
httpsServer.PORT = httpsPort;
|
||||
httpsServer.PREFIX = `https://localhost:${httpsPort}`;
|
||||
httpsServer.CROSS_PROCESS_PREFIX = `https://127.0.0.1:${httpsPort}`;
|
||||
httpsServer.EMPTY_PAGE = `https://localhost:${httpsPort}/empty.html`;
|
||||
|
||||
await test(server);
|
||||
|
||||
await Promise.all([
|
||||
server.stop(),
|
||||
httpsServer.stop(),
|
||||
]);
|
||||
});
|
||||
|
||||
global.registerWorkerFixture('playwright', async({}, test) => {
|
||||
if (process.env.PWCHANNEL) {
|
||||
setUseApiName(false);
|
||||
const connection = new Connection();
|
||||
let toImpl;
|
||||
let spawnedProcess;
|
||||
let expectExit;
|
||||
if (process.env.PWCHANNEL === 'wire') {
|
||||
spawnedProcess = childProcess.fork(path.join(__dirname, '..', '..', 'lib', 'rpc', 'server'), [], {
|
||||
stdio: 'pipe',
|
||||
detached: process.platform !== 'win32',
|
||||
});
|
||||
spawnedProcess.once('exit', (exitCode, signal) => {
|
||||
spawnedProcess = undefined;
|
||||
if (!expectExit)
|
||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||
});
|
||||
const transport = new Transport(spawnedProcess.stdin, spawnedProcess.stdout);
|
||||
connection.onmessage = message => transport.send(JSON.stringify(message));
|
||||
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
||||
} else {
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
dispatcherConnection.onmessage = async message => {
|
||||
setImmediate(() => connection.dispatch(message));
|
||||
};
|
||||
connection.onmessage = async message => {
|
||||
const result = await dispatcherConnection.dispatch(message);
|
||||
await new Promise(f => setImmediate(f));
|
||||
return result;
|
||||
};
|
||||
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
|
||||
toImpl = x => dispatcherConnection._dispatchers.get(x._guid)._object;
|
||||
}
|
||||
|
||||
const playwrightObject = await connection.waitForObjectWithKnownName('playwright');
|
||||
playwrightObject.toImpl = toImpl;
|
||||
await test(playwrightObject);
|
||||
|
||||
if (spawnedProcess) {
|
||||
const exited = new Promise(f => spawnedProcess.once('exit', f));
|
||||
expectExit = true;
|
||||
spawnedProcess.kill();
|
||||
await exited;
|
||||
}
|
||||
return;
|
||||
}
|
||||
playwright.toImpl = x => x;
|
||||
await test(playwright);
|
||||
});
|
||||
|
||||
global.registerFixture('toImpl', async ({playwright}, test) => {
|
||||
await test(playwright.toImpl);
|
||||
});
|
||||
|
||||
global.registerWorkerFixture('browserType', async ({playwright}, test) => {
|
||||
await test(playwright[process.env.BROWSER || 'chromium']);
|
||||
});
|
||||
|
||||
global.registerWorkerFixture('browser', async ({browserType}, test) => {
|
||||
const browser = await browserType.launch({ headless: !!global.HEADLESS });
|
||||
await test(browser);
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
global.registerFixture('context', async ({browser}, test) => {
|
||||
const context = await browser.newContext();
|
||||
await test(context);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
global.registerFixture('page', async ({context}, test) => {
|
||||
const page = await context.newPage();
|
||||
await test(page);
|
||||
});
|
||||
}
|
@ -15,38 +15,26 @@
|
||||
*/
|
||||
|
||||
const NodeEnvironment = require('jest-environment-node');
|
||||
const path = require('path');
|
||||
const playwright = require('../../index');
|
||||
const registerFixtures = require('./fixtures');
|
||||
|
||||
class PlaywrightEnvironment extends NodeEnvironment {
|
||||
constructor(config, context) {
|
||||
super(config, context);
|
||||
this.fixturePool = new FixturePool();
|
||||
this.global.CHROMIUM = process.env.BROWSER === 'chromium' || !process.env.BROWSER;
|
||||
this.global.FFOX = process.env.BROWSER === 'firefox';
|
||||
this.global.WEBKIT = process.env.BROWSER === 'webkit';
|
||||
this.global.USES_HOOKS = process.env.PWCHANNEL === 'wire';
|
||||
this.global.CHANNEL = !!process.env.PWCHANNEL;
|
||||
this.global.HEADLESS = !!valueFromEnv('HEADLESS', true);
|
||||
|
||||
this.global.registerFixture = (name, fn) => {
|
||||
this.fixturePool.registerFixture(name, 'test', fn);
|
||||
};
|
||||
|
||||
this.global.registerWorkerFixture = (name, fn) => {
|
||||
this.fixturePool.registerFixture(name, 'worker', fn);
|
||||
};
|
||||
|
||||
this.global.registerWorkerFixture('browser', async (test) => {
|
||||
const browser = await playwright[process.env.BROWSER || 'chromium'].launch();
|
||||
await test(browser);
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
this.global.registerFixture('context', async (browser, test) => {
|
||||
const context = await browser.newContext();
|
||||
await test(context);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
this.global.registerFixture('page', async (context, test) => {
|
||||
const page = await context.newPage();
|
||||
await test(page);
|
||||
});
|
||||
registerFixtures(this.global);
|
||||
}
|
||||
|
||||
async setup() {
|
||||
@ -93,16 +81,20 @@ class Fixture {
|
||||
this.pool.instances.get(name).usages.add(this.name);
|
||||
}
|
||||
|
||||
const params = this.deps.map(n => this.pool.instances.get(n).value);
|
||||
let setupFenceCallback;
|
||||
const setupFence = new Promise(f => setupFenceCallback = f);
|
||||
const params = {};
|
||||
for (const n of this.deps)
|
||||
params[n] = this.pool.instances.get(n).value;
|
||||
let setupFenceFulfill;
|
||||
let setupFenceReject;
|
||||
const setupFence = new Promise((f, r) => { setupFenceFulfill = f; setupFenceReject = r; });
|
||||
const teardownFence = new Promise(f => this._teardownFenceCallback = f);
|
||||
this._tearDownComplete = this.fn(...params, async value => {
|
||||
this._tearDownComplete = this.fn(params, async value => {
|
||||
this.value = value;
|
||||
setupFenceCallback();
|
||||
setupFenceFulfill();
|
||||
await teardownFence;
|
||||
});
|
||||
}).catch(e => setupFenceReject(e));
|
||||
await setupFence;
|
||||
this._setup = true;
|
||||
}
|
||||
|
||||
async teardown() {
|
||||
@ -115,6 +107,7 @@ class Fixture {
|
||||
continue;
|
||||
await fixture.teardown();
|
||||
}
|
||||
if (this._setup)
|
||||
this._teardownFenceCallback();
|
||||
await this._tearDownComplete;
|
||||
this.pool.instances.delete(this.name);
|
||||
@ -136,6 +129,8 @@ class FixturePool {
|
||||
if (fixture)
|
||||
return fixture;
|
||||
|
||||
if (!this.registrations.has(name))
|
||||
throw new Error('Unknown fixture: ' + name);
|
||||
const { scope, fn } = this.registrations.get(name);
|
||||
fixture = new Fixture(this, name, scope, fn);
|
||||
this.instances.set(name, fixture);
|
||||
@ -154,7 +149,10 @@ class FixturePool {
|
||||
const names = fixtureParameterNames(fn);
|
||||
for (const name of names)
|
||||
await this.setupFixture(name);
|
||||
await fn(...names.map(n => this.instances.get(n).value));
|
||||
const params = {};
|
||||
for (const n of names)
|
||||
params[n] = this.instances.get(n).value;
|
||||
await fn(params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,14 +161,15 @@ exports.default = exports.getPlaywrightEnv();
|
||||
|
||||
function fixtureParameterNames(fn) {
|
||||
const text = fn.toString();
|
||||
const match = text.match(/async\ (.*) =>/);
|
||||
if (!match)
|
||||
const match = text.match(/async\s*\(\s*{\s*([^}]*)\s*}/);
|
||||
if (!match || !match[1].trim())
|
||||
return [];
|
||||
let signature = match[1];
|
||||
if (signature.startsWith('(') && signature.endsWith(')'))
|
||||
signature = signature.substring(1, signature.length - 1);
|
||||
if (!signature.trim())
|
||||
return [];
|
||||
const result = signature.split(',').map(t => t.trim());
|
||||
return result.filter(s => s !== 'test');
|
||||
return signature.split(',').map(t => t.trim());
|
||||
}
|
||||
|
||||
function valueFromEnv(name, defaultValue) {
|
||||
if (!(name in process.env))
|
||||
return defaultValue;
|
||||
return JSON.parse(process.env[name]);
|
||||
}
|
||||
|
@ -14,12 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
test('test 1', async (page, context) => {
|
||||
expect(page.url()).toBe('about:blank');
|
||||
expect(page.context()).toEqual(context);
|
||||
});
|
||||
|
||||
test('test 2', async (page, context) => {
|
||||
expect(page.url()).toBe('about:blank');
|
||||
expect(page.context()).toEqual(context);
|
||||
});
|
||||
module.exports = async function setup() {
|
||||
};
|
18
test/jest/teardown.js
Normal file
18
test/jest/teardown.js
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = async function teardown() {
|
||||
};
|
@ -81,7 +81,6 @@ module.exports = {
|
||||
'./download.spec.js',
|
||||
'./elementhandle.spec.js',
|
||||
'./emulation.spec.js',
|
||||
'./evaluation.spec.js',
|
||||
'./frame.spec.js',
|
||||
'./focus.spec.js',
|
||||
'./input.spec.js',
|
||||
|
Loading…
x
Reference in New Issue
Block a user