Skip to content
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

Cannot query children in <Portal>s #62

Open
gBasil opened this issue May 12, 2024 · 6 comments
Open

Cannot query children in <Portal>s #62

gBasil opened this issue May 12, 2024 · 6 comments

Comments

@gBasil
Copy link

gBasil commented May 12, 2024

The query commands (getByRole, getByTestId, etc.) fail to pick up children of <Portal>s.


The children of <Portal>s get rendered in a separate <div> from the content of the render call. The various query commands seem to use the container element, which is the first <div>, and fail to pick up anything in a portal:

import { expect, test } from 'vitest';
import { render } from '@solidjs/testing-library';
import { Portal } from 'solid-js/web';

test('Portal test', () => {
  const { getByTestId, debug } = render(() => <>
    <p data-testid='one'>One</p>
    <Portal>
      <p data-testid='two'>Two</p>
    </Portal>
  </>);

  getByTestId('one'); // Succeeds
  getByTestId('two'); // Throws an error

  debug(); // Prints the following:
  /*
    <body>
      <div>
        <p data-testid="one">
          One
        </p>

      </div>
      <div>
        <p data-testid="two">
          Two
        </p>
      </div>
    </body>
  */
});

One workaround is to use the baseElement property with a query selector, i.e. baseElement.querySelector('[data-testid="two"]'). However, Solid Testing Library reuses the <body> between render()s:

test('aaa', () => {
  render(() => <p>test 1</p>);
  render(() => <p>test 2</p>);
  const res = render(() => <p>test 3</p>);

  res.debug(); // Prints out the following:
  /*
    <body>
      <div>
        <p>test 1</p>
      </div>
      <div>
        <p>test 2</p>
      </div>
      <div>
        <p>test 3</p>
      </div>
    </body>
  */
});

So, if you have two tests in one file, they will both be rendered in the same document, and so you'll likely run into issues when using baseElement.querySelector, as it might select elements from a different test.

@gBasil
Copy link
Author

gBasil commented May 12, 2024

When using Vitest, adding this to a file solves the duplication issue for it and allows you to use baseElement.querySelector safely:

import { afterEach } from 'vitest';
import { cleanup } from '@solidjs/testing-library';

afterEach(() => {
  cleanup();
});

However, this might break (I haven't tested it extensively) when rendering multiple times in one test(), as you'd have to call it manually in that case.

@atk
Copy link
Collaborator

atk commented May 12, 2024

You don't need to cleanup afterwards, this is already done automatically. However, unless you choose isolation: true in the testing config, tests might influence each other.

@gBasil
Copy link
Author

gBasil commented May 12, 2024

You don't need to cleanup afterwards, this is already done automatically.

I saw that in the docs somewhere, but it didn't seem to work properly, and I had to call it manually.

Also, I'd rather not incur the slowdown of isolating all tests, just the ones in a specific file.

@atk
Copy link
Collaborator

atk commented May 12, 2024

I don't want to encourage using isolation of tests at all costs, just explain the mechanism. Your issue might be timing- or error-related (tests could be cleaned up slightly delayed or may not be cleaned up after failure).

@artonio
Copy link

artonio commented May 19, 2024

it wont work with a Portal because when you use Portal it will render html attached to the body, you need to use:

document.body.querySelector('[data-testid="two"]');

PS: I had the same issue and Github Copilot Chat told me to do it this way

@atk
Copy link
Collaborator

atk commented May 20, 2024

Please use screen.get... accessible queries instead of CSS selectors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants