Skip to content

Commit 630d8a5

Browse files
authored
chore: add frontend integration test (#516)
1 parent 4650362 commit 630d8a5

File tree

6 files changed

+133
-1
lines changed

6 files changed

+133
-1
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Jumble Integration
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 10
15+
defaults:
16+
run:
17+
working-directory: ./typescript/packages/jumble
18+
19+
services:
20+
redis:
21+
image: redis
22+
ports:
23+
- 6379:6379
24+
options: >-
25+
--health-cmd "redis-cli ping"
26+
--health-interval 10s
27+
--health-timeout 5s
28+
--health-retries 5
29+
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- name: Setup Deno
34+
uses: denoland/setup-deno@v2
35+
with:
36+
deno-version: "2.2.2"
37+
38+
- name: Cache dependencies
39+
uses: actions/cache@v3
40+
with:
41+
path: |
42+
~/.deno
43+
~/.cache/deno
44+
key: ${{ runner.os }}-deno-${{ hashFiles('**/deno.json') }}
45+
46+
- name: Run Toolshed
47+
working-directory: typescript/packages/toolshed
48+
run: deno task dev &
49+
50+
- name: Run Vite
51+
working-directory: typescript/packages/jumble
52+
run: TOOLSHED_API_URL=http://localhost:8000 deno task dev &
53+
# For Astral
54+
# https://github.com/lino-levan/astral/blob/f5ef833b2c5bde3783564a6b925073d5d46bb4b8/README.md#no-usable-sandbox-with-user-namespace-cloning-enabled
55+
- name: Disable AppArmor
56+
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
57+
58+
- name: Run Integration
59+
working-directory: ./typescript/packages/jumble
60+
run: deno task integration

typescript/packages/deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
},
4747
"imports": {
4848
"ai": "npm:ai@^4.1.5",
49+
"@astral/astral": "jsr:@astral/astral",
4950
"@cfworker/json-schema": "npm:@cfworker/json-schema@^4.1.0",
5051
"@codemirror/lang-javascript": "npm:@codemirror/lang-javascript@^6.2.2",
5152
"@codemirror/lang-markdown": "npm:@codemirror/lang-markdown@^6.3.2",

typescript/packages/deno.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

typescript/packages/jumble/deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"dev": "deno run -A --node-modules-dir=auto npm:vite",
44
"build": "deno run -A --node-modules-dir=auto npm:vite build",
55
"preview": "deno run -A --node-modules-dir=auto npm:vite preview",
6-
"test": "echo 'No tests to run.'"
6+
"test": "echo 'No tests to run.'",
7+
"integration": "deno run -A ./integration/smoke-test.ts"
78
},
89
"imports": {
910
"@/": "./src/",
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { launch } from "@astral/astral";
2+
import { assert } from "@std/assert";
3+
import { login } from "./utils.ts";
4+
5+
const FRONTEND_URL = "http://localhost:5173/";
6+
7+
async function main() {
8+
const browser = await launch();
9+
console.log(`Waiting to open website at ${FRONTEND_URL}`);
10+
const page = await browser.newPage(FRONTEND_URL);
11+
console.log(`Opened website at ${FRONTEND_URL}`);
12+
13+
await login(page);
14+
15+
const anchor = await page.waitForSelector("nav a");
16+
assert(
17+
(await anchor.innerText()) === "common-knowledge",
18+
"Logged in and Common Knowledge title renders",
19+
);
20+
await browser.close();
21+
}
22+
23+
try {
24+
await main();
25+
} catch (e) {
26+
console.error(e);
27+
Deno.exit(1);
28+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Page } from "@astral/astral";
2+
3+
export const login = async (page: Page) => {
4+
// First, see if any credential data is
5+
// persisting. If so, destroy local data.
6+
let buttons = await page.$$("button");
7+
for (const button of buttons) {
8+
if ((await button.innerText()) === "Clear Saved Credentials") {
9+
await button.click();
10+
}
11+
}
12+
13+
// Click the first button, "register"
14+
let button = await page.$("button");
15+
await button!.click();
16+
17+
// Click the first button, "register with passphrase"
18+
button = await page.$("button");
19+
await button!.click();
20+
21+
// Get the mnemonic from textarea.
22+
let input = await page.$("textarea");
23+
const mnemonic = await input!.evaluate((textarea: HTMLInputElement) =>
24+
textarea.value
25+
);
26+
27+
// Click the SECOND button, "continue to login"
28+
buttons = await page.$$("button");
29+
await buttons[1]!.click();
30+
31+
// Paste the mnemonic in the input.
32+
input = await page.$("input");
33+
await input!.evaluate(
34+
(input: HTMLInputElement, mnemonic: string) => input.value = mnemonic,
35+
{ args: [mnemonic] },
36+
);
37+
38+
// Click the only button, "login"
39+
button = await page.$("button");
40+
await button!.click();
41+
};

0 commit comments

Comments
 (0)