Error when running Worker instance in e2e jest test with yarn PnP

Hello,
I’m facing an error when trying to create a Worker in my jest test like so:

import { TestWorkflowEnvironment } from '@temporalio/testing';
import { Worker, Runtime, DefaultLogger, LogEntry } from '@temporalio/worker';
import { v4 as uuid4 } from 'uuid';
import { httpWorkflow } from './workflows';
import { WorkflowCoverage } from '@temporalio/nyc-test-coverage';

let testEnv: TestWorkflowEnvironment;

const workflowCoverage = new WorkflowCoverage();

beforeAll(async () => {
  // Use console.log instead of console.error to avoid red output
  // Filter INFO log messages for clearer test output
  Runtime.install({
    logger: new DefaultLogger('WARN', (entry: LogEntry) => console.log(`[${entry.level}]`, entry.message)),
  });

  testEnv = await TestWorkflowEnvironment.createTimeSkipping();
});

afterAll(async () => {
  await testEnv?.teardown();
});

afterAll(() => {
  workflowCoverage.mergeIntoGlobalCoverage();
});

test('httpWorkflow with mock activity', async () => {
  const { client, nativeConnection } = testEnv;
  const worker = await Worker.create(
    workflowCoverage.augmentWorkerOptions({
      connection: nativeConnection,
      taskQueue: 'test',
      workflowsPath: require.resolve('./workflows'),
      activities: {
        makeHTTPRequest: async () => '99',
      },
    })
  );

  await worker.runUntil(async () => {
    const result = await client.workflow.execute(httpWorkflow, {
      workflowId: uuid4(),
      taskQueue: 'test',
    });
    expect(result).toEqual('The answer is 99');
  });
});

The stack trace I get is:

console.error
Error: Cannot find module 'pnpapi' from '/.yarn/berry/cache/enhanced-resolve-npm-5.15.0-16eb7ddef9-10c0.zip/node_modules/enhanced-resolve/lib'

Require stack:
  .yarn/berry/cache/enhanced-resolve-npm-5.15.0-16eb7ddef9-10c0.zip/node_modules/enhanced-resolve/lib/index.js
  .yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/CacheFacade.js
  .yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/Compiler.js
  .yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/webpack.js
  .yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/index.js
  .yarn/berry/cache/@temporalio-worker-npm-1.8.6-908efba78e-10c0.zip/node_modules/@temporalio/worker/lib/workflow/bundler.js
  .yarn/berry/cache/@temporalio-worker-npm-1.8.6-908efba78e-10c0.zip/node_modules/@temporalio/worker/lib/worker-options.js
  .yarn/berry/cache/@temporalio-worker-npm-1.8.6-908efba78e-10c0.zip/node_modules/@temporalio/worker/lib/worker.js
  .yarn/berry/cache/@temporalio-worker-npm-1.8.6-908efba78e-10c0.zip/node_modules/@temporalio/worker/lib/debug-replayer/index.js
  .yarn/berry/cache/@temporalio-worker-npm-1.8.6-908efba78e-10c0.zip/node_modules/@temporalio/worker/lib/index.js
  .yarn/berry/cache/@temporalio-testing-npm-1.8.6-0a367472e0-10c0.zip/node_modules/@temporalio/testing/lib/index.js
  tests/src/web/temporal/e2e/denseReconstruction.test.ts

    at resolveSync (.yarn/berry/cache/resolve-patch-61fc5136ce-10c0.zip/node_modules/resolve/lib/sync.js:111:15)
    at defaultResolver (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/defaultResolver.js:118:38)
    at Function.findNodeModule (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:159:14)
    at resolveNodeModule (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:244:23)
    at Resolver.resolveModuleFromDirIfExists (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:256:16)
    at Resolver.resolveModule (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:352:12)
    at Resolver._getVirtualMockPath (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:619:14)
    at Resolver._getAbsolutePath (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:587:14)
    at Resolver.getModuleID (.yarn/berry/cache/jest-resolve-npm-29.7.0-5c36f0eefb-10c0.zip/node_modules/jest-resolve/build/resolver.js:530:31)
    at Runtime._shouldMockCjs (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1713:37)
    at Runtime.requireModuleOrMock (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1045:16)
    at processPnpApiOption (.yarn/berry/cache/enhanced-resolve-npm-5.15.0-16eb7ddef9-10c0.zip/node_modules/enhanced-resolve/lib/ResolverFactory.js:129:10)
    at createOptions (.yarn/berry/cache/enhanced-resolve-npm-5.15.0-16eb7ddef9-10c0.zip/node_modules/enhanced-resolve/lib/ResolverFactory.js:244:11)
    at Object.<anonymous>.exports.createResolver (.yarn/berry/cache/enhanced-resolve-npm-5.15.0-16eb7ddef9-10c0.zip/node_modules/enhanced-resolve/lib/ResolverFactory.js:259:28)
    at Object.<anonymous> (.yarn/berry/cache/enhanced-resolve-npm-5.15.0-16eb7ddef9-10c0.zip/node_modules/enhanced-resolve/lib/index.js:39:39)
    at Runtime._execModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1439:24)
    at Runtime._loadModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1022:12)
    at Runtime.requireModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:882:12)
    at Runtime.requireModuleOrMock (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1048:21)
    at Object.<anonymous> (Documents/Projects/roheboam/roheboam.backend/.yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/CacheFacade.js:8:25)
    at Runtime._execModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1439:24)
    at Runtime._loadModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1022:12)
    at Runtime.requireModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:882:12)
    at Runtime.requireModuleOrMock (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1048:21)
    at Object.<anonymous> (Documents/Projects/roheboam/roheboam.backend/.yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/Compiler.js:19:21)
    at Runtime._execModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1439:24)
    at Runtime._loadModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1022:12)
    at Runtime.requireModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:882:12)
    at Runtime.requireModuleOrMock (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1048:21)
    at Object.<anonymous> (Documents/Projects/roheboam/roheboam.backend/.yarn/__virtual__/webpack-virtual-baf906f249/5/.yarn/berry/cache/webpack-npm-5.89.0-3800e9efd0-10c0.zip/node_modules/webpack/lib/webpack.js:11:18)
    at Runtime._execModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1439:24)
    at Runtime._loadModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1022:12)
    at Runtime.requireModule (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:882:12)
    at Runtime.requireModuleOrMock (.yarn/berry/cache/jest-runtime-npm-29.7.0-120fa64128-10c0.zip/node_modules/jest-runtime/build/index.js:1048:21)

Though I don’t get the issue when I start the Worker directly outside of jest (i.e. when I run the worker instances through ts-node ./src/startWorker.ts)

I’m using “yarn@4.0.2” and my tsconfig is:

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  globalSetup: './tests/setup/globalSetup.ts'
};

I think you are hitting a known issue involving Yarn PnP + Jest + Webpack’s enhanced-resolved package.

There are some scenarios in which pnpapi is not currently resolvable (e.g. Cannot find module 'pnpapi'). This happens when using jest to execute tests that make use of webpack.

See the following tickets from enhanced-resolve’s GitHub repo for some context:

The TS SDK internally uses Webpack to bundle Workflow code so that it can be correctly loaded in the Workflow sandboxed environment. I don’t think there is anything that can be done from the SDK’s side to avoid this issue, but you may want to try modifying the Webpack configuration using WorkerOptions.bundlerOptions.webpackConfigHook (see docs).

You can most probably avoid this error by using a different test engine (there are several known issues related to using Jest to test Temporal Workflows), or by disabling Yarn’s PnP.

Alternatively, you may want to modify your testing process to bundle your Workflow code before executing Jest, using bundleWorkflowCode() (docs).

1 Like

Thanks! Solved this but using YarnV1 instead!