-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Adding web client testing framework (#498)
* test: Adding web client testing framework
- Loading branch information
1 parent
8853be0
commit 6bb3930
Showing
14 changed files
with
2,249 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"require": ["ts-node/register", "esm"], | ||
"extension": ["ts"], | ||
"spec": "test/**/*.test.ts", | ||
"timeout": 600000 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
export { | ||
WebClient, | ||
NewTransactionResult, | ||
SerializedAccountStub, | ||
NewSwapTransactionResult | ||
WebClient, | ||
NewTransactionResult, | ||
SerializedAccountStub, | ||
NewSwapTransactionResult, | ||
} from "./crates/miden_client"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Testing | ||
|
||
The .wasm must be run within the context of a webpage. To this end, we've set up a Mocha | ||
test suite which hosts the .wasm on a local server and then executes WebClient commands | ||
within the context of the web page. | ||
|
||
## Prerequisites | ||
|
||
1. [Node](https://nodejs.org/en/download/package-manager) | ||
- Node Version >= v20.16.0 | ||
1. These instructions utilize [yarn](https://classic.yarnpkg.com/lang/en/docs/install) but can also be executed with npm | ||
|
||
## Running tests | ||
|
||
1. Install dependencies via `yarn` | ||
1. Ensure the .wasm is built by running `yarn build` | ||
1. In crates/web-client run `yarn test` to run all tests | ||
|
||
- Can alternatively run `yarn test:clean` to run the .wasm build process prior to testing. We provide both paths as the build process can take some time. | ||
|
||
1. For running an individual test by name run `yarn test -g <test-name>` | ||
1. To enable logging from the client to the terminal, run `yarn test:logs` | ||
|
||
## Writing tests | ||
|
||
1. The test setup in `mocha.global.setup.mjs` should expose the `create_client` function which can be used inside tests. | ||
- Any further setup of wasm code should be done in this file and similarly expose a function for testing here | ||
1. `webClientTestUtils.js` should contain all interfaces for interacting with the web client. If further methods need to be added, follow existing patterns which use the exposed `testingPage` and pass through any required arguments to the page execution. Example: | ||
|
||
``` | ||
/** | ||
* | ||
* @param {string} arg1 | ||
* @param {boolean} arg2 | ||
* | ||
* @returns {Promise<string>} The result | ||
*/ | ||
export const webClientCall = async (arg1, arg2) => { | ||
return await testingPage.evaluate( | ||
async (_arg1, _arg2) => { | ||
if (!window.client) { | ||
await window.create_client(); | ||
} | ||
/** @type {WebClient} */ | ||
const client = window.client; | ||
const result = client.webClientCall(_arg1, _arg2); | ||
return result; | ||
}, | ||
arg1, | ||
arg2 | ||
); | ||
}; | ||
``` | ||
|
||
- Add JSDocs to methods. This will allow typing in the `*.test.ts` files. | ||
- We add the `if (!window.client)` to avoid spinning up clients unnecessarily lengthening test time. This unfortunately cannot be pulled out to a helper method as the testingPage scope does not share the scope of the file. | ||
- Similarly, the boilerplate for passing args through as shown above is necessary due to scoping. | ||
|
||
## Debugging | ||
|
||
1. When inside of a `page.evaluate` , console logs are being sent to the servers console rather than your IDE's. You can uncomment the line as seen below in the `mocha.global.setup.mjs`: | ||
|
||
``` | ||
page.on("console", (msg) => console.log("PAGE LOG:", msg.text())); | ||
``` | ||
|
||
This will forward logs from the server to your terminal logs | ||
|
||
## Troubleshooting | ||
|
||
1. When trying to run the tests, if you receieve the following error: | ||
|
||
``` | ||
Error: Could not find Chrome (ver. 128.0.6613.119). This can occur if either | ||
1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install ${browserType}`) or | ||
2. your cache path is incorrectly configured (which is: /Users/ignacioamigo/.cache/puppeteer). | ||
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration. | ||
``` | ||
|
||
Try running: `npx puppeteer browsers install` and then run the tests again |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { createNewFaucet, isValidAddress } from "./webClientTestUtils.js"; | ||
|
||
describe("faucet tests", () => { | ||
it("create a new faucet", async () => { | ||
const result = await createNewFaucet( | ||
"OffChain", | ||
false, | ||
"DMX", | ||
"10", | ||
"1000000" | ||
); | ||
|
||
isValidAddress(result); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { Page } from "puppeteer"; | ||
|
||
declare module "./mocha.global.setup.mjs" { | ||
export const testingPage: Page; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import puppeteer from "puppeteer"; | ||
import { spawn } from "child_process"; | ||
|
||
import { register } from "ts-node"; | ||
import { env } from "process"; | ||
|
||
register({ | ||
project: "./tsconfig.json", | ||
}); | ||
|
||
let serverProcess; | ||
let browser; | ||
let testingPage; | ||
|
||
const TEST_SERVER_PORT = 8080; | ||
const TEST_SERVER = `http://localhost:${TEST_SERVER_PORT}`; | ||
|
||
// Should be in sync with the rpc port in tests/config/miden-node.toml | ||
const LOCAL_MIDEN_NODE_PORT = 57291; | ||
|
||
before(async () => { | ||
console.log("Starting test server..."); | ||
serverProcess = spawn("http-server", ["./dist", "-p", TEST_SERVER_PORT], { | ||
stdio: "inherit", | ||
}); | ||
|
||
browser = await puppeteer.launch({ headless: true }); | ||
testingPage = await browser.newPage(); | ||
await testingPage.goto(TEST_SERVER); | ||
|
||
if (env.DEBUG_MODE) { | ||
testingPage.on("console", (msg) => console.log("PAGE LOG:", msg.text())); | ||
} | ||
|
||
// Creates the client in the test context and attach to window object | ||
await testingPage.exposeFunction("create_client", async () => { | ||
await testingPage.evaluate(async (port) => { | ||
const { WebClient } = await import("./index.js"); | ||
let rpc_url = `http://localhost:${port}`; | ||
const client = new WebClient(); | ||
await client.create_client(rpc_url); | ||
|
||
window.client = client; | ||
}, LOCAL_MIDEN_NODE_PORT); | ||
}); | ||
}); | ||
|
||
after(async () => { | ||
console.log("Stopping test server..."); | ||
|
||
console.log("Closing browser..."); | ||
await browser.close(); | ||
console.log("Browser closed."); | ||
|
||
console.log("Beginning server process cleanup..."); | ||
if (serverProcess && !serverProcess.killed) { | ||
console.log("Killing server process..."); | ||
serverProcess.kill("SIGTERM"); // Send the SIGTERM signal to terminate the server | ||
} | ||
|
||
console.log("Waiting for server process to exit..."); | ||
await new Promise((resolve, reject) => { | ||
if (serverProcess.exitCode !== null) { | ||
// Process has already exited, resolve immediately | ||
console.log( | ||
`Server process had already exited with code ${serverProcess.exitCode}` | ||
); | ||
return resolve(); | ||
} | ||
|
||
serverProcess.on("close", (code) => { | ||
console.log(`Server process exited with code ${code}`); | ||
resolve(); | ||
}); | ||
|
||
serverProcess.on("error", (error) => { | ||
console.error("Error killing server process:", error); | ||
reject(error); | ||
}); | ||
}); | ||
|
||
console.log("Test server stopped."); | ||
}); | ||
|
||
export { testingPage }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { createNewWallet, isValidAddress } from "./webClientTestUtils.js"; | ||
|
||
describe("wallet tests", () => { | ||
it("create a new wallet", async () => { | ||
const result = await createNewWallet("OffChain", false); | ||
|
||
isValidAddress(result); | ||
}); | ||
}); |
Oops, something went wrong.