diff --git a/tests/config/baseTest.ts b/tests/config/baseTest.ts index 04a1791b81..32a1928036 100644 --- a/tests/config/baseTest.ts +++ b/tests/config/baseTest.ts @@ -18,9 +18,8 @@ import { Fixtures, _baseTest } from '@playwright/test'; import * as path from 'path'; import * as fs from 'fs'; import { installCoverageHooks } from './coverage'; -import * as childProcess from 'child_process'; import { start } from 'playwright-core/lib/outofprocess'; -import { PlaywrightClient } from 'playwright-core/lib/remote/playwrightClient'; +import { GridClient } from 'playwright-core/src/grid/gridClient'; import type { LaunchOptions } from 'playwright-core'; import { commonFixtures, CommonFixtures, serverFixtures, ServerFixtures, ServerOptions } from './commonFixtures'; @@ -57,36 +56,15 @@ class DriverMode { } class ServiceMode { - private _client: import('playwright-core/src/remote/playwrightClient').PlaywrightClient; - private _serviceProcess: childProcess.ChildProcess; + private _gridClient: GridClient; async setup(workerIndex: number) { - const port = 10507 + workerIndex; - this._serviceProcess = childProcess.fork(path.join(__dirname, '..', '..', 'packages', 'playwright-core', 'lib', 'cli', 'cli.js'), ['run-server', String(port)], { - stdio: 'pipe' - }); - this._serviceProcess.stderr.pipe(process.stderr); - await new Promise(f => { - this._serviceProcess.stdout.on('data', data => { - if (data.toString().includes('Listening on')) - f(); - }); - }); - this._serviceProcess.on('exit', this._onExit); - this._client = await PlaywrightClient.connect({ wsEndpoint: `ws://localhost:${port}/ws` }); - return this._client.playwright(); + this._gridClient = await GridClient.connect('http://localhost:3333'); + return this._gridClient.playwright(); } async teardown() { - await this._client.close(); - this._serviceProcess.removeListener('exit', this._onExit); - const processExited = new Promise(f => this._serviceProcess.on('exit', f)); - this._serviceProcess.kill(); - await processExited; - } - - private _onExit(exitCode: number, signal: string) { - throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`); + await this._gridClient.close(); } } diff --git a/tests/config/default.config.ts b/tests/config/default.config.ts index 0db460447d..4c1ab52212 100644 --- a/tests/config/default.config.ts +++ b/tests/config/default.config.ts @@ -60,6 +60,11 @@ const config: Config = { [ 'json', { outputFile: path.join(outputDir, 'report.json') } ], ] : 'line', projects: [], + webServer: mode === 'service' ? { + command: 'npx playwright experimental-grid-server', + port: 3333, + reuseExistingServer: true, + } : undefined, }; const browserNames = ['chromium', 'webkit', 'firefox'] as BrowserName[]; diff --git a/tests/har.spec.ts b/tests/har.spec.ts index fcf2efb8e4..f2d5e4eea4 100644 --- a/tests/har.spec.ts +++ b/tests/har.spec.ts @@ -402,17 +402,18 @@ it('should not contain internal pages', async ({ browserName, contextFactory, se expect(log.pages.length).toBe(1); }); -it('should have connection details', async ({ contextFactory, server, browserName, platform }, testInfo) => { +it('should have connection details', async ({ contextFactory, server, browserName, platform, mode }, testInfo) => { const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.EMPTY_PAGE); const log = await getLog(); const { serverIPAddress, _serverPort: port, _securityDetails: securityDetails } = log.entries[0]; expect(serverIPAddress).toMatch(/^127\.0\.0\.1|\[::1\]/); - expect(port).toBe(server.PORT); + if (mode !== 'service') + expect(port).toBe(server.PORT); expect(securityDetails).toEqual({}); }); -it('should have security details', async ({ contextFactory, httpsServer, browserName, platform }, testInfo) => { +it('should have security details', async ({ contextFactory, httpsServer, browserName, platform, mode }, testInfo) => { it.fail(browserName === 'webkit' && platform === 'linux', 'https://github.com/microsoft/playwright/issues/6759'); it.fail(browserName === 'webkit' && platform === 'win32'); @@ -421,14 +422,15 @@ it('should have security details', async ({ contextFactory, httpsServer, browser const log = await getLog(); const { serverIPAddress, _serverPort: port, _securityDetails: securityDetails } = log.entries[0]; expect(serverIPAddress).toMatch(/^127\.0\.0\.1|\[::1\]/); - expect(port).toBe(httpsServer.PORT); + if (mode !== 'service') + expect(port).toBe(httpsServer.PORT); if (browserName === 'webkit' && platform === 'darwin') expect(securityDetails).toEqual({ protocol: 'TLS 1.3', subjectName: 'puppeteer-tests', validFrom: 1550084863, validTo: 33086084863 }); else expect(securityDetails).toEqual({ issuer: 'puppeteer-tests', protocol: 'TLS 1.3', subjectName: 'puppeteer-tests', validFrom: 1550084863, validTo: 33086084863 }); }); -it('should have connection details for redirects', async ({ contextFactory, server, browserName }, testInfo) => { +it('should have connection details for redirects', async ({ contextFactory, server, browserName, mode }, testInfo) => { server.setRedirect('/foo.html', '/empty.html'); const { page, getLog } = await pageWithHar(contextFactory, testInfo); await page.goto(server.PREFIX + '/foo.html'); @@ -442,15 +444,17 @@ it('should have connection details for redirects', async ({ contextFactory, serv expect(detailsFoo._serverPort).toBeUndefined(); } else { expect(detailsFoo.serverIPAddress).toMatch(/^127\.0\.0\.1|\[::1\]/); - expect(detailsFoo._serverPort).toBe(server.PORT); + if (mode !== 'service') + expect(detailsFoo._serverPort).toBe(server.PORT); } const detailsEmpty = log.entries[1]; expect(detailsEmpty.serverIPAddress).toMatch(/^127\.0\.0\.1|\[::1\]/); - expect(detailsEmpty._serverPort).toBe(server.PORT); + if (mode !== 'service') + expect(detailsEmpty._serverPort).toBe(server.PORT); }); -it('should have connection details for failed requests', async ({ contextFactory, server, browserName, platform }, testInfo) => { +it('should have connection details for failed requests', async ({ contextFactory, server, browserName, platform, mode }, testInfo) => { server.setRoute('/one-style.css', (_, res) => { res.setHeader('Content-Type', 'text/css'); res.connection.destroy(); @@ -460,14 +464,16 @@ it('should have connection details for failed requests', async ({ contextFactory const log = await getLog(); const { serverIPAddress, _serverPort: port } = log.entries[0]; expect(serverIPAddress).toMatch(/^127\.0\.0\.1|\[::1\]/); - expect(port).toBe(server.PORT); + if (mode !== 'service') + expect(port).toBe(server.PORT); }); -it('should return server address directly from response', async ({ page, server }) => { +it('should return server address directly from response', async ({ page, server, mode }) => { const response = await page.goto(server.EMPTY_PAGE); const { ipAddress, port } = await response.serverAddr(); expect(ipAddress).toMatch(/^127\.0\.0\.1|\[::1\]/); - expect(port).toBe(server.PORT); + if (mode !== 'service') + expect(port).toBe(server.PORT); }); it('should return security details directly from response', async ({ contextFactory, httpsServer, browserName, platform }) => { diff --git a/tests/page/page-goto.spec.ts b/tests/page/page-goto.spec.ts index f4d7db01cc..5433779cce 100644 --- a/tests/page/page-goto.spec.ts +++ b/tests/page/page-goto.spec.ts @@ -289,10 +289,12 @@ it('should throw if networkidle2 is passed as an option', async ({ page, server expect(error.message).toContain(`waitUntil: expected one of (load|domcontentloaded|networkidle)`); }); -it('should fail when main resources failed to load', async ({ page, browserName, isWindows }) => { +it('should fail when main resources failed to load', async ({ page, browserName, isWindows, mode }) => { let error = null; await page.goto('http://localhost:44123/non-existing-url').catch(e => error = e); - if (browserName === 'chromium') + if (mode === 'service') + expect(error.message).toContain('net::ERR_SOCKS_CONNECTION_FAILED'); + else if (browserName === 'chromium') expect(error.message).toContain('net::ERR_CONNECTION_REFUSED'); else if (browserName === 'webkit' && isWindows) expect(error.message).toContain(`Couldn\'t connect to server`); diff --git a/tests/proxy.spec.ts b/tests/proxy.spec.ts index 23293598e9..e45a52632c 100644 --- a/tests/proxy.spec.ts +++ b/tests/proxy.spec.ts @@ -18,6 +18,8 @@ import { playwrightTest as it, expect } from './config/browserTest'; import socks from 'socksv5'; import net from 'net'; +it.skip(({ mode }) => mode === 'service'); + it('should throw for bad server value', async ({ browserType, browserOptions }) => { const error = await browserType.launch({ ...browserOptions,