microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
66.31k stars 3.62k forks source link

[Question] How to detect a bad locator #20957

Closed kcpevey closed 1 year ago

kcpevey commented 1 year ago

Hi there, thank you for your awesome tool!

I have a web service where the UI changes depending on if you've logged in recently. This means that I may get one of two options for my locator. I need a clean way to see if my locator is valid.

The issue is I can create a "bad" locator (one that doesn't actually link to anything on the screen), but I won't know its bad until I call a method on it (e.g. locator.click()) - at which time I'll have to wait for the timeout period before the error is raised.

Is there a way to check if the locator is actually a valid html element before calling a method on it?

My current workaround is using locator.wait_for(timeout=300, state='attached') so I can control how long the wait is, but it seems like there should be a more streamlined way to do this?

ksktech-abhi commented 1 year ago

how about if(locator.count() > 1) {//exists}

sdettaran commented 1 year ago

From my side I see at least 2 ways:

const el1 = page.locator(selector1)
const el2 = page.locator(selector2)
if(await el1.count() > 0) {
    el1.click()
}else{
    el2.click()
}

OR

Use XPath union https://playwright.dev/docs/other-locators#xpath-union which can be more preferable

aslushnikov commented 1 year ago

Additionally to XPath union, you can just have a bunch of CSS selectors comma-separated:

import { test, expect } from '@playwright/test';

test('Please work', async ({ page }) => {
  await page.setContent(`<div>yo</div>`);
  await expect(page.locator('p,div')).toHaveText('yo');
});

Overall, lots of good advices! Closing as per all the responses above.

kcpevey commented 1 year ago

Thank you all!💕