From 4fd37f679c9d500c36b2c565e7d42f0a256e08a3 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:19:45 -0500 Subject: [PATCH 01/17] Add lighthouse formatting scripts --- .gitignore | 1 + scripts/lighthouse/index.js | 51 +++++++++++++++++++++++ scripts/lighthouse/index.test.js | 70 ++++++++++++++++++++++++++++++++ vitest.config.js | 4 +- 4 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 scripts/lighthouse/index.js create mode 100644 scripts/lighthouse/index.test.js diff --git a/.gitignore b/.gitignore index c4d8ebd7..a6fbfe3b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ playwright-report/index.html yarn-error.log lighthouse-report .vscode/settings.json +/test-results \ No newline at end of file diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js new file mode 100644 index 00000000..5cb52d9e --- /dev/null +++ b/scripts/lighthouse/index.js @@ -0,0 +1,51 @@ +/* eslint-disable jsdoc/require-param */ +"use strict"; + +const stoplight = (res) => (res >= 90 ? "🟢" : res >= 75 ? "🟠" : "🔴"); +const normalizeScore = (res) => Math.round(res * 100); +const formatScore = (res) => { + const normalizedScore = normalizeScore(res); + return `${stoplight(normalizedScore)} ${normalizedScore}`; +}; + +/** + * `core` is in scope from https://github.com/actions/github-script + */ +export const formatLighthouseResults = ({ core }) => { + // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest + const results = JSON.parse(process.env.LIGHTHOUSE_RESULT); + + // this will be the shape of https://github.com/treosh/lighthouse-ci-action#links + const links = JSON.parse(process.env.LIGHTHOUSE_LINKS); + + // start creating our markdown table + const header = [ + "Lighthouse Results", + "URL | Performance | Accessibility | Best Practices | SEO | Report", + "| - | - | - | - | - | - |" + ]; + + // map over each url result, formatting and linking to the output + const urlResults = results.map(({ url, summary }) => { + // make the tested link as a markdown link, without the long-generated host + const shortPreviewLink = `[${url.replace( + process.env.VERCEL_PREVIEW_URL, + "" + )}](${url})`; + + // make each formatted score from our lighthouse properties + const performanceScore = formatScore(summary.performance); + const accessibilityScore = formatScore(summary.accessibility); + const bestPracticesScore = formatScore(summary["best-practices"]); + const seoScore = formatScore(summary.seo); + + // create the markdown table row + return `${shortPreviewLink} | ${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore} | [🔗](${links[url]})`; + }); + + // join the header and the rows together + const finalResults = [...header, ...urlResults].join("\n"); + + // return our output to the github action + core.setOutput("comment", finalResults); +}; diff --git a/scripts/lighthouse/index.test.js b/scripts/lighthouse/index.test.js new file mode 100644 index 00000000..c44ad30e --- /dev/null +++ b/scripts/lighthouse/index.test.js @@ -0,0 +1,70 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { formatLighthouseResults } from "./index"; + +describe("formatLighthouseResults", () => { + const MOCK_VERCEL_PREVIEW_URL = "https://some.vercel.preview.url"; + + const MOCK_LIGHTHOUSE_RESULT = `[ + { + "url": "${MOCK_VERCEL_PREVIEW_URL}/en", + "isRepresentativeRun": true, + "summary": { "performance": 0.99, "accessibility": 0.98, "best-practices": 1, "seo": 0.96, "pwa": 0.71 } + }, + { + "url": "${MOCK_VERCEL_PREVIEW_URL}/en/download", + "isRepresentativeRun": true, + "summary": { "performance": 0.49, "accessibility": 0.75, "best-practices": 1, "seo": 0.90, "pwa": 0.71 } + } + ]`; + + const MOCK_LIGHTHOUSE_LINKS = `{ + "${MOCK_VERCEL_PREVIEW_URL}/en": "fake.url/to/result/1", + "${MOCK_VERCEL_PREVIEW_URL}/en/download" : "fake.url/to/result/2" + }`; + + let mockCore, originalEnv; + + beforeEach(() => { + mockCore = { setOutput: vi.fn() }; + originalEnv = process.env; + process.env = { + ...process.env, + LIGHTHOUSE_RESULT: MOCK_LIGHTHOUSE_RESULT, + LIGHTHOUSE_LINKS: MOCK_LIGHTHOUSE_LINKS, + VERCEL_PREVIEW_URL: MOCK_VERCEL_PREVIEW_URL + }; + }); + + afterEach(() => { + process.env = originalEnv; + }); + + it("formats preview urls correctly", () => { + formatLighthouseResults({ core: mockCore }); + + const expectations = [ + expect.stringContaining(`[/en](${MOCK_VERCEL_PREVIEW_URL}/en)`), + expect.stringContaining( + `[/en/download](${MOCK_VERCEL_PREVIEW_URL}/en/download)` + ) + ]; + + expectations.forEach((expectation) => { + expect(mockCore.setOutput).toBeCalledWith("comment", expectation); + }); + }); + + it("formats stoplight colors correctly", () => { + formatLighthouseResults({ core: mockCore }); + + const expectations = [ + expect.stringContaining("🟢 90"), + expect.stringContaining("🟠 75"), + expect.stringContaining("🔴 49") + ]; + + expectations.forEach((expectation) => { + expect(mockCore.setOutput).toBeCalledWith("comment", expectation); + }); + }); +}); diff --git a/vitest.config.js b/vitest.config.js index 4805fd60..b83c200a 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -7,9 +7,9 @@ export default defineConfig({ globals: true, environment: "jsdom", setupFiles: "./vitest-setup.js", - include: ["src/**/*.test.*"], + include: ["src/**/*.test.*", "scripts/**/*.test.*"], coverage: { - include: ["src/components/**/*.svelte"], + include: ["src/components/**/*.svelte", "scripts/**/*.js"], thresholds: { statements: 100, branches: 100, From 7aaa3b07fa03b3430096fce559268bf6acfc9493 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:20:15 -0500 Subject: [PATCH 02/17] Add lighthouse formatting script to CI pipeline --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 599f1861..b85da449 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,3 +88,27 @@ jobs: # Run Lighthouse Playwright tests - name: Run Playwright tests run: bun run test:lighthouse + - name: Format Lighthouse Score + # Transform the audit results into a single, friendlier output + id: format_lighthouse_score + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 + env: + # using env as input to our script + # see https://github.com/actions/github-script#use-env-as-input + LIGHTHOUSE_RESULT: ${{ steps.lighthouse_audit.outputs.manifest }} + LIGHTHOUSE_LINKS: ${{ steps.lighthouse_audit.outputs.links }} + VERCEL_PREVIEW_URL: ${{ steps.vercel_preview_url.outputs.url }} + with: + # Run as a separate file so we do not have to inline all of our formatting logic. + # See https://github.com/actions/github-script#run-a-separate-file for more info. + script: | + const { formatLighthouseResults } = await import('${{github.workspace}}/scripts/lighthouse/index.mjs') + await formatLighthouseResults({core}) + - name: Add Comment to PR + # Replace the previous message with our formatted lighthouse results + uses: thollander/actions-comment-pull-request@d61db783da9abefc3437960d0cce08552c7c004f # v2.4.2 + with: + # Reference the previously created comment + comment_tag: "lighthouse_audit" + message: | + ${{ steps.format_lighthouse_score.outputs.comment }} From c7366e7350ab335b53a332a8afeb4ac1f523a388 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:24:45 -0500 Subject: [PATCH 03/17] Remove custom link formatting from lighthouse reporting --- .github/workflows/ci.yml | 1 - scripts/lighthouse/index.js | 8 +------- scripts/lighthouse/index.test.js | 18 +----------------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b85da449..137fdf2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,6 @@ jobs: # see https://github.com/actions/github-script#use-env-as-input LIGHTHOUSE_RESULT: ${{ steps.lighthouse_audit.outputs.manifest }} LIGHTHOUSE_LINKS: ${{ steps.lighthouse_audit.outputs.links }} - VERCEL_PREVIEW_URL: ${{ steps.vercel_preview_url.outputs.url }} with: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 5cb52d9e..27c39d22 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -27,12 +27,6 @@ export const formatLighthouseResults = ({ core }) => { // map over each url result, formatting and linking to the output const urlResults = results.map(({ url, summary }) => { - // make the tested link as a markdown link, without the long-generated host - const shortPreviewLink = `[${url.replace( - process.env.VERCEL_PREVIEW_URL, - "" - )}](${url})`; - // make each formatted score from our lighthouse properties const performanceScore = formatScore(summary.performance); const accessibilityScore = formatScore(summary.accessibility); @@ -40,7 +34,7 @@ export const formatLighthouseResults = ({ core }) => { const seoScore = formatScore(summary.seo); // create the markdown table row - return `${shortPreviewLink} | ${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore} | [🔗](${links[url]})`; + return `${url} | ${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore} | [🔗](${links[url]})`; }); // join the header and the rows together diff --git a/scripts/lighthouse/index.test.js b/scripts/lighthouse/index.test.js index c44ad30e..386d6e48 100644 --- a/scripts/lighthouse/index.test.js +++ b/scripts/lighthouse/index.test.js @@ -30,8 +30,7 @@ describe("formatLighthouseResults", () => { process.env = { ...process.env, LIGHTHOUSE_RESULT: MOCK_LIGHTHOUSE_RESULT, - LIGHTHOUSE_LINKS: MOCK_LIGHTHOUSE_LINKS, - VERCEL_PREVIEW_URL: MOCK_VERCEL_PREVIEW_URL + LIGHTHOUSE_LINKS: MOCK_LIGHTHOUSE_LINKS }; }); @@ -39,21 +38,6 @@ describe("formatLighthouseResults", () => { process.env = originalEnv; }); - it("formats preview urls correctly", () => { - formatLighthouseResults({ core: mockCore }); - - const expectations = [ - expect.stringContaining(`[/en](${MOCK_VERCEL_PREVIEW_URL}/en)`), - expect.stringContaining( - `[/en/download](${MOCK_VERCEL_PREVIEW_URL}/en/download)` - ) - ]; - - expectations.forEach((expectation) => { - expect(mockCore.setOutput).toBeCalledWith("comment", expectation); - }); - }); - it("formats stoplight colors correctly", () => { formatLighthouseResults({ core: mockCore }); From 9bbef55ce4a4b156f5e9b5e1e8b993e4f5ba9648 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:28:26 -0500 Subject: [PATCH 04/17] Fix ids in CI file --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 137fdf2b..0afe4786 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,13 +90,13 @@ jobs: run: bun run test:lighthouse - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output - id: format_lighthouse_score + id: format-lighthouse-score uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input - LIGHTHOUSE_RESULT: ${{ steps.lighthouse_audit.outputs.manifest }} - LIGHTHOUSE_LINKS: ${{ steps.lighthouse_audit.outputs.links }} + LIGHTHOUSE_RESULT: ${{ steps.lighthouse-test.outputs.manifest }} + LIGHTHOUSE_LINKS: ${{ steps.lighthouse-test.outputs.links }} with: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. @@ -108,6 +108,6 @@ jobs: uses: thollander/actions-comment-pull-request@d61db783da9abefc3437960d0cce08552c7c004f # v2.4.2 with: # Reference the previously created comment - comment_tag: "lighthouse_audit" + comment_tag: "lighthouse-audit" message: | - ${{ steps.format_lighthouse_score.outputs.comment }} + ${{ steps.format-lighthouse-score.outputs.comment }} From ecd573989b1dff6ccf2c2e500660e238d236e865 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:29:19 -0500 Subject: [PATCH 05/17] Fix file name extension in CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0afe4786..bb706de1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,7 @@ jobs: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. script: | - const { formatLighthouseResults } = await import('${{github.workspace}}/scripts/lighthouse/index.mjs') + const { formatLighthouseResults } = await import('${{github.workspace}}/scripts/lighthouse/index.js') await formatLighthouseResults({core}) - name: Add Comment to PR # Replace the previous message with our formatted lighthouse results From a86cedafd30c446921d61db3ecf6f0001cf15b2b Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:49:47 -0500 Subject: [PATCH 06/17] Write and comment Vitest test coverage results --- .github/workflows/ci.yml | 8 ++++++++ vitest.config.js | 2 ++ 2 files changed, 10 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb706de1..c233dc44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,14 @@ jobs: # Finally we run svelte-check for some last minute svelte sanity - name: Run svelte-check run: bun run svelte-check + - name: Jest Coverage Comment + # This comments the current Jest Coverage Report containing JUnit XML reports + # and a Code Coverage Summary + uses: MishaKav/jest-coverage-comment@434e6d2d37116d23d812809b61d499639842fa3b # v1.0.26 + with: + title: "Unit Test Coverage Report" + junitxml-path: ./test-results.xml + junitxml-title: Unit Test Report test: # Runs on execution of build diff --git a/vitest.config.js b/vitest.config.js index b83c200a..953d7978 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -8,6 +8,8 @@ export default defineConfig({ environment: "jsdom", setupFiles: "./vitest-setup.js", include: ["src/**/*.test.*", "scripts/**/*.test.*"], + outputFile: "test-results.xml", + reporters: ["default", "junit"], coverage: { include: ["src/components/**/*.svelte", "scripts/**/*.js"], thresholds: { From f44f4eeab8638dbd0a0f16e56c8e5ff5effafbaa Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 16:50:18 -0500 Subject: [PATCH 07/17] Comment lighthouse results to help debugging in the pipeline --- .gitignore | 3 ++- scripts/lighthouse/index.js | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a6fbfe3b..9e1cb422 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ playwright-report/index.html yarn-error.log lighthouse-report .vscode/settings.json -/test-results \ No newline at end of file +/test-results +test-results.xml \ No newline at end of file diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 27c39d22..3cb06eec 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /* eslint-disable jsdoc/require-param */ "use strict"; @@ -12,6 +13,8 @@ const formatScore = (res) => { * `core` is in scope from https://github.com/actions/github-script */ export const formatLighthouseResults = ({ core }) => { + console.log("LIGHTHOUSE_RESULT", process.env.LIGHTHOUSE_RESULT); + console.log("LIGHTHOUSE_LINKS", process.env.LIGHTHOUSE_LINKS); // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest const results = JSON.parse(process.env.LIGHTHOUSE_RESULT); From 48aafe49129f02286653c30760cc90e0456aab43 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 17:40:08 -0500 Subject: [PATCH 08/17] Write output and pick up as context in CI --- .github/workflows/ci.yml | 3 +- .gitignore | 3 +- playwright.config.js | 3 +- scripts/lighthouse/index.js | 28 +++++++----------- scripts/lighthouse/index.test.js | 50 +++++++++++++++++--------------- tests/lighthouse.test.js | 9 ++++++ 6 files changed, 51 insertions(+), 45 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c233dc44..549ad9fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,8 +103,7 @@ jobs: env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input - LIGHTHOUSE_RESULT: ${{ steps.lighthouse-test.outputs.manifest }} - LIGHTHOUSE_LINKS: ${{ steps.lighthouse-test.outputs.links }} + LIGHTHOUSE_RESULT: ./lighthouse-reports/lighthouse.json with: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. diff --git a/.gitignore b/.gitignore index 9e1cb422..60e684b9 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ yarn-error.log lighthouse-report .vscode/settings.json /test-results -test-results.xml \ No newline at end of file +test-results.xml +/lighthouse-reports \ No newline at end of file diff --git a/playwright.config.js b/playwright.config.js index 00a43a56..c99953ba 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -25,7 +25,8 @@ export default defineConfig({ { name: "lighthouse", testMatch: "lighthouse.test.js", - use: { baseURL: "http://localhost:4173" } + use: { baseURL: "http://localhost:4173" }, + outputDir: "lighthouse-reports" }, /* Test against desktop viewports. */ diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 3cb06eec..9cd9a801 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -14,34 +14,26 @@ const formatScore = (res) => { */ export const formatLighthouseResults = ({ core }) => { console.log("LIGHTHOUSE_RESULT", process.env.LIGHTHOUSE_RESULT); - console.log("LIGHTHOUSE_LINKS", process.env.LIGHTHOUSE_LINKS); // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest - const results = JSON.parse(process.env.LIGHTHOUSE_RESULT); - - // this will be the shape of https://github.com/treosh/lighthouse-ci-action#links - const links = JSON.parse(process.env.LIGHTHOUSE_LINKS); + const resultsJson = JSON.parse(process.env.LIGHTHOUSE_RESULT).categories; // start creating our markdown table const header = [ "Lighthouse Results", - "URL | Performance | Accessibility | Best Practices | SEO | Report", - "| - | - | - | - | - | - |" + "| Performance | Accessibility | Best Practices | SEO |", + "| - | - | - | - |" ]; - // map over each url result, formatting and linking to the output - const urlResults = results.map(({ url, summary }) => { - // make each formatted score from our lighthouse properties - const performanceScore = formatScore(summary.performance); - const accessibilityScore = formatScore(summary.accessibility); - const bestPracticesScore = formatScore(summary["best-practices"]); - const seoScore = formatScore(summary.seo); + // make each formatted score from our lighthouse properties + const performanceScore = formatScore(resultsJson.performance.score); + const accessibilityScore = formatScore(resultsJson.accessibility.score); + const bestPracticesScore = formatScore(resultsJson["best-practices"].score); + const seoScore = formatScore(resultsJson.seo.score); - // create the markdown table row - return `${url} | ${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore} | [🔗](${links[url]})`; - }); + const results = `${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore}`; // join the header and the rows together - const finalResults = [...header, ...urlResults].join("\n"); + const finalResults = header + results; // return our output to the github action core.setOutput("comment", finalResults); diff --git a/scripts/lighthouse/index.test.js b/scripts/lighthouse/index.test.js index 386d6e48..e67b8f0d 100644 --- a/scripts/lighthouse/index.test.js +++ b/scripts/lighthouse/index.test.js @@ -2,25 +2,30 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { formatLighthouseResults } from "./index"; describe("formatLighthouseResults", () => { - const MOCK_VERCEL_PREVIEW_URL = "https://some.vercel.preview.url"; - - const MOCK_LIGHTHOUSE_RESULT = `[ - { - "url": "${MOCK_VERCEL_PREVIEW_URL}/en", - "isRepresentativeRun": true, - "summary": { "performance": 0.99, "accessibility": 0.98, "best-practices": 1, "seo": 0.96, "pwa": 0.71 } - }, - { - "url": "${MOCK_VERCEL_PREVIEW_URL}/en/download", - "isRepresentativeRun": true, - "summary": { "performance": 0.49, "accessibility": 0.75, "best-practices": 1, "seo": 0.90, "pwa": 0.71 } - } - ]`; - - const MOCK_LIGHTHOUSE_LINKS = `{ - "${MOCK_VERCEL_PREVIEW_URL}/en": "fake.url/to/result/1", - "${MOCK_VERCEL_PREVIEW_URL}/en/download" : "fake.url/to/result/2" - }`; + const MOCK_LIGHTHOUSE_RESULT = `{ + "categories": { + "performance": { + "title": "Performance", + "id": "performance", + "score": 0.65 + }, + "accessibility": { + "title": "Accessibility", + "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", + "score": 0.75 + }, + "best-practices": { + "id": "best-practices", + "score": 1 + }, + "seo": { + "title": "SEO", + "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", + "id": "seo", + "score": 1 + } + } + }`; let mockCore, originalEnv; @@ -29,8 +34,7 @@ describe("formatLighthouseResults", () => { originalEnv = process.env; process.env = { ...process.env, - LIGHTHOUSE_RESULT: MOCK_LIGHTHOUSE_RESULT, - LIGHTHOUSE_LINKS: MOCK_LIGHTHOUSE_LINKS + LIGHTHOUSE_RESULT: MOCK_LIGHTHOUSE_RESULT }; }); @@ -42,9 +46,9 @@ describe("formatLighthouseResults", () => { formatLighthouseResults({ core: mockCore }); const expectations = [ - expect.stringContaining("🟢 90"), + expect.stringContaining("🟢 100"), expect.stringContaining("🟠 75"), - expect.stringContaining("🔴 49") + expect.stringContaining("🔴 65") ]; expectations.forEach((expectation) => { diff --git a/tests/lighthouse.test.js b/tests/lighthouse.test.js index 0b28565f..2350b532 100644 --- a/tests/lighthouse.test.js +++ b/tests/lighthouse.test.js @@ -20,6 +20,15 @@ test.describe("audit", () => { "best-practices": 100, seo: 100 }, + reports: { + formats: { + json: true, //defaults to false + html: false, //defaults to false + csv: false //defaults to false + }, + name: "lighthouse", //defaults to `lighthouse-${new Date().getTime()}` + directory: "lighthouse-reports" //defaults to `${process.cwd()}/lighthouse` + }, port: 9222 }); From 1401e7162cd8588e816c57c6a59ae6f3f4012f51 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 17:48:04 -0500 Subject: [PATCH 09/17] Read in JSON file --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 549ad9fc..819f9905 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,6 +96,11 @@ jobs: # Run Lighthouse Playwright tests - name: Run Playwright tests run: bun run test:lighthouse + - name: Read JSON and set output + id: json-reader + run: | + json_content=$(cat ./lighthouse-reports/lighthouse.json | jq -c .) + echo "::set-output name=json::$json_content" - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output id: format-lighthouse-score @@ -103,7 +108,7 @@ jobs: env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input - LIGHTHOUSE_RESULT: ./lighthouse-reports/lighthouse.json + LIGHTHOUSE_RESULT: ${{ steps.json-reader.outputs.json }} with: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. From 1901fb08ca8956a274316a4e5072fa2849a02b65 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 17:58:15 -0500 Subject: [PATCH 10/17] Read in just categories part of JSON to shorten output --- .github/workflows/ci.yml | 4 ++-- scripts/lighthouse/index.js | 2 +- scripts/lighthouse/index.test.js | 40 +++++++++++++++----------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 819f9905..c325f820 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,8 +99,8 @@ jobs: - name: Read JSON and set output id: json-reader run: | - json_content=$(cat ./lighthouse-reports/lighthouse.json | jq -c .) - echo "::set-output name=json::$json_content" + categories=$(jq -c '.categories' ./lighthouse-reports/lighthouse.json) + echo "::set-output name=json::$categories" - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output id: format-lighthouse-score diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 9cd9a801..273becb2 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -15,7 +15,7 @@ const formatScore = (res) => { export const formatLighthouseResults = ({ core }) => { console.log("LIGHTHOUSE_RESULT", process.env.LIGHTHOUSE_RESULT); // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest - const resultsJson = JSON.parse(process.env.LIGHTHOUSE_RESULT).categories; + const resultsJson = JSON.parse(process.env.LIGHTHOUSE_RESULT); // start creating our markdown table const header = [ diff --git a/scripts/lighthouse/index.test.js b/scripts/lighthouse/index.test.js index e67b8f0d..3ca711e9 100644 --- a/scripts/lighthouse/index.test.js +++ b/scripts/lighthouse/index.test.js @@ -3,27 +3,25 @@ import { formatLighthouseResults } from "./index"; describe("formatLighthouseResults", () => { const MOCK_LIGHTHOUSE_RESULT = `{ - "categories": { - "performance": { - "title": "Performance", - "id": "performance", - "score": 0.65 - }, - "accessibility": { - "title": "Accessibility", - "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", - "score": 0.75 - }, - "best-practices": { - "id": "best-practices", - "score": 1 - }, - "seo": { - "title": "SEO", - "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", - "id": "seo", - "score": 1 - } + "performance": { + "title": "Performance", + "id": "performance", + "score": 0.65 + }, + "accessibility": { + "title": "Accessibility", + "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", + "score": 0.75 + }, + "best-practices": { + "id": "best-practices", + "score": 1 + }, + "seo": { + "title": "SEO", + "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", + "id": "seo", + "score": 1 } }`; From 1efcda0af93ce8ff9657bd85c12b133657e5416a Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 18:05:13 -0500 Subject: [PATCH 11/17] Fix lighthouse comment formatting --- scripts/lighthouse/index.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 273becb2..93b748e3 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ /* eslint-disable jsdoc/require-param */ "use strict"; @@ -13,16 +12,14 @@ const formatScore = (res) => { * `core` is in scope from https://github.com/actions/github-script */ export const formatLighthouseResults = ({ core }) => { - console.log("LIGHTHOUSE_RESULT", process.env.LIGHTHOUSE_RESULT); // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest const resultsJson = JSON.parse(process.env.LIGHTHOUSE_RESULT); // start creating our markdown table - const header = [ - "Lighthouse Results", - "| Performance | Accessibility | Best Practices | SEO |", - "| - | - | - | - |" - ]; + const header = + "# Lighthouse Results\n" + + "| Performance | Accessibility | Best Practices | SEO |\n" + + "| - | - | - | - |\n"; // make each formatted score from our lighthouse properties const performanceScore = formatScore(resultsJson.performance.score); @@ -30,7 +27,7 @@ export const formatLighthouseResults = ({ core }) => { const bestPracticesScore = formatScore(resultsJson["best-practices"].score); const seoScore = formatScore(resultsJson.seo.score); - const results = `${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore}`; + const results = `| ${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore} |`; // join the header and the rows together const finalResults = header + results; From 763d39e275b1131ce9918369cde63f7286cd1228 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Tue, 7 May 2024 18:12:39 -0500 Subject: [PATCH 12/17] Update to use all update to date functions --- .github/workflows/ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c325f820..2049fef1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,16 +99,15 @@ jobs: - name: Read JSON and set output id: json-reader run: | - categories=$(jq -c '.categories' ./lighthouse-reports/lighthouse.json) - echo "::set-output name=json::$categories" + echo "categories=$(jq -c '.categories' ./lighthouse-reports/lighthouse.json)" >> $GITHUB_OUTPUT - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output id: format-lighthouse-score - uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 + uses: actions/github-script@v7 # v6.4.1 env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input - LIGHTHOUSE_RESULT: ${{ steps.json-reader.outputs.json }} + LIGHTHOUSE_RESULT: ${{ env.categories }} with: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. From 87802f19c78a8f7be94cba343c1655f6d92405fa Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Wed, 8 May 2024 07:25:42 -0500 Subject: [PATCH 13/17] Debug output processing --- .github/workflows/ci.yml | 4 ++-- scripts/lighthouse/index.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2049fef1..a02e8f77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,7 +103,7 @@ jobs: - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output id: format-lighthouse-score - uses: actions/github-script@v7 # v6.4.1 + uses: actions/github-script@v7 env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input @@ -116,7 +116,7 @@ jobs: await formatLighthouseResults({core}) - name: Add Comment to PR # Replace the previous message with our formatted lighthouse results - uses: thollander/actions-comment-pull-request@d61db783da9abefc3437960d0cce08552c7c004f # v2.4.2 + uses: thollander/actions-comment-pull-request@v2 # v2.4.2 with: # Reference the previously created comment comment_tag: "lighthouse-audit" diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 93b748e3..7cd0bbde 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -13,6 +13,7 @@ const formatScore = (res) => { */ export const formatLighthouseResults = ({ core }) => { // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest + console.log(process.env.LIGHTHOUSE_RESULT); const resultsJson = JSON.parse(process.env.LIGHTHOUSE_RESULT); // start creating our markdown table From a65ac7c053e8fda034e6852c3a24b5db54d2cb50 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Wed, 8 May 2024 07:38:05 -0500 Subject: [PATCH 14/17] Debug output processing --- .github/workflows/ci.yml | 2 ++ scripts/lighthouse/index.js | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a02e8f77..8456be0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,8 @@ jobs: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. script: | + console.log(`Lighthouse LIGHTHOUSE_RESULT: ${process.env.LIGHTHOUSE_RESULT}`); + console.log(`Lighthouse Categories: ${process.env.CATEGORIES}`); const { formatLighthouseResults } = await import('${{github.workspace}}/scripts/lighthouse/index.js') await formatLighthouseResults({core}) - name: Add Comment to PR diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 7cd0bbde..94153179 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /* eslint-disable jsdoc/require-param */ "use strict"; From bd6d5e6f99db5fb1be8b05f858e85ca8ede70c60 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Wed, 8 May 2024 07:43:31 -0500 Subject: [PATCH 15/17] Revert "Debug output processing" This reverts commit a65ac7c053e8fda034e6852c3a24b5db54d2cb50. --- .github/workflows/ci.yml | 2 -- scripts/lighthouse/index.js | 1 - 2 files changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8456be0a..a02e8f77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,8 +112,6 @@ jobs: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info. script: | - console.log(`Lighthouse LIGHTHOUSE_RESULT: ${process.env.LIGHTHOUSE_RESULT}`); - console.log(`Lighthouse Categories: ${process.env.CATEGORIES}`); const { formatLighthouseResults } = await import('${{github.workspace}}/scripts/lighthouse/index.js') await formatLighthouseResults({core}) - name: Add Comment to PR diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 94153179..7cd0bbde 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ /* eslint-disable jsdoc/require-param */ "use strict"; From 0acccf57b5a5512af8fca44a3e04f753e3262fd1 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Wed, 8 May 2024 07:43:39 -0500 Subject: [PATCH 16/17] Revert "Debug output processing" This reverts commit 87802f19c78a8f7be94cba343c1655f6d92405fa. --- .github/workflows/ci.yml | 4 ++-- scripts/lighthouse/index.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a02e8f77..2049fef1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,7 +103,7 @@ jobs: - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output id: format-lighthouse-score - uses: actions/github-script@v7 + uses: actions/github-script@v7 # v6.4.1 env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input @@ -116,7 +116,7 @@ jobs: await formatLighthouseResults({core}) - name: Add Comment to PR # Replace the previous message with our formatted lighthouse results - uses: thollander/actions-comment-pull-request@v2 # v2.4.2 + uses: thollander/actions-comment-pull-request@d61db783da9abefc3437960d0cce08552c7c004f # v2.4.2 with: # Reference the previously created comment comment_tag: "lighthouse-audit" diff --git a/scripts/lighthouse/index.js b/scripts/lighthouse/index.js index 7cd0bbde..93b748e3 100644 --- a/scripts/lighthouse/index.js +++ b/scripts/lighthouse/index.js @@ -13,7 +13,6 @@ const formatScore = (res) => { */ export const formatLighthouseResults = ({ core }) => { // this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest - console.log(process.env.LIGHTHOUSE_RESULT); const resultsJson = JSON.parse(process.env.LIGHTHOUSE_RESULT); // start creating our markdown table From 62624235acfa01d30307cb497e01dcc45ebc2831 Mon Sep 17 00:00:00 2001 From: Sean Coughlin Date: Wed, 8 May 2024 07:43:53 -0500 Subject: [PATCH 17/17] Revert "Update to use all update to date functions" This reverts commit 763d39e275b1131ce9918369cde63f7286cd1228. --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2049fef1..c325f820 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,15 +99,16 @@ jobs: - name: Read JSON and set output id: json-reader run: | - echo "categories=$(jq -c '.categories' ./lighthouse-reports/lighthouse.json)" >> $GITHUB_OUTPUT + categories=$(jq -c '.categories' ./lighthouse-reports/lighthouse.json) + echo "::set-output name=json::$categories" - name: Format Lighthouse Score # Transform the audit results into a single, friendlier output id: format-lighthouse-score - uses: actions/github-script@v7 # v6.4.1 + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 env: # using env as input to our script # see https://github.com/actions/github-script#use-env-as-input - LIGHTHOUSE_RESULT: ${{ env.categories }} + LIGHTHOUSE_RESULT: ${{ steps.json-reader.outputs.json }} with: # Run as a separate file so we do not have to inline all of our formatting logic. # See https://github.com/actions/github-script#run-a-separate-file for more info.