Skip to content

Commit b719a54

Browse files
committed
added browser tests
1 parent f4d2382 commit b719a54

16 files changed

+998
-47
lines changed

.eslintrc.cjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module.exports = {
22
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
33
parser: "@typescript-eslint/parser",
44
plugins: ["@typescript-eslint"],
5+
env: {
6+
browser: true,
7+
node: true,
8+
},
59
rules: {
610
"@typescript-eslint/no-this-alias": "off",
711
},

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
node_modules/
22
dist/
33
typings/
4+
/test-results/
5+
/playwright-report/
6+
/playwright/.cache/
7+
8+
wasmtime/

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ $ npm install
3838
$ npm run build
3939
```
4040

41+
## Running tests
42+
43+
This project uses playwright to run tests in a browser using WebAssembly built from the Wasmtime project.
44+
45+
To clone wasmtime and build the test WebAssembly, run:
46+
47+
```
48+
$ npm test:build
49+
```
50+
51+
Once the WebAssembly is built, you can run the tests with:
52+
53+
```
54+
$ npm test
55+
```
56+
4157
## Running the demo
4258

4359
The demo requires the wasm rustc artifacts and the xterm js package. To get them run:

e2e/harness.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<html>
2+
<head>
3+
<title>Test Harness</title>
4+
</head>
5+
<h1>Status: <span id=status data-testid=status>Not started</span></h1>
6+
<h2>Check console for details</h2>
7+
<script src="harness.js" type="module"></script>
8+
</html>

e2e/harness.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { WASI, File, PreopenDirectory } from "../dist/index.js";
2+
3+
const stdio = {
4+
stdin: undefined,
5+
stdout: new File(),
6+
stderr: new File(),
7+
};
8+
9+
const WASI_ENVS = {
10+
DEFAULT: [
11+
stdio.stdin,
12+
stdio.stdout,
13+
stdio.stderr,
14+
new PreopenDirectory("/", {}),
15+
],
16+
};
17+
18+
async function main(options) {
19+
const wasmReq = await fetch(options.file);
20+
21+
const args = [options.file];
22+
args.push(...(options.args || []));
23+
24+
const wasi = new WASI(
25+
args,
26+
(options.env || "").split(","),
27+
WASI_ENVS[options.wasi_env] || WASI_ENVS.DEFAULT,
28+
{
29+
debug: true,
30+
},
31+
);
32+
const module = await WebAssembly.compileStreaming(wasmReq);
33+
34+
const instance = await WebAssembly.instantiate(module, {
35+
wasi_snapshot_preview1: wasi.wasiImport,
36+
});
37+
38+
const status = document.getElementById("status");
39+
try {
40+
if (options.reactor) {
41+
wasi.initialize(instance);
42+
}
43+
if (options.command) {
44+
wasi.start(instance);
45+
}
46+
printBuffer(stdio, "stdout", "log");
47+
printBuffer(stdio, "stderr", "log");
48+
status.innerText = "success";
49+
} catch (e) {
50+
printBuffer(stdio, "stdout", "log");
51+
printBuffer(stdio, "stderr", "error");
52+
status.innerText = "failure";
53+
throw e;
54+
}
55+
}
56+
57+
function printBuffer(stdio, type, logger) {
58+
const output = new TextDecoder().decode(stdio[type].data);
59+
if (output.trim().length > 0) {
60+
console[logger](`${type}`, output);
61+
}
62+
}
63+
64+
main(JSON.parse(decodeURI(location.search.slice(1))))
65+
.then(() => {
66+
console.log("done");
67+
})
68+
.catch((e) => {
69+
console.error(e);
70+
throw e;
71+
});

e2e/wasmtime.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { test, expect } from "@playwright/test";
2+
3+
const URL = "http://127.0.0.1:3000/e2e/harness.html";
4+
const WASMDIR = "../wasmtime/artifacts";
5+
6+
const tests = [
7+
{
8+
file: `${WASMDIR}/preview1_path_open_read_write.wasm`,
9+
command: true,
10+
args: ["/"],
11+
},
12+
];
13+
14+
for (const testDef of tests) {
15+
test(`first ${testDef.file}`, async ({ page }) => {
16+
await page.goto(`${URL}?${JSON.stringify(testDef)}`);
17+
await page.waitForFunction(
18+
() => document.getElementById("status")?.textContent !== "Not started",
19+
);
20+
expect(await await page.getByTestId("status").textContent()).toBe(
21+
"success",
22+
);
23+
});
24+
}

0 commit comments

Comments
 (0)