Playwright+Django测试:如何等待自定义事件触发?
问题原因
page.expect_event()只能监听Playwright Page对象内置的事件(比如load、domcontentloaded、request等),无法直接捕获DOM元素上触发的自定义事件(比如你定义的boop),这就是测试超时的核心原因。
解决方案
针对DOM自定义事件,需要在页面上下文内监听事件触发,以下是两种可行的实现方式:
方式一:使用page.wait_for_function等待事件
在页面中创建一个Promise,当boop事件触发时resolve,然后通过wait_for_function等待这个Promise完成:
def test(page, live_server): page.goto(live_server.url) btn = page.get_by_text('Click me') # 在页面上下文注册事件监听的Promise wait_for_boop = page.wait_for_function(""" new Promise(resolve => { document.addEventListener('boop', resolve, { once: true }); }) """) btn.click() # 等待事件触发的Promise完成 wait_for_boop.result() # 添加断言验证效果 assert page.evaluate("document.body.style.backgroundColor") == "darkcyan"
方式二:通过expose_function暴露Python回调
把Python的回调函数暴露给页面JS,当boop事件触发时调用该回调,再用Python的事件对象等待:
import threading def test(page, live_server): page.goto(live_server.url) btn = page.get_by_text('Click me') # 创建事件对象用于等待 event_triggered = threading.Event() # 暴露Python回调给页面JS def on_boop(): event_triggered.set() page.expose_function("notifyBoop", on_boop) # 在页面上下文添加事件监听器,触发时调用Python回调 page.evaluate(""" document.addEventListener('boop', () => { window.notifyBoop(); }, { once: true }); """) btn.click() # 等待事件触发,超时则断言失败 assert event_triggered.wait(timeout=1000) # 验证背景色变化 assert page.evaluate("document.body.style.backgroundColor") == "darkcyan"
补充说明
两种方式都能正确捕获DOM自定义事件,方式一更简洁,适合简单场景;方式二更灵活,适合需要在Python端处理事件数据的场景。测试中可以去掉不必要的wait_for_timeout,改用明确的事件等待或断言来保证测试稳定性。
内容的提问来源于stack exchange,提问作者CoffeeBasedLifeform
相关产品推荐
相关产品推荐

