Skip to content

Commit

Permalink
Merge pull request #192 from chromaui/steven/AP-4886-cdp-basic-auth
Browse files Browse the repository at this point in the history
Support using `httpCredentials` in Playwright global config for basic authentication
  • Loading branch information
andrewortwein authored Sep 4, 2024
2 parents b7b98b4 + 23635f7 commit e629f2b
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 44 deletions.
6 changes: 6 additions & 0 deletions .changeset/shaggy-candles-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@chromatic-com/playwright': minor
'@chromatic-com/shared-e2e': minor
---

Support using httpCredentials in Playwright global config for basic authentication
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@babel/preset-typescript": "^7.21.4",
"@changesets/cli": "^2.27.1",
"@jest/types": "^27.0.6",
"@playwright/test": "^1.39.0",
"@playwright/test": "^1.46.1",
"@storybook/eslint-config-storybook": "^3.1.2",
"@swc/core": "^1.4.6",
"@testing-library/dom": "^8.1.0",
Expand All @@ -50,12 +50,13 @@
"cypress": "^13.6.1",
"eslint": "^7.32.0",
"express": "^4.18.2",
"express-basic-auth": "^1.2.1",
"husky": ">=6",
"jest": "^27.0.6",
"jest-environment-jsdom": "^27.0.6",
"lint-staged": ">=10",
"node-fetch": "2",
"playwright": "^1.32.2",
"playwright": "^1.46.1",
"prettier": "^2.3.1",
"prompts": "^2.4.2",
"rimraf": "^3.0.2",
Expand Down
6 changes: 3 additions & 3 deletions packages/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@
},
"devDependencies": {
"@chromatic-com/shared-e2e": "workspace:*",
"@playwright/test": "^1.39.0",
"@playwright/test": "^1.46.1",
"@storybook/types": "^8.1.5",
"express": "^4.18.2",
"playwright": "^1.32.2",
"playwright-core": "^1.32.2"
"playwright": "^1.46.1",
"playwright-core": "^1.46.1"
},
"lint-staged": {
"*.{ts,js,css,md}": "prettier --write"
Expand Down
4 changes: 4 additions & 0 deletions packages/playwright/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export default defineConfig({
testDir: './tests',
use: {
baseURL: 'http://localhost:3000',
httpCredentials: {
username: 'admin',
password: 'supersecret',
},
},
projects: [
{
Expand Down
5 changes: 4 additions & 1 deletion packages/playwright/src/createResourceArchive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ResourceArchive,
DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS,
logger,
HttpCredentials,
} from '@chromatic-com/shared-e2e';

const idle = async (page: Page, networkTimeoutMs = DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS) => {
Expand Down Expand Up @@ -36,14 +37,16 @@ export const createResourceArchive = async ({
page,
networkTimeout,
assetDomains,
httpCredentials,
}: {
page: Page;
networkTimeout?: number;
assetDomains?: string[];
httpCredentials?: HttpCredentials;
}): Promise<() => Promise<ResourceArchive>> => {
const cdpClient = await page.context().newCDPSession(page);

const resourceArchiver = new ResourceArchiver(cdpClient, assetDomains);
const resourceArchiver = new ResourceArchiver(cdpClient, assetDomains, httpCredentials);
await resourceArchiver.watch();

return async () => {
Expand Down
4 changes: 3 additions & 1 deletion packages/playwright/src/makeTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export const performChromaticSnapshot = async (
use: () => Promise<void>,
testInfo: TestInfo
) => {
const { testId } = testInfo;
const { testId, project } = testInfo;
const httpCredentials = project?.use?.httpCredentials;

try {
trackRun();
Expand All @@ -53,6 +54,7 @@ export const performChromaticSnapshot = async (
page,
networkTimeout: resourceArchiveTimeout,
assetDomains,
httpCredentials,
});
await use();

Expand Down
9 changes: 9 additions & 0 deletions packages/playwright/tests/auth.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { test, expect } from '../src';

test.describe(() => {
test('can login', async ({ page }) => {
await page.goto('/auth');

await expect(page.getByText('I AM PROTECTED!!!')).toBeVisible();
});
});
6 changes: 3 additions & 3 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.4",
"@jest/types": "^27.0.6",
"@playwright/test": "^1.39.0",
"@playwright/test": "^1.46.1",
"@storybook/addon-essentials": "^8.1.5",
"@storybook/eslint-config-storybook": "^3.1.2",
"@storybook/server-webpack5": "^8.1.5",
Expand All @@ -96,8 +96,8 @@
"lint-staged": ">=10",
"mime": "^3.0.0",
"node-fetch": "2",
"playwright": "^1.32.2",
"playwright-core": "^1.32.2",
"playwright": "^1.46.1",
"playwright-core": "^1.46.1",
"prettier": "^2.3.1",
"prompts": "^2.4.2",
"rimraf": "^3.0.2",
Expand Down
26 changes: 24 additions & 2 deletions packages/shared/src/resource-archiver/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export type ArchiveResponse =

export type ResourceArchive = Record<UrlString, ArchiveResponse>;

export type HttpCredentials = {
username: string;
password: string;
};

// a custom interface that satisfies both playwright's CDPSession and chrome-remote-interface's CDP.Client types.
interface CDPClient {
on: (eventName: keyof Protocol.Events, handlerFunction: (params?: any) => void) => void;
Expand All @@ -40,15 +45,22 @@ export class ResourceArchiver {
*/
private firstUrl: URL;

constructor(cdpClient: CDPClient, allowedDomains?: string[]) {
/**
* HTTP Basic Auth credentials to use when accessing protected resources.
*/
private httpCredentials: HttpCredentials;

constructor(cdpClient: CDPClient, allowedDomains?: string[], httpCredentials?: HttpCredentials) {
this.client = cdpClient;
// tack on the protocol so we can properly check if requests are cross-origin
this.assetDomains = (allowedDomains || []).map((domain) => `https://${domain}`);
this.httpCredentials = httpCredentials;
}

async watch() {
this.client.on('Fetch.requestPaused', this.requestPaused.bind(this));
await this.client.send('Fetch.enable');
this.client.on('Fetch.authRequired', this.authRequired.bind(this));
await this.client.send('Fetch.enable', { handleAuthRequests: true });
}

async clientSend<T extends keyof Protocol.CommandParameters>(
Expand All @@ -65,6 +77,16 @@ export class ResourceArchiver {
}
}

async authRequired({ requestId, request }: Protocol.Fetch.authRequiredPayload): Promise<void> {
await this.clientSend(request, 'Fetch.continueWithAuth', {
requestId,
authChallengeResponse: {
response: 'ProvideCredentials',
...this.httpCredentials,
},
});
}

async requestPaused({
requestId,
request,
Expand Down
17 changes: 17 additions & 0 deletions test-server/fixtures/auth/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<style>
summary {
font-size: 22px;
}

p {
padding-inline-start: 32px;
}
</style>
</head>
<body>
<p>I AM PROTECTED!!!</p>
</body>
</html>
13 changes: 12 additions & 1 deletion test-server/server.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
const path = require('path');
// eslint-disable-next-line import/no-extraneous-dependencies
const express = require('express');
const basicAuth = require('express-basic-auth');

const app = express();
const port = 3000;

const htmlIntro = `<!doctype html><html>`;
const htmlOutro = `</html>`;

// Assets
app.use(
'/auth',
basicAuth({
users: { admin: 'supersecret' },
challenge: true,
})
);

app.get('/css.urls.css', (req, res) => {
res.sendFile(path.join(__dirname, 'fixtures/css.urls.css'));
Expand All @@ -29,6 +36,10 @@ app.get('/img', (req, res) => {
}
});

app.get('/auth', (req, res) => {
res.sendFile(path.join(__dirname, 'fixtures/auth/index.html'));
});

app.get('/img/another', (req, res) => {
res.sendFile(path.join(__dirname, 'fixtures/pink.png'));
});
Expand Down
72 changes: 41 additions & 31 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3594,16 +3594,16 @@ __metadata:
resolution: "@chromatic-com/playwright@workspace:packages/playwright"
dependencies:
"@chromatic-com/shared-e2e": "workspace:*"
"@playwright/test": "npm:^1.39.0"
"@playwright/test": "npm:^1.46.1"
"@segment/analytics-node": "npm:^1.1.0"
"@storybook/addon-essentials": "npm:^8.1.5"
"@storybook/csf": "npm:^0.1.0"
"@storybook/manager-api": "npm:^8.1.5"
"@storybook/server-webpack5": "npm:^8.1.5"
"@storybook/types": "npm:^8.1.5"
express: "npm:^4.18.2"
playwright: "npm:^1.32.2"
playwright-core: "npm:^1.32.2"
playwright: "npm:^1.46.1"
playwright-core: "npm:^1.46.1"
rrweb-snapshot: "npm:2.0.0-alpha.14"
storybook: "npm:^8.1.5"
ts-dedent: "npm:^2.2.0"
Expand All @@ -3623,7 +3623,7 @@ __metadata:
"@babel/preset-react": "npm:^7.18.6"
"@babel/preset-typescript": "npm:^7.21.4"
"@jest/types": "npm:^27.0.6"
"@playwright/test": "npm:^1.39.0"
"@playwright/test": "npm:^1.46.1"
"@segment/analytics-node": "npm:^1.1.0"
"@storybook/addon-essentials": "npm:^8.1.5"
"@storybook/eslint-config-storybook": "npm:^3.1.2"
Expand All @@ -3642,8 +3642,8 @@ __metadata:
lint-staged: "npm:>=10"
mime: "npm:^3.0.0"
node-fetch: "npm:2"
playwright: "npm:^1.32.2"
playwright-core: "npm:^1.32.2"
playwright: "npm:^1.46.1"
playwright-core: "npm:^1.46.1"
prettier: "npm:^2.3.1"
prompts: "npm:^2.4.2"
rimraf: "npm:^3.0.2"
Expand All @@ -3666,7 +3666,7 @@ __metadata:
"@babel/preset-typescript": "npm:^7.21.4"
"@changesets/cli": "npm:^2.27.1"
"@jest/types": "npm:^27.0.6"
"@playwright/test": "npm:^1.39.0"
"@playwright/test": "npm:^1.46.1"
"@storybook/eslint-config-storybook": "npm:^3.1.2"
"@swc/core": "npm:^1.4.6"
"@testing-library/dom": "npm:^8.1.0"
Expand All @@ -3683,12 +3683,13 @@ __metadata:
cypress: "npm:^13.6.1"
eslint: "npm:^7.32.0"
express: "npm:^4.18.2"
express-basic-auth: "npm:^1.2.1"
husky: "npm:>=6"
jest: "npm:^27.0.6"
jest-environment-jsdom: "npm:^27.0.6"
lint-staged: "npm:>=10"
node-fetch: "npm:2"
playwright: "npm:^1.32.2"
playwright: "npm:^1.46.1"
prettier: "npm:^2.3.1"
prompts: "npm:^2.4.2"
rimraf: "npm:^3.0.2"
Expand Down Expand Up @@ -4805,14 +4806,14 @@ __metadata:
languageName: node
linkType: hard

"@playwright/test@npm:^1.39.0":
version: 1.39.0
resolution: "@playwright/test@npm:1.39.0"
"@playwright/test@npm:^1.46.1":
version: 1.46.1
resolution: "@playwright/test@npm:1.46.1"
dependencies:
playwright: "npm:1.39.0"
playwright: "npm:1.46.1"
bin:
playwright: cli.js
checksum: d808ca36f0a411ae09eece19fc93fcbd048541253c6c9e341fc9488613395bb94ebf65ad64e920d6be0fb20e887cf317c532a45d2c30e1804d6842e55c1fe6e9
checksum: b2d33f33bedfa5a5c72cfc5ee212dfbf531d9c46320b0af901e71ab61b96845e43cc636181b33b3faae27f2f87ce2d44017ac65235bf9c95209f476477b16f93
languageName: node
linkType: hard

Expand Down Expand Up @@ -7958,6 +7959,15 @@ __metadata:
languageName: node
linkType: hard

"basic-auth@npm:^2.0.1":
version: 2.0.1
resolution: "basic-auth@npm:2.0.1"
dependencies:
safe-buffer: "npm:5.1.2"
checksum: 05f56db3a0fc31c89c86b605231e32ee143fb6ae38dc60616bc0970ae6a0f034172def99e69d3aed0e2c9e7cac84e2d63bc51a0b5ff6ab5fc8808cc8b29923c1
languageName: node
linkType: hard

"bcrypt-pbkdf@npm:^1.0.0":
version: 1.0.2
resolution: "bcrypt-pbkdf@npm:1.0.2"
Expand Down Expand Up @@ -10913,6 +10923,15 @@ __metadata:
languageName: node
linkType: hard

"express-basic-auth@npm:^1.2.1":
version: 1.2.1
resolution: "express-basic-auth@npm:1.2.1"
dependencies:
basic-auth: "npm:^2.0.1"
checksum: 01a14cff7a9d1d243d502b0aef287b2e4199e1c3cabd4a2ab3166ad6b122bc77fdeefcc743f57948b2ab59c4a2bcbe8761f3877a0e28959fa53f415667e348f6
languageName: node
linkType: hard

"express@npm:^4.17.3, express@npm:^4.18.2":
version: 4.18.2
resolution: "express@npm:4.18.2"
Expand Down Expand Up @@ -15830,36 +15849,27 @@ __metadata:
languageName: node
linkType: hard

"playwright-core@npm:1.39.0":
version: 1.39.0
resolution: "playwright-core@npm:1.39.0"
bin:
playwright-core: cli.js
checksum: dbd719ae77ae84a43f831beb89514ca5cca62840a2f0cce445645002ac045c256c19b5f4f3cf9a7aa205428a1571e9e8d946ff1937cc316033ea58090c549a76
languageName: node
linkType: hard

"playwright-core@npm:^1.32.2":
version: 1.40.1
resolution: "playwright-core@npm:1.40.1"
"playwright-core@npm:1.46.1, playwright-core@npm:^1.46.1":
version: 1.46.1
resolution: "playwright-core@npm:1.46.1"
bin:
playwright-core: cli.js
checksum: 56c283012974982313a6ae583b975ee4af76d52059fb9a25d9cc616a11224685ec64682b391910c795d2b12d2ab5c7eec31124722c75c0b1703a76ac9b6fd1c2
checksum: 98e48e271caccaa6c54b3c591cbddbef36a679eef011b38e2af11fbaba0aab1f997b45f9207c4099468a0c79047a1e879bbd9e81bd880ae24501a0ee3c7a33c7
languageName: node
linkType: hard

"playwright@npm:1.39.0, playwright@npm:^1.32.2":
version: 1.39.0
resolution: "playwright@npm:1.39.0"
"playwright@npm:1.46.1, playwright@npm:^1.46.1":
version: 1.46.1
resolution: "playwright@npm:1.46.1"
dependencies:
fsevents: "npm:2.3.2"
playwright-core: "npm:1.39.0"
playwright-core: "npm:1.46.1"
dependenciesMeta:
fsevents:
optional: true
bin:
playwright: cli.js
checksum: b55adb3453a9c2a02fe61dbcbd5fcb0cbae1038ea6115158c7933d203ae5b62a13cb294905d6661836751a5825bc2cfdc71b67988082ec47ac6930ca744af724
checksum: 2a328a2073313136192d74b48b981d9aeb1d4cc54926ed235f638c875f9de59c41370bb20bb2d8cf30126c52c6e25cc02db21ffafeb487c92c84c52c84846912
languageName: node
linkType: hard

Expand Down

0 comments on commit e629f2b

Please sign in to comment.