mirror of
https://github.com/microsoft/playwright.git
synced 2025-01-05 02:02:05 +03:00
chore: add websocket connection mode (#4510)
This commit is contained in:
parent
14a96ca21f
commit
e72d9a4185
14
.github/workflows/tests.yml
vendored
14
.github/workflows/tests.yml
vendored
@ -165,13 +165,13 @@ jobs:
|
||||
name: headful-${{ matrix.browser }}-linux-test-results
|
||||
path: test-results
|
||||
|
||||
wire_linux:
|
||||
name: "Wire Linux"
|
||||
transport_linux:
|
||||
name: "Transport"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
browser: [chromium, firefox, webkit]
|
||||
runs-on: ubuntu-18.04
|
||||
mode: [driver, service]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
@ -188,15 +188,15 @@ jobs:
|
||||
# Enable core dumps in the subshell.
|
||||
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "ulimit -c unlimited && npx folio test/ --workers=1 --forbid-only --global-timeout=5400000 --retries=3 --reporter=dot,json"
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
PWWIRE: true
|
||||
BROWSER: "chromium"
|
||||
PWMODE: "${{ matrix.mode }}"
|
||||
FOLIO_JSON_OUTPUT_NAME: "test-results/report.json"
|
||||
- run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json
|
||||
if: always() && github.ref == 'refs/heads/master'
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: wire-${{ matrix.browser }}-linux-test-results
|
||||
name: mode-${{ matrix.mode }}-linux-test-results
|
||||
path: test-results
|
||||
|
||||
video_linux:
|
||||
|
55
src/remote/playwrightClient.ts
Normal file
55
src/remote/playwrightClient.ts
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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 * as WebSocket from 'ws';
|
||||
import { Connection } from '../client/connection';
|
||||
import { Playwright } from '../client/playwright';
|
||||
|
||||
export class PlaywrightClient {
|
||||
private _playwright: Playwright;
|
||||
private _ws: WebSocket;
|
||||
private _closePromise: Promise<void>;
|
||||
|
||||
static async connect(wsEndpoint: string): Promise<PlaywrightClient> {
|
||||
const connection = new Connection();
|
||||
const ws = new WebSocket(wsEndpoint);
|
||||
connection.onmessage = message => ws.send(JSON.stringify(message));
|
||||
ws.on('message', message => connection.dispatch(JSON.parse(message.toString())));
|
||||
const errorPromise = new Promise((_, reject) => ws.on('error', error => reject(error)));
|
||||
const closePromise = new Promise((_, reject) => ws.on('close', () => reject(new Error('Connection closed'))));
|
||||
const playwright = await Promise.race([
|
||||
connection.waitForObjectWithKnownName('Playwright'),
|
||||
errorPromise,
|
||||
closePromise
|
||||
]);
|
||||
return new PlaywrightClient(playwright as Playwright, ws);
|
||||
}
|
||||
|
||||
constructor(playwright: Playwright, ws: WebSocket) {
|
||||
this._playwright = playwright;
|
||||
this._ws = ws;
|
||||
this._closePromise = new Promise(f => ws.on('close', f));
|
||||
}
|
||||
|
||||
playwright(): Playwright {
|
||||
return this._playwright;
|
||||
}
|
||||
|
||||
async close() {
|
||||
this._ws.close();
|
||||
await this._closePromise;
|
||||
}
|
||||
}
|
84
src/remote/playwrightServer.ts
Normal file
84
src/remote/playwrightServer.ts
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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 * as debug from 'debug';
|
||||
import * as http from 'http';
|
||||
import * as WebSocket from 'ws';
|
||||
import { installDebugController } from '../debug/debugController';
|
||||
import { DispatcherConnection } from '../dispatchers/dispatcher';
|
||||
import { PlaywrightDispatcher } from '../dispatchers/playwrightDispatcher';
|
||||
import { Electron } from '../server/electron/electron';
|
||||
import { Playwright } from '../server/playwright';
|
||||
import { gracefullyCloseAll } from '../server/processLauncher';
|
||||
import { installTracer } from '../trace/tracer';
|
||||
import { installHarTracer } from '../trace/harTracer';
|
||||
|
||||
const debugLog = debug('pw:server');
|
||||
|
||||
installDebugController();
|
||||
installTracer();
|
||||
installHarTracer();
|
||||
|
||||
export class PlaywrightServer {
|
||||
private _server: http.Server | undefined;
|
||||
private _client: WebSocket | undefined;
|
||||
|
||||
listen(port: number) {
|
||||
this._server = http.createServer((request, response) => {
|
||||
response.end('Running');
|
||||
});
|
||||
this._server.on('error', error => debugLog(error));
|
||||
this._server.listen(port);
|
||||
debugLog('Listening on ' + port);
|
||||
|
||||
const wsServer = new WebSocket.Server({ server: this._server, path: '/ws' });
|
||||
wsServer.on('connection', async ws => {
|
||||
if (this._client) {
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
this._client = ws;
|
||||
debugLog('Incoming connection');
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
ws.on('message', message => dispatcherConnection.dispatch(JSON.parse(message.toString())));
|
||||
ws.on('close', () => {
|
||||
debugLog('Client closed');
|
||||
this._onDisconnect();
|
||||
});
|
||||
ws.on('error', error => {
|
||||
debugLog('Client error ' + error);
|
||||
this._onDisconnect();
|
||||
});
|
||||
dispatcherConnection.onmessage = message => ws.send(JSON.stringify(message));
|
||||
const playwright = new Playwright(__dirname, require('../../browsers.json')['browsers']);
|
||||
(playwright as any).electron = new Electron();
|
||||
new PlaywrightDispatcher(dispatcherConnection.rootDispatcher(), playwright);
|
||||
});
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (!this._server)
|
||||
return;
|
||||
debugLog('Closing server');
|
||||
await new Promise(f => this._server!.close(f));
|
||||
await gracefullyCloseAll();
|
||||
}
|
||||
|
||||
private async _onDisconnect() {
|
||||
await gracefullyCloseAll();
|
||||
this._client = undefined;
|
||||
}
|
||||
}
|
21
src/service.ts
Normal file
21
src/service.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 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 { PlaywrightServer } from './remote/playwrightServer';
|
||||
|
||||
const server = new PlaywrightServer();
|
||||
server.listen(+process.argv[2]);
|
||||
console.log('Listening on ' + process.argv[2]); // eslint-disable-line no-console
|
@ -201,8 +201,8 @@ it('should work with goto following click', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should report navigation in the log when clicking anchor', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should report navigation in the log when clicking anchor', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({page, server}) => {
|
||||
await page.setContent(`<a href="${server.PREFIX + '/frames/one-frame.html'}">click me</a>`);
|
||||
const __testHookAfterPointerAction = () => new Promise(f => setTimeout(f, 6000));
|
||||
|
@ -19,8 +19,8 @@ import { folio } from './remoteServer.fixture';
|
||||
import * as fs from 'fs';
|
||||
const { it, expect, describe } = folio;
|
||||
|
||||
describe('connect', (suite, { wire }) => {
|
||||
suite.skip(wire);
|
||||
describe('connect', (suite, { mode }) => {
|
||||
suite.skip(mode !== 'default');
|
||||
suite.slow();
|
||||
}, () => {
|
||||
it('should be able to reconnect to a browser', async ({browserType, remoteServer, server}) => {
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
import { it, expect, describe } from './fixtures';
|
||||
|
||||
describe('lauch server', (suite, { wire }) => {
|
||||
suite.skip(wire);
|
||||
describe('lauch server', (suite, { mode }) => {
|
||||
suite.skip(mode !== 'default');
|
||||
}, () => {
|
||||
it('should work', async ({browserType, browserOptions}) => {
|
||||
const browserServer = await browserType.launchServer(browserOptions);
|
||||
|
@ -73,8 +73,8 @@ it('should reject if executable path is invalid', async ({browserType, browserOp
|
||||
expect(waitError.message).toContain('Failed to launch');
|
||||
});
|
||||
|
||||
it('should handle timeout', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should handle timeout', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browserType, browserOptions}) => {
|
||||
const options = { ...browserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
|
||||
const error = await browserType.launch(options).catch(e => e);
|
||||
@ -83,8 +83,8 @@ it('should handle timeout', (test, { wire }) => {
|
||||
expect(error.message).toContain(`<launched> pid=`);
|
||||
});
|
||||
|
||||
it('should handle exception', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should handle exception', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browserType, browserOptions}) => {
|
||||
const e = new Error('Dummy');
|
||||
const options = { ...browserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
|
||||
@ -92,8 +92,8 @@ it('should handle exception', (test, { wire }) => {
|
||||
expect(error.message).toContain('Dummy');
|
||||
});
|
||||
|
||||
it('should report launch log', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should report launch log', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browserType, browserOptions}) => {
|
||||
const e = new Error('Dummy');
|
||||
const options = { ...browserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
|
||||
|
@ -18,8 +18,8 @@ import { it, expect } from '../fixtures';
|
||||
import path from 'path';
|
||||
import type { ChromiumBrowser, ChromiumBrowserContext } from '../..';
|
||||
|
||||
it('should throw with remote-debugging-pipe argument', (test, { browserName, wire }) => {
|
||||
test.skip(wire || browserName !== 'chromium');
|
||||
it('should throw with remote-debugging-pipe argument', (test, { browserName, mode }) => {
|
||||
test.skip(mode !== 'default' || browserName !== 'chromium');
|
||||
}, async ({browserType, browserOptions}) => {
|
||||
const options = Object.assign({}, browserOptions);
|
||||
options.args = ['--remote-debugging-pipe'].concat(options.args || []);
|
||||
@ -27,8 +27,8 @@ it('should throw with remote-debugging-pipe argument', (test, { browserName, wir
|
||||
expect(error.message).toContain('Playwright manages remote debugging connection itself');
|
||||
});
|
||||
|
||||
it('should not throw with remote-debugging-port argument', (test, { browserName, wire }) => {
|
||||
test.skip(wire || browserName !== 'chromium');
|
||||
it('should not throw with remote-debugging-port argument', (test, { browserName, mode }) => {
|
||||
test.skip(mode !== 'default' || browserName !== 'chromium');
|
||||
}, async ({browserType, browserOptions}) => {
|
||||
const options = Object.assign({}, browserOptions);
|
||||
options.args = ['--remote-debugging-port=0'].concat(options.args || []);
|
||||
@ -36,8 +36,8 @@ it('should not throw with remote-debugging-port argument', (test, { browserName,
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should open devtools when "devtools: true" option is given', (test, { wire, browserName, platform}) => {
|
||||
test.skip(browserName !== 'chromium' || wire || platform === 'win32');
|
||||
it('should open devtools when "devtools: true" option is given', (test, { mode, browserName, platform}) => {
|
||||
test.skip(browserName !== 'chromium' || mode !== 'default' || platform === 'win32');
|
||||
}, async ({browserType, browserOptions}) => {
|
||||
let devtoolsCallback;
|
||||
const devtoolsPromise = new Promise(f => devtoolsCallback = f);
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
import { it, expect } from './fixtures';
|
||||
|
||||
it('should avoid side effects after timeout', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should avoid side effects after timeout', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const error = await page.click('button', { timeout: 2000, __testHookBeforePointerAction: () => new Promise(f => setTimeout(f, 2500))} as any).catch(e => e);
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
import { it, expect } from './fixtures';
|
||||
|
||||
it('should fail when element jumps during hit testing', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should fail when element jumps during hit testing', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({page}) => {
|
||||
await page.setContent('<button>Click me</button>');
|
||||
let clicked = false;
|
||||
|
@ -154,8 +154,8 @@ it('should throw if page argument is passed', (test, { browserName }) => {
|
||||
expect(error.message).toContain('can not specify page');
|
||||
});
|
||||
|
||||
it('should have passed URL when launching with ignoreDefaultArgs: true', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should have passed URL when launching with ignoreDefaultArgs: true', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browserType, browserOptions, server, createUserDataDir, toImpl}) => {
|
||||
const userDataDir = await createUserDataDir();
|
||||
const args = toImpl(browserType)._defaultArgs(browserOptions, 'persistent', userDataDir, 0).filter(a => a !== 'about:blank');
|
||||
@ -173,16 +173,16 @@ it('should have passed URL when launching with ignoreDefaultArgs: true', (test,
|
||||
await browserContext.close();
|
||||
});
|
||||
|
||||
it('should handle timeout', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should handle timeout', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browserType, browserOptions, createUserDataDir}) => {
|
||||
const options = { ...browserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
|
||||
const error = await browserType.launchPersistentContext(await createUserDataDir(), options).catch(e => e);
|
||||
expect(error.message).toContain(`browserType.launchPersistentContext: Timeout 5000ms exceeded.`);
|
||||
});
|
||||
|
||||
it('should handle exception', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should handle exception', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browserType, browserOptions, createUserDataDir}) => {
|
||||
const e = new Error('Dummy');
|
||||
const options = { ...browserOptions, __testHookBeforeCreateBrowser: () => { throw e; } };
|
||||
|
@ -145,8 +145,8 @@ describe('download event', () => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should save when connected remotely', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should save when connected remotely', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({testInfo, server, browserType, remoteServer}) => {
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
@ -191,8 +191,8 @@ describe('download event', () => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should error when saving after deletion when connected remotely', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should error when saving after deletion when connected remotely', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({testInfo, server, browserType, remoteServer}) => {
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
|
@ -289,8 +289,8 @@ describe('element screenshot', (suite, parameters) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should restore viewport after page screenshot and exception', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should restore viewport after page screenshot and exception', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
|
||||
const page = await context.newPage();
|
||||
@ -302,8 +302,8 @@ describe('element screenshot', (suite, parameters) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should restore viewport after page screenshot and timeout', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should restore viewport after page screenshot and timeout', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
|
||||
const page = await context.newPage();
|
||||
@ -348,8 +348,8 @@ describe('element screenshot', (suite, parameters) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should restore viewport after element screenshot and exception', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should restore viewport after element screenshot and exception', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({browser}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
|
||||
const page = await context.newPage();
|
||||
|
@ -26,6 +26,7 @@ import { Transport } from '../lib/protocol/transport';
|
||||
import { installCoverageHooks } from './coverage';
|
||||
import { folio as httpFolio } from './http.fixtures';
|
||||
import { folio as playwrightFolio } from './playwright.fixtures';
|
||||
import { PlaywrightClient } from '../lib/remote/playwrightClient';
|
||||
export { expect, config } from 'folio';
|
||||
|
||||
const removeFolderAsync = util.promisify(require('rimraf'));
|
||||
@ -40,8 +41,8 @@ const getExecutablePath = browserName => {
|
||||
return process.env.WKPATH;
|
||||
};
|
||||
|
||||
type WireParameters = {
|
||||
wire: boolean;
|
||||
type ModeParameters = {
|
||||
mode: 'default' | 'driver' | 'service';
|
||||
};
|
||||
type WorkerFixtures = {
|
||||
toImpl: (rpcObject: any) => any;
|
||||
@ -51,9 +52,9 @@ type TestFixtures = {
|
||||
launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{ context: BrowserContext, page: Page }>;
|
||||
};
|
||||
|
||||
const fixtures = playwrightFolio.union(httpFolio).extend<TestFixtures, WorkerFixtures, WireParameters>();
|
||||
const fixtures = playwrightFolio.union(httpFolio).extend<TestFixtures, WorkerFixtures, ModeParameters>();
|
||||
|
||||
fixtures.wire.initParameter('Wire testing mode', !!process.env.PWWIRE);
|
||||
fixtures.mode.initParameter('Testing mode', process.env.PWMODE as any || 'default');
|
||||
|
||||
fixtures.createUserDataDir.init(async ({ }, run) => {
|
||||
const dirs: string[] = [];
|
||||
@ -99,10 +100,10 @@ fixtures.browserOptions.override(async ({ browserName, headful, slowMo }, run) =
|
||||
});
|
||||
});
|
||||
|
||||
fixtures.playwright.override(async ({ browserName, testWorkerIndex, platform, wire }, run) => {
|
||||
fixtures.playwright.override(async ({ browserName, testWorkerIndex, platform, mode }, run) => {
|
||||
assert(platform); // Depend on platform to generate all tests.
|
||||
const { coverage, uninstall } = installCoverageHooks(browserName);
|
||||
if (wire) {
|
||||
if (mode === 'driver') {
|
||||
require('../lib/utils/utils').setUnderTest();
|
||||
const connection = new Connection();
|
||||
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'driver.js'), ['serve'], {
|
||||
@ -124,6 +125,29 @@ fixtures.playwright.override(async ({ browserName, testWorkerIndex, platform, wi
|
||||
spawnedProcess.stdout.destroy();
|
||||
spawnedProcess.stderr.destroy();
|
||||
await teardownCoverage();
|
||||
} else if (mode === 'service') {
|
||||
require('../lib/utils/utils').setUnderTest();
|
||||
const port = 9407 + testWorkerIndex * 2;
|
||||
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'service.js'), [String(port)], {
|
||||
stdio: 'pipe'
|
||||
});
|
||||
await new Promise(f => {
|
||||
spawnedProcess.stdout.on('data', data => {
|
||||
if (data.toString().includes('Listening on'))
|
||||
f();
|
||||
});
|
||||
});
|
||||
spawnedProcess.unref();
|
||||
const onExit = (exitCode, signal) => {
|
||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||
};
|
||||
spawnedProcess.on('exit', onExit);
|
||||
const client = await PlaywrightClient.connect(`ws://localhost:${port}/ws`);
|
||||
await run(client.playwright());
|
||||
spawnedProcess.removeListener('exit', onExit);
|
||||
await client.close();
|
||||
spawnedProcess.kill();
|
||||
await teardownCoverage();
|
||||
} else {
|
||||
const playwright = require('../index');
|
||||
await run(playwright);
|
||||
|
@ -44,8 +44,8 @@ function expectContexts(pageImpl, count, isChromium) {
|
||||
expect(pageImpl._delegate._contextIdToContext.size).toBe(count);
|
||||
}
|
||||
|
||||
it('should dispose context on navigation', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should dispose context on navigation', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({ page, server, toImpl, isChromium }) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
@ -54,8 +54,8 @@ it('should dispose context on navigation', (test, { wire }) => {
|
||||
expectContexts(toImpl(page), 2, isChromium);
|
||||
});
|
||||
|
||||
it('should dispose context on cross-origin navigation', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should dispose context on cross-origin navigation', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({ page, server, toImpl, isChromium }) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
|
@ -435,8 +435,8 @@ it('should not throw an error when evaluation does a synchronous navigation and
|
||||
expect(result).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should transfer 100Mb of data from page to node.js', (test, { wire }) => {
|
||||
test.skip(wire);
|
||||
it('should transfer 100Mb of data from page to node.js', (test, { mode }) => {
|
||||
test.skip(mode !== 'default');
|
||||
}, async ({ page }) => {
|
||||
// This is too slow with wire.
|
||||
const a = await page.evaluate(() => Array(100 * 1024 * 1024 + 1).join('a'));
|
||||
|
@ -27,8 +27,8 @@ function crash(page, toImpl, browserName) {
|
||||
toImpl(page)._delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
}
|
||||
|
||||
describe('', (suite, { browserName, platform, wire }) => {
|
||||
suite.skip(wire && browserName !== 'chromium');
|
||||
describe('', (suite, { browserName, platform, mode }) => {
|
||||
suite.skip(mode !== 'default' && browserName !== 'chromium');
|
||||
suite.flaky(browserName === 'firefox' && platform === 'win32');
|
||||
const isBigSur = platform === 'darwin' && parseInt(os.release(), 10) >= 20;
|
||||
suite.fixme(isBigSur && browserName === 'webkit', 'Timing out after roll');
|
||||
|
@ -97,7 +97,7 @@ it('should amend method on main request', async ({page, server}) => {
|
||||
expect((await request).method).toBe('POST');
|
||||
});
|
||||
|
||||
describe('', (suite, { browserName, platform, wire }) => {
|
||||
describe('', (suite, { browserName, platform }) => {
|
||||
const isBigSur = platform === 'darwin' && parseInt(os.release(), 10) >= 20;
|
||||
suite.flaky(isBigSur && browserName === 'webkit', 'Flaky after roll');
|
||||
}, () => {
|
||||
|
@ -44,8 +44,8 @@ async function checkPageSlowMo(toImpl, page, task) {
|
||||
`);
|
||||
await checkSlowMo(toImpl, page, task);
|
||||
}
|
||||
describe('slowMo', (suite, { wire }) => {
|
||||
suite.skip(wire);
|
||||
describe('slowMo', (suite, { mode }) => {
|
||||
suite.skip(mode !== 'default');
|
||||
}, () => {
|
||||
it('Page SlowMo $$eval', async ({page, toImpl}) => {
|
||||
await checkPageSlowMo(toImpl, page, () => page.$$eval('button', () => void 0));
|
||||
|
Loading…
Reference in New Issue
Block a user