diff --git a/test/__mocks__/node-polyfill-web-streams.js b/test/__mocks__/node-polyfill-web-streams.js new file mode 100644 index 000000000000..6f8b0246a2b2 --- /dev/null +++ b/test/__mocks__/node-polyfill-web-streams.js @@ -0,0 +1,21 @@ +// Use CJS format for represent next/dist/compiled/node-polyfill-web-streams.js + +const { + WritableStreamDefaultWriter, + ReadableStream, + TransformStream, +} = require('next/dist/compiled/web-streams-polyfill') + +const OriginWritableStreamWrite = WritableStreamDefaultWriter.prototype.write + +// Override writable stream write method to validate chunk type. +// Currently CF workers only allow to write the encoded chunk in Uint8Array format. +WritableStreamDefaultWriter.prototype.write = (chunk) => { + if (!(chunk instanceof Uint8Array)) { + throw new Error('Writing non Uint8Array chunk in streaming is not allowed') + } + OriginWritableStreamWrite(chunk) +} + +global.ReadableStream = ReadableStream +global.TransformStream = TransformStream diff --git a/test/lib/mocks-require-hook.js b/test/lib/mocks-require-hook.js new file mode 100644 index 000000000000..6bf9f8229814 --- /dev/null +++ b/test/lib/mocks-require-hook.js @@ -0,0 +1,24 @@ +const mod = require('module') + +const hookPropertyMap = new Map([ + [ + /node-polyfill-web-streams/, + require.resolve('../__mocks__/node-polyfill-web-streams.js'), + ], +]) + +function matchModule(request) { + for (const [key, value] of hookPropertyMap) { + if (key.test(request)) { + return value + } + } + return null +} + +const resolveFilename = mod._resolveFilename +mod._resolveFilename = function (request, parent, isMain, options) { + const hookResolved = matchModule(request) // hookPropertyMap.get(request) + if (hookResolved) request = hookResolved + return resolveFilename.call(mod, request, parent, isMain, options) +} diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index a33c5970a128..589dd66b6899 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -31,7 +31,13 @@ export function initNextServerScript( return new Promise((resolve, reject) => { const instance = spawn( 'node', - [...((opts && opts.nodeArgs) || []), '--no-deprecation', scriptPath], + [ + ...((opts && opts.nodeArgs) || []), + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + scriptPath, + ], { env, cwd: opts && opts.cwd, @@ -147,7 +153,14 @@ export function runNextCommand(argv, options = {}) { console.log(`Running command "next ${argv.join(' ')}"`) const instance = spawn( 'node', - [...(options.nodeArgs || []), '--no-deprecation', nextBin, ...argv], + [ + ...(options.nodeArgs || []), + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + nextBin, + ...argv, + ], { ...options.spawnOptions, cwd, @@ -237,7 +250,14 @@ export function runNextCommandDev(argv, stdOut, opts = {}) { return new Promise((resolve, reject) => { const instance = spawn( 'node', - [...nodeArgs, '--no-deprecation', nextBin, ...argv], + [ + ...nodeArgs, + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + nextBin, + ...argv, + ], { cwd, env,