Executing mockttp remotes from a Cypress test suite broken since [email protected] #188
Description
Since [email protected]
the package cannot successfully load and execute getRemote()
in any Cypress test out of the box. The error seems to arise from the (incorrect?) export configuration of brotli-wasm
which was a new dependency since 2.0.0
.
This is a real shame as the mockttp design is exactly what's needed to work around the limitation that Cypress tests all execute within a browser context, so if you want to control mocks, mockttp remoting is a perfect solution.
Is it still possible to run mockttp in a browser with a typical bundling process (I assume that cypress has a mainstream bundling process that we can consider canonical) ?
Is there any obvious workaround to prevent brotli-wasm
bundling issues being fatal for all Cypress tests?
Repro
I started to investigate by forking the the original cypress+mockttp working reference from @mvasin from 2020 linked at #35 (comment)
You can see my fork at https://github.com/cefn/cypress-mockttp/tree/283ce5e2facf0c166907c4abb0ca7cd9df7bf072
In my fork I upgraded all dependencies except mockttp to get it to function in modern Chrome and Cypress, then I upgraded to latest [email protected]
which remained functional.
However, upgrading to [email protected]
or mockttp@latest
were both failures. I know there are API changes needed also to align with latest mockttp, but this failure is profound and immediate to do with the fact the newer mockttp
includes elements which can't be bundled for the browser at all, so we never get that far. Aligning with the new API makes no difference.
Instructions
You can prove the repro runs correctly in 1.x.x
by running...
yarn
yarn cy
...then clicking on the Cypress E2E Testing button that appears, then click on Start E2E Testing in Chrome
in the next screen choose the example dummy.spec.ts
in the eventually-loaded Chrome instance. It correctly shows expected this is a mocked response to equal this is a mocked response
.
After proving that it's functional with [email protected]
you can recreate the error within the project by running...
yarn add [email protected]; DEBUG=cypress:* yarn cy
...or...
yarn add mockttp@latest; DEBUG=cypress:* yarn cy
The failure presents in the UI like this...
Looking at debug logs the issue shows more detail about the module load failure which fingers loading brotli-wasm
as the cause.
[
{
moduleIdentifier:
"/Users/myuser/workspace/github/cypress-mockttp/node_modules/brotli-wasm/pkg.bundler/brotli_wasm_bg.wasm",
moduleName: "./node_modules/brotli-wasm/pkg.bundler/brotli_wasm_bg.wasm",
loc: "1:0",
message:
"Module parse failed: Unexpected character '\x00' (1:0)\n" +
"The module seem to be a WebAssembly module, but module is not flagged as WebAssembly module for webpack.\n" +
"BREAKING CHANGE: Since webpack 5 WebAssembly is not enabled by default and flagged as experimental feature.\n" +
"You need to enable one of the WebAssembly experiments via 'experiments.asyncWebAssembly: true' (based on async modules) or 'experiments.syncWebAssembly: true' (like webpack 4, deprecated).\n" +
`For files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: "webassembly/async"').\n` +
"(Source code omitted for this binary file)",
moduleId: "./node_modules/brotli-wasm/pkg.bundler/brotli_wasm_bg.wasm",
moduleTrace: [[Object], [Object], [Object], [Object], [Object], [Object]],
details: undefined,
stack:
"ModuleParseError: Module parse failed: Unexpected character '\x00' (1:0)\n" +
"The module seem to be a WebAssembly module, but module is not flagged as WebAssembly module for webpack.\n" +
"BREAKING CHANGE: Since webpack 5 WebAssembly is not enabled by default and flagged as experimental feature.\n" +
"You need to enable one of the WebAssembly experiments via 'experiments.asyncWebAssembly: true' (based on async modules) or 'experiments.syncWebAssembly: true' (like webpack 4, deprecated).\n" +
`For files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: "webassembly/async"').\n` +
"(Source code omitted for this binary file)\n" +
" at handleParseError (/Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/webpack/lib/NormalModule.js:982:19)\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/webpack/lib/NormalModule.js:1101:5\n" +
" at processResult (/Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/webpack/lib/NormalModule.js:806:11)\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/webpack/lib/NormalModule.js:866:5\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/loader-runner/lib/LoaderRunner.js:407:3\n" +
" at iterateNormalLoaders (/Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/loader-runner/lib/LoaderRunner.js:233:10)\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/loader-runner/lib/LoaderRunner.js:224:4\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/webpack/lib/NormalModule.js:840:15\n" +
" at Array.eval (eval at create (/Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:12:1)\n" +
" at runCallbacks (/Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:45:15)\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:279:5\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/node_modules/graceful-fs/graceful-fs.js:123:16\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/packages/server/node_modules/graceful-fs/graceful-fs.js:123:16\n" +
" at /Users/myuser/Library/Caches/Cypress/14.1.0/Cypress.app/Contents/Resources/app/packages/server/node_modules/graceful-fs/graceful-fs.js:123:16\n" +
" at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read/context:68:3)",
},
];