From 1058522bc38290fabde46cc80924e7436c09362b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Mon, 4 Mar 2024 17:25:10 +0100 Subject: [PATCH] feat: Switch to `playwright-test` as test runner --- car-mirror-wasm/README.md | 51 +------- car-mirror-wasm/package.json | 31 ++++- car-mirror-wasm/playwright.config.js | 54 -------- car-mirror-wasm/test/{init.js => index.js} | 19 +-- car-mirror-wasm/test/protocol.spec.js | 144 +++++++-------------- 5 files changed, 87 insertions(+), 212 deletions(-) delete mode 100644 car-mirror-wasm/playwright.config.js rename car-mirror-wasm/test/{init.js => index.js} (88%) diff --git a/car-mirror-wasm/README.md b/car-mirror-wasm/README.md index 35a32f8..35d4fea 100644 --- a/car-mirror-wasm/README.md +++ b/car-mirror-wasm/README.md @@ -49,62 +49,19 @@ Description. ## Set-up -We'll use [`wasm-pack`][wasm-pack] for building, testing, and publishing -our Wasm project. +TODO ### Build for Javascript -The `wasm-pack build` command will compile the code in this directory into -Wasm and generate a `pkg` folder by default, containing the Wasm binary, a -Javascript-wrapper file, the car-mirror-wasm README (and version), and a -`package.json` file. - -- Targetting node: - - ```console - wasm-pack build --target nodejs - ``` - -- Targetting browswers: - - ```console - wasm-pack build --target web - ``` - -- Targetting bundlers like [webpack][webpack]: - - ```console - wasm-pack build --target bundler - ``` +TODO ## Testing the Project -For running tests in the current directory, use one of these commands: - -- Run tests expected to execute in [Node.js][node-js]: - -```console -wasm-pack test --node -``` - -- Run browser tests in a headless browwer: - -```console -wasm-pack test --headless --firefox --chrome --safari -``` - -*Note*: Make sure you have the appropriate browser installed when running -locally. +TODO ## Publishing a Package -Once you've [built the package](#build-for-javascript), which lives under -`pkg` by default (or a sub-directory of your choosing), you can pack and -publish it to [npm][npm] via (given credentials): - -```console -wasm-pack publish -``` +TODO ## License diff --git a/car-mirror-wasm/package.json b/car-mirror-wasm/package.json index 99a8bc9..1d71aa2 100644 --- a/car-mirror-wasm/package.json +++ b/car-mirror-wasm/package.json @@ -4,6 +4,24 @@ "description": "Wasm bindings to the rust implementation of the car mirror protocol", "main": "index.js", "type": "module", + "module": "dist/bundler/car_mirror_wasm.js", + "types": "dist/nodejs/car_mirror_wasm.d.ts", + "exports": { + ".": { + "browser": "./dist/bundler/car_mirror_wasm.js", + "node": "./dist/nodejs/car_mirror_wasm.cjs", + "default": "./dist/bundler/car_mirror_wasm.js", + "types": "./dist/nodejs/car_mirror_wasm.d.ts" + }, + "./nodejs": { + "default": "./dist/nodejs/car_mirror_wasm.cjs", + "types": "./dist/nodejs/car_mirror_wasm.d.ts" + }, + "./web": { + "default": "./dist/web/car_mirror_wasm.js", + "types": "./dist/web/car_mirror_wasm.d.ts" + } + }, "directories": { "test": "tests" }, @@ -20,7 +38,8 @@ "dependencies": { "@ipld/unixfs": "^3.0.0", "fetch-h2": "^3.0.2", - "multiformats": "^13.1.0" + "multiformats": "^13.1.0", + "playwright-test": "^14.1.1" }, "devDependencies": { "@playwright/test": "^1.42.0", @@ -162,12 +181,18 @@ } }, "test": { - "command": "playwright test", + "command": "playwright-test 'test/**/*.spec.js'", "dependencies": [ - "bindgen:web", + "bindgen:bundler", "http-server", "car-mirror-server" ] } + }, + "playwright-test": { + "browserContextOptions": { + "baseURL": "http://127.0.0.1:8081", + "ignoreHTTPSErrors": true + } } } diff --git a/car-mirror-wasm/playwright.config.js b/car-mirror-wasm/playwright.config.js deleted file mode 100644 index 45ef728..0000000 --- a/car-mirror-wasm/playwright.config.js +++ /dev/null @@ -1,54 +0,0 @@ -// @ts-check -import { defineConfig, devices } from "@playwright/test"; - -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// require("dotenv").config(); - -/** - * @see https://playwright.dev/docs/test-configuration - */ -export default defineConfig({ - testDir: "./test", - /* Run tests in files in parallel */ - fullyParallel: true, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: "list", - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Base URL to use in actions like `await page.goto("/")`. */ - baseURL: "http://127.0.0.1:8081", - - // We use fetch(https://) with self-signed certs on the axum server - ignoreHTTPSErrors: true, - - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: "on-first-retry", - }, - - /* Configure projects for major browsers */ - projects: [ - { - name: "chromium", - use: { ...devices["Desktop Chrome"] }, - }, - - { - name: "firefox", - use: { ...devices["Desktop Firefox"] }, - }, - - { - name: "webkit", - use: { ...devices["Desktop Safari"] }, - }, - ], -}); diff --git a/car-mirror-wasm/test/init.js b/car-mirror-wasm/test/index.js similarity index 88% rename from car-mirror-wasm/test/init.js rename to car-mirror-wasm/test/index.js index ade0183..47b6fdf 100644 --- a/car-mirror-wasm/test/init.js +++ b/car-mirror-wasm/test/index.js @@ -1,9 +1,7 @@ +import { setPanicHook, push_request, push_request_streaming, pull_request, pull_handle_response_streaming, PushResponse } from "../dist/bundler/car_mirror_wasm.js" +import { CID } from "multiformats" +import * as UnixFS from "@ipld/unixfs" -import { setPanicHook, initSync, push_request, push_request_streaming, pull_request, pull_handle_response_streaming, PushResponse } from "/dist/web/car_mirror_wasm.js" -import { CID } from "https://esm.sh/multiformats" -import * as UnixFS from "https://esm.sh/@ipld/unixfs" - -initSync(await (await fetch("/dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer()); setPanicHook(); const supportsRequestStreams = (() => { @@ -85,11 +83,12 @@ export async function runCarMirrorPush(serverUrl, cidString, store) { let lastResponse = null; while (!lastResponse?.indicatesFinished()) { console.debug(`Creating push request body (supports streams? ${supportsRequestStreams} isHTTPS? ${isHTTPS})`) + /** @type {ReadableStream | Uint8Array} */ const body = useStreaming ? await push_request_streaming(cid.bytes, lastResponse == null ? undefined : lastResponse, store) : await push_request(cid.bytes, lastResponse == null ? undefined : lastResponse, store); - console.debug("Initiating request", url.toString(), body); + console.debug("Initiating request", url.toString(), body.length ?? "(can't print length of stream)"); const response = await fetch(url, { method: "POST", headers: { @@ -143,11 +142,3 @@ export async function exampleFile(store, writes) { return cid; } - -window.runCarMirrorPull = runCarMirrorPull; -window.runCarMirrorPush = runCarMirrorPush; -window.supportsRequestStreams = supportsRequestStreams; -window.MemoryBlockStore = MemoryBlockStore; -window.exampleFile = exampleFile; -window.CID = CID; -window.UnixFS = UnixFS; diff --git a/car-mirror-wasm/test/protocol.spec.js b/car-mirror-wasm/test/protocol.spec.js index dfb34f2..0148e31 100644 --- a/car-mirror-wasm/test/protocol.spec.js +++ b/car-mirror-wasm/test/protocol.spec.js @@ -1,110 +1,66 @@ -import { test, expect } from "@playwright/test"; +import { MemoryBlockStore, exampleFile, runCarMirrorPull, runCarMirrorPush } from "./index.js" +import { CID } from "multiformats" +import { assert, suite } from 'playwright-test/taps' -test.beforeEach(async ({ page }) => { - page.addListener("console", msg => { - let logfn = console.log; - switch (msg.type()) { - case "debug": logfn = console.debug; break; - case "info": logfn = console.info; break; - case "error": logfn = console.error; break; - case "warning": logfn = console.warning; break; - } - logfn(`type=${msg.type()} text=\"${msg.text()}\" src=${msg.location().url} line=${msg.location().lineNumber}`); - }); - - page.addListener("pageerror", err => { - throw new Error(`${err.name}: ${err.message}\n${err.stack}`); - }); +const test = suite("protocol"); - page.addListener("crash", () => console.error("Page crashed!")); +test("car mirror pull http", () => testPull("http")); +test("car mirror pull https", () => testPull("https")); - await page.goto("/index.html"); - await page.waitForFunction(() => window.runCarMirrorPull != null); -}) +test("car mirror incremental push http", () => testIncrementalPush("http")); +test("car mirror incremental push https", () => testIncrementalPush("https")); -test("car mirror pull http", testPull("http")); -test("car mirror pull https", testPull("https")); +test("car mirror both push then pull http", () => testPushThenPull("http")); +test("car mirror both push then pull https", () => testPushThenPull("https")); -test("car mirror incremental push http", testIncrementalPush("http")); -test("car mirror incremental push https", testIncrementalPush("https")); -test("car mirror both push then pull http", testPushThenPull("http")); -test("car mirror both push then pull https", testPushThenPull("https")); +async function testPull(protocol) { + const store = new MemoryBlockStore(); + // This is the sample data that the server serves. 100MB of ChaCha8 data from the 0 seed encoded as UnixFS file + const cid = CID.parse("bafyb4ifjd76kkpos2uiv5mqifs4vi2xtywhf7pnu2pqtlg2vzmtmpyzdfa"); + await runCarMirrorPull(`${protocol}://localhost:3344/dag/pull`, cid.toString(), store); - -function testPull(protocol) { - return async ({ page }) => { - const { hasRootBlock, totalBlocks } = await page.evaluate(async (protocol) => { - const store = new MemoryBlockStore(); - // This is the sample data that the server serves. 100MB of ChaCha8 data from the 0 seed encoded as UnixFS file - const cid = CID.parse("bafyb4ifjd76kkpos2uiv5mqifs4vi2xtywhf7pnu2pqtlg2vzmtmpyzdfa"); - await runCarMirrorPull(`${protocol}://localhost:3344/dag/pull`, cid.toString(), store); - return ({ - hasRootBlock: await store.hasBlock(cid.bytes), - totalBlocks: store.store.size - }); - }, protocol); - - expect(hasRootBlock).toBeTruthy(); - expect(totalBlocks).toBeGreaterThan(300); - } + assert.equal(await store.hasBlock(cid.bytes), true); + assert.equal(store.store.size > 300, true); } -function testIncrementalPush(protocol) { - return async ({ page }) => { - const success = await page.evaluate(async (protocol) => { - const store = new MemoryBlockStore(); - const wasmCid = await exampleFile(store, async (file) => { - const wasm = await (await fetch("./dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer(); - for (let i = 0; i < 5; i++) { - file.write(new Uint8Array(wasm)); - } - }); - await runCarMirrorPush(`${protocol}://localhost:3344/dag/push`, wasmCid.toString(), store); - return "success"; - }, protocol); - expect(success).toBe("success"); - - // and then push another time, this time more data, but sharing data with the previous push - const secondSuccess = await page.evaluate(async (protocol) => { - const store = new MemoryBlockStore(); - const wasmCid = await exampleFile(store, async (file) => { - const wasm = await (await fetch("./dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer(); - for (let i = 0; i < 10; i++) { - file.write(new Uint8Array(wasm)); - } - }); - await runCarMirrorPush(`${protocol}://localhost:3344/dag/push`, wasmCid.toString(), store); - return "success"; - }, protocol); - expect(secondSuccess).toBe("success"); - } +async function testIncrementalPush(protocol) { + const storeSmall = new MemoryBlockStore(); + const wasmCidSmall = await exampleFile(storeSmall, async (file) => { + const wasm = await (await fetch("./dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer(); + for (let i = 0; i < 5; i++) { + file.write(new Uint8Array(wasm)); + } + }); + await runCarMirrorPush(`${protocol}://localhost:3344/dag/push`, wasmCidSmall.toString(), storeSmall); + + // and then push another time, this time more data, but sharing data with the previous push + const storeBig = new MemoryBlockStore(); + const wasmCidBig = await exampleFile(storeBig, async (file) => { + const wasm = await (await fetch("./dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer(); + for (let i = 0; i < 10; i++) { + file.write(new Uint8Array(wasm)); + } + }); + await runCarMirrorPush(`${protocol}://localhost:3344/dag/push`, wasmCidBig.toString(), storeBig); } -function testPushThenPull(protocol) { - return async ({ page }) => { - const { hasRootBlock, totalBlocks } = await page.evaluate(async (protocol) => { - let store = new MemoryBlockStore(); - const wasmCid = await exampleFile(store, async (file) => { - const wasm = await (await fetch("./dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer(); - for (let i = 0; i < 5; i++) { - file.write(new Uint8Array(wasm)); - } - }); - await runCarMirrorPush(`${protocol}://localhost:3344/dag/push`, wasmCid.toString(), store); +async function testPushThenPull(protocol) { + let store = new MemoryBlockStore(); + const wasmCid = await exampleFile(store, async (file) => { + const wasm = await (await fetch("./dist/web/car_mirror_wasm_bg.wasm")).arrayBuffer(); + for (let i = 0; i < 5; i++) { + file.write(new Uint8Array(wasm)); + } + }); + await runCarMirrorPush(`${protocol}://localhost:3344/dag/push`, wasmCid.toString(), store); - // Clear the store - store = new MemoryBlockStore(); - await runCarMirrorPull(`${protocol}://localhost:3344/dag/pull`, wasmCid.toString(), store); + // Clear the store + store = new MemoryBlockStore(); + await runCarMirrorPull(`${protocol}://localhost:3344/dag/pull`, wasmCid.toString(), store); - return ({ - hasRootBlock: await store.hasBlock(wasmCid.bytes), - totalBlocks: store.store.size - }); - }, protocol); - expect(hasRootBlock).toBeTruthy(); - expect(totalBlocks).toBeGreaterThan(10); - } + assert.equal(await store.hasBlock(wasmCid.bytes), true); + assert.equal(store.store.size > 10, true); }