test-runner icon indicating copy to clipboard operation
test-runner copied to clipboard

[Bug] getStoryContext (globalThis) returns undefined

Open VickyKoblinski opened this issue 2 years ago • 7 comments

Describe the bug

storyContext is undefined

// test-runner.js
const { getStoryContext } = require("@storybook/test-runner");

module.exports = {
  async postRender(page, context) {
    const storyContext = await getStoryContext(page, context);
    console.log(storyContext) // undefined
    const globalThis = await page.evaluate(() => globalThis);
    console.log(globalThis) // undefined
  },
};

Steps to reproduce the behavior

Use the above file

Expected behavior

To be able to access the storyContext like here https://github.com/storybookjs/test-runner/blob/next/.storybook/test-runner.ts

Screenshots and/or logs

n/a

Environment

  • OS: mac
  • Node.js version: Tried both 14 and 16

Additional context

~I think the problem may be because default test-runner-jest.config.js is missing the globalSetup and globalTeardown operations that this repo is using.~ I was wrong about this, test-runner-jest.config.js does get the setup and teardown from getJestConfig.

Could this be because globalThis has been introduced in Jest 28 but we're still on Jest 27?

VickyKoblinski avatar Jul 08 '22 01:07 VickyKoblinski

It turned out that globalThis.__STORYBOOK_PREVIEW__.storyStore.loadStory({ storyId }) contained circular dependencies and Playwright doesn't allow you to return Js objects with circular dependencies, which is why I was getting undefined. I'm not sure where they came from, but I think this would be common. Here's my not-so-elegant solution:

    const storyContext = await page.evaluate(
      async ({ storyId }) => {
        const getCircularReplacer = () => {
          const seen = new WeakSet();
          return (key, value) => {
            if (typeof value === "object" && value !== null) {
              if (seen.has(value)) {
                return;
              }
              seen.add(value);
            }
            return value;
          };
        };

        return JSON.parse(
          JSON.stringify(
            await globalThis.__STORYBOOK_PREVIEW__.storyStore.loadStory({ storyId }),
            getCircularReplacer()
          )
        );
      },
      {
        storyId: context.id,
      }
    );

VickyKoblinski avatar Jul 08 '22 03:07 VickyKoblinski

Oh wow! That's new to me. Thanks a lot for sharing this @VickyKoblinski ! 🙌 I'll have to chew on this for a bit. cc @shilman

yannbf avatar Jul 08 '22 16:07 yannbf

Seeing the same issue, am not able to get this patch to work, @ndelangen any guidance here?

myufa avatar Jun 14 '23 19:06 myufa

have been getting page.evaluate: TypeError: Cannot read properties of undefined (reading 'storyStore') at getStoryContext (node_modules/@storybook/test-runner/dist/cjs/playwright/hooks.js:17:15)

myufa avatar Jun 14 '23 19:06 myufa

@myufa can you share a reproduction for us to take a look? thanks!

yannbf avatar Jun 17 '23 08:06 yannbf

Any update on this?, we're facing this too. Thank you.

MRamonLeon avatar Feb 20 '24 10:02 MRamonLeon

have been getting page.evaluate: TypeError: Cannot read properties of undefined (reading 'storyStore') at getStoryContext (node_modules/@storybook/test-runner/dist/cjs/playwright/hooks.js:17:15)

~~It was issue with my test runner previsiting about:blank instead. I could get around with the "undefined (reading 'storyStore')" with if (page.url() === 'about:blank') return;~~

~~but now I'm getting "Timed out waiting for Storybook to load after 10 seconds."~~

Sorry, it was caused by an issue with not implementing defaultPrepare in my custom prepare

zb-sj avatar Apr 22 '24 16:04 zb-sj