more real world tests

This commit is contained in:
Max Schmitt 2024-07-10 22:35:45 +02:00
parent 51e938e3e9
commit 22cba2d64d
4 changed files with 13 additions and 30 deletions

View file

@ -16,8 +16,9 @@
import type * as channels from '@protocol/channels'; import type * as channels from '@protocol/channels';
import type { LookupAddress } from 'dns'; import type { LookupAddress } from 'dns';
import * as http from 'http'; import http from 'http';
import * as https from 'https'; import fs from 'fs';
import https from 'https';
import type { Readable, TransformCallback } from 'stream'; import type { Readable, TransformCallback } from 'stream';
import { pipeline, Transform } from 'stream'; import { pipeline, Transform } from 'stream';
import url from 'url'; import url from 'url';
@ -192,6 +193,7 @@ export abstract class APIRequestContext extends SdkObject {
maxRedirects: params.maxRedirects === 0 ? -1 : params.maxRedirects === undefined ? 20 : params.maxRedirects, maxRedirects: params.maxRedirects === 0 ? -1 : params.maxRedirects === undefined ? 20 : params.maxRedirects,
timeout, timeout,
deadline, deadline,
...(process.env.PW_DO_NOT_USE_EXTRA_CA_CERTS ? { ca: [fs.readFileSync(process.env.PW_DO_NOT_USE_EXTRA_CA_CERTS)] } : {}),
...clientCertificatesToTLSOptions(this._defaultOptions().clientCertificates, requestUrl.toString()), ...clientCertificatesToTLSOptions(this._defaultOptions().clientCertificates, requestUrl.toString()),
__testHookLookup: (params as any).__testHookLookup, __testHookLookup: (params as any).__testHookLookup,
}; };

View file

@ -92,7 +92,6 @@ class SocksProxyConnection {
this.internal = new SocksConnectionDuplex(data => this.socksProxy._socksProxy.sendSocketData({ uid: this.uid, data })); this.internal = new SocksConnectionDuplex(data => this.socksProxy._socksProxy.sendSocketData({ uid: this.uid, data }));
const internalTLS = new tls.TLSSocket(this.internal, { const internalTLS = new tls.TLSSocket(this.internal, {
isServer: true, isServer: true,
// openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -keyout key.pem -out cert.pem -subj "/CN=localhost"
key: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/key.pem')), key: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/key.pem')),
cert: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/cert.pem')), cert: fs.readFileSync(path.join(__dirname, '../../bin/socks-certs/cert.pem')),
}); });

View file

@ -424,9 +424,9 @@ function resolveFileToConfig(file: string | undefined) {
const config = test.info().config.configFile; const config = test.info().config.configFile;
if (!config || !file) if (!config || !file)
return file; return file;
if (!path.isAbsolute(file)) if (path.isAbsolute(file))
return path.resolve(path.dirname(config), file); return file;
return file; return path.resolve(path.dirname(config), file);
} }
type ClientCertificates = NonNullable<PlaywrightTestOptions['clientCertificates']>; type ClientCertificates = NonNullable<PlaywrightTestOptions['clientCertificates']>;

View file

@ -43,6 +43,7 @@ const test = base.extend<{ serverURL: string, serverURLRewrittenToLocalhost: str
res.end(`Sorry, but you need to provide a client certificate to continue.`); res.end(`Sorry, but you need to provide a client certificate to continue.`);
} }
}); });
process.env.PW_DO_NOT_USE_EXTRA_CA_CERTS = asset('client-certificates/server/server_cert.pem');
await new Promise<void>(f => server.listen(0, 'localhost', () => f())); await new Promise<void>(f => server.listen(0, 'localhost', () => f()));
await use(`https://localhost:${(server.address() as net.AddressInfo).port}/`); await use(`https://localhost:${(server.address() as net.AddressInfo).port}/`);
await new Promise<void>(resolve => server.close(() => resolve())); await new Promise<void>(resolve => server.close(() => resolve()));
@ -93,7 +94,7 @@ test.describe('fetch', () => {
}); });
test('should fail with no client certificates provided', async ({ playwright, serverURL }) => { test('should fail with no client certificates provided', async ({ playwright, serverURL }) => {
const request = await playwright.request.newContext({ ignoreHTTPSErrors: true }); const request = await playwright.request.newContext();
const response = await request.get(serverURL); const response = await request.get(serverURL);
expect(response.status()).toBe(401); expect(response.status()).toBe(401);
expect(await response.text()).toBe('Sorry, but you need to provide a client certificate to continue.'); expect(await response.text()).toBe('Sorry, but you need to provide a client certificate to continue.');
@ -117,22 +118,8 @@ test.describe('fetch', () => {
await request.dispose(); await request.dispose();
}); });
test('should throw with a untrusted CA', async ({ playwright, serverURL, asset }) => { test('should throw with untrusted client certs', async ({ playwright, serverURL, asset }) => {
const request = await playwright.request.newContext({ const request = await playwright.request.newContext({
clientCertificates: [{
url: serverURL,
certs: [{
certPath: asset('client-certificates/client/trusted/cert.pem'),
keyPath: asset('client-certificates/client/trusted/key.pem'),
}],
}],
});
await expect(request.get(serverURL)).rejects.toThrow('self-signed certificate');
});
test('should throw with matching CA but untrusted client certs', async ({ playwright, serverURL, asset }) => {
const request = await playwright.request.newContext({
ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
url: serverURL, url: serverURL,
certs: [{ certs: [{
@ -148,7 +135,7 @@ test.describe('fetch', () => {
await request.dispose(); await request.dispose();
}); });
test('should work without CA', async ({ playwright, serverURL, asset }) => { test('pass with trusted client certificates', async ({ playwright, serverURL, asset }) => {
const request = await playwright.request.newContext({ const request = await playwright.request.newContext({
clientCertificates: [{ clientCertificates: [{
url: serverURL, url: serverURL,
@ -157,7 +144,6 @@ test.describe('fetch', () => {
keyPath: asset('client-certificates/client/trusted/key.pem'), keyPath: asset('client-certificates/client/trusted/key.pem'),
}], }],
}], }],
ignoreHTTPSErrors: true,
}); });
const response = await request.get(serverURL); const response = await request.get(serverURL);
expect(response.url()).toBe(serverURL); expect(response.url()).toBe(serverURL);
@ -168,7 +154,6 @@ test.describe('fetch', () => {
test('should work in the browser with request interception', async ({ browser, playwright, serverURL, asset }) => { test('should work in the browser with request interception', async ({ browser, playwright, serverURL, asset }) => {
const request = await playwright.request.newContext({ const request = await playwright.request.newContext({
ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
url: serverURL, url: serverURL,
certs: [{ certs: [{
@ -214,7 +199,6 @@ test.describe('browser', () => {
test('should fail with no client certificates', async ({ browser, serverURLRewrittenToLocalhost, asset }) => { test('should fail with no client certificates', async ({ browser, serverURLRewrittenToLocalhost, asset }) => {
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
url: 'https://not-matching.com', url: 'https://not-matching.com',
certs: [{ certs: [{
@ -228,7 +212,7 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should throw with a untrusted CA', async ({ browser, serverURLRewrittenToLocalhost, asset }) => { test('should fail with self-signed client certificates', async ({ browser, serverURLRewrittenToLocalhost, asset }) => {
const page = await browser.newPage({ const page = await browser.newPage({
clientCertificates: [{ clientCertificates: [{
url: serverURLRewrittenToLocalhost, url: serverURLRewrittenToLocalhost,
@ -245,7 +229,6 @@ test.describe('browser', () => {
test('should pass with matching certificates', async ({ browser, serverURLRewrittenToLocalhost, asset }) => { test('should pass with matching certificates', async ({ browser, serverURLRewrittenToLocalhost, asset }) => {
const page = await browser.newPage({ const page = await browser.newPage({
ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
url: serverURLRewrittenToLocalhost, url: serverURLRewrittenToLocalhost,
certs: [{ certs: [{
@ -260,15 +243,14 @@ test.describe('browser', () => {
}); });
test.describe('persistentContext', () => { test.describe('persistentContext', () => {
test('validate input', async ({ launchPersistent }) => { test('validate input', async ({ launchPersistent }) => {
test.slow();
for (const [contextOptions, expected] of kValidationSubTests) for (const [contextOptions, expected] of kValidationSubTests)
await expect(launchPersistent(contextOptions)).rejects.toThrow(expected); await expect(launchPersistent(contextOptions)).rejects.toThrow(expected);
}); });
test('should pass with matching certificates', async ({ launchPersistent, serverURLRewrittenToLocalhost, asset }) => { test('should pass with matching certificates', async ({ launchPersistent, serverURLRewrittenToLocalhost, asset }) => {
const { page } = await launchPersistent({ const { page } = await launchPersistent({
ignoreHTTPSErrors: true,
clientCertificates: [{ clientCertificates: [{
url: serverURLRewrittenToLocalhost, url: serverURLRewrittenToLocalhost,
certs: [{ certs: [{