Skip to content

Commit

Permalink
chore: update specs and readme - removed port parameter from fn calls
Browse files Browse the repository at this point in the history
  • Loading branch information
asambstack committed Feb 20, 2023
1 parent 772bc14 commit 5e2fd2e
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 99 deletions.
135 changes: 60 additions & 75 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,20 @@ $ npm install --save-dev playwright-lighthouse playwright lighthouse

After completion of the Installation, you can use `playwright-lighthouse` in your code to audit the current page.

In your test code you need to import `playwright-lighthouse` and assign a `port` for the lighthouse scan. You can choose any non-allocated port.
In your test code you need to import `playwright-lighthouse` and pass the `page` for the lighthouse scan. The tests will be executed in the very same `page` passed to `playAudit`.

```js
const { playAudit } = require('playwright-lighthouse');
const playwright = require('playwright');

describe('audit example', () => {
it('open browser', async () => {
const browser = await playwright['chromium'].launch({
args: ['--remote-debugging-port=9222'],
});
const browser = await playwright['chromium'].launch();
const page = await browser.newPage();
await page.goto('https://angular.io/');
await page.goto('https://www.github.com');

await playAudit({
page: page,
port: 9222,
});

await browser.close();
Expand All @@ -62,11 +59,9 @@ const playwright = require('playwright');

describe('audit example', () => {
it('open browser', async () => {
const browser = await playwright['chromium'].launch({
args: ['--remote-debugging-port=9222'],
});
const browser = await playwright['chromium'].launch();
const page = await browser.newPage();
await page.goto('https://angular.io/');
await page.goto('https://www.github.com');

await playAudit({
page: page,
Expand All @@ -77,7 +72,6 @@ describe('audit example', () => {
seo: 50,
pwa: 50,
},
port: 9222,
});

await browser.close();
Expand All @@ -94,8 +88,7 @@ await playAudit({
page: page,
thresholds: {
performance: 85,
},
port: 9222,
}
});
```

Expand Down Expand Up @@ -150,14 +143,48 @@ const opts = {

await playAudit({
page,
port: 9222,
opts,
});
```

## Running lighthouse on authenticated routes

Playwright by default does not share any context (eg auth state) between pages. Lighthouse will open a new page and thus any previous authentication steps are void. To persist auth state you need to use a persistent context:
Since `playAudit` utilises the `page` object of playwright for its tests, we can utilise the same authenticated `page` for lighthouse tests. Consequently we can also perform lighthouse tests on device clouds such as Browserstack using the playwright connect method.

### Running lighthouse with device clouds and authenticated pages
```js
const { playAudit } = require('playwright-lighthouse');
const playwright = require('playwright');
import { test, expect } from '@playwright/test';

describe('audit example', () => {
it('open browser', async () => {
const browser = await playwright['chromium'].connect(`wss://cdp.browserstack.com/...`);
const page = await browser.newPage({
ignoreHTTPSErrors: true,
httpCredentials: { username: "admin", password: "admin" }
});
await page.goto('https://the-internet.herokuapp.com/basic_auth');

await playAudit({
page: page,
thresholds: {
performance: 50,
accessibility: 50,
'best-practices': 50,
seo: 50,
pwa: 50,
},
});

await browser.close();
});
});
```

### Running lighthouse with persistent context

Playwright by default does not share any context (eg auth state) between pages. To persist auth state you need to use a persistent context:

```js
const os = require('os');
Expand All @@ -167,9 +194,7 @@ const { chromium } = require('playwright');
describe('audit example', () => {
it('open browser', async () => {
const userDataDir = path.join(os.tmpdir(), 'pw', String(Math.random()));
const context = await chromium.launchPersistentContext(userDataDir, {
args: ['--remote-debugging-port=9222'],
});
const context = await chromium.launchPersistentContext(userDataDir);
const page = await context.newPage();
await page.goto('http://localhost:3000/');

Expand All @@ -178,7 +203,6 @@ describe('audit example', () => {
// When lighthouse opens a new page the storage will be persisted meaning the new page will have the same user session
await playAudit({
page: page,
port: 9222,
});

await context.close();
Expand Down Expand Up @@ -210,49 +234,35 @@ import { chromium } from 'playwright';
import type { Browser } from 'playwright';
import { playAudit } from 'playwright-lighthouse';
import { test as base } from '@playwright/test';
import getPort from 'get-port';

export const lighthouseTest = base.extend<
{},
{ port: number; browser: Browser }
{ browser: Browser }
>({
port: [
async ({}, use) => {
// Assign a unique port for each playwright worker to support parallel tests
const port = await getPort();
await use(port);
},
{ scope: 'worker' },
],

browser: [
async ({ port }, use) => {
const browser = await chromium.launch({
args: [`--remote-debugging-port=${port}`],
});
async ({ }, use) => {
const browser = await chromium.launch();
await use(browser);
},
{ scope: 'worker' },
],
});

lighthouseTest.describe('Lighthouse', () => {
lighthouseTest('should pass lighthouse tests', async ({ page, port }) => {
lighthouseTest('should pass lighthouse tests', async ({ page }) => {
await page.goto('http://example.com');
await page.waitForSelector('#some-element');
await playAudit({
page,
port,
});
});
});
```

### Running lighthouse on authenticated routes with the test runner
### Running lighthouse on authenticated routes with the test runner and persistent context

```ts
import os from 'os';
import getPort from 'get-port';
import { BrowserContext, chromium, Page } from 'playwright';
import { test as base } from '@playwright/test';
import { playAudit } from 'playwright-lighthouse';
Expand All @@ -262,29 +272,15 @@ export const lighthouseTest = base.extend<
authenticatedPage: Page;
context: BrowserContext;
},
{
port: number;
}
{}
>({
// We need to assign a unique port for each lighthouse test to allow
// lighthouse tests to run in parallel
port: [
async ({}, use) => {
const port = await getPort();
await use(port);
},
{ scope: 'worker' },
],

// As lighthouse opens a new page, and as playwright does not by default allow
// shared contexts, we need to explicitly create a persistent context to
// allow lighthouse to run behind authenticated routes.
context: [
async ({ port }, use) => {
async ({}, use) => {
const userDataDir = path.join(os.tmpdir(), 'pw', String(Math.random()));
const context = await chromium.launchPersistentContext(userDataDir, {
args: [`--remote-debugging-port=${port}`],
});
const context = await chromium.launchPersistentContext(userDataDir);
await use(context);
await context.close();
},
Expand Down Expand Up @@ -320,11 +316,10 @@ export const lighthouseTest = base.extend<
lighthouseTest.describe('Authenticated route', () => {
lighthouseTest(
'should pass lighthouse tests',
async ({ port, authenticatedPage: page }) => {
async ({ authenticatedPage: page }) => {
await page.goto('http://localhost:3000/my-profile');
await playAudit({
page,
port,
});
}
);
Expand All @@ -341,28 +336,17 @@ import os from 'os';
import path from 'path';
import { chromium, test as base } from '@playwright/test';
import type { BrowserContext } from '@playwright/test';
import getPort from 'get-port'; // version ^5.1.1 due to issues with imports in playwright 1.20.1
import { playAudit } from 'playwright-lighthouse';

export const lighthouseTest = base.extend<
{ context: BrowserContext },
{ port: number }
{ context: BrowserContext }
>({
port: [
async ({}, use) => {
// Assign a unique port for each playwright worker to support parallel tests
const port = await getPort();
await use(port);
},
{ scope: 'worker' },
],

context: [
async ({ port, launchOptions }, use) => {
async ({ launchOptions }, use) => {
const userDataDir = path.join(os.tmpdir(), 'pw', String(Math.random()));
const context = await chromium.launchPersistentContext(userDataDir, {
args: [
...(launchOptions.args || []),
`--remote-debugging-port=${port}`,
],
});

Expand All @@ -377,12 +361,13 @@ export const lighthouseTest = base.extend<
});

lighthouseTest.describe('Authenticated route after globalSetup', () => {
lighthouseTest('should pass lighthouse tests', async ({ port }) => {
// it's possible to pass url directly instead of a page
// to avoid opening a page an extra time and keeping it opened
lighthouseTest('should pass lighthouse tests', async ({ context }) => {
// We need to pass in page object to playAudt
// We can create a new page from the context and pass it to playAudit specifically for lighthouse tests
const page = await context.newPage();
await playAudit({
url: 'http://localhost:3000/my-profile',
port,
page: page
});
});
});
Expand Down
6 changes: 2 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Page } from 'playwright-core';

export interface playwrightLighthouseConfig {
page?: Page;
page: Page;
url?: string;
port: number;
thresholds?: Record<string, number>;
opts?: Record<string, any>;
config?: Record<string, any>;
Expand Down Expand Up @@ -37,8 +36,7 @@ export interface playwrightLighthouseConfig {
* 'best-practices': 50,
* seo: 50,
* pwa: 50,
* },
* port: 9222
* }
* });
* });
*
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
"ua-parser-js": "^1.0.2"
"ua-parser-js": "^1.0.2",
"lighthouse": "^9.5.0"
},
"devDependencies": {
"@types/mocha": "9.1.0",
Expand All @@ -34,7 +35,6 @@
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"lighthouse": "^9.5.0",
"mocha": "9.2.2",
"playwright-core": "1.19.2",
"prettier": "^2.6.1"
Expand Down
7 changes: 3 additions & 4 deletions src/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ const {
checkBrowserIsValid,
defaultReports,
defaultThresholds,
NO_PAGE_ERROR,
} = require('./util');

const playAudit = async function (auditConfig = {}) {
if (!auditConfig.page && !auditConfig.url) {
throw new Error(
`page or url is not set in playwright lighthouse config. Refer to https://github.com/abhinaba-ghosh/playwright-lighthouse to have more information and set it by yourself :). `
);
if (!auditConfig.page) {
throw new Error(NO_PAGE_ERROR);
}

const log = auditConfig.disableLogs ? () => {} : console.log;
Expand Down
2 changes: 2 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const events = require('events');
const ReportGenerator = require('lighthouse/report/generator/report-generator');
const fs = require('fs/promises');

const NO_PAGE_ERROR = `page not set in playwright lighthouse config. Refer to https://github.com/abhinaba-ghosh/playwright-lighthouse to have more information and set it by yourself :). `;
const VALID_BROWSERS = ['Chrome', 'Chromium', 'Canary'];

const defaultThresholds = {
Expand Down Expand Up @@ -80,6 +81,7 @@ const getReport = async (lhr, dir, name, type) => {
module.exports = {
defaultReports,
defaultThresholds,
NO_PAGE_ERROR,
patchPageObject,
checkBrowserIsValid,
compare,
Expand Down
14 changes: 5 additions & 9 deletions test/audit.spec.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
const { playAudit } = require('../index');
const playwright = require('playwright-core');
const chai = require('chai');
const expect = chai.expect;
const { expect } = require('chai');

describe('audit example', () => {
let browser, page;

before(async () => {
browser = await playwright['chromium'].launch({
args: ['--remote-debugging-port=9223'],
});
browser = await playwright['chromium'].launch();
page = await browser.newPage();
await page.goto('https://angular.io/');
await page.goto('https://www.google.com/');
});

after(async () => {
Expand All @@ -28,21 +25,20 @@ describe('audit example', () => {
seo: 50,
pwa: 50,
},
port: 9223,
});
});

it('no logs, no page, no errors', async () => {
const result = await playAudit({
url: 'https://angular.io/',
url: 'https://www.google.com/',
page: page,
thresholds: {
performance: 100,
accessibility: 100,
'best-practices': 100,
seo: 100,
pwa: 100,
},
port: 9223,
ignoreError: true,
disableLogs: true,
});
Expand Down
Loading

0 comments on commit 5e2fd2e

Please sign in to comment.