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

[BUG]check() method in Playwright Python is not working #15420

Closed
soumya-kar opened this issue Jul 6, 2022 · 5 comments
Closed

[BUG]check() method in Playwright Python is not working #15420

soumya-kar opened this issue Jul 6, 2022 · 5 comments

Comments

@soumya-kar
Copy link

Context:

  • Playwright Version:1.23, 1.22
  • Operating System: [e.g. Windows]
  • Python- 3.9.6
  • Browser: [e.g. All, Chromium, Firefox, WebKit]
  • Extra: [any specific details about your environment]

Code Snippet

Help us help you! Put down a short code snippet that illustrates your bug and
that we can run and debug locally. For example:
import time

from playwright.sync_api import Page

def test_check_checkbox(page: Page) -> None:
page.goto("https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407")
time.sleep(5)
page.locator(get_days_locator("Monday")).check()
assert page.locator(get_days_locator("Monday")).is_checked()

def get_days_locator(day):
return f"//label[text()='{day}']/preceding-sibling::input"

Describe the bug

When I run the above code with Pytest. Browser gets launched. Url is loaded. After that, it just trying to check the checkbox but unable to do it. Doing retrying multiple times
E retrying click action, attempt #14
E waiting 500ms
E waiting for element to be visible, enabled and stable
E element is not stable - waiting...
E element is visible, enabled and stable
E scrolling into view if needed
E done scrolling
E performing click action
E Monday intercepts pointer events
E retrying click action, attempt #15
E waiting 500ms

@rwoll rwoll added the triaging label Jul 6, 2022
@rwoll
Copy link
Member

rwoll commented Jul 6, 2022

In the error message above, the line that reads:

<label for="RESULT_CheckBox-8_1">Monday</label> intercepts pointer events

indicates there is an element on top of the input element that is being re-targeted when you click the label. This element is getting in the way of actually clicking the input element.

If you inspect the DOM of the sample page where that label element is, you'll see the "checkbox" is implemented like:

  1. <input …> element with opacity zero
  2. overlayed on that is <label> that has ::before content of a square which is overlayed where the <input> would be if it wasn't opacity: 0.

Simplified, it's like: https://jsfiddle.net/12pdg56z/16/ (and if you change opacity of the actual input you can see it visually https://jsfiddle.net/0uxL2fez/).

Let me review with the team what the expected behavior here should be. As a workaround, for this specific element, you can set force=True as an argument of check which will disable some of the internal conditions.

@rwoll

This comment was marked as outdated.

@rwoll rwoll added triaging and removed triaging labels Jul 6, 2022
@rwoll
Copy link
Member

rwoll commented Jul 7, 2022

Your selector //label[text()='{day}']/preceding-sibling::input is trying to directly click the input element which is behind the label. With this site's particular implementation of the multiple choice element, you'll need to call check on an element a user can click. In this case, it's the label which the site manipulates to overlay on top of the actual input.

With this, you won't need force. Change:

def get_days_locator(day):
    return f"//label[text()='{day}']/preceding-sibling::input"

to:

def get_days_locator(day):
    return f"//label[text()='{day}']"

or more idiomatically with Playwright, just do:

page.locator('label', has_text='Monday').check()

The following works:

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context()
    page =context.new_page()
    page.goto('https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407')
    page.locator('label', has_text='Monday').check()
    assert page.locator(get_days_locator("Monday")).is_checked()

Let us know if this makes sense!

Aside: Playwright has auto-waiting built-in, so you shouldn't need time.sleep. And if you really must have a sleep, use page.wait_for_timeout instead.

@soumya-kar
Copy link
Author

Hello,
Thank you for the prompt response and the detailed RCA.
I tried the above work arounds which you mentioned. It is working fine with those work arounds.
But I feel Playwright could handle that gracefully. It prints infinite logs in console if I use my old code where it is interacting with the input tag. It should throw some error and stop the execution there.
It would be great if that can be fixed.

Thanks again.

@rwoll
Copy link
Member

rwoll commented Jul 7, 2022

@soumya-kar When I run the broken snippet below, it times out after about 30seconds and prints the logs.

python example.py:

from playwright.sync_api import sync_playwright


with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context()
    page =context.new_page()
    page.goto('https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407')
    page.locator("//label[text()='Monday']/preceding-sibling::input").check() #BROKEN

This also happens when running through pytest:

pytest:

def test_it_timesout(page):
    page.goto('https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407')
    page.locator("//label[text()='Monday']/preceding-sibling::input").check() # BROKEN

Can file a new issue with a repro for the infinite waiting you are observing? Thanks!

@rwoll rwoll closed this as completed Jul 7, 2022
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