Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: [tests] within(canvasElement) cannot find elements rendered via portal to the document.body #26963

Closed
csantos1113 opened this issue Apr 26, 2024 · 6 comments

Comments

@csantos1113
Copy link

csantos1113 commented Apr 26, 2024

Describe the bug

https://github.com/storybookjs/storybook/tree/next/code/lib/test says I should be using within(canvasElement) in my play functions, instead of screen. but it doesn't work for portal elements rendered to the document.body

To Reproduce

System

Storybook Environment Info:

  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm <----- active
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    @storybook/addon-essentials: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/addon-interactions: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/addon-links: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/addon-onboarding: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/addon-webpack5-compiler-swc: ^1.0.2 => 1.0.2 
    @storybook/blocks: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/react: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/react-webpack5: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    @storybook/test: ^8.1.0-alpha.7 => 8.1.0-alpha.7 
    storybook: ^8.1.0-alpha.7 => 8.1.0-alpha.7 

Additional context

Real live case: I'm opening a Dialog/Drawer which is rendered via portals.

Any recommendation on how to reach elements rendered via portals to the document.body that adheres to the expected behavior defined by Storybook?

@valentinpalkovic
Copy link
Contributor

Instead of within(canvasElement) you could use within(canvasElement.parentNode) to target the body and therefore to assert your dialog.

@csantos1113
Copy link
Author

csantos1113 commented Apr 29, 2024

Instead of within(canvasElement) you could use within(canvasElement.parentNode) to target the body and therefore to assert your dialog.

Thanks for the response, but TypeScript doesn't seem to like it :(

image

UPDATE: ah, I'm using storybook 7.6.17 locally, which seems to have the type issue

And also, in 8.x I need to do within(canvasElement.parentElement) instead

@csantos1113
Copy link
Author

I actually seems my types issue are not related to Storybook version. when I use canvastElement.parentElement I get HTMLElement | null. But not sure where those wrong types are coming from.

I'm using:

    "typescript": "5.4.2",
    "@types/react": "17.0.50",
    "@types/react-dom": "17.0.17",

@csantos1113
Copy link
Author

UPDATE:

@valentinpalkovic - Okay, I'm not sure where did I get that other stackblitz example from; but here is an up-to-date as of today: https://stackblitz.com/edit/github-yrt7dh?file=src%2Fstories%2FPage.stories.ts&preset=node

Which is failing the same TypeScript error I'm experiencing locally

image

@przemyslaw-wlodek
Copy link

@csantos1113 the error isn't coming from any of the libraries you mentioned but from the nature of DOM being untyped. TypeScript can't guarantee that your HTMLElement (canvasElement) has a parentNode.

I see 2 possible options here:

  1. Quick and a little bit dirty non-null type assertion (within(canvasElement.parentNode!)) since it's only test + you are sure that there's always some body above your element.
  2. Create a custom Page decorator that renders the element that could be used as a portal container (it will be a part of canvas then). When you have a ref to your custom portal container, then you can easily pass it to your Portal component (which defaults to document.body).

I had a very similar problem when testing Radix components that use portals. You may find some inspiration in this PR.

@valentinpalkovic
Copy link
Contributor

I will close this issue since a solution was provided and the Typescript issue was elaborated above

@storybookjs storybookjs locked and limited conversation to collaborators May 4, 2024
@valentinpalkovic valentinpalkovic converted this issue into discussion #27024 May 4, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

3 participants