Skip to content

Commit

Permalink
Add visual regression testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-Electron authored Mar 11, 2024
1 parent c6a7123 commit 40b20a9
Show file tree
Hide file tree
Showing 7 changed files with 2,809 additions and 1,565 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/argos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Argos CI Screenshots

on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
take-screenshots:
if: ${{ github.ref_name == 'main' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'Argos')) }}
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4

- name: Prepare Yarn
uses: ./.github/actions/prepare/
- name: Prepare build
run: yarn prepare
shell: bash
- name: Checkout remote
run: yarn checkout:remote
- name: Generate API
run: yarn generate:api
shell: bash

- name: Install Playwright browsers
run: yarn playwright install --with-deps chromium

- name: Build the website
run: yarn build

- name: Take screenshots with Playwright
run: yarn playwright test

- name: Upload screenshots to Argos
run: yarn argos upload ./screenshots
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,19 @@
]
},
"devDependencies": {
"@argos-ci/cli": "^1.0.11",
"@argos-ci/playwright": "^1.9.3",
"@docusaurus/module-type-aliases": "2.4.3",
"@docusaurus/plugin-google-gtag": "2.4.3",
"@iota-wiki/cli": "workspace:^",
"@playwright/test": "^1.42.1",
"@tsconfig/docusaurus": "^1.0.6",
"@types/react": "18.2.51",
"@types/react-dom": "18.2.14",
"@types/webpack-env": "^1.18.3",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.9.1",
"cheerio": "^1.0.0-rc.12",
"eslint": "^8.48.0",
"eslint-config-prettier": "^8.9.0",
"eslint-plugin-react": "^7.26.0",
Expand Down
19 changes: 19 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { devices } from '@playwright/test';
import type { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
webServer: {
port: 3000,
command: 'yarn docusaurus serve',
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
],
};

export default config;
19 changes: 19 additions & 0 deletions screenshot.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* Iframes can load lazily */
iframe,
/* Avatars can be flaky due to using external sources: GitHub/Unavatar */
.avatar__photo,
/* Gifs load lazily and are animated */
img[src$='.gif'],
/* Algolia keyboard shortcuts appear with a little delay */
.DocSearch-Button-Keys > kbd,
/* The live playground preview can often display dates/counters */
[class*='playgroundPreview'] {
visibility: hidden;
}

/* Different docs last-update dates can alter layout */
.theme-last-updated,
/* Mermaid diagrams are rendered client-side and produce layout shifts */
.docusaurus-mermaid-container {
display: none;
}
42 changes: 42 additions & 0 deletions screenshot.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as fs from 'fs';
import { test } from '@playwright/test';
import { argosScreenshot } from '@argos-ci/playwright';
import { extractSitemapPathnames, pathnameToArgosName } from './utils';

// Constants
const siteUrl = 'http://localhost:3000';
const sitemapPath = './build/sitemap.xml';
const stylesheetPath = './screenshot.css';
const stylesheet = fs.readFileSync(stylesheetPath).toString();

// Wait for hydration, requires Docusaurus v2.4.3+
// Docusaurus adds a <html data-has-hydrated="true"> once hydrated
// See https://github.com/facebook/docusaurus/pull/9256
function waitForDocusaurusHydration() {
return document.documentElement.dataset.hasHydrated === 'true';
}

function screenshotPathname(pathname: string) {
test(`pathname ${pathname}`, async ({ page }) => {
const url = siteUrl + pathname;
await page.goto(url);
await page.waitForFunction(waitForDocusaurusHydration);
await page.addStyleTag({ content: stylesheet });
await argosScreenshot(page, pathnameToArgosName(pathname));
});
}

test.describe('Docusaurus site screenshots', () => {
const pathnames = extractSitemapPathnames(sitemapPath).filter((pathname) =>
pathname.match(
' ^/$|' +
'mana-calculator|' +
'learn/glossary|' +
'build/networks-endpoints|' +
'create-mnemonic|' +
'(api|apis)/core',
),
);
console.log('Pathnames to screenshot:', pathnames);
pathnames.forEach(screenshotPathname);
});
19 changes: 19 additions & 0 deletions utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as cheerio from 'cheerio';
import * as fs from 'fs';

// Extract a list of pathnames, given a fs path to a sitemap.xml file
// Docusaurus generates a build/sitemap.xml file for you!
export function extractSitemapPathnames(sitemapPath: string): string[] {
const sitemap = fs.readFileSync(sitemapPath).toString();
const $ = cheerio.load(sitemap, { xmlMode: true });
const urls: string[] = [];
$('loc').each(function handleLoc() {
urls.push($(this).text());
});
return urls.map((url) => new URL(url).pathname);
}

// Converts a pathname to a decent screenshot name
export function pathnameToArgosName(pathname: string): string {
return pathname.replace(/^\/|\/$/g, '') || 'index';
}
Loading

0 comments on commit 40b20a9

Please sign in to comment.