Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to test wasm-pack generated webassembly from a javascript context?

I have a rust + wasm project like this:

wasm-pack-example/
  pkg/
    .gitignore
    package.json
    wasm_pack_example.d.ts
    wasm_pack_example.js
    wasm_pack_example_bg.d.ts
    wasm_pack_example_bg.js
    wasm_pack_example_bg.wasm
  src/
    lib.rs
  Cargo.toml

The contents of pkg get built when I run wasm-pack build.

The emitted js files aren't simple pass-throughs of the public rust functions - wasm-pack adds some logic to them. It looks mostly like memory management wrappers over the public rust functions.

What I really want to do at this point in my project is to write automated tests against the js interface to the emitted wasm. This is what my app does, and this is what I need to test. I'm happy using any testing framework (I've been doing a lot of this experimentation with jest).

I've tried numerous guides and tools to do this, including https://github.com/DrSensor/rs-jest, which was promising, but lacks the ability to test the specific js interface produced by wasm-pack. Also, it seems to lack what's needed by my particular lib, perhaps in the particular way I'm using wasm_bindgen. When instantiating the WebAssembly according to rs-jest's, I'd see TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object, and if I passed an empty object to the instantiation, I'd see TypeError: WebAssembly.instantiate(): Import #0 module="__wbindgen_placeholder__" error: module is not an object or function.

I also tried for a while to simulate the particular way wasm might be fetched and instantiated by the browser using JsDom. I produced an index.html file that loaded the wasm-pack js files via a script tag, then I created a JsDom instance using that index.html file. It properly tried to fetch the wasm from an import in the js (which required me to add my own fetch implementation to the JsDom instance's window, serving back the wasm file from the filesystem), but then choked halfway down the js file because module.require is not a function. I was unable to make any progress past that.

Anyway, this is just to show that I haven't been able to find any solution for this. Has anybody out there been able to write automated tests against the js interfaces produced by wasm-pack?

like image 417
samgqroberts Avatar asked Jul 03 '26 21:07

samgqroberts


1 Answers

I'm in the same situation. I use wasm-pack and Jest, but not rs-jest. I just want to write Jest tests against the wasm-pack-generated JavaScript package.

I couldn't get my tests to work with Jest testEnvironment: "jsdom" and wasm-pack build: Jest would complain that it cannot find module 'foo_wasm' on import * as wasm from "foo_wasm";.

However, setting testEnvironment: "node" in jest.config.ts and running wasm-pack build --target nodejs worked for me!

However, I really do need --target bundler for my web app. So I run wasm-pack twice:

wasm-pack build --target bundler --out-dir pkg  # (the defaults)
wasm-pack build --target nodejs --out-dir pkg_node

Then in my package.json I point to the bundler/web bindings:

{
  "dependencies": {
    "foo_wasm": "file:../wasm/foo/pkg",
  }
}

And in jest.config.ts I override it with the node bindings:

export default {
  moduleNameMapper: {
    foo_wasm: "<rootDir>/../wasm/foo/pkg_node",
  },
};

Then in my tests I can just import * as wasm from "foo_wasm";.

See this wasm-pack issue which would add --target all so we wouldn't have to run wasm-pack twice.

like image 180
Lynn Avatar answered Jul 06 '26 09:07

Lynn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!