Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/jumble-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Jumble Integration

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
working-directory: ./typescript/packages/jumble

services:
redis:
image: redis
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4

- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: "2.2.2"

- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.deno
~/.cache/deno
key: ${{ runner.os }}-deno-${{ hashFiles('**/deno.json') }}

- name: Run Toolshed
working-directory: typescript/packages/toolshed
run: deno task dev &

- name: Run Vite
working-directory: typescript/packages/jumble
run: TOOLSHED_API_URL=http://localhost:8000 deno task dev &
# For Astral
# https://github.com/lino-levan/astral/blob/f5ef833b2c5bde3783564a6b925073d5d46bb4b8/README.md#no-usable-sandbox-with-user-namespace-cloning-enabled
- name: Disable AppArmor
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns

- name: Run Integration
working-directory: ./typescript/packages/jumble
run: deno task integration
1 change: 1 addition & 0 deletions typescript/packages/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
},
"imports": {
"ai": "npm:ai@^4.1.5",
"@astral/astral": "jsr:@astral/astral",
"@cfworker/json-schema": "npm:@cfworker/json-schema@^4.1.0",
"@codemirror/lang-javascript": "npm:@codemirror/lang-javascript@^6.2.2",
"@codemirror/lang-markdown": "npm:@codemirror/lang-markdown@^6.3.2",
Expand Down
1 change: 1 addition & 0 deletions typescript/packages/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion typescript/packages/jumble/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"dev": "deno run -A --node-modules-dir=auto npm:vite",
"build": "deno run -A --node-modules-dir=auto npm:vite build",
"preview": "deno run -A --node-modules-dir=auto npm:vite preview",
"test": "echo 'No tests to run.'"
"test": "echo 'No tests to run.'",
"integration": "deno run -A ./integration/smoke-test.ts"
},
"imports": {
"@/": "./src/",
Expand Down
28 changes: 28 additions & 0 deletions typescript/packages/jumble/integration/smoke-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { launch } from "@astral/astral";
import { assert } from "@std/assert";
import { login } from "./utils.ts";

const FRONTEND_URL = "http://localhost:5173/";

async function main() {
const browser = await launch();
console.log(`Waiting to open website at ${FRONTEND_URL}`);
const page = await browser.newPage(FRONTEND_URL);
console.log(`Opened website at ${FRONTEND_URL}`);

await login(page);

const anchor = await page.waitForSelector("nav a");
assert(
(await anchor.innerText()) === "common-knowledge",
"Logged in and Common Knowledge title renders",
);
await browser.close();
}

try {
await main();
} catch (e) {
console.error(e);
Deno.exit(1);
}
41 changes: 41 additions & 0 deletions typescript/packages/jumble/integration/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Page } from "@astral/astral";

export const login = async (page: Page) => {
// First, see if any credential data is
// persisting. If so, destroy local data.
let buttons = await page.$$("button");
for (const button of buttons) {
if ((await button.innerText()) === "Clear Saved Credentials") {
await button.click();
}
}

// Click the first button, "register"
let button = await page.$("button");
await button!.click();

// Click the first button, "register with passphrase"
button = await page.$("button");
await button!.click();

// Get the mnemonic from textarea.
let input = await page.$("textarea");
const mnemonic = await input!.evaluate((textarea: HTMLInputElement) =>
textarea.value
);

// Click the SECOND button, "continue to login"
buttons = await page.$$("button");
await buttons[1]!.click();

// Paste the mnemonic in the input.
input = await page.$("input");
await input!.evaluate(
(input: HTMLInputElement, mnemonic: string) => input.value = mnemonic,
{ args: [mnemonic] },
);

// Click the only button, "login"
button = await page.$("button");
await button!.click();
};