简体   繁体   中英

How do I use a helper function as typing.Callable argument with the playwright page.wait_for_event function in Python?

I'm trying to use the playwright page.wait_for_event function. One of the kwargs accepts a Callable. I'm trying to use a helper function that would take two arguments: the event that I'm waiting to fire, and a global variable. But I can't seem to figure out how to find and/or use a variable for the event to pass into the helper function. Most examples I see that use the wait_for_event function use a lambda function for the predicate argument which works great, but I need to perform an action before I return a boolean value which I also don't know how to do with a lambda function.

My apologies if my terminology is incorrect.

The helper function I'm trying to use as an argument:

def test(event, global_variable):
    page.locator('//*[@id="n-currentevents"]/a').click() # Action before boolean
    if event.url == 'https://en.wikipedia.org/':
        return True

The variations of the page.wait_for_event function I tried:

# Doesn't work
r = page.wait_for_event('request', test('request', global_variable))
r = page.wait_for_event('request', test(event, global_variable))
r = page.wait_for_event(event='request', test(event, global_variable))
r = page.wait_for_event(event:'request', test(event, global_variable))

# Lambda works, but I need to click an element before returning the truth value
r = page.wait_for_event(event='request', lambda req : req.url == 
'https://en.wikipedia.org/')

The wait_for_event function:

    def wait_for_event(
    self, event: str, predicate: typing.Callable = None, *, timeout: float = None
) -> typing.Any:
    """Page.wait_for_event

    > NOTE: In most cases, you should use `page.expect_event()`.

    Waits for given `event` to fire. If predicate is provided, it passes event's value into the `predicate` function and
    waits for `predicate(event)` to return a truthy value. Will throw an error if the page is closed before the `event` is
    fired.

    Parameters
    ----------
    event : str
        Event name, same one typically passed into `*.on(event)`.
    predicate : Union[Callable, NoneType]
        Receives the event data and resolves to truthy value when the waiting should resolve.
    timeout : Union[float, NoneType]
        Maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default
        value can be changed by using the `browser_context.set_default_timeout()`.

    Returns
    -------
    Any
    """

    return mapping.from_maybe_impl(
        self._sync(
            self._impl_obj.wait_for_event(
                event=event,
                predicate=self._wrap_handler(predicate),
                timeout=timeout,
            )
        )
    )

You can use a factory function here to pass the page , and the global_variable . Keep in mind that navigating away from the page from inside the callable will lead to an error. So make sure whatever you are clicking does not change the current URL of the page.

def wrapper(page, global_variable):
    def test(event):
        page.locator('//*[@id="n-currentevents"]/a').click()  # Action before boolean
        if event.url == 'https://en.wikipedia.org/':
            return True
    return test

Then, you can register the above function using page.wait_for_event like this:

page.wait_for_event('request', wrapper(page, global_variable))

Remember: You need to pass functions/callables (not their return values) to page.wait_for_event

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM