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

[Feature]: Allow browser API without browser (jsdom) #27424

Closed
GermanJablo opened this issue Oct 4, 2023 · 4 comments
Closed

[Feature]: Allow browser API without browser (jsdom) #27424

GermanJablo opened this issue Oct 4, 2023 · 4 comments

Comments

@GermanJablo
Copy link

GermanJablo commented Oct 4, 2023

From the documentation:

Under the hood

When Playwright Test is used to test web components, tests run in Node.js, while components run in the real browser. This brings together the best of both worlds: components run in the real browser environment, real clicks are triggered, real layout is executed, visual regression is possible. At the same time, test can use all the powers of Node.js as well as all the Playwright Test features. As a result, the same parallel, parametrized tests with the same post-mortem Tracing story are available during component testing.

This is somewhat different from testing library, which allows you to test a component using an end-user API, but without having to deploy a browser in each test.

While one can use testing library to test components in a simulated browser and Playwright in a real browser, it would be great if we could use the same API for both cases.

The simulated browser (jsdom) offers incredible speeds, while the real browser offers more confidence. By sharing the same API, depending on the level of trust you have in the tests, it would be trivial to change it from one environment to another. This would certainly be "the best of both worlds."

Clarification note: I understand that if one does not use Playwright fixtures, no browser is instantiated, and in theory it could be used with jsdom:

import { test } from "@playwright/test";
import { createRoot } from "react-dom/client";
import * as ReactTestUtils from "react-dom/test-utils";
import { JSDOM } from "jsdom";
import { MyComponent } from "./MyComponent";

test.beforeAll(() => {
  const { window } = new JSDOM();
  global.document = window.document;
  global.window = global.document.defaultView!;
  global.navigator = global.window.navigator;
});

test("test in jsdom()", async () => {
  ReactTestUtils.act(() => {
    createRoot(document.body).render(<MyComponent />);
  });
  const myComponent = document.body.firstChild;
  // ...
});

However, what I would like is to be able to test those components using APIs like page.keyboard or locator.click().

@denis-domanskii
Copy link

One of main issues in RTL for me is a lack of visualisation. It's much harder to debug tests when instead of rendered UI you see textual DOM description, especially when the component is big.

So, I want to join to @GermanJablo in this request and also want to add that if rendering of the component together with Playwright Inspector will be added to this feature, it could replace RTL for me.

@pavelfeldman
Copy link
Member

@GermanJablo, @denis-domanskii, I'm not sure you want the same thing here.

@GermanJablo: You seem to be interested in using page., page.locator. APIs against JSDOM. This would be a fairly large project on our side, starting with seeding the jsdom environment, all the way to implementing all the actions programmatically. It is unlikely that we sign up for this task given our real browser focus. We would be much more interested in improving the speed of your component test execution.

@denis-domanskii you seem to be interested in Playwright offering a drop-in-replacement for jsdom+rtl in a way that components are rendered and tested in the browser, so that you could see what is going on. I believe there are projects that do just that in the internet. Similarly, I don't think we'll sign up for such a resource-demanding task.

@GermanJablo
Copy link
Author

GermanJablo commented Oct 5, 2023

Maybe I shouldn't have mentioned page or locator in general. I perfectly understand how achieving that compatibility with jsdom would involve an immense task.

Let me narrow the scope of my suggestion to something much more modest:

Make user-event bindings with the Playwright API, so that a subset of the tests that can be done in playwright can be executed in jsdom.

The Playwright documentation has a cheatsheet of equivalences between the Playwright API and the RTL API.

Testing Library Playwright
await user.click(screen.getByText('Click me')) await component.getByText('Click me').click()
await user.type(screen.getByLabel('Password'), 'secret') await component.getByLabel('Password').fill('secret')

My idea is that if you decide to run a test in jsdom, bindings could be made to user-events.

This seems much more feasible since user-events is a small library with little surface API.

To be clear, with this reformulation of my suggestion I am not pretending that any Playwright test can run successfully in jsdom, but rather that any test that someone would do in testing library, they can do in Playwright using a single API.

@pavelfeldman
Copy link
Member

To be clear, with this reformulation of my suggestion I am not pretending that any Playwright test can run successfully in jsdom, but rather that any test that someone would do in testing library, they can do in Playwright using a single API

Yeah, that's how I understood it. And thinking that this is feasible would be a misconception sadly. Closing as outside of scope for Playwright.

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