Tal Angel
Tal Angel

Reputation: 1782

Waiting for a visible locator returns a non-clickable element

Together with my tech lead, we implemented this method:

def get_visible_locator(self, selector):
        locators = self.page.query_selector_all(selector)
        for locator in locators:
            if locator.is_visible():
                return locator
        else:
            raise Exception('Can not find visible object with given selector:'
                            f' {selector}')

Calling the method sometimes fails:

self.get_visible_locator('text="Select All"').click(timeout=1000)

One workaround is using sleep of 2 seconds before calling the method, but my tech lead doesn't like this.

How to return the first visible and clickable / enabled element?

Upvotes: 0

Views: 958

Answers (1)

Charchit Agarwal
Charchit Agarwal

Reputation: 3757

The misconception here seems to be that visible == clickable. That is not the case. In fact the docs explain what exact actionability checks are performed that determines whether the element is clickable

For example, for page.click(selector, **kwargs), Playwright will ensure that:

element is Attached to the DOM

element is Visible

element is Stable, as in not animating or completed animation

element Receives Events, as in not obscured by other elements

element is Enabled

Functionality to check whether all this is True for any element is currently not exposed in playwright (specifically, for checking whether the element is stable and reactive). The best you can do is change if locator.is_visible() to if locator.is_visible() and locator.is_enabled() to additionally check whether it is enabled as well (which would be done as part of the actionability checks later).

You can track the relevant issue here

Upvotes: 2

Related Questions