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
  • Loading branch information
titiBeOne committed Dec 3, 2024
1 parent 5200e44 commit 444f8a9
Show file tree
Hide file tree
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
Expand Up @@ -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",
Expand Down
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;
};
Loading

0 comments on commit 444f8a9

Please sign in to comment.