Skip to content

Commit

Permalink
🧪 Add test suite using Jest and Puppeteer
Browse files Browse the repository at this point in the history
  • Loading branch information
kierandrewett committed Jul 22, 2023
1 parent 60d5e41 commit b6e83e6
Show file tree
Hide file tree
Showing 6 changed files with 2,617 additions and 20 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ jobs:
run: |
yarn build
- name: Test
run: |
yarn dev &
SERVER_PID=$!
while ! nc -z localhost 3000; do
sleep 0.1
done
yarn test
deploy:
runs-on: ubuntu-latest
needs: build
Expand Down
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
"build": "node scripts/build",
"dev": "cross-env NODE_ENV=develop yarn build && cross-env NODE_ENV=develop yarn start",
"watch": "nodemon -e js,ts,tsx,scss,ftl,yml --exec \"yarn dev\"",
"generate:l10n": "node scripts/l10n"
"generate:l10n": "node scripts/l10n",
"test:firefox": "BROWSER=firefox jest --detectOpenHandles",
"test:chrome": "BROWSER=chrome jest --detectOpenHandles",
"test": "yarn test:firefox && yarn test:chrome"
},
"dependencies": {
"@dothq/id": "^1.0.1",
Expand Down Expand Up @@ -47,18 +50,26 @@
"devDependencies": {
"@types/ejs": "^3.1.1",
"@types/glob": "^8.0.0",
"@types/jest": "^29.5.3",
"@types/node": "^18.11.7",
"@types/tcp-port-used": "^1.0.1",
"@types/ua-parser-js": "^0.7.36",
"broken-link-checker": "^0.7.8",
"chalk": "^5.1.2",
"compare-versions": "^6.0.0",
"concurrently": "^8.2.0",
"cross-env": "^7.0.3",
"esbuild": "^0.15.12",
"fs-extra": "^10.1.0",
"html-prettify": "^1.0.7",
"jest": "^29.6.1",
"locate-app": "^2.0.0",
"nodemon": "^2.0.22",
"puppeteer": "^20.9.0",
"rimraf": "^3.0.2",
"sass": "^1.55.0",
"tcp-port-used": "^1.0.2",
"ts-jest": "^29.1.1",
"typescript": "^4.8.4"
}
}
}
25 changes: 25 additions & 0 deletions tests/renders-landing-page.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { Runner, createRunner } from "./utils";

let runner: Runner;

beforeAll(async () => {
runner = await createRunner();
});

test("renders landing page", async () => {
await runner.page.waitForSelector("#main-content");

const title = await runner.page.$eval(
"#main-content > section:first-of-type .fdn-hero-body h1",
(e) => e.innerText?.trim().replace(/\n/g, " ")
);
expect(title).toBe("A safer way to surf the web.");
});

afterAll(async () => {
await runner.browser.close();
});
61 changes: 61 additions & 0 deletions tests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { locateApp, locateChrome, locateFirefox } from "locate-app";
import puppeteer, { Browser, Page, Product } from "puppeteer";
import { check } from "tcp-port-used";

export interface Runner {
page: Page;
browser: Browser;
}

const browsers: any = {
// For Firefox, we want to see if Nightly is installed also
firefox: async () => {
try {
return await locateFirefox();
} catch (e) {
try {
return await locateApp({
appName: "Firefox Nightly",
linuxWhich: "firefox-nightly",
windowsSuffix: "\\Mozilla Firefox\\firefox.exe",
macOsName: "Firefox Nightly"
});
} catch (e) {
throw e;
}
}
},
chrome: locateChrome
};

export const createRunner = async () => {
if (!((process.env.BROWSER as string) in browsers)) {
throw new Error(`Unknown browser '${process.env.BROWSER}'`);
}

if (!(await check(3000))) {
throw new Error(`Server needs to be running first!`);
}

const executablePath = await browsers[
process.env.BROWSER as string
]();

const browser = await puppeteer.launch({
headless: process.env.BROWSER == "chrome" ? "new" : true,
product: process.env.BROWSER as Product,
executablePath
});

const page = await browser.newPage();
await page.goto("http://localhost:3000/");

return {
page,
browser
};
};
Loading

0 comments on commit b6e83e6

Please sign in to comment.