Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"express": "^4.17.1",
"html-minifier": "^4.0.0",
"lighthouse": "^9.6.3",
"puppeteer": "^18.0.0"
"puppeteer": "^24.8.2"
},
"engines": {
"node": ">=18.14.0"
Expand Down
2 changes: 2 additions & 0 deletions src/e2e/fail-threshold-onpostbuild.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ describe('lighthousePlugin with failed threshold run (onPostBuild)', () => {

it('should output expected log content', async () => {
const logs = [
'Persisting Lighthouse cache...',
'Lighthouse cache persisted',
'Generating Lighthouse report. This may take a minute…',
'Running Lighthouse on example/',
'Serving and scanning site from directory example',
Expand Down
4 changes: 4 additions & 0 deletions src/e2e/fixture/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ const mockUtils = {
status: {
show: jest.fn(),
},
cache: {
save: jest.fn(),
restore: jest.fn(),
},
};

export default mockUtils;
6 changes: 3 additions & 3 deletions src/e2e/mocks/puppeteer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const puppeteer = () =>
jest.unstable_mockModule('puppeteer', () => {
return {
default: {
createBrowserFetcher: () => ({
localRevisions: () => Promise.resolve(['123']),
revisionInfo: () => Promise.resolve({ executablePath: 'path' }),
launch: () => ({
process: () => ({ spawnfile: 'path' }),
close: () => Promise.resolve(),
}),
},
};
Expand Down
2 changes: 2 additions & 0 deletions src/e2e/not-found-onpostbuild.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ describe('lighthousePlugin with single not-found run (onPostBuild)', () => {

it('should output expected log content', async () => {
const logs = [
'Persisting Lighthouse cache...',
'Lighthouse cache persisted',
'Generating Lighthouse report. This may take a minute…',
'Running Lighthouse on example/this-page-does-not-exist',
'Serving and scanning site from directory example',
Expand Down
2 changes: 2 additions & 0 deletions src/e2e/success-onpostbuild.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ describe('lighthousePlugin with single report per run (onPostBuild)', () => {

it('should output expected log content', async () => {
const logs = [
'Persisting Lighthouse cache...',
'Lighthouse cache persisted',
'Generating Lighthouse report. This may take a minute…',
'Running Lighthouse on example/',
'Serving and scanning site from directory example',
Expand Down
22 changes: 22 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
import { join } from 'path';
import { homedir } from 'os';

import * as dotenv from 'dotenv';

import runEvent from './lib/run-event/index.js';
import getUtils from './lib/get-utils/index.js';

dotenv.config();

const puppeteerCacheDir = join(homedir(), '.cache', 'puppeteer');

const onPreBuild = async ({ utils } = {}) => {
console.log('Restoring Lighthouse cache...');
// Puppeteer relies on a global cache since v19.x, which otherwise would not be persisted in Netlify builds
await utils?.cache.restore(puppeteerCacheDir);
console.log('Lighthouse cache restored');
};

const persistCache = async ({ utils } = {}) => {
console.log('Persisting Lighthouse cache...');
await utils?.cache.save(puppeteerCacheDir);
console.log('Lighthouse cache persisted');
};

export default function lighthousePlugin(inputs) {
// Run onSuccess by default, unless inputs specify we should fail_deploy_on_score_thresholds
const defaultEvent =
Expand All @@ -14,6 +32,8 @@ export default function lighthousePlugin(inputs) {

if (defaultEvent === 'onSuccess') {
return {
onPreBuild,
onPostBuild: ({ utils }) => persistCache({ utils }),
onSuccess: async ({ constants, utils, inputs } = {}) => {
// Mock the required `utils` functions if running locally
const { failPlugin, show } = getUtils({ utils });
Expand All @@ -29,10 +49,12 @@ export default function lighthousePlugin(inputs) {
};
} else {
return {
onPreBuild,
onPostBuild: async ({ constants, utils, inputs } = {}) => {
// Mock the required `utils` functions if running locally
const { failBuild, show } = getUtils({ utils });

await persistCache({ utils });
await runEvent({
event: 'onPostBuild',
constants,
Expand Down
11 changes: 7 additions & 4 deletions src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import lighthousePlugin from './index.js';

describe('lighthousePlugin plugin events', () => {
describe('onPostBuild', () => {
it('should return only the expected event function', async () => {
describe('when fail_deploy_on_score_thresholds is true', () => {
it('should return onPreBuild and onPostBuild events', async () => {
const events = lighthousePlugin({
fail_deploy_on_score_thresholds: 'true',
});
expect(events).toEqual({
onPreBuild: expect.any(Function),
onPostBuild: expect.any(Function),
});
});
});

describe('onSuccess', () => {
it('should return only the expected event function', async () => {
describe('default behavior', () => {
it('should return onPreBuild, onPostBuild and onSuccess events', async () => {
const events = lighthousePlugin();
expect(events).toEqual({
onPreBuild: expect.any(Function),
onPostBuild: expect.any(Function),
onSuccess: expect.any(Function),
});
});
Expand Down
14 changes: 7 additions & 7 deletions src/run-lighthouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import log from 'lighthouse-logger';
import chromeLauncher from 'chrome-launcher';

export const getBrowserPath = async () => {
const browserFetcher = puppeteer.createBrowserFetcher();
const revisions = await browserFetcher.localRevisions();
if (revisions.length <= 0) {
throw new Error('Could not find local browser');
}
const info = await browserFetcher.revisionInfo(revisions[0]);
return info.executablePath;
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage'],
});
const path = browser.process().spawnfile;
await browser.close();
return path;
};

export const runLighthouse = async (browserPath, url, settings) => {
Expand Down
Loading
Loading