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] codegen: choose between multiple generated selectors #5178

Open
Meir017 opened this issue Sep 11, 2020 · 21 comments · Fixed by #29154
Open

[Feature] codegen: choose between multiple generated selectors #5178

Meir017 opened this issue Sep 11, 2020 · 21 comments · Fixed by #29154

Comments

@Meir017
Copy link
Contributor

Meir017 commented Sep 11, 2020

In some cases the generated selector isn't stable enough for rerunning the code.

Having multiple selectors per element could solve this, similar to how testim.io does this - https://help.testim.io/docs/working-with-locators#:~:text=Testim%20Smart%20Locators%20are%20a,application%20to%20write%20the%20tests.

@pavelfeldman
Copy link
Member

The main goal of the codegen tool is to help users learn the Playwright API. We don't aim at creating re-runnable scripts that are production-ready. That's why we emit them into terminal rather than write into the live IDE. Having said that, it should be relatively easy for us to offer several version of the selector, preferring one aspect or the other for user to pick from.

The QA world is split on the self-healing topic (some prefer to assert behavior, others to keep test running in a best effort manner). We don't have an opinion on this matter, we consider this to be a higher-up-the-stack decision.

@dgozman dgozman transferred this issue from microsoft/playwright-cli Jan 27, 2021
@dgozman dgozman changed the title codegen: create smart selectors [Feature] codegen: improve generated selectors Jan 27, 2021
@dgozman dgozman self-assigned this Jan 27, 2021
@dgozman dgozman added v1.10 and removed v1.9 labels Feb 4, 2021
@rmallof
Copy link

rmallof commented Feb 17, 2021

Maybe another cool approach for this would be: https://playwright.dev/docs/selectors#selecting-elements-based-on-layout

@pavelfeldman pavelfeldman added v1.11 and removed v1.10 labels Mar 18, 2021
@dgozman dgozman changed the title [Feature] codegen: improve generated selectors [Feature] codegen: choose between multiple generated selectors Mar 31, 2021
@dgozman
Copy link
Contributor

dgozman commented Mar 31, 2021

In v1.10, generated selectors overall work pretty good. If there are any specific instances where the selector is really bad, please file a separate issue with repro steps.

I am renaming this issue to be about generating multiple selectors and choosing one of them (as suggested in the original request).

@ZooDoo4U
Copy link

As a user would like an option to explicitly define or influence what properties the recorder looks for and uses for the selectors in the generated code emitted by the recorder.

Personally, not a big fan of tools second guessing and assuming they know what is best, would assert there are "data-XXX" defined in the HTML spec that could be used for this purpose. Would assert it would actually make it easier and more often since we as users know and understand our specific code bases, might make it easier for all involved. Cases where the selector fails because multiple items match... Fine easy to understand and fix up my code as needed and handle thos cases needed, but at least we get what we needed.

@water-love
Copy link

What I am doing now is to add an eventlistener to elements with the attribute I want to record, for example:

<button testid="buybutton">Buy</button>

and then console.log the actual selector that I want. I can imagine that something like this would be helpful:

  • make an input field in the codegen option for an attribute you want to search for when you click something.
  • Add an eventlistener that searches for the closest it can find (https://developer.mozilla.org/en-US/docs/Web/API/Element/closest)
  • Spit out that css selector to the codegen window, if it cant find one, spit out the regular one.

@aolanrewaju
Copy link

Hello, just wanting to bring attention to this thread again because it is also something my team would like implemented.

The selectors codegen generates are not always the ideal selectors for our codebase. For example, they use class names or aria labels that change more frequently rather than more stable elements such as data-unique-id. Having the option to choose would greatly improve the usefulness of codegen. Any updates on if this feature will get development?

@ZooDoo4U
Copy link

ZooDoo4U commented May 19, 2022

I think to be fair, when entering my comment before, it seemed the recorder wouldn't pick up the data-test-id, running with 1.21 i'm seeing if data-test-id is present it is using it. Was hard to justify asking the devs to go to the trouble of putting the id's in the product code but they would be used... From my simple test, it appears data-test-id will be used.

@surfmuggle
Copy link

surfmuggle commented Jun 3, 2022

Based on id, data-testid, data-test-id, data-test selectors and a short test it seems that npx playwright codegen <url> allready uses data-test as a selector.

This markup

<label>Name<input type="text" data-test="trader_search_by_name"  data-val="true" 
    data-val-required="The Name field is required." 
    id="Name"  name="Name" >
</label>

resulted in

  await page.locator('[data-test="trader_search_by_name"]').fill('Foo');

@Jojoshua
Copy link

Jojoshua commented Jun 9, 2022

Based on id, data-testid, data-test-id, data-test selectors and a short test it seems that npx playwright codegen <url> allready uses data-test as a selector.

This markup

<label>Name<input type="text" data-test="trader_search_by_name"  data-val="true" 
    data-val-required="The Name field is required." 
    id="Name"  name="Name" >
</label>

resulted in

  await page.locator('[data-test="trader_search_by_name"]').fill('Foo');

Is this behavior something we can count on @dgozman @pavelfeldman? We have been interested in providing codegen a hint to use a data attribute as well. This would save immense time.

@dgozman
Copy link
Contributor

dgozman commented Jun 9, 2022

Is this behavior something we can count on @dgozman @pavelfeldman? We have been interested in providing codegen a hint to use a data attribute as well. This would save immense time.

@Jojoshua Yes, codegen always checks and suggests test ids.

@0pilatos0
Copy link

Would love to see this feature implemented (see my issue linked by dgozman above for another way it could be implemented)

@Attic0n
Copy link

Attic0n commented Jun 1, 2023

Even just being able to exclude id from the codegen would be a big help (our app uses dynamic id's throughout).

@tesar-tech
Copy link

Yes please. That would be quite useful!

@millerick
Copy link

I would also find it very useful to be able to define an order of precedence for attributes to use as selectors through codegen.

@amenk
Copy link

amenk commented Oct 27, 2023

Another idea: Add a configuration option that adds all the alternative selectors as commented-out code in the generated code.

@raulsanchez1024
Copy link

+1 on adding an option to prefer user-facing locators.

Playwright comes with multiple built-in locators. To make tests resilient, we recommend prioritizing user-facing attributes and explicit contracts such as page.getByRole().

dgozman added a commit that referenced this issue Jan 25, 2024
When possible, "pick locator" generates:
- default locator;
- locator without any text;
- locator without css `#id`.

Fixes #27875, fixes #5178.
@esther-86
Copy link

Related: #9015
@dgozman: This seems to have been completed. How do I use it to generate multiple selectors to choose from?

@esther-86
Copy link

esther-86 commented May 15, 2024

@dgozman : Thanks to a colleague,
We found this

  1. It looks to be set to false for the microsoft repo - https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/injected/recorder/recorder.ts#L135
  2. However, set to true for the fork - https://github.com/dgozman/playwright/blob/434ac3327ca76ef582d68a30a59acc9a3eb5f430/packages/playwright-core/src/server/injected/recorder/recorder.ts#L134

How does multiple: true ever get passed in? I tried upgrading playwright to 1.44 and still can't use this feature.

Also, I tried downloading the source code and I tried to hardcode the value

export function generateSelector(injectedScript: InjectedScript, targetElement: Element, options: GenerateSelectorOptions): { selector: string, selectors: string[], elements: Element[] } {
  injectedScript._evaluator.begin();
  options.multiple = true;
  beginAriaCaches();

Then
npm run build
Then
npx playwright codegen
But still don't see multiple selectors. I don't know if it's running the code I changed or not since the only breakpoints I can trigger are in packages\playwright\lib but I need to trigger bps in packages/playwright-core/src/server/injected/recorder/recorder.ts. Please help me to either get the changes from the source code to work or how to run using installed playwright
Thank you in advance

@dgozman
Copy link
Contributor

dgozman commented May 15, 2024

@esther-86 This feature was disabled, as it was deemed not yet ready. Sorry for confusion. Let me reopen the issue.

@dgozman dgozman reopened this May 15, 2024
@0pilatos0
Copy link

ah... sad to see it go for now, i had been using it in a forked repo as well. what was not ready about the feature? (as it was really usefull to the team)

@ducan-ne
Copy link

it would be great if the inspecting element suggests "react", "vue" selectors as well

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

Successfully merging a pull request may close this issue.