Skip to content

Commit

Permalink
feat(playwright): add a sample of playwright generation report
Browse files Browse the repository at this point in the history
titiBeOne committed Dec 3, 2024

Verified

This commit was signed with the committer’s verified signature.
snyk-bot Snyk bot
1 parent 5200e44 commit 444f8a9
Showing 17 changed files with 5,107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
"scripts": {
"start": "node src/cli.js --srcLighthouse=./example/lighthouse --srcEcoIndex=./example/ecoindex --reports=html --outputPath=./example/report_final",
"lint": "eslint",
"test": "jest --coverage",
"test": "jest --coverage src/",
"prepare": "husky install"
},
"license": "MIT",
6 changes: 6 additions & 0 deletions playwright-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/reports/
5 changes: 5 additions & 0 deletions playwright-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
To use this demo :
- npm install
- npm run test or with vscode run the test explorer (you can add the Playwright Test for VSCode to help you write your own test)
- the test in the Tests folder welcomeAxaPage.spec.ts will be run wait a couple of minutes.
- In the [reports folder](reports) you will see [the report file aggregate](reports/green-it/report.html) with all the lighthouse and ecoindex analyzes.
38 changes: 38 additions & 0 deletions playwright-demo/Tests/welcomeAxaPage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { test, expect } from '@playwright/test';
import { ExtensionWrapper } from "../extensions/extensionWrapper.js";

const extensions = new ExtensionWrapper();


test('test welcome page', async ({ page }) => {
await page.goto('https://www.axa.fr/');
await page.getByRole('button', { name: 'Accepter et fermer' }).click();
await extensions.analyse({page, stepName: "1_Welcome_page_AXA", selectorToWaitBeforeAnalyse:'.o-herobanner__content' });
await page.waitForTimeout(1000);
await page.getByRole('button', { name: 'Véhicules' }).click();
await page.getByRole('link', { name: 'Assurance auto' }).click();

await expect(page.locator('h1')).toContainText('Assurance auto');

await page.getByText('Estimation express').click({
button: 'right'
});

await extensions.analyse({page, stepName: "2_Auto_page_AXA", selectorToWaitBeforeAnalyse:'.universe-auto' });

});



test('test health page', async ({ page }) => {
await page.goto('https://www.axa.fr/complementaire-sante.html');
await page.getByRole('button', { name: 'Accepter et fermer' }).click();
await extensions.analyse({page, stepName: "3_health_page_AXA", selectorToWaitBeforeAnalyse:'.universe-health' });
});

test.afterAll(async ({}, testinfo) => {
if (testinfo.status === 'passed')
{
await extensions.generateFinalReports();
}
});
14 changes: 14 additions & 0 deletions playwright-demo/extensions/aggregator/aggregator-args-builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import fs from "fs";
import { AGGREGATOR_OPTIONS } from './aggregator-config.js';

const { reports, verbose, srcLighthouse, srcEcoIndex, outputPath } = AGGREGATOR_OPTIONS;

export const buildAggregatorArgs = () => ({
reports,
verbose,
srcLighthouse,
srcEcoIndex,
outputPath,
});

export const shouldRunAggregator = () => fs.existsSync(srcLighthouse) && fs.existsSync(srcEcoIndex);
7 changes: 7 additions & 0 deletions playwright-demo/extensions/aggregator/aggregator-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const AGGREGATOR_OPTIONS = {
reports: 'html',
verbose: true,
srcLighthouse: './reports/lighthouse',
srcEcoIndex: './reports/eco-index',
outputPath: './reports/green-it',
};
8 changes: 8 additions & 0 deletions playwright-demo/extensions/aggregator/aggregatorExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import aggregateGreenItReports from '@cnumr/lighthouse-eco-index-aggregator/src/main.js';
import { buildAggregatorArgs } from "./aggregator-args-builder.js";

export class AggregatorExtension {
async generateFinalReports() {
await aggregateGreenItReports(buildAggregatorArgs());
}
}
12 changes: 12 additions & 0 deletions playwright-demo/extensions/ecoIndex/ecoIndexConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable no-unused-vars */
export const ECOINDEX_OPTIONS = {
ecoIndex: 50,
grade: 'B',
visits: 2000,
checkThresholds: false,
beforeScript: (globals) => {
},
afterScript: (globals) => {},
output: ['json'],
outputPathDir: './reports/eco-index',
};
23 changes: 23 additions & 0 deletions playwright-demo/extensions/ecoIndex/ecoIndexExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { AnalyseConfiguration, PwExtension } from "../extensionWrapper.js";
import check from "@cnumr/eco-index-audit";
import { ECOINDEX_OPTIONS } from "./ecoIndexConfig.js";


export class EcoIndexExtension implements PwExtension {
async analyse(config: AnalyseConfiguration) {
const page = config.page
var cookies = await page.context().cookies();
await check(
{
outputFileName: config.stepName,
url: page.url(),
cookies,
remote_debugging_address : "127.0.0.1",
remote_debugging_port: 9222,
waitForSelector: config.selectorToWaitBeforeAnalyse,
...ECOINDEX_OPTIONS
},
true
);
}
}
36 changes: 36 additions & 0 deletions playwright-demo/extensions/extensionWrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Page } from "playwright-core";
import { LighthouseExtension } from "./lighthouse/lighthouseExtension.js";
import { EcoIndexExtension } from "./ecoIndex/ecoIndexExtension.js";
import { AggregatorExtension } from "./aggregator/aggregatorExtension.js";

export type AnalyseConfiguration = {
stepName: string;
selectorToWaitBeforeAnalyse?:string;
page: Page;
};


export interface PwExtension {
analyse(config: AnalyseConfiguration): Promise<void>;
}

export class ExtensionWrapper {
extensions: PwExtension[] = [];

constructor(extensions?: PwExtension[]) {
this.extensions = extensions ?? getExtensions();
}

public analyse = async (config: AnalyseConfiguration) =>
await Promise.all(this.extensions.map(async (o) => await o.analyse(config)));

public generateFinalReports = () =>{
console.log("aggrege");
new AggregatorExtension().generateFinalReports();
}
}

const getExtensions = (): PwExtension[] => {
const lh = [new EcoIndexExtension(), new LighthouseExtension()];
return [...lh];
};
71 changes: 71 additions & 0 deletions playwright-demo/extensions/lighthouse/lighthouseConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* eslint-disable no-undef */

import { Config, Flags } from "lighthouse";

export const LIGHTHOUSE_THRESHOLDS: Record<string, number> = {
performance: 80,
accessibility: 80,
'best-practices':80
};

export const LIGHTHOUSE_OPTIONS: Flags = {
formFactor: 'desktop',
screenEmulation: {
mobile: false,
disabled: false,
width: 1920,
height: 1080,
deviceScaleFactor: 1,
},
throttling: {
rttMs: 40,
throughputKbps: 11024,
cpuSlowdownMultiplier: 1,
requestLatencyMs: 0,
downloadThroughputKbps: 0,
uploadThroughputKbps: 0,
},
output: 'html',
};

export const LIGHTHOUSE_CONFIG: Config = {
extends: 'lighthouse:default',
settings: {
pauseAfterLoadMs: 1000,
networkQuietThresholdMs: 1000
}
};

export interface LighthousePaths {
reportsPath: string;
lighthouseReportsPath: string;
}

export const LIGHTHOUSE_PATHS: LighthousePaths = {
reportsPath: './reports/',
lighthouseReportsPath: './reports/lighthouse/',
};

export interface LighthouseReportOptions {
minifyHtmlReports: boolean;
htmlMinifierOptions: Record<string, boolean>;
fileName : string;
}

export const LIGHTHOUSE_REPORT_OPTIONS: LighthouseReportOptions = {
minifyHtmlReports: true,
fileName:'',
htmlMinifierOptions: {
includeAutoGeneratedTags: true,
removeAttributeQuotes: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortClassName: true,
useShortDoctype: true,
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
},
};
36 changes: 36 additions & 0 deletions playwright-demo/extensions/lighthouse/lighthouseExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { LIGHTHOUSE_CONFIG, LIGHTHOUSE_OPTIONS, LIGHTHOUSE_PATHS, LIGHTHOUSE_REPORT_OPTIONS, LIGHTHOUSE_THRESHOLDS, LighthouseReportOptions} from "./lighthouseConfig.js";
import lighthouse from 'lighthouse';
import { launch } from 'puppeteer';
import {
AnalyseConfiguration,
PwExtension,
} from "../extensionWrapper.js";
import { lighthouseReport } from "./lighthouseReport.js";


export class LighthouseExtension implements PwExtension {
async analyse(config: AnalyseConfiguration) {
const page = config.page;
const puppeteerBrowser = await launch({headless: 'new'});

const puppeteerPage = await puppeteerBrowser.newPage();
const cookies = await page.context().cookies();
await puppeteerPage.setCookie(...cookies);
const url = page.url();

await puppeteerPage.goto(url);

if (config.selectorToWaitBeforeAnalyse)
{
await puppeteerPage.waitForSelector(config.selectorToWaitBeforeAnalyse);
}

const lighthouseAudit = await lighthouse(url, LIGHTHOUSE_OPTIONS, LIGHTHOUSE_CONFIG, puppeteerPage);
const reportOption = LIGHTHOUSE_REPORT_OPTIONS;
reportOption.fileName = config.stepName;


lighthouseReport(reportOption, LIGHTHOUSE_PATHS, lighthouseAudit);
}
}

45 changes: 45 additions & 0 deletions playwright-demo/extensions/lighthouse/lighthouseReport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable import/no-extraneous-dependencies */
import fs from "fs";
import { minify } from "html-minifier";
import { LighthousePaths, LighthouseReportOptions } from './lighthouseConfig.js';

const createLighthouseReportsDirectories = (paths: LighthousePaths) => {
if (!fs.existsSync(paths.reportsPath)) {
fs.mkdirSync(paths.reportsPath);
}

if (!fs.existsSync(paths.lighthouseReportsPath)) {
fs.mkdirSync(paths.lighthouseReportsPath, {recursive : true});
}
};

const cleanLighthouseReportsFiles = (options: LighthouseReportOptions, paths : LighthousePaths) => {
if (fs.existsSync(`${paths.lighthouseReportsPath}${options.fileName}.json`)) {
fs.unlinkSync(`${paths.lighthouseReportsPath}${options.fileName}.json`);
}
if (fs.existsSync(`${paths.lighthouseReportsPath}${options.fileName}.html`)) {
fs.unlinkSync(`${paths.lighthouseReportsPath}${options.fileName}.html`);
}
};

const writeLighthouseReportJsonFile = (options: LighthouseReportOptions, paths : LighthousePaths, lighthouseAudit) => {
const reportContent = JSON.stringify(lighthouseAudit.lhr);
fs.writeFileSync(`${paths.lighthouseReportsPath}${options.fileName}.json`, reportContent, { flag: 'a+' });
};

const writeLighthouseReportHtmlFile = (options : LighthouseReportOptions, paths : LighthousePaths, lighthouseAudit) => {
let reportContent = lighthouseAudit.report;
if (options && options.minifyHtmlReports) {
reportContent = minify(reportContent, options.htmlMinifierOptions);
}
fs.writeFileSync(`${paths.lighthouseReportsPath}${options.fileName}.html`, reportContent, {
flag: 'a+',
});
};
export const lighthouseReport = (options : LighthouseReportOptions, paths : LighthousePaths, lighthouseAudit) => {
createLighthouseReportsDirectories(paths);
cleanLighthouseReportsFiles(options, paths);
writeLighthouseReportJsonFile(options, paths, lighthouseAudit);
writeLighthouseReportHtmlFile(options, paths, lighthouseAudit);
return lighthouseReport;
};
4,705 changes: 4,705 additions & 0 deletions playwright-demo/package-lock.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions playwright-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "lighthouse-eco-index-aggregatore-playwright-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "playwright test"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@cnumr/eco-index-audit": "4.7.2",
"@cnumr/lighthouse-eco-index-aggregator": "1.1.0",
"@playwright/test": "^1.40.0",
"@types/node": "^20.9.3",
"lighthouse": "^11.3.0"
},
"type": "module"
}
74 changes: 74 additions & 0 deletions playwright-demo/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { defineConfig, devices } from '@playwright/test';

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: '',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [['html', { outputFolder: 'reports/playwright', open: 'never' }]],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://127.0.0.1:3000',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on',
},

/* Configure projects for major browsers */
projects: [
{
timeout:60*5*1000,
name: "chromium",
use: {
headless: true,
...devices["Desktop Chrome"],
serviceWorkers:'allow',
launchOptions: {
args: ["--remote-debugging-port=9222"],
},
},
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
});
6 changes: 6 additions & 0 deletions playwright-demo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"module": "NodeNext",
"resolveJsonModule": true
}
}

0 comments on commit 444f8a9

Please sign in to comment.