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

React selectors #28

Open
pdufour opened this issue Jul 9, 2022 · 1 comment
Open

React selectors #28

pdufour opened this issue Jul 9, 2022 · 1 comment

Comments

@pdufour
Copy link

pdufour commented Jul 9, 2022

I've noticed if you are using React things are typically a lot easier to select using the new(ish) React selectors playwright supports. https://playwright.dev/docs/selectors#react-selectors. This is because a lot of times you would not have assigned unique classes / ids to your dom elements unless you set up your app with this concept from the start.

Would you accept a PR to add support for using React selectors instead of classes etc? Maybe have an option in the UI to toggle between the two? And any idea how I could get started with those changes?

Thanks.

@MikeShi42
Copy link
Contributor

Hi @pdufour! Sorry I totally missed this issue in my GH notifications. Absolutely would love contributions. Here's two approaches I can think of (one being the pragmatic one, the other being quite ambitious).

Hacky Solution

The hackiest and likely easiest way is to create a new ScriptType defined as possibly "PlaywrightReact" or something. ScriptType is what we define when we show the dropdown options in the UI for what library a user wants to generate code for, this way a user can choose between "Playwright" or "Playwright for React" or something like that in the library dropdown to specify what kind of selectors they want.

Next you'll need to actually generate the selector that can be used, I'm not sure if this is easy to do so as you'll need to convert HTMLElement -> component name (perhaps there is a React API to do so?). Though if you can do that, you'll just need to add a new property returned from genSelectors, maybe call it reactComponentNameSelector or something depending on what the logic is. The property should be nullable if a suitable selector is not found.

Once a new script type is defined and the selector is returned from genSelectors, you'll want to update getBestSelectorForAction to actually use your selector. You can see the function basically takes some action data (the type of action like is it a click, hover, type, etc.), and possibly some data about the target of the action (tagname) and then returns a single selector value, going down a specific chain of options returned from genSelectors.

Once this is done, you'll want to update the script generator logic to actually output code for your new ScriptType, you likely only need to add a 1-line case statement to the genCode function here to make sure your new PlaywrightReact script type uses the PlaywrightScriptBuilder as well (since it doesn't seem like any changes to the builder need to happen, just the selector logic you've done above).

At this point, you'll only need to update the UI to actually show the option to the user, which should only involve adding a new option to this component, but I'd double check when manually testing just in case we haven't migrated any selectors over to this centralized selector component.

Nicer solution?

A nicer solution is likely allowing the user to choose (at action-time or post code-gen) what kind of selector they'd like to use for a given action. This would likely require a pretty big change to the genCode function as well as the UI in general to support that. It's where we'd likely need to go long term, but I think the hacky solution at least allows this new PlaywrightReact logic to look like the rest of our existing patterns, so a future migration would be simple and not incur a lot of new tech debt.

If you want to take on a nicer solution, the above functions are a good starting point to look at (I'd imagine it's either modifying codeGen to take in additional options for user overrides on a per-action basis, or baking the user override selector option into the action objects themselves). The only other things I'd look at is probably our CodeGen React component which will need to be updated to support user interaction.


Sorry I know the above is probably a mouthful, but hopefully can serve as some insight into the inner mechanisms of the extension :)

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

2 participants