Skip to content

Commit

Permalink
build: setup argos
Browse files Browse the repository at this point in the history
  • Loading branch information
gotson committed Dec 15, 2023
1 parent 38ca31f commit 8cc0eea
Show file tree
Hide file tree
Showing 168 changed files with 1,636 additions and 48 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/argos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Argos CI

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
take-screenshots:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile

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

- name: Build website fast
run: yarn workspace website build

- name: Take Argos screenshots
run: yarn workspace argos screenshot

- name: Upload Argos screenshots
run: yarn workspace argos upload
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: yarn install
run: yarn install --frozen-lockfile
- name: yarn build
run: yarn build
run: yarn workspace website build

# Popular action to deploy to GitHub Pages:
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
Expand All @@ -26,7 +26,7 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# Build output to publish to the `gh-pages` branch:
publish_dir: ./build
publish_dir: ./website/build
# Assign commit authorship to the official GH-Actions bot for deploys to `gh-pages` branch:
# https://github.com/actions/checkout/issues/13#issuecomment-724415212
# The GH actions bot is used by default if you didn't specify the two fields.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ jobs:
- name: yarn install
run: yarn install --frozen-lockfile
- name: yarn build
run: yarn build
run: yarn workspace website build
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ npm-debug.log
.idea

# Production
/build
build

# Generated files
.docusaurus
Expand Down
4 changes: 4 additions & 0 deletions argos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/screenshots/
/test-results/
/playwright-report/
/playwright/.cache/
17 changes: 17 additions & 0 deletions argos/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "argos",
"version": "0.0.0",
"description": "Argos visual diff tests",
"license": "MIT",
"private": true,
"scripts": {
"screenshot": "playwright test",
"upload": "npx @argos-ci/cli upload ./screenshots"
},
"devDependencies": {
"@argos-ci/cli": "^1.0.4",
"@argos-ci/playwright": "^1.4.0",
"@playwright/test": "^1.40.1",
"cheerio": "^1.0.0-rc.12"
}
}
19 changes: 19 additions & 0 deletions argos/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;
35 changes: 35 additions & 0 deletions argos/screenshot.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
We need to hide some elements in Argos/Playwright screenshots
Those elements are source of flakiness due to nondeterministic rendering
They don't consistently render exactly the same across CI runs
*/

/******* DOCUSAURUS GLOBAL / THEME *******/

/* Iframes can load lazily */
iframe,
/* Avatar images 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
"visibility: hidden" is not enough
*/
.theme-last-updated {
display: none;
}

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

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

// Wait for hydration, requires Docusaurus v2.4.3+
// See https://github.com/facebook/docusaurus/pull/9256
// Docusaurus adds a <html data-has-hydrated="true"> once hydrated
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);
console.log("Pathnames to screenshot:", pathnames);
pathnames.forEach(screenshotPathname);
});
17 changes: 17 additions & 0 deletions argos/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as cheerio from "cheerio";
import * as fs from "fs";

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 8cc0eea

Please sign in to comment.