You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:10:31