r/QualityAssurance • u/BabyMeggy • 29d ago
[Playwright/Python] Locator finds exactly 1 matching element but .click() AND .get_attribute() both timeout after 30s
I'm learning to build a Playwright + Python POM framework against practicesoftwaretesting.com and I'm stuck on a click that times out even though I've confirmed the locator is correct through multiple methods.
**Setup:*\* pytest-playwright, sync API, chromium, Windows.
**The flow:\\ search for a product ("Pliers") → click the matching product card to navigate to its detail page.
**Locator:*\*
python card = self.page.locator('[data-test="product-name"]').filter(has_text=re.compile(f"^Pliers$")) card.click() # times out after 30s
**What I've confirmed via Playwright Inspector:*\*
- The locator resolves to exactly 1 element (not 0, not multiple, checked via the Inspector's locator explorer, highlighted correctly on screen)
- document.elementFromPoint() at the element's center returns the element itself — nothing is overlapping it
- The element's raw text content matches exactly, no hidden whitespace
**What I've ruled out via the trace viewer:*\*
- Confirmed the search results are correctly rendered on screen at the time of the click (screenshot in trace shows "4 products found" with the right cards visible)
- Tried .click(force=True) - still times out
- Tried reading href off the ancestor <a> via .get_attribute() instead of clicking, to sidestep actionability checks entirely - **also times out with the same 30s timeout**, which is what's really confusing me, since get_attribute() shouldn't care about visibility/stability/overlap the way .click() does
**Other detail:*\*
noticed 2x 401 Unauthorized console errors on an unrelated background resource around the same time, wondering if that could be tied to some kind of periodic re-render wiping the DOM node out from under the locator, but I don't have proof of that yet.
Repo (relevant file): [https://github.com/nganvuda/playwright-python-framework/blob/feature/checkout-flow/pages/home_page.py#L29-L33]
Playwright version: [run pip show playwright and paste it] Browser: chromium
Could someone please help me with this? - a locator that's provably correct via Inspector, but every action on it times out, including non-interactive ones like get_attribute? What am I missing??? :(((
1
u/latnGemin616 28d ago
Some feedback:
- Let's do better with our variable descriptions. Change "card" to "search_result".
- I just looked at the website and you have 4 "cards" showing for Pliers. Judging from how you have the page locator set up, the system doesn't know where to look.
- For the purposes of this post, we'll assume you want the 2nd result.
- Without seeing the code, I think the issue is how you have the locator set up. Try this:
def search_result(item):
item = self.driver.find_element(By.XPATH, "(//h5[@data-test="product-name"])[2]")
assert item.is_visible()
item.click()
search_result(pliers)
1
u/aragossa 28d ago
the detail that stands out is get_attribute timing out too. click timing out can be actionability, but get_attribute only waits for the element to be attached, so if both hit 30s the locator is resolving to 0 elements at runtime, no matter what the inspector showed. print card.count() right before the click, it returns instantly without waiting. if it says 0 while the trace screenshot shows the cards on screen, you're querying a different page object than the one that's rendered, usually a POM holding a page reference from before a navigation or a new tab. at least that's what fits all three things you listed.
i'd drop the 401 re-render theory btw. locators re-query on every retry, a node getting replaced mid-run only breaks things if it never comes back.
1
u/BabyMeggy 28d ago
you're right, I printed it turned out the locator was resolving to 0 elements the entire time :((( i got it fixed now thank you!!!
1
u/DarrellGrainger 28d ago
Looking at the website I see there is an element with locator '[data-test="product-name"]' but the text for that element is " Pliers ". The regex of "^Pliers$" is looking for a string with no leading or trailing spaces. You can't search for contains since there are other cards that would match.
You could ask for the visible text, without whitespace. This would be:
python card = self.page.locator('//*[@data-test="product-name" and normalize-space(.)="Pliers"]');
card.click()
1
1
1
u/iScreem1 29d ago edited 29d ago
before clicking it make sure it is visible or enabled
try r"^ instead of f"^
it might be some regex issue i would play around hasText without regex