chore: make tests pass on Node.js 17+ (#13678)

This commit is contained in:
Max Schmitt 2022-04-22 13:42:52 +02:00 committed by GitHub
parent f8515d11c1
commit ca4cfca8ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 42 additions and 35 deletions

View file

@ -119,6 +119,7 @@ jobs:
- "^12.0.0" - "^12.0.0"
- "^14.1.0" # pre 14.1, zip extraction was broken (https://github.com/microsoft/playwright/issues/1988) - "^14.1.0" # pre 14.1, zip extraction was broken (https://github.com/microsoft/playwright/issues/1988)
- "^16.0.0" - "^16.0.0"
- "^18.0.0"
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View file

@ -375,7 +375,10 @@ export class SocksProxyHandler extends EventEmitter {
async socketRequested({ uid, host, port }: SocksSocketRequestedPayload): Promise<void> { async socketRequested({ uid, host, port }: SocksSocketRequestedPayload): Promise<void> {
if (host === 'local.playwright') if (host === 'local.playwright')
host = 'localhost'; host = '127.0.0.1';
// Node.js 17 does resolve localhost to ipv6
if (host === 'localhost')
host = '127.0.0.1';
try { try {
if (this._redirectPortForTest) if (this._redirectPortForTest)
port = this._redirectPortForTest; port = this._redirectPortForTest;

View file

@ -225,7 +225,8 @@ export class Chromium extends BrowserType {
const chromeOptions = maybeChromeOptions && typeof maybeChromeOptions === 'object' ? maybeChromeOptions : undefined; const chromeOptions = maybeChromeOptions && typeof maybeChromeOptions === 'object' ? maybeChromeOptions : undefined;
const debuggerAddress = chromeOptions && typeof chromeOptions.debuggerAddress === 'string' ? chromeOptions.debuggerAddress : undefined; const debuggerAddress = chromeOptions && typeof chromeOptions.debuggerAddress === 'string' ? chromeOptions.debuggerAddress : undefined;
const chromeOptionsURL = typeof maybeChromeOptions === 'string' ? maybeChromeOptions : undefined; const chromeOptionsURL = typeof maybeChromeOptions === 'string' ? maybeChromeOptions : undefined;
const endpointURLString = addProtocol(debuggerAddress || chromeOptionsURL); // TODO(dgozman): figure out if we can make ChromeDriver to return 127.0.0.1 instead of localhost.
const endpointURLString = addProtocol(debuggerAddress || chromeOptionsURL).replace('localhost', '127.0.0.1');
progress.log(`<selenium> retrieved endpoint ${endpointURLString} for sessionId=${sessionId}`); progress.log(`<selenium> retrieved endpoint ${endpointURLString} for sessionId=${sessionId}`);
endpointURL = new URL(endpointURLString); endpointURL = new URL(endpointURLString);
if (endpointURL.hostname === 'localhost' || endpointURL.hostname === '127.0.0.1') { if (endpointURL.hostname === 'localhost' || endpointURL.hostname === '127.0.0.1') {

View file

@ -364,11 +364,12 @@ export abstract class APIRequestContext extends SdkObject {
if (e) if (e)
reject(new Error(`failed to decompress '${encoding}' encoding: ${e}`)); reject(new Error(`failed to decompress '${encoding}' encoding: ${e}`));
}); });
} else {
body.on('error', reject);
} }
body.on('data', chunk => chunks.push(chunk)); body.on('data', chunk => chunks.push(chunk));
body.on('end', notifyBodyFinished); body.on('end', notifyBodyFinished);
body.on('error', reject);
}); });
request.on('error', reject); request.on('error', reject);

View file

@ -16,7 +16,8 @@
"import": "./index.mjs", "import": "./index.mjs",
"require": "./index.js" "require": "./index.js"
}, },
"./": "./" "./cli": "./cli.js",
"./package.json": "./package.json"
}, },
"bin": { "bin": {
"playwright": "./cli.js" "playwright": "./cli.js"

View file

@ -141,7 +141,7 @@ export const commonFixtures: Fixtures<CommonFixtures, {}> = {
await use(async port => { await use(async port => {
while (!token.canceled) { while (!token.canceled) {
const promise = new Promise<boolean>(resolve => { const promise = new Promise<boolean>(resolve => {
const conn = net.connect(port) const conn = net.connect(port, '127.0.0.1')
.on('error', () => resolve(false)) .on('error', () => resolve(false))
.on('connect', () => { .on('connect', () => {
conn.end(); conn.end();

View file

@ -963,7 +963,7 @@ it('should work with connectOverCDP', async ({ browserName, browserType, server
args: ['--remote-debugging-port=' + port] args: ['--remote-debugging-port=' + port]
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP(`http://localhost:${port}/`); const cdpBrowser = await browserType.connectOverCDP(`http://127.0.0.1:${port}/`);
const [context] = cdpBrowser.contexts(); const [context] = cdpBrowser.contexts();
const response = await context.request.get(server.PREFIX + '/simple.json'); const response = await context.request.get(server.PREFIX + '/simple.json');
expect(response.url()).toBe(server.PREFIX + '/simple.json'); expect(response.url()).toBe(server.PREFIX + '/simple.json');

View file

@ -47,7 +47,7 @@ test('selenium grid 3.141.59 standalone chromium', async ({ browserName, childPr
}); });
await waitForPort(port); await waitForPort(port);
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`; const __testHookSeleniumRemoteURL = `http://127.0.0.1:${port}/wd/hub`;
const browser = await browserType.launch({ __testHookSeleniumRemoteURL } as any); const browser = await browserType.launch({ __testHookSeleniumRemoteURL } as any);
const page = await browser.newPage(); const page = await browser.newPage();
await page.setContent('<title>Hello world</title><div>Get Started</div>'); await page.setContent('<title>Hello world</title><div>Get Started</div>');
@ -71,7 +71,7 @@ test('selenium grid 3.141.59 hub + node chromium', async ({ browserName, childPr
await waitForPort(port); await waitForPort(port);
const node = childProcess({ const node = childProcess({
command: ['java', `-Dwebdriver.chrome.driver=${chromeDriver}`, '-jar', standalone_3_141_59, '-role', 'node', '-host', '127.0.0.1', '-hub', `http://localhost:${port}/grid/register`], command: ['java', `-Dwebdriver.chrome.driver=${chromeDriver}`, '-jar', standalone_3_141_59, '-role', 'node', '-host', '127.0.0.1', '-hub', `http://127.0.0.1:${port}/grid/register`],
cwd: __dirname, cwd: __dirname,
}); });
await Promise.all([ await Promise.all([
@ -79,7 +79,7 @@ test('selenium grid 3.141.59 hub + node chromium', async ({ browserName, childPr
hub.waitForOutput('Registered a node'), hub.waitForOutput('Registered a node'),
]); ]);
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`; const __testHookSeleniumRemoteURL = `http://127.0.0.1:${port}/wd/hub`;
const browser = await browserType.launch({ __testHookSeleniumRemoteURL } as any); const browser = await browserType.launch({ __testHookSeleniumRemoteURL } as any);
const page = await browser.newPage(); const page = await browser.newPage();
await page.setContent('<title>Hello world</title><div>Get Started</div>'); await page.setContent('<title>Hello world</title><div>Get Started</div>');
@ -103,7 +103,7 @@ test('selenium grid 4.0.0-rc-1 standalone chromium', async ({ browserName, child
}); });
await waitForPort(port); await waitForPort(port);
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`; const __testHookSeleniumRemoteURL = `http://127.0.0.1:${port}/wd/hub`;
const browser = await browserType.launch({ __testHookSeleniumRemoteURL } as any); const browser = await browserType.launch({ __testHookSeleniumRemoteURL } as any);
const page = await browser.newPage(); const page = await browser.newPage();
await page.setContent('<title>Hello world</title><div>Get Started</div>'); await page.setContent('<title>Hello world</title><div>Get Started</div>');
@ -125,10 +125,10 @@ test('selenium grid 4.0.0-rc-1 hub + node chromium', async ({ browserName, child
cwd: __dirname, cwd: __dirname,
}); });
await waitForPort(port); await waitForPort(port);
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`; const __testHookSeleniumRemoteURL = `http://127.0.0.1:${port}/wd/hub`;
const node = childProcess({ const node = childProcess({
command: ['java', `-Dwebdriver.chrome.driver=${chromeDriver}`, '-jar', selenium_4_0_0_rc1, 'node', '--grid-url', `http://localhost:${port}`, '--port', String(port + 1)], command: ['java', `-Dwebdriver.chrome.driver=${chromeDriver}`, '-jar', selenium_4_0_0_rc1, 'node', '--grid-url', `http://127.0.0.1:${port}`, '--port', String(port + 1)],
cwd: __dirname, cwd: __dirname,
}); });
await Promise.all([ await Promise.all([
@ -158,9 +158,9 @@ test('selenium grid 4.0.0-rc-1 standalone chromium broken driver', async ({ brow
}); });
await waitForPort(port); await waitForPort(port);
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`; const __testHookSeleniumRemoteURL = `http://127.0.0.1:${port}/wd/hub`;
const error = await browserType.launch({ __testHookSeleniumRemoteURL } as any).catch(e => e); const error = await browserType.launch({ __testHookSeleniumRemoteURL } as any).catch(e => e);
expect(error.message).toContain(`Error connecting to Selenium at http://localhost:${port}/wd/hub/session: Could not start a new session`); expect(error.message).toContain(`Error connecting to Selenium at http://127.0.0.1:${port}/wd/hub/session: Could not start a new session`);
expect(grid.output).not.toContain('Starting ChromeDriver'); expect(grid.output).not.toContain('Starting ChromeDriver');
}); });
@ -168,7 +168,7 @@ test('selenium grid 4.0.0-rc-1 standalone chromium broken driver', async ({ brow
test('selenium grid 3.141.59 standalone non-chromium', async ({ browserName, browserType }, testInfo) => { test('selenium grid 3.141.59 standalone non-chromium', async ({ browserName, browserType }, testInfo) => {
test.skip(browserName === 'chromium'); test.skip(browserName === 'chromium');
const __testHookSeleniumRemoteURL = `http://localhost:4444/wd/hub`; const __testHookSeleniumRemoteURL = `http://127.0.0.1:4444/wd/hub`;
const error = await browserType.launch({ __testHookSeleniumRemoteURL } as any).catch(e => e); const error = await browserType.launch({ __testHookSeleniumRemoteURL } as any).catch(e => e);
expect(error.message).toContain('Connecting to SELENIUM_REMOTE_URL is only supported by Chromium'); expect(error.message).toContain('Connecting to SELENIUM_REMOTE_URL is only supported by Chromium');
}); });
@ -184,7 +184,7 @@ test('selenium grid 3.141.59 standalone chromium through run-driver', async ({ b
await waitForPort(port); await waitForPort(port);
const { playwright: pw, stop } = await start({ const { playwright: pw, stop } = await start({
SELENIUM_REMOTE_URL: `http://localhost:${port}/wd/hub`, SELENIUM_REMOTE_URL: `http://127.0.0.1:${port}/wd/hub`,
}); });
const browser = await pw.chromium.launch(); const browser = await pw.chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();

View file

@ -102,7 +102,7 @@ playwrightTest('should connect to an existing cdp session', async ({ browserType
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP({ const cdpBrowser = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
const contexts = cdpBrowser.contexts(); const contexts = cdpBrowser.contexts();
expect(contexts.length).toBe(1); expect(contexts.length).toBe(1);
@ -120,7 +120,7 @@ playwrightTest('should cleanup artifacts dir after connectOverCDP disconnects du
args: ['--remote-debugging-port=' + port] args: ['--remote-debugging-port=' + port]
}); });
const cdpBrowser = await browserType.connectOverCDP({ const cdpBrowser = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
const dir = toImpl(cdpBrowser).options.artifactsDir; const dir = toImpl(cdpBrowser).options.artifactsDir;
const exists1 = fs.existsSync(dir); const exists1 = fs.existsSync(dir);
@ -140,10 +140,10 @@ playwrightTest('should connect to an existing cdp session twice', async ({ brows
}); });
try { try {
const cdpBrowser1 = await browserType.connectOverCDP({ const cdpBrowser1 = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
const cdpBrowser2 = await browserType.connectOverCDP({ const cdpBrowser2 = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
const contexts1 = cdpBrowser1.contexts(); const contexts1 = cdpBrowser1.contexts();
expect(contexts1.length).toBe(1); expect(contexts1.length).toBe(1);
@ -178,7 +178,7 @@ playwrightTest('should connect to existing page with iframe and navigate', async
const page = await context1.newPage(); const page = await context1.newPage();
await page.goto(server.PREFIX + '/frames/one-frame.html'); await page.goto(server.PREFIX + '/frames/one-frame.html');
} }
const cdpBrowser = await browserType.connectOverCDP(`http://localhost:${port}/`); const cdpBrowser = await browserType.connectOverCDP(`http://127.0.0.1:${port}/`);
const contexts = cdpBrowser.contexts(); const contexts = cdpBrowser.contexts();
expect(contexts.length).toBe(1); expect(contexts.length).toBe(1);
await contexts[0].pages()[0].goto(server.EMPTY_PAGE); await contexts[0].pages()[0].goto(server.EMPTY_PAGE);
@ -195,7 +195,7 @@ playwrightTest('should connect to existing service workers', async ({ browserTyp
}); });
try { try {
const cdpBrowser1 = await browserType.connectOverCDP({ const cdpBrowser1 = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}`, endpointURL: `http://127.0.0.1:${port}`,
}); });
const context = cdpBrowser1.contexts()[0]; const context = cdpBrowser1.contexts()[0];
const page = await cdpBrowser1.contexts()[0].newPage(); const page = await cdpBrowser1.contexts()[0].newPage();
@ -207,7 +207,7 @@ playwrightTest('should connect to existing service workers', async ({ browserTyp
await cdpBrowser1.close(); await cdpBrowser1.close();
const cdpBrowser2 = await browserType.connectOverCDP({ const cdpBrowser2 = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}`, endpointURL: `http://127.0.0.1:${port}`,
}); });
const context2 = cdpBrowser2.contexts()[0]; const context2 = cdpBrowser2.contexts()[0];
expect(context2.serviceWorkers().length).toBe(1); expect(context2.serviceWorkers().length).toBe(1);
@ -224,7 +224,7 @@ playwrightTest('should connect over a ws endpoint', async ({ browserType, server
}); });
try { try {
const json = await new Promise<string>((resolve, reject) => { const json = await new Promise<string>((resolve, reject) => {
http.get(`http://localhost:${port}/json/version/`, resp => { http.get(`http://127.0.0.1:${port}/json/version/`, resp => {
let data = ''; let data = '';
resp.on('data', chunk => data += chunk); resp.on('data', chunk => data += chunk);
resp.on('end', () => resolve(data)); resp.on('end', () => resolve(data));
@ -306,7 +306,7 @@ playwrightTest('should report all pages in an existing browser', async ({ browse
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP({ const cdpBrowser = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
const contexts = cdpBrowser.contexts(); const contexts = cdpBrowser.contexts();
expect(contexts.length).toBe(1); expect(contexts.length).toBe(1);
@ -315,7 +315,7 @@ playwrightTest('should report all pages in an existing browser', async ({ browse
await cdpBrowser.close(); await cdpBrowser.close();
const cdpBrowser2 = await browserType.connectOverCDP({ const cdpBrowser2 = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
expect(cdpBrowser2.contexts()[0].pages().length).toBe(3); expect(cdpBrowser2.contexts()[0].pages().length).toBe(3);
@ -332,7 +332,7 @@ playwrightTest('should connect via https', async ({ browserType, httpsServer, mo
args: ['--remote-debugging-port=' + port] args: ['--remote-debugging-port=' + port]
}); });
const json = await new Promise<string>((resolve, reject) => { const json = await new Promise<string>((resolve, reject) => {
http.get(`http://localhost:${port}/json/version/`, resp => { http.get(`http://127.0.0.1:${port}/json/version/`, resp => {
let data = ''; let data = '';
resp.on('data', chunk => data += chunk); resp.on('data', chunk => data += chunk);
resp.on('end', () => resolve(data)); resp.on('end', () => resolve(data));
@ -366,7 +366,7 @@ playwrightTest('should return valid browser from context.browser()', async ({ br
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP({ const cdpBrowser = await browserType.connectOverCDP({
endpointURL: `http://localhost:${port}/`, endpointURL: `http://127.0.0.1:${port}/`,
}); });
const contexts = cdpBrowser.contexts(); const contexts = cdpBrowser.contexts();
expect(contexts.length).toBe(1); expect(contexts.length).toBe(1);
@ -410,7 +410,7 @@ playwrightTest('should connect to an existing cdp session when passed as a first
args: ['--remote-debugging-port=' + port] args: ['--remote-debugging-port=' + port]
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP(`http://localhost:${port}/`); const cdpBrowser = await browserType.connectOverCDP(`http://127.0.0.1:${port}/`);
const contexts = cdpBrowser.contexts(); const contexts = cdpBrowser.contexts();
expect(contexts.length).toBe(1); expect(contexts.length).toBe(1);
await cdpBrowser.close(); await cdpBrowser.close();
@ -428,7 +428,7 @@ playwrightTest('should use proxy with connectOverCDP', async ({ browserType, ser
args: ['--remote-debugging-port=' + port, ...(process.platform === 'win32' ? ['--proxy-server=some-value'] : [])] args: ['--remote-debugging-port=' + port, ...(process.platform === 'win32' ? ['--proxy-server=some-value'] : [])]
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP(`http://localhost:${port}/`); const cdpBrowser = await browserType.connectOverCDP(`http://127.0.0.1:${port}/`);
const context = await cdpBrowser.newContext({ const context = await cdpBrowser.newContext({
proxy: { server: `localhost:${server.PORT}` } proxy: { server: `localhost:${server.PORT}` }
}); });

View file

@ -51,7 +51,7 @@ it.describe('permissions', () => {
it('should prompt for geolocation permission when origin is not listed', async ({ page, context, server }) => { it('should prompt for geolocation permission when origin is not listed', async ({ page, context, server }) => {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE }); await context.grantPermissions(['geolocation'], { origin: server.EMPTY_PAGE });
await page.goto(server.EMPTY_PAGE.replace('localhost', '127.0.0.1')); await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html');
expect(await getPermission(page, 'geolocation')).toBe('prompt'); expect(await getPermission(page, 'geolocation')).toBe('prompt');
}); });

View file

@ -117,7 +117,7 @@ it('should proxy localhost requests @smoke', async ({ pageFactory, server, brows
}); });
const examplePort = 20_000 + workerInfo.workerIndex * 3; const examplePort = 20_000 + workerInfo.workerIndex * 3;
const page = await pageFactory(testServerPort); const page = await pageFactory(testServerPort);
await page.goto(`http://localhost:${examplePort}/foo.html`); await page.goto(`http://127.0.0.1:${examplePort}/foo.html`);
expect(await page.content()).toContain('from-retargeted-server'); expect(await page.content()).toContain('from-retargeted-server');
expect(reachedOriginalTarget).toBe(false); expect(reachedOriginalTarget).toBe(false);
stopTestServer(); stopTestServer();
@ -134,7 +134,7 @@ it('should proxy localhost requests from fetch api', async ({ pageFactory, serve
}); });
const examplePort = 20_000 + workerInfo.workerIndex * 3; const examplePort = 20_000 + workerInfo.workerIndex * 3;
const page = await pageFactory(testServerPort); const page = await pageFactory(testServerPort);
const response = await page.request.get(`http://localhost:${examplePort}/foo.html`); const response = await page.request.get(`http://127.0.0.1:${examplePort}/foo.html`);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
expect(await response.text()).toContain('from-retargeted-server'); expect(await response.text()).toContain('from-retargeted-server');
expect(reachedOriginalTarget).toBe(false); expect(reachedOriginalTarget).toBe(false);
@ -159,9 +159,9 @@ it('should proxy local.playwright requests', async ({ pageFactory, server, brows
it('should lead to the error page for forwarded requests when the connection is refused', async ({ pageFactory, browserName }, workerInfo) => { it('should lead to the error page for forwarded requests when the connection is refused', async ({ pageFactory, browserName }, workerInfo) => {
const examplePort = 20_000 + workerInfo.workerIndex * 3; const examplePort = 20_000 + workerInfo.workerIndex * 3;
const page = await pageFactory(); const page = await pageFactory();
const error = await page.goto(`http://localhost:${examplePort}`).catch(e => e); const error = await page.goto(`http://127.0.0.1:${examplePort}`).catch(e => e);
if (browserName === 'chromium') if (browserName === 'chromium')
expect(error.message).toContain('net::ERR_SOCKS_CONNECTION_FAILED at http://localhost:20'); expect(error.message).toContain('net::ERR_SOCKS_CONNECTION_FAILED at http://127.0.0.1:20');
else if (browserName === 'webkit') else if (browserName === 'webkit')
expect(error.message).toBeTruthy(); expect(error.message).toBeTruthy();
else if (browserName === 'firefox') else if (browserName === 'firefox')