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] Simultaneous React/Vue/Svelte component testing #14516

Closed
thecrypticace opened this issue May 31, 2022 · 2 comments
Closed

[Feature] Simultaneous React/Vue/Svelte component testing #14516

thecrypticace opened this issue May 31, 2022 · 2 comments

Comments

@thecrypticace
Copy link

thecrypticace commented May 31, 2022

Hi! I'm one of the people working on Headless UI at Tailwind Labs and am investigating using Playwright Component Testing to make our test suite more robust. And, for real, thank you for this feature — it's so cool! 💯

For a bit of background, Headless UI is a component library with a focus on accessibility and customization and works with Vue and React. We're investigating using Playwright to test Headless UI so we can be more confident in our tests and make them more robust. Our current test suite uses JSDOM but it's not ideal because there can be significant behavioral differences between actual browsers and JSDOM — especially when it comes to event handling. We have a WIP version of a setup using Playwright Component Testing located here. Our current focus is to attempt to match the test code to our JSDOM implementation as much as possible to ease migration. We'll likely write the tests to be a bit more idiomatic w/ regards to usage of the expect() API in the future.

We've run into some interesting limitations of the current setup that assumes that only one of the React or Vue component testing plugins are active at one time whereas we'd really like to have them both registered and be able to process files. We want to implement a shared test suite that works with both React and Vue. The primary focus for these tests is to verify everything works using the "Public API" of the components as consumed by the user. This would be done using clicks, taps, focus events, keyboard interactions, etc… The only significant difference between the React and Vue tests are the initial setup / rendering and we don't need very deep Vue / React integration for this — as such the steps taken and assertions fired are identical across React / Vue. There will, of course, be some tests that only work with one or the other the majority of tests will be shared between both.

We have a solution to this right now that conditionally requires the appropriate package based on an environment variable we've set but this doesn't feel like the most ideal situation. I think, ideally for us, it would be beneficial to have a single test configuration with multiple projects. One per-browser, per-library. So in all we'd have 6 playwright projects: Chrome / FF / Webkit + React / Vue.

This solution works but has some limitations:

  • Sometimes we're unable to compile Vue SFCs when running in React mode because Playwright is scanning the files and tries to compile them without the Vue plugin. This results in compilation errors. I say "sometimes" because at one point this was working with a very small test but as we tried to port existing tests over it started erroring. I suspect it was capable of "proving" that the Vue file wasn't imported so it didn't try to. Now it can't do this so it defers to trying to include (and compile) the file just in case and fails when parsing.
  • We can't run playwright just by using npm run test — we have to set an environment variable in order to set up the correct test configuration. Admittedly this is a minor annoyance rather than anything significant.
  • The TypeScript types between the packages aren't fully compatible. Now this makes perfect sense because one's react and one is Vue but it would be super neat if installing the React and Vue plugins together overloaded the mount function with more signatures.

We've resorted to doing things like this to work around these limitations:

const plugin: typeof vue & typeof react = pick({
  vue: () => require("@playwright/experimental-ct-vue"),
  react: () => require("@playwright/experimental-ct-react"),
});

export let test = plugin.test;
export let expect = plugin.expect;
export let devices = plugin.devices;
export type PlaywrightTestConfig = vue.PlaywrightTestConfig &
  react.PlaywrightTestConfig;

Questions

  1. Is there a (future?) situation in which we can set up Vue and React (and other libraries) in the same test suite without needing to go through a few hoops like this?
  2. I was investigating the internals to see if we could work around some limitations and ran into registerSource.mjs being different between the packages. The "public-ish" API for it seems similar enough that a somehow unified version of this API could be useful. While the only thing that cares about the component library is the registry (easier said than done for sure). Obviously this is just an implementation detail — just throwing out ideas.
  3. Are there alternative setups you would recommend keeping in mind that we're trying to share as much test code as possible between Vue and React?
@pavelfeldman
Copy link
Member

Wow, this looks impressive! Appreciate the detailed explanation and the repo link.

Is there a (future?) situation in which we can set up Vue and React (and other libraries) in the same test suite without needing to go through a few hoops like this?

No such feature. And if I were to run same test across different frameworks, I'd probably end up with exact same structure that you did.

The "public-ish" API for it seems similar enough that a somehow unified version of this API could be useful.

Yes, the public-ish API is tiny, pretty much a way to render registered component. Theoretically, with some copy-paste, you should be able to implement you own register.mjs/registerSource.mjs that encapsulates the framework switch. That way you'll diverge from our implementations though.

Are there alternative setups you would recommend keeping in mind that we're trying to share as much test code as possible between Vue and React?

I actually like what you currently have. It is verbose, but it works, is built on the respective plugins, it gives us a great idea on your use case. We have not considered running same tests cross-frameworks, but now we have your use case on file.

@pavelfeldman
Copy link
Member

Why was this issue closed?

Thank you for your involvement. This issue was closed due to limited engagement (upvotes/activity), lack of recent activity, and insufficient actionability. To maintain a manageable database, we prioritize issues based on these factors.

If you disagree with this closure, please open a new issue and reference this one. More support or clarity on its necessity may prompt a review. Your understanding and cooperation are appreciated.

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

No branches or pull requests

3 participants