the official Swift WebAssembly book points us to carton for testing WebAssembly applications. but of course, that is severely out of date, as carton is now deprecated.
i don’t need to run a full in-browser integration test, all i really need is to be able to instantiate a few JSObject instances and pass them to the Swift WebAssembly component.
how should we test Swift WebAssembly applications today?
I honestly think that Carton's deprecation needs to be reëvaluated. The instructions that I was given (that I can't find now) to debug now are honestly, a pain, and I gave up on it. Carton's features need to be merged into the current solution.
Another thing that Carton did was add a randomized string to the name of the product so it would force the browser to re-download the wasm file due to convoluted caching policies. Now you have to do it yourself.
This page here https://www.swift.org/documentation/articles/wasm-getting-started.html should be updated with more examples on how to debug in the same way that Carton allowed.
The old way https://book.swiftwasm.org/getting-started/debugging.html was, in my opinion, perfect.
I think there's a misunderstanding here in the usage of carton and debugging workflows. These are pretty much orthogonal. This link you've provided is not "the old way". Workflow described there should work just as well with swift package js plugin. WRT debugging nothing changed or have been deprecated, as far as I'm aware.
Would you be able list the missing features here so that we're on the same page?
Other than in-browser testing (which is highly project-specific and there's no readily available workflow that would work for everyone I can recommend at this point), I'm not aware of anything else missing.
The page you've linked to is focused on command-line use cases, which is again orthogonal to carton, and as described above didn't have anything special for debugging in the first place. We do plan to write separate sections for the browser setup, but that needs careful planning, there's no one size that fits all here.
With Carton, it would automatically launch a web browser, and when errors or exception were thrown, you would see the output in the console and in Chrome. It had a HTTPS server which facilitated running the webpage as well as automatically rebuilding and refreshing when files changes. That saved hours and hours of debugging for me when that was introduced. Now that binaries can be nearly 50mb with the full unicode information in it, uploading each build to a server to run it is not a great way to debug, so having a built in HTTP server made running local builds more efficient. Some web browsers do not work well with the local filesystem (i.e file:///), some need special permissions, others won't link outside of file:/// loaded pages regardless. The built in HTTP server did the trick.
I am unaware that this is available with js. When I inquired about it, I was given different instructions -- which I couldn't find for this post. I think it would have provided better context as to why I gave up. It was probably something trivial that I was missing, but the old way was superior
What we are learning here is that a lot of these changes happen that I am unprepared for and the documentation is often outdated or incomplete. I build using Swift WASM almost every day, and have learned to be caution about going to newer versions because I know when something changes I have to hunt down help for that change. I had no choice but to move to 6.1 recently.
I think what could fix all of this is a blog post and an account of what is changing and how to get deprecated features in the new build with exact instructions for novice people. I know I am not novice, but sometimes, I just am confused.
I make sure to send money every month to the SwiftWasm project on github, would it help to get some of this documentation more up-to-date and precise if I upped that donation?
unlike @austintatious , i do not want to launch a web browser to run my test suite, what i want is to run the compiled wasm in a JavaScript environment (probably, a NodeJS runtime) such that it can decode its input data from a JSObject instance.
the lynchpin here is JSObject – i cannot meaningfully test the application without being able to pass it a data model encoded as a JSObject.
1 Like
What wasm environment supports JavaScript outside of a web browser?
Node.js, Deno, and Bun to name a few, but there of course many more out there, given a good amount of embeddable JavaScript runtimes that people may be using.
2 Likes
Is there a reason that npx serve as described in JavaScriptKit tutorials and examples is not suitable for your use case? There's no need to upload anything anywhere during development, the built-in local HTTP server in this command is just as good if not better than what carton could've provided.
Likewise, there are many watchers that can invoke and rebuild your project on modification. watchexec is one I've occasionally used in the past, but sure there are more out there that would fit your setup. Similarly, multiple extension in VS Code and other editors can integrate with a browser to refresh an open web page on a given command that you can add sequentially after a swift package js invocation, wrapped in something like watchexec.
The larger point is that we're focusing with JavaScriptKit specifically on JavaScript <-> Swift interop that only this library and its plugins can provide, instead of attempting a kitchen sink approach that carton had. Everything outside of that scope is served better by stable and advanced enough specialized commands that already exist (watchers, HTTP servers, page refreshers, bundlers, cache-busting renaming utilities), and can be customized for different projects and different environments.
3 Likes
I see. I have never heard of this command. I didn't know it was introduced. I go to the https://book.swiftwasm.org reference frequently but I am unaware of a place where these features or changes are announced.
When I went just now to JavaScript interoperation - Swift and WebAssembly, there are two links
(1) JavaScriptKit consists of a runtime library package hosted on npm the link https://www.npmjs.com/package/javascript-kit-swift leads to a page that says:
This package has been deprecated
Author message:
Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
On that page carton is mentioned frequently. So I just assume it doth not apply.
(2) A link that says You can get more documentation here that leads to https://swiftwasm.github.io/JavaScriptKit/ which is a 404 not found page.
Simply, I just am not aware of these features. Almost everything on book.swiftwasm.org references carton.
Looking at https://www.swift.org/documentation/articles/wasm-getting-started.html I don't see a link to tutorials.
I found the Example projects in the JavaScriptKit, but not examples of how to use npx serve. You're calling them Tutorials, so I assume those are somewhere, but I don't know where. I totally believe that they exist and I know y'all have done a great job, it's just that I am only discovering this here and it's not for lack of trying to find the information.
I truly felt like a lot was just being abandoned and overlooked.
I apologize if this feels like complaining, I know there are only a few people working on this stuff and for Free so we are just lucky that we get what we have. I am hoping that this feedback feels friendly. I know it can be frustrating when someone says they can't find things, but you can. So I hope I am not presenting like that.
i find working with Swift WebAssembly frustrating, and i often feel like there is little to no up-to-date guidance on how to do many useful things at the project scale, like run a WebAssembly binary in a NodeJS environment for testing purposes.
LLMs are next to useless as an educational/development aid, because they are only as good as their training data, and they were never trained to work with Swift WebAssembly.
a few months ago, an LLM gave me this test harness, which recently stopped working as of a few JavaScriptKit releases ago.
import {
instantiate,
InstantiateOptions
} from '../.build.wasm/plugins/PackageToJS/outputs/Package/instantiate.js';
import {
defaultNodeSetup
} from '../.build.wasm/plugins/PackageToJS/outputs/Package/platforms/node.js';
const options: InstantiateOptions = await defaultNodeSetup({});
await instantiate(options);
the error it gives me now, is Argument of type '{}' is not assignable to parameter of type 'DefaultNodeSetupOptions'. Property 'spawnWorker' is missing in type '{}' but required in type 'DefaultNodeSetupOptions'.
i tried asking the LLM to fix it for me, but gave me several pages of elaborate shims that did not give me confidence that the LLM understood the workings of Swift WebAssembly.
as a human who can occasionally pass a turing test, i suspect the lego bricks snap together like this:
const options: InstantiateOptions = await defaultNodeSetup(
{
spawnWorker: createDefaultWorkerFactory()
}
);
am i on the right track?
1 Like
I realize this is not a timely response, but does this new testing guide in JavaScriptKit docs cover your use cases?
2 Likes
no worries, late response is better than no response!
i’ll take a look tonight, thank you!
1 Like
I added a short explanation for how to instantiate Swift code on Node.js:
https://swiftpackageindex.com/swiftwasm/javascriptkit/main/documentation/javascriptkit/package-output-structure#In-Nodejs
Let me know if there is any missing information 
3 Likes
i gave this a try today (still using 6.1-RELEASE-wasm32-unknown-wasip1-threads unfortunately due to [6.2] Global Concurrency executor hook seems not working · Issue #450 · swiftwasm/JavaScriptKit · GitHub ), and ran into an error importing the Testing module:
IntegrationTests.swift:5:8: error: no such module 'Testing'
4 | import JavaScriptKit
5 | import Testing
| `- error: no such module 'Testing'
test target is defined like this:
.testTarget(
name: "IntegrationTests",
dependencies: [
.target(name: "ApplicationEngine"),
.product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
.product(name: "JavaScriptEventLoopTestSupport", package: "JavaScriptKit"),
],
),
i noticed that there is a conditional import in the official example: JavaScriptKit/Examples/Testing/Tests/CounterTests/CounterTests.swift at main · swiftwasm/JavaScriptKit · GitHub
does this mean Swift Testing is not supported, and XCTest must be used instead?
swift-testing is not supported in Swift SDKs for wasip1-threads before 6.2. It should be available after 6.2.
1 Like