import { isNextDev, nextTestSetup } from 'e2e-utils' describe('node-worker-threads', () => { const { next, skipped, isTurbopack } = nextTestSetup({ files: __dirname, skipDeployment: true, dependencies: { pino: '9.6.0', }, }) if (skipped) { return } // These tests are Turbopack-specific since they rely on Turbopack's worker bundling if (!isTurbopack) { it.skip('webpack doesnt support bundling worker-threads', () => {}) return } it('should handle simple worker with relative path', async () => { const res = await next.fetch('/api/simple-worker-test') const data = await res.json() expect(res.status).toBe(200) expect(data.success).toBe(true) expect(data.message).toBe('pong from simple worker') }) it('should handle self-referencing worker with __filename', async () => { const res = await next.fetch('/api/worker-test') const data = await res.json() expect(res.status).toBe(200) expect(data.success).toBe(true) expect(data.message).toBe('pong') }) it('should handle pino logger with transport (thread-stream)', async () => { // Pino with transports uses thread-stream internally, which creates worker_threads // with a broad pattern like join(__dirname, 'lib', 'worker.js') that can match // non-evaluatable files like package.json. This tests that we properly downgrade // those errors to warnings via loose_errors. const res = await next.fetch('/api/pino-test') const data = await res.json() expect(res.status).toBe(200) expect(data.success).toBe(true) }) it('should not expose __turbopack internal workerData to user code', async () => { // Verify that internal __turbopack_globals__ data used to forward globals // is not visible to user code accessing workerData const res = await next.fetch('/api/workerdata-check') const data = await res.json() expect(res.status).toBe(200) expect(data.success).toBe(true) // The __turbopack_globals__ key should NOT be visible to user code expect(data.hasTurbopackKeys).toBe(false) expect(data.turbopackKeys).toEqual([]) }) it('should handle PNG file import in worker', async () => { // Test that static assets (like PNG images) can be imported and used in workers // The server worker returns the PNG URL, then we fetch it from the client // to verify the URL is correctly formed and accessible const res = await next.fetch('/api/png-worker-test') const data = await res.json() expect(res.status).toBe(200) expect(data.success).toBe(true) expect(data.pngInfo).toBeDefined() expect(data.pngInfo.width).toBe(1) expect(data.pngInfo.height).toBe(1) const url = new URL(data.pngInfo.url, 'http://localhost') expect(url.pathname).toMatch( /\/_next\/static.*\/test-image\.[a-f0-9]+\.png/ ) if (!isNextDev) { expect(next.assetToken).toMatch(/.+/) expect(url.searchParams.get('dpl')).toBe(next.assetToken) } // Now fetch the PNG URL from the client to verify it's accessible // This tests that the URL generated by the server worker is correct const pngRes = await next.fetch(data.pngInfo.url) expect(pngRes.status).toBe(200) expect(pngRes.headers.get('content-type')).toBe('image/png') }) })