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

无法在Behave步骤文件中集成Playwright,遇事件循环关闭错误

解决Behave+Playwright中浏览器秒开秒关及事件循环关闭问题

问题现象

执行Behave步骤文件时,浏览器秒开秒关无实际操作,抛出错误:

Error: raise Error("Event loop is closed! Is Playwright already stopped?")
   playwright._impl._errors.Error: Event loop is closed! Is Playwright already stopped?

  When the user enters a valid username.        # None
  And the user logs out from the application.     # None

原代码示例

from behave import *
from playwright.sync_api import sync_playwright

# Initialize playwright outside step definitions
with sync_playwright() as p:
    browser = p.chromium.launch(headless=False, slow_mo=800)
    page = browser.new_page()


@given(u'the user is on Pilot server login page.')
def step_impl(context):
    page.goto("https://playwright.dev/")


@when(u'the user enters a valid username.')
def step_impl(context):
    button_by_role = page.get_by_role('link', name="Docs")
    button_by_role.click()


@when(u'the user logs out from the application.')
def step_impl(context):
    page.screenshot(path="features/Screenshots/demo.png")  # Taking screenshot for the proof

问题根源

sync_playwright()的with语句会在代码块执行完毕后自动关闭Playwright实例和对应的事件循环。原代码中初始化逻辑放在with块内,程序加载阶段执行完with块就直接销毁了Playwright实例,后续执行步骤时调用的page已失效,导致浏览器秒关并抛出事件循环关闭的错误。

解决方案

使用Behave的钩子函数管理Playwright实例的生命周期,确保在测试全程实例有效,测试结束后正确清理资源。修改后的代码如下:

from behave import *
from playwright.sync_api import sync_playwright

# 全局变量存储Playwright相关实例
p = None
browser = None
page = None


def before_all(context):
    """所有测试步骤执行前初始化Playwright、浏览器和页面"""
    global p, browser, page
    p = sync_playwright().start()
    browser = p.chromium.launch(headless=False, slow_mo=800)
    page = browser.new_page()


def after_all(context):
    """所有测试步骤执行完成后清理资源"""
    global p, browser, page
    page.close()
    browser.close()
    p.stop()


@given(u'the user is on Pilot server login page.')
def step_impl(context):
    page.goto("https://playwright.dev/")


@when(u'the user enters a valid username.')
def step_impl(context):
    button_by_role = page.get_by_role('link', name="Docs")
    button_by_role.click()


@when(u'the user logs out from the application.')
def step_impl(context):
    page.screenshot(path="features/Screenshots/demo.png")

修改说明

  • 通过before_all钩子在测试开始前启动Playwright、浏览器和页面,保证实例在整个测试周期内可用。
  • 通过after_all钩子在测试结束后依次关闭页面、浏览器并停止Playwright,正确释放资源,避免内存泄漏。
  • 移除原有的with块,避免Playwright实例被提前销毁。

内容的提问来源于stack exchange,提问作者AbdulRehman Rizwan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:42:42