playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] codegen: choose between multiple generated selectors

Open Meir017 opened this issue 4 years ago • 11 comments

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.

Meir017 avatar Sep 11 '20 12:09 Meir017

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.

pavelfeldman avatar Sep 11 '20 21:09 pavelfeldman

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

rmallof avatar Feb 17 '21 21:02 rmallof

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).

dgozman avatar Mar 31 '21 17:03 dgozman

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.

ZooDoo4U avatar Jul 11 '21 05:07 ZooDoo4U

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.

water-love avatar Nov 25 '21 14:11 water-love

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?

aolanrewaju avatar May 18 '22 23:05 aolanrewaju

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.

ZooDoo4U avatar May 19 '22 00:05 ZooDoo4U

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');

surfmuggle avatar Jun 03 '22 11:06 surfmuggle

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.

Jojoshua avatar Jun 09 '22 02:06 Jojoshua

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.

dgozman avatar Jun 09 '22 16:06 dgozman

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

0pilatos0 avatar May 21 '23 09:05 0pilatos0

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

Attic0n avatar Jun 01 '23 11:06 Attic0n

Yes please. That would be quite useful!

tesar-tech avatar Sep 22 '23 09:09 tesar-tech

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

millerick avatar Oct 24 '23 15:10 millerick

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

amenk avatar Oct 27 '23 10:10 amenk

+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().

raulsanchez1024 avatar Nov 02 '23 12:11 raulsanchez1024

Related: https://github.com/microsoft/playwright/issues/9015 @dgozman: This seems to have been completed. How do I use it to generate multiple selectors to choose from?

esther-86 avatar Apr 21 '24 03:04 esther-86

@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

esther-86 avatar May 15 '24 18:05 esther-86

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

dgozman avatar May 15 '24 19:05 dgozman

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)

0pilatos0 avatar May 17 '24 11:05 0pilatos0