test: brush up fixtures, unflake some tests (#32854)

This commit is contained in:
Dmitry Gozman 2024-09-27 07:06:37 -07:00 committed by GitHub
parent a395fb22c4
commit 5947c21dc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 99 additions and 94 deletions

View file

@ -70,25 +70,23 @@ const test = baseTest.extend<BrowserTestTestFixtures, BrowserTestWorkerFixtures>
await run(false); await run(false);
}, { scope: 'worker' }], }, { scope: 'worker' }],
defaultSameSiteCookieValue: [async ({ browserName, platform }, run) => { defaultSameSiteCookieValue: [async ({ browserName, platform, macVersion }, run) => {
if (browserName === 'chromium' || browserName as any === '_bidiChromium') if (browserName === 'chromium' || browserName as any === '_bidiChromium')
await run('Lax'); await run('Lax');
else if (browserName === 'webkit' && platform === 'linux') else if (browserName === 'webkit' && platform === 'linux')
await run('Lax'); await run('Lax');
else if (browserName === 'webkit' && platform === 'darwin' && parseInt(os.release(), 10) >= 24) else if (browserName === 'webkit' && platform === 'darwin' && macVersion >= 15)
// macOS 15 Sequoia onwards
await run('Lax'); await run('Lax');
else if (browserName === 'webkit') else if (browserName === 'webkit')
// Windows + older macOS await run('None'); // Windows + older macOS
await run('None');
else if (browserName === 'firefox' || browserName as any === '_bidiFirefox') else if (browserName === 'firefox' || browserName as any === '_bidiFirefox')
await run('None'); await run('None');
else else
throw new Error('unknown browser - ' + browserName); throw new Error('unknown browser - ' + browserName);
}, { scope: 'worker' }], }, { scope: 'worker' }],
sameSiteStoredValueForNone: [async ({ browserName, isMac }, run) => { sameSiteStoredValueForNone: [async ({ browserName, isMac, macVersion }, run) => {
if (browserName === 'webkit' && isMac && parseInt(os.release(), 10) >= 24) if (browserName === 'webkit' && isMac && macVersion >= 15)
await run('Lax'); await run('Lax');
else else
await run('None'); await run('None');

View file

@ -15,12 +15,14 @@
*/ */
import { test } from '@playwright/test'; import { test } from '@playwright/test';
import os from 'os';
export type PlatformWorkerFixtures = { export type PlatformWorkerFixtures = {
platform: 'win32' | 'darwin' | 'linux'; platform: 'win32' | 'darwin' | 'linux';
isWindows: boolean; isWindows: boolean;
isMac: boolean; isMac: boolean;
isLinux: boolean; isLinux: boolean;
macVersion: number; // major only, 11 or later, zero if not mac
}; };
function platform(): 'win32' | 'darwin' | 'linux' { function platform(): 'win32' | 'darwin' | 'linux' {
@ -33,9 +35,16 @@ function platform(): 'win32' | 'darwin' | 'linux' {
return process.platform as 'win32' | 'darwin' | 'linux'; return process.platform as 'win32' | 'darwin' | 'linux';
} }
function macVersion() {
if (process.platform !== 'darwin')
return 0;
return +os.release().split('.')[0] - 9;
}
export const platformTest = test.extend<{}, PlatformWorkerFixtures>({ export const platformTest = test.extend<{}, PlatformWorkerFixtures>({
platform: [platform(), { scope: 'worker' }], platform: [platform(), { scope: 'worker' }],
isWindows: [platform() === 'win32', { scope: 'worker' }], isWindows: [platform() === 'win32', { scope: 'worker' }],
isMac: [platform() === 'darwin', { scope: 'worker' }], isMac: [platform() === 'darwin', { scope: 'worker' }],
isLinux: [platform() === 'linux', { scope: 'worker' }], isLinux: [platform() === 'linux', { scope: 'worker' }],
macVersion: [macVersion(), { scope: 'worker' }],
}); });

View file

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
import os from 'os';
import { contextTest as it, expect } from '../config/browserTest'; import { contextTest as it, expect } from '../config/browserTest';
it('should return no cookies in pristine browser context', async ({ context, page, server }) => { it('should return no cookies in pristine browser context', async ({ context, page, server }) => {
@ -351,7 +350,7 @@ it('should be able to send third party cookies via an iframe', async ({ browser,
} }
}); });
it('should support requestStorageAccess', async ({ page, server, channel, browserName, isMac, isLinux, isWindows }) => { it('should support requestStorageAccess', async ({ page, server, channel, browserName, isMac, isLinux, isWindows, macVersion }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/17285' }); it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/17285' });
it.skip(browserName === 'chromium', 'requestStorageAccess API is not available in Chromium'); it.skip(browserName === 'chromium', 'requestStorageAccess API is not available in Chromium');
it.skip(channel === 'firefox-beta', 'hasStorageAccess returns true, but no cookie is sent'); it.skip(channel === 'firefox-beta', 'hasStorageAccess returns true, but no cookie is sent');
@ -397,7 +396,7 @@ it('should support requestStorageAccess', async ({ page, server, channel, browse
server.waitForRequest('/title.html'), server.waitForRequest('/title.html'),
frame.evaluate(() => fetch('/title.html')) frame.evaluate(() => fetch('/title.html'))
]); ]);
if ((isLinux || (isMac && parseInt(os.release(), 10) >= 24)) && browserName === 'webkit') if ((isLinux || (isMac && macVersion >= 15)) && browserName === 'webkit')
expect(serverRequest.headers.cookie).toBe(undefined); expect(serverRequest.headers.cookie).toBe(undefined);
else else
expect(serverRequest.headers.cookie).toBe('name=value'); expect(serverRequest.headers.cookie).toBe('name=value');

View file

@ -19,7 +19,6 @@ import { devices } from '@playwright/test';
import { contextTest as it, expect } from '../config/browserTest'; import { contextTest as it, expect } from '../config/browserTest';
import { browserTest } from '../config/browserTest'; import { browserTest } from '../config/browserTest';
import { verifyViewport } from '../config/utils'; import { verifyViewport } from '../config/utils';
import * as os from 'os';
it('should get the proper default viewport size', async ({ page, server }) => { it('should get the proper default viewport size', async ({ page, server }) => {
await verifyViewport(page, 1280, 720); await verifyViewport(page, 1280, 720);
@ -176,10 +175,10 @@ browserTest('should be able to get correct orientation angle on non-mobile devic
await context.close(); await context.close();
}); });
it('should set window.screen.orientation.type for mobile devices', async ({ contextFactory, browserName, server, isMac }) => { it('should set window.screen.orientation.type for mobile devices', async ({ contextFactory, browserName, server, isMac, macVersion }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31151' }); it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31151' });
it.skip(browserName === 'firefox', 'Firefox does not support mobile emulation'); it.skip(browserName === 'firefox', 'Firefox does not support mobile emulation');
it.skip(browserName === 'webkit' && isMac && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS 12 is frozen and does not support orientation.type override'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS 12 is frozen and does not support orientation.type override');
const context = await contextFactory(devices['iPhone 14']); const context = await contextFactory(devices['iPhone 14']);
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.PREFIX + '/index.html'); await page.goto(server.PREFIX + '/index.html');

View file

@ -16,7 +16,6 @@
*/ */
import fs from 'fs'; import fs from 'fs';
import os from 'os';
import type http from 'http'; import type http from 'http';
import type net from 'net'; import type net from 'net';
import * as path from 'path'; import * as path from 'path';
@ -678,9 +677,9 @@ for (const kind of ['launchServer', 'run-server'] as const) {
expect(await response.json()).toEqual({ 'foo': 'bar' }); expect(await response.json()).toEqual({ 'foo': 'bar' });
}); });
test('should upload large file', async ({ connect, startRemoteServer, server, browserName, isMac, mode }, testInfo) => { test('should upload large file', async ({ connect, startRemoteServer, server, browserName, isMac, macVersion, mode }, testInfo) => {
test.skip(mode.startsWith('service'), 'Take it easy on service'); test.skip(mode.startsWith('service'), 'Take it easy on service');
test.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 20, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.'); test.skip(browserName === 'webkit' && isMac && macVersion < 11, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.');
test.slow(); test.slow();
const remoteServer = await startRemoteServer(kind); const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint()); const browser = await connect(remoteServer.wsEndpoint());

View file

@ -19,8 +19,8 @@ import url from 'url';
import { contextTest as it, expect } from '../config/browserTest'; import { contextTest as it, expect } from '../config/browserTest';
import { hostPlatform } from '../../packages/playwright-core/src/utils/hostPlatform'; import { hostPlatform } from '../../packages/playwright-core/src/utils/hostPlatform';
it('SharedArrayBuffer should work @smoke', async function({ contextFactory, httpsServer, isMac, browserName }) { it('SharedArrayBuffer should work @smoke', async function({ contextFactory, httpsServer, isMac, macVersion, browserName }) {
it.skip(browserName === 'webkit' && isMac && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS 12 is frozen and does not support SharedArrayBuffer'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS 12 is frozen and does not support SharedArrayBuffer');
const context = await contextFactory({ ignoreHTTPSErrors: true }); const context = await contextFactory({ ignoreHTTPSErrors: true });
const page = await context.newPage(); const page = await context.newPage();
httpsServer.setRoute('/sharedarraybuffer', (req, res) => { httpsServer.setRoute('/sharedarraybuffer', (req, res) => {
@ -65,13 +65,13 @@ it('should respect CSP @smoke', async ({ page, server }) => {
expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS'); expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS');
}); });
it('should play video @smoke', async ({ page, asset, browserName, platform, mode }) => { it('should play video @smoke', async ({ page, asset, browserName, platform, macVersion, mode }) => {
// TODO: the test passes on Windows locally but fails on GitHub Action bot, // TODO: the test passes on Windows locally but fails on GitHub Action bot,
// apparently due to a Media Pack issue in the Windows Server. // apparently due to a Media Pack issue in the Windows Server.
// Also the test is very flaky on Linux WebKit. // Also the test is very flaky on Linux WebKit.
it.fixme(browserName === 'webkit' && platform !== 'darwin'); it.fixme(browserName === 'webkit' && platform !== 'darwin');
it.fixme(browserName === 'firefox', 'https://github.com/microsoft/playwright/issues/5721'); it.fixme(browserName === 'firefox', 'https://github.com/microsoft/playwright/issues/5721');
it.fixme(browserName === 'webkit' && platform === 'darwin' && parseInt(os.release(), 10) === 20, 'Does not work on BigSur'); it.fixme(browserName === 'webkit' && platform === 'darwin' && macVersion === 11, 'Does not work on BigSur');
it.skip(mode.startsWith('service')); it.skip(mode.startsWith('service'));
// Safari only plays mp4 so we test WebKit with an .mp4 clip. // Safari only plays mp4 so we test WebKit with an .mp4 clip.
@ -84,8 +84,8 @@ it('should play video @smoke', async ({ page, asset, browserName, platform, mode
await page.$eval('video', v => v.pause()); await page.$eval('video', v => v.pause());
}); });
it('should play webm video @smoke', async ({ page, asset, browserName, platform, mode }) => { it('should play webm video @smoke', async ({ page, asset, browserName, platform, macVersion, mode }) => {
it.fixme(browserName === 'webkit' && platform === 'darwin' && parseInt(os.release(), 10) === 20, 'Does not work on BigSur'); it.fixme(browserName === 'webkit' && platform === 'darwin' && macVersion === 11, 'Does not work on BigSur');
it.fixme(browserName === 'webkit' && platform === 'win32'); it.fixme(browserName === 'webkit' && platform === 'win32');
it.skip(mode.startsWith('service')); it.skip(mode.startsWith('service'));
@ -143,6 +143,8 @@ it('should not crash on showDirectoryPicker', async ({ page, server, browserName
it.skip(browserName === 'chromium' && browserMajorVersion < 99, 'Fixed in Chromium r956769'); it.skip(browserName === 'chromium' && browserMajorVersion < 99, 'Fixed in Chromium r956769');
it.skip(browserName !== 'chromium', 'showDirectoryPicker is only available in Chromium'); it.skip(browserName !== 'chromium', 'showDirectoryPicker is only available in Chromium');
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
// "User activation is required to show a file picker." - so we click first.
await page.locator('body').click();
page.evaluate(async () => { page.evaluate(async () => {
const dir = await (window as any).showDirectoryPicker(); const dir = await (window as any).showDirectoryPicker();
return dir.name; return dir.name;
@ -240,9 +242,9 @@ it('make sure that XMLHttpRequest upload events are emitted correctly', async ({
expect(events).toEqual(['loadstart', 'progress', 'load', 'loadend']); expect(events).toEqual(['loadstart', 'progress', 'load', 'loadend']);
}); });
it('loading in HTMLImageElement.prototype', async ({ page, server, browserName, isMac }) => { it('loading in HTMLImageElement.prototype', async ({ page, server, browserName, isMac, macVersion }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22738' }); it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22738' });
it.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 21, 'macOS 11 is frozen'); it.skip(browserName === 'webkit' && isMac && macVersion < 12, 'macOS 11 is frozen');
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const defined = await page.evaluate(() => 'loading' in HTMLImageElement.prototype); const defined = await page.evaluate(() => 'loading' in HTMLImageElement.prototype);
expect(defined).toBeTruthy(); expect(defined).toBeTruthy();

View file

@ -409,13 +409,13 @@ test('should connect to an existing cdp session when passed as a first argument'
} }
}); });
test('should use proxy with connectOverCDP', async ({ browserType, server, mode }, testInfo) => { test('should use proxy with connectOverCDP', async ({ browserType, server }, testInfo) => {
server.setRoute('/target.html', async (req, res) => { server.setRoute('/target.html', async (req, res) => {
res.end('<html><title>Served by the proxy</title></html>'); res.end('<html><title>Served by the proxy</title></html>');
}); });
const port = 9339 + testInfo.workerIndex; const port = 9339 + testInfo.workerIndex;
const browserServer = await browserType.launch({ const browserServer = await browserType.launch({
args: ['--remote-debugging-port=' + port, ...(process.platform === 'win32' ? ['--proxy-server=some-value'] : [])] args: ['--remote-debugging-port=' + port]
}); });
try { try {
const cdpBrowser = await browserType.connectOverCDP(`http://127.0.0.1:${port}/`); const cdpBrowser = await browserType.connectOverCDP(`http://127.0.0.1:${port}/`);

View file

@ -291,8 +291,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should fail with no client certificates', async ({ browser, startCCServer, asset, browserName }) => { test('should fail with no client certificates', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -306,8 +306,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should fail with self-signed client certificates', async ({ browser, startCCServer, asset, browserName }) => { test('should fail with self-signed client certificates', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -321,8 +321,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should pass with matching certificates', async ({ browser, startCCServer, asset, browserName }) => { test('should pass with matching certificates', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -336,8 +336,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should pass with matching certificates when passing as content', async ({ browser, startCCServer, asset, browserName }) => { test('should pass with matching certificates when passing as content', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -351,8 +351,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should pass with matching certificates and when a http proxy is used', async ({ browser, startCCServer, asset, browserName, proxyServer }) => { test('should pass with matching certificates and when a http proxy is used', async ({ browser, startCCServer, asset, browserName, proxyServer, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
proxyServer.forwardTo(parseInt(new URL(serverURL).port, 10), { allowConnectRequests: true }); proxyServer.forwardTo(parseInt(new URL(serverURL).port, 10), { allowConnectRequests: true });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
@ -365,14 +365,14 @@ test.describe('browser', () => {
}); });
expect(proxyServer.connectHosts).toEqual([]); expect(proxyServer.connectHosts).toEqual([]);
await page.goto(serverURL); await page.goto(serverURL);
const host = browserName === 'webkit' && process.platform === 'darwin' ? 'localhost' : '127.0.0.1'; const host = browserName === 'webkit' && isMac ? 'localhost' : '127.0.0.1';
expect([...new Set(proxyServer.connectHosts)]).toEqual([`${host}:${new URL(serverURL).port}`]); expect([...new Set(proxyServer.connectHosts)]).toEqual([`${host}:${new URL(serverURL).port}`]);
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!'); await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
await page.close(); await page.close();
}); });
test('should pass with matching certificates and when a socks proxy is used', async ({ browser, startCCServer, asset, browserName }) => { test('should pass with matching certificates and when a socks proxy is used', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const serverPort = parseInt(new URL(serverURL).port, 10); const serverPort = parseInt(new URL(serverURL).port, 10);
const { proxyServerAddr, closeProxyServer, connectHosts } = await setupSocksForwardingServer({ const { proxyServerAddr, closeProxyServer, connectHosts } = await setupSocksForwardingServer({
port: test.info().workerIndex + 2048 + 2, port: test.info().workerIndex + 2048 + 2,
@ -390,7 +390,7 @@ test.describe('browser', () => {
}); });
expect(connectHosts).toEqual([]); expect(connectHosts).toEqual([]);
await page.goto(serverURL); await page.goto(serverURL);
const host = browserName === 'webkit' && process.platform === 'darwin' ? 'localhost' : '127.0.0.1'; const host = browserName === 'webkit' && isMac ? 'localhost' : '127.0.0.1';
expect(connectHosts).toEqual([`${host}:${serverPort}`]); expect(connectHosts).toEqual([`${host}:${serverPort}`]);
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!'); await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
await page.close(); await page.close();
@ -439,8 +439,8 @@ test.describe('browser', () => {
} }
}); });
test('should pass with matching certificates in pfx format', async ({ browser, startCCServer, asset, browserName }) => { test('should pass with matching certificates in pfx format', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -514,7 +514,7 @@ test.describe('browser', () => {
const stylesheet = ` const stylesheet = `
button { button {
background-color: red; background-color: red;
} }
`; `;
const stylesheetBuffer = await new Promise<Buffer>((resolve, reject) => { const stylesheetBuffer = await new Promise<Buffer>((resolve, reject) => {
@ -586,8 +586,8 @@ test.describe('browser', () => {
await new Promise<void>(resolve => server.close(() => resolve())); await new Promise<void>(resolve => server.close(() => resolve()));
}); });
test('should pass with matching certificates in pfx format when passing as content', async ({ browser, startCCServer, asset, browserName }) => { test('should pass with matching certificates in pfx format when passing as content', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -601,8 +601,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should fail with matching certificates in legacy pfx format', async ({ browser, startCCServer, asset, browserName }) => { test('should fail with matching certificates in legacy pfx format', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
await expect(browser.newPage({ await expect(browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -613,8 +613,8 @@ test.describe('browser', () => {
})).rejects.toThrow('Unsupported TLS certificate'); })).rejects.toThrow('Unsupported TLS certificate');
}); });
test('should throw a http error if the pfx passphrase is incorect', async ({ browser, startCCServer, asset, browserName }) => { test('should throw a http error if the pfx passphrase is incorect', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
await expect(browser.newPage({ await expect(browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -649,8 +649,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should pass with matching certificates and trailing slash', async ({ browser, startCCServer, asset, browserName }) => { test('should pass with matching certificates and trailing slash', async ({ browser, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
@ -677,8 +677,8 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('support http2', async ({ browser, startCCServer, asset, browserName }) => { test('support http2', async ({ browser, startCCServer, asset, browserName, isMac }) => {
test.skip(browserName === 'webkit' && process.platform === 'darwin', 'WebKit on macOS doesn\n proxy localhost'); test.skip(browserName === 'webkit' && isMac, 'WebKit on macOS doesn\n proxy localhost');
const serverURL = await startCCServer({ http2: true }); const serverURL = await startCCServer({ http2: true });
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
@ -727,9 +727,9 @@ test.describe('browser', () => {
await browser.close(); await browser.close();
}); });
test('should return target connection errors when using http2', async ({ browser, startCCServer, asset, browserName }) => { test('should return target connection errors when using http2', async ({ browser, startCCServer, asset, browserName, isMac, isLinux }) => {
test.skip(browserName === 'webkit' && process.platform === 'darwin', 'WebKit on macOS doesn\n proxy localhost'); test.skip(browserName === 'webkit' && isMac, 'WebKit on macOS doesn\n proxy localhost');
test.fixme(browserName === 'webkit' && process.platform === 'linux', 'WebKit on Linux does not support http2 https://bugs.webkit.org/show_bug.cgi?id=276990'); test.fixme(browserName === 'webkit' && isLinux, 'WebKit on Linux does not support http2 https://bugs.webkit.org/show_bug.cgi?id=276990');
test.skip(+process.versions.node.split('.')[0] < 20, 'http2.performServerHandshake is not supported in older Node.js versions'); test.skip(+process.versions.node.split('.')[0] < 20, 'http2.performServerHandshake is not supported in older Node.js versions');
const serverURL = await startCCServer({ http2: true }); const serverURL = await startCCServer({ http2: true });
@ -785,8 +785,8 @@ test.describe('browser', () => {
await expect(launchPersistent(contextOptions)).rejects.toThrow(expected); await expect(launchPersistent(contextOptions)).rejects.toThrow(expected);
}); });
test('should pass with matching certificates', async ({ launchPersistent, startCCServer, asset, browserName }) => { test('should pass with matching certificates', async ({ launchPersistent, startCCServer, asset, browserName, isMac }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' }); const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && isMac });
const { page } = await launchPersistent({ const { page } = await launchPersistent({
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{

View file

@ -22,8 +22,12 @@ it('context request should pick up proxy credentials', async ({ browserType, ser
proxyServer.forwardTo(server.PORT, { allowConnectRequests: true }); proxyServer.forwardTo(server.PORT, { allowConnectRequests: true });
let auth; let auth;
proxyServer.setAuthHandler(req => { proxyServer.setAuthHandler(req => {
auth = req.headers['proxy-authorization']; const header = req.headers['proxy-authorization'];
return !!auth; // Browser can issue various unrelated requests over the proxy,
// but we are only interested in our own request.
if (proxyServer.connectHosts.includes('non-existent.com:80'))
auth = header;
return !!header;
}); });
const browser = await browserType.launch({ const browser = await browserType.launch({
proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' } proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' }

View file

@ -59,11 +59,11 @@ test('should remove temp dir on process.exit', async ({ startRemoteServer, serve
test.describe('signals', () => { test.describe('signals', () => {
test.skip(({ platform }) => platform === 'win32'); test.skip(({ platform }) => platform === 'win32');
test('should report browser close signal 2', async ({ startRemoteServer, server, isMac, browserName }) => { test('should report browser close signal 2', async ({ startRemoteServer, server, isMac, macVersion, browserName }) => {
const remoteServer = await startRemoteServer('launchServer', { url: server.EMPTY_PAGE }); const remoteServer = await startRemoteServer('launchServer', { url: server.EMPTY_PAGE });
const pid = await remoteServer.out('pid'); const pid = await remoteServer.out('pid');
process.kill(-pid, 'SIGKILL'); process.kill(-pid, 'SIGKILL');
if (isMac && browserName === 'webkit' && parseInt(os.release(), 10) > 22 && os.arch() === 'arm64') { if (isMac && browserName === 'webkit' && macVersion > 13 && os.arch() === 'arm64') {
// WebKit on newer macOS exits sometimes with exit code, sometimes with signal. // WebKit on newer macOS exits sometimes with exit code, sometimes with signal.
expect('exitCode:' + await remoteServer.out('exitCode') + expect('exitCode:' + await remoteServer.out('exitCode') +
'signal:' + await remoteServer.out('signal')).toMatch(/exitCode:137|signal:SIGKILL/); 'signal:' + await remoteServer.out('signal')).toMatch(/exitCode:137|signal:SIGKILL/);

View file

@ -16,7 +16,6 @@
*/ */
import { test as it, expect } from './pageTest'; import { test as it, expect } from './pageTest';
import os from 'os';
it('should press @smoke', async ({ page }) => { it('should press @smoke', async ({ page }) => {
await page.setContent(`<input type='text' />`); await page.setContent(`<input type='text' />`);
@ -43,9 +42,9 @@ it('should scroll into view', async ({ page, server, isAndroid }) => {
} }
}); });
it('should scroll zero-sized element into view', async ({ page, isAndroid, isElectron, isWebView2, browserName, isMac }) => { it('should scroll zero-sized element into view', async ({ page, isAndroid, isElectron, isWebView2, browserName, isMac, macVersion }) => {
it.fixme(isAndroid || isElectron || isWebView2); it.fixme(isAndroid || isElectron || isWebView2);
it.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 20, 'WebKit for macOS 10.15 is frozen.'); it.skip(browserName === 'webkit' && isMac && macVersion < 11, 'WebKit for macOS 10.15 is frozen.');
await page.setContent(` await page.setContent(`
<style> <style>

View file

@ -15,11 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import os from 'os';
import { test as it, expect } from './pageTest'; import { test as it, expect } from './pageTest';
import { chromiumVersionLessThan } from '../config/utils'; import { chromiumVersionLessThan } from '../config/utils';
it('should work @smoke', async ({ page, browserName }) => { it('should work @smoke', async ({ page, browserName, macVersion }) => {
await page.setContent(` await page.setContent(`
<head> <head>
<title>Accessibility Test</title> <title>Accessibility Test</title>
@ -76,7 +75,8 @@ it('should work @smoke', async ({ page, browserName }) => {
{ role: 'textbox', name: '', value: 'value only' }, { role: 'textbox', name: '', value: 'value only' },
{ role: 'textbox', name: 'placeholder', value: 'and a value' }, { role: 'textbox', name: 'placeholder', value: 'and a value' },
// due to frozen WebKit on macOS 11 we have the if/else here // due to frozen WebKit on macOS 11 we have the if/else here
{ role: 'textbox', name: parseInt(os.release(), 10) >= 21 ? 'placeholder' : 'This is a description!', value: 'and a value' }, // webkit uses the description over placeholder for the name // old webkit uses the description over placeholder for the name
{ role: 'textbox', name: macVersion >= 12 ? 'placeholder' : 'This is a description!', value: 'and a value' },
] ]
}; };
expect(await page.accessibility.snapshot()).toEqual(golden); expect(await page.accessibility.snapshot()).toEqual(golden);

View file

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
import os from 'os';
import type { Route } from 'playwright-core'; import type { Route } from 'playwright-core';
import { test as it, expect } from './pageTest'; import { test as it, expect } from './pageTest';
@ -300,15 +299,14 @@ it('should be abortable', async ({ page, server }) => {
expect(failed).toBe(true); expect(failed).toBe(true);
}); });
it('should be abortable with custom error codes', async ({ page, server, browserName, isMac }) => { it('should be abortable with custom error codes', async ({ page, server, browserName, isMac, macVersion }) => {
await page.route('**/*', route => route.abort('internetdisconnected')); await page.route('**/*', route => route.abort('internetdisconnected'));
let failedRequest = null; let failedRequest = null;
page.on('requestfailed', request => failedRequest = request); page.on('requestfailed', request => failedRequest = request);
await page.goto(server.EMPTY_PAGE).catch(e => {}); await page.goto(server.EMPTY_PAGE).catch(e => {});
expect(failedRequest).toBeTruthy(); expect(failedRequest).toBeTruthy();
const isFrozenWebKit = isMac && parseInt(os.release(), 10) < 20;
if (browserName === 'webkit') if (browserName === 'webkit')
expect(failedRequest.failure().errorText).toBe(isFrozenWebKit ? 'Request intercepted' : 'Blocked by Web Inspector'); expect(failedRequest.failure().errorText).toBe(isMac && macVersion < 11 ? 'Request intercepted' : 'Blocked by Web Inspector');
else if (browserName === 'firefox') else if (browserName === 'firefox')
expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE'); expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE');
else else
@ -345,14 +343,13 @@ it('should send referer', async ({ page, server }) => {
expect(request.headers['referer']).toBe('http://google.com/'); expect(request.headers['referer']).toBe('http://google.com/');
}); });
it('should fail navigation when aborting main resource', async ({ page, server, browserName, isMac }) => { it('should fail navigation when aborting main resource', async ({ page, server, browserName, isMac, macVersion }) => {
await page.route('**/*', route => route.abort()); await page.route('**/*', route => route.abort());
let error = null; let error = null;
await page.goto(server.EMPTY_PAGE).catch(e => error = e); await page.goto(server.EMPTY_PAGE).catch(e => error = e);
expect(error).toBeTruthy(); expect(error).toBeTruthy();
const isFrozenWebKit = isMac && parseInt(os.release(), 10) < 20;
if (browserName === 'webkit') if (browserName === 'webkit')
expect(error.message).toContain(isFrozenWebKit ? 'Request intercepted' : 'Blocked by Web Inspector'); expect(error.message).toContain(isMac && macVersion < 11 ? 'Request intercepted' : 'Blocked by Web Inspector');
else if (browserName === 'firefox') else if (browserName === 'firefox')
expect(error.message).toContain('NS_ERROR_FAILURE'); expect(error.message).toContain('NS_ERROR_FAILURE');
else else

View file

@ -280,12 +280,12 @@ it.describe('page screenshot', () => {
expect(screenshot).toMatchSnapshot('screenshot-clip-odd-size.png'); expect(screenshot).toMatchSnapshot('screenshot-clip-odd-size.png');
}); });
it('should work for canvas', async ({ page, server, isElectron, isMac, browserName, headless }) => { it('should work for canvas', async ({ page, server, isElectron, isMac, macVersion, browserName, headless }) => {
it.fixme(isElectron && isMac, 'Fails on the bots'); it.fixme(isElectron && isMac, 'Fails on the bots');
await page.setViewportSize({ width: 500, height: 500 }); await page.setViewportSize({ width: 500, height: 500 });
await page.goto(server.PREFIX + '/screenshots/canvas.html'); await page.goto(server.PREFIX + '/screenshots/canvas.html');
const screenshot = await page.screenshot(); const screenshot = await page.screenshot();
if (!headless && browserName === 'chromium' && isMac && os.arch() === 'arm64' && /* macOS 14+ */ parseInt(os.release(), 10) >= 23) if (!headless && browserName === 'chromium' && isMac && os.arch() === 'arm64' && macVersion >= 14)
expect(screenshot).toMatchSnapshot('screenshot-canvas-with-accurate-corners.png'); expect(screenshot).toMatchSnapshot('screenshot-canvas-with-accurate-corners.png');
else else
expect(screenshot).toMatchSnapshot('screenshot-canvas.png'); expect(screenshot).toMatchSnapshot('screenshot-canvas.png');

View file

@ -20,7 +20,6 @@ import { attachFrame } from '../config/utils';
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import os from 'os';
import formidable from 'formidable'; import formidable from 'formidable';
it('should upload the file', async ({ page, server, asset }) => { it('should upload the file', async ({ page, server, asset }) => {
@ -37,9 +36,9 @@ it('should upload the file', async ({ page, server, asset }) => {
}, input)).toBe('contents of the file'); }, input)).toBe('contents of the file');
}); });
it('should upload a folder', async ({ page, server, browserName, headless, browserMajorVersion, isAndroid }) => { it('should upload a folder', async ({ page, server, browserName, headless, browserMajorVersion, isAndroid, macVersion, isMac }) => {
it.skip(isAndroid); it.skip(isAndroid);
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS-12 is frozen');
await page.goto(server.PREFIX + '/input/folderupload.html'); await page.goto(server.PREFIX + '/input/folderupload.html');
const input = await page.$('input'); const input = await page.$('input');
@ -70,9 +69,9 @@ it('should upload a folder', async ({ page, server, browserName, headless, brows
} }
}); });
it('should upload a folder and throw for multiple directories', async ({ page, server, isAndroid, browserName }) => { it('should upload a folder and throw for multiple directories', async ({ page, server, isAndroid, browserName, macVersion, isMac }) => {
it.skip(isAndroid); it.skip(isAndroid);
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS-12 is frozen');
await page.goto(server.PREFIX + '/input/folderupload.html'); await page.goto(server.PREFIX + '/input/folderupload.html');
const input = await page.$('input'); const input = await page.$('input');
@ -89,9 +88,9 @@ it('should upload a folder and throw for multiple directories', async ({ page, s
])).rejects.toThrow('Multiple directories are not supported'); ])).rejects.toThrow('Multiple directories are not supported');
}); });
it('should throw if a directory and files are passed', async ({ page, server, isAndroid, browserName }) => { it('should throw if a directory and files are passed', async ({ page, server, isAndroid, browserName, macVersion, isMac }) => {
it.skip(isAndroid); it.skip(isAndroid);
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS-12 is frozen');
await page.goto(server.PREFIX + '/input/folderupload.html'); await page.goto(server.PREFIX + '/input/folderupload.html');
const input = await page.$('input'); const input = await page.$('input');
@ -106,9 +105,9 @@ it('should throw if a directory and files are passed', async ({ page, server, is
])).rejects.toThrow('File paths must be all files or a single directory'); ])).rejects.toThrow('File paths must be all files or a single directory');
}); });
it('should throw when uploading a folder in a normal file upload input', async ({ page, server, isAndroid, browserName }) => { it('should throw when uploading a folder in a normal file upload input', async ({ page, server, isAndroid, browserName, macVersion, isMac }) => {
it.skip(isAndroid); it.skip(isAndroid);
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS-12 is frozen');
await page.goto(server.PREFIX + '/input/fileupload.html'); await page.goto(server.PREFIX + '/input/fileupload.html');
const input = await page.$('input'); const input = await page.$('input');
@ -120,9 +119,9 @@ it('should throw when uploading a folder in a normal file upload input', async (
await expect(input.setInputFiles(dir)).rejects.toThrow('File input does not support directories, pass individual files instead'); await expect(input.setInputFiles(dir)).rejects.toThrow('File input does not support directories, pass individual files instead');
}); });
it('should throw when uploading a file in a directory upload input', async ({ page, server, isAndroid, asset, browserName }) => { it('should throw when uploading a file in a directory upload input', async ({ page, server, isAndroid, asset, browserName, macVersion, isMac }) => {
it.skip(isAndroid); it.skip(isAndroid);
it.skip(browserName === 'webkit' && os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen'); it.skip(browserName === 'webkit' && isMac && macVersion <= 12, 'WebKit on macOS-12 is frozen');
await page.goto(server.PREFIX + '/input/folderupload.html'); await page.goto(server.PREFIX + '/input/folderupload.html');
const input = await page.$('input'); const input = await page.$('input');
@ -145,8 +144,8 @@ it('should upload a file after popup', async ({ page, server, asset }) => {
expect(await page.evaluate(e => e.files[0].name, input)).toBe('file-to-upload.txt'); expect(await page.evaluate(e => e.files[0].name, input)).toBe('file-to-upload.txt');
}); });
it('should upload large file', async ({ page, server, browserName, isMac, isAndroid, isWebView2, mode }, testInfo) => { it('should upload large file', async ({ page, server, browserName, isMac, isAndroid, isWebView2, mode, macVersion }, testInfo) => {
it.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 20, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.'); it.skip(browserName === 'webkit' && isMac && macVersion < 11, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.');
it.skip(isAndroid); it.skip(isAndroid);
it.skip(isWebView2); it.skip(isWebView2);
it.skip(mode.startsWith('service')); it.skip(mode.startsWith('service'));
@ -204,8 +203,8 @@ it('should throw an error if the file does not exist', async ({ page, server, as
expect(error.message).toContain('i actually do not exist.txt'); expect(error.message).toContain('i actually do not exist.txt');
}); });
it('should upload multiple large files', async ({ page, server, browserName, isMac, isAndroid, isWebView2, mode }, testInfo) => { it('should upload multiple large files', async ({ page, server, browserName, isMac, isAndroid, isWebView2, mode, macVersion }, testInfo) => {
it.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 20, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.'); it.skip(browserName === 'webkit' && isMac && macVersion < 11, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.');
it.skip(isAndroid); it.skip(isAndroid);
it.skip(isWebView2); it.skip(isWebView2);
it.skip(mode.startsWith('service')); it.skip(mode.startsWith('service'));
@ -245,8 +244,8 @@ it('should upload multiple large files', async ({ page, server, browserName, isM
await Promise.all(uploadFiles.map(path => fs.promises.unlink(path))); await Promise.all(uploadFiles.map(path => fs.promises.unlink(path)));
}); });
it('should upload large file with relative path', async ({ page, server, browserName, isMac, isAndroid, isWebView2, mode }, testInfo) => { it('should upload large file with relative path', async ({ page, server, browserName, isMac, isAndroid, isWebView2, mode, macVersion }, testInfo) => {
it.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 20, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.'); it.skip(browserName === 'webkit' && isMac && macVersion < 11, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.');
it.skip(isAndroid); it.skip(isAndroid);
it.skip(isWebView2); it.skip(isWebView2);
it.skip(mode.startsWith('service')); it.skip(mode.startsWith('service'));