From d7349ae38bf9eca5aef1892b2440095d726fa608 Mon Sep 17 00:00:00 2001 From: Maud Leray Date: Fri, 17 Oct 2025 12:27:43 +0200 Subject: [PATCH] Implement snapshots in Playwright This could be used for visual regression testing --- .gitignore | 1 + playwright.config.js | 3 +- tests/e2e/snapshots.spec.js | 10 ++++++ tests/e2e/tools/setup/global-setup.js | 18 ++++++++++ tests/e2e/tools/setup/sitemap.js | 47 +++++++++++++++++++++++++++ tests/e2e/tools/setup/sitemap.json | 21 ++++++++++++ 6 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/snapshots.spec.js create mode 100644 tests/e2e/tools/setup/global-setup.js create mode 100644 tests/e2e/tools/setup/sitemap.js create mode 100644 tests/e2e/tools/setup/sitemap.json diff --git a/.gitignore b/.gitignore index 42c58f1cc2..f81bcd4f1b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ assets/build/* /e2e-report/ /playwright/.cache/ /playwright/.auth/ +/tests/e2e/snapshots.spec.js-snapshots/ .env diff --git a/playwright.config.js b/playwright.config.js index c1c4a34ed1..46151783b1 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -4,7 +4,7 @@ const dotenv = require('dotenv'); const testDir = './tests/e2e'; const envFile = process.env.CI ? `${testDir}/env/.env.ci` : `${testDir}/env/.env.default`; dotenv.config({path: envFile}); -dotenv.config({override: true});// prioritize .env file if exists +dotenv.config({override: true}); // prioritize .env file if exists /** * @see https://playwright.dev/docs/test-configuration @@ -113,6 +113,7 @@ const config = { // command: 'npm run start', // port: 3000, // }, + globalSetup: require.resolve('./tests/e2e/tools/setup/global-setup'), }; module.exports = config; diff --git a/tests/e2e/snapshots.spec.js b/tests/e2e/snapshots.spec.js new file mode 100644 index 0000000000..1a3b9aecbc --- /dev/null +++ b/tests/e2e/snapshots.spec.js @@ -0,0 +1,10 @@ +import {test, expect} from './tools/lib/test-utils.js'; +import {readSiteMap} from './tools/setup/sitemap.js'; + +test('Snapshots', async ({page}) => { + const urls = await readSiteMap(); + for (const url of urls) { + await page.goto(url); + await expect(page).toHaveScreenshot(); + } +}); diff --git a/tests/e2e/tools/setup/global-setup.js b/tests/e2e/tools/setup/global-setup.js new file mode 100644 index 0000000000..b1422645e2 --- /dev/null +++ b/tests/e2e/tools/setup/global-setup.js @@ -0,0 +1,18 @@ +const playwright = require('@playwright/test'); + +import {createSiteMap, readSiteMap} from './sitemap'; + +export default async () => { + // only create site map if it doesn't already exist + const sitemap = await readSiteMap(); + if (sitemap) { + return; + } + + // launch browser and initiate crawler + let browser = playwright.devices['Desktop Chrome'].defaultBrowserType; + browser = await playwright[browser].launch(); + const page = await browser.newPage(); + await createSiteMap(process.env.WP_BASE_URL, page); + await browser.close(); +}; diff --git a/tests/e2e/tools/setup/sitemap.js b/tests/e2e/tools/setup/sitemap.js new file mode 100644 index 0000000000..6e760c6f59 --- /dev/null +++ b/tests/e2e/tools/setup/sitemap.js @@ -0,0 +1,47 @@ +import {readFileSync, writeFileSync} from 'node:fs'; +import {join} from 'node:path'; + +const extractLocalLinks = baseURL => { + const urls = new Set(); + const offset = baseURL.length; + for (const {href} of document.links) { + if (href.startsWith(baseURL)) { + const path = href.slice(offset); + urls.add(path); + } + } + return Array.from(urls); +}; + +const ENTRY_POINT = '/topics'; +const SITEMAP = join(__dirname, './sitemap.json'); + +/** + * Determines URLs and writes them to disk. + * + * @param {string} baseURL - The site's base URL. + * @param {Object} page - The current page object. + */ +const createSiteMap = async (baseURL, page) => { + await page.goto(baseURL + ENTRY_POINT); + const urls = await page.evaluate(extractLocalLinks, baseURL); + const data = JSON.stringify(urls, null, 4); + writeFileSync(SITEMAP, data, {encoding: 'utf-8'}); +}; + +/** + * Reads any previously created site map from disk. + * + * @return {Object} Sitemap data. + */ +const readSiteMap = async () => { + let data = null; + try { + data = readFileSync(SITEMAP, {encoding: 'utf-8'}); + } catch (err) { + return null; + } + return JSON.parse(data); +}; + +export {createSiteMap, readSiteMap}; diff --git a/tests/e2e/tools/setup/sitemap.json b/tests/e2e/tools/setup/sitemap.json new file mode 100644 index 0000000000..405d2cea63 --- /dev/null +++ b/tests/e2e/tools/setup/sitemap.json @@ -0,0 +1,21 @@ +[ + "/topics#header", + "/topics#content", + "/topics#footer", + "/", + "/take-action/", + "/petitions/consectetur-adipiscing/", + "/petitions/vestibulum-placerat/", + "/petitions/consectetur-adipiscing-elit/", + "/get-informed/", + "/get-informed/energy/", + "/get-informed/nature/", + "/get-informed/people/", + "/about-us-2/", + "/press-center/", + "/sitemap/", + "/privacy-and-cookies/", + "/community-policy/", + "/terms/", + "/copyright/" +] \ No newline at end of file