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

Python Playwright页面对象模型(POM)中处理新标签页切换的方案问询

Python Playwright页面对象模型(POM)中处理新标签页切换的方案问询

我现在遇到个自动化测试的问题想请教下:用Python Playwright做自动化,场景是点击页面上的链接会打开新标签页,后续所有操作都需要在这个新页面上完成。

不用页面对象模型(POM)的时候我已经搞定这个场景了,代码如下:

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch()
    context = browser.new_context()
    page = context.new_page()
    page.goto(URL)
    with context.expect_page as Account_setup_page:
         accountSetup_link.click()
    new_page = Account_setup_page.value
    startaccount = new_page.locator('<<Xpath>>')

这段代码运行正常,因为浏览器上下文(context)就在同一个代码文件里,直接就能用它监听新页面。

但现在改用页面对象模型之后,我就不知道该怎么处理新标签页的切换了。另外我的conftest.py文件里已经定义了包含context引用的fixture,代码大概是这样:

@pytest.fixture(scope="function")
def accsetup(request, playwright):
    browser=playwright.chromium.launch()    
    context=browser.new_context()
    page=context.new_page()
    # 后续应该还有返回和清理逻辑

给你两个贴合POM的解决方案思路,都是把新页面的处理逻辑封装到页面对象里:

思路1:通过页面对象接收context实例

你可以在创建页面对象的时候,把conftest里的context传递进去,这样在页面对象内部就能用context监听新页面的生成:

首先定义首页的页面对象:

class HomePage:
    def __init__(self, page, context):
        self.page = page
        self.context = context
        # 定位要点击的链接元素
        self.account_setup_link = self.page.locator("你的链接定位符")

    def click_account_setup_link(self):
        # 监听新页面的生成
        with self.context.expect_page() as new_page_info:
            self.account_setup_link.click()
        # 返回新页面对应的页面对象实例
        return AccountSetupPage(new_page_info.value)

然后定义新页面的页面对象:

class AccountSetupPage:
    def __init__(self, page):
        self.page = page
        self.start_account_btn = self.page.locator('<<Xpath>>')

    def click_start_account(self):
        self.start_account_btn.click()

最后调整conftest的fixture让它返回page和context:

@pytest.fixture(scope="function")
def accsetup(request, playwright):
    browser=playwright.chromium.launch()    
    context=browser.new_context()
    page=context.new_page()
    yield page, context
    # 测试结束后清理资源
    context.close()
    browser.close()

测试用例里这样调用:

def test_account_setup(accsetup):
    page, context = accsetup
    home_page = HomePage(page, context)
    # 点击链接后直接拿到新页面的页面对象
    account_setup_page = home_page.click_account_setup_link()
    # 在新页面执行操作
    account_setup_page.click_start_account()

思路2:通过page对象直接获取context(更简洁)

其实Playwright的page对象本身自带context属性,所以不用单独传递context,直接在页面对象里用self.page.context就能拿到上下文:

修改首页的页面对象:

class HomePage:
    def __init__(self, page):
        self.page = page
        self.account_setup_link = self.page.locator("你的链接定位符")

    def click_account_setup_link(self):
        # 直接用page的context监听新页面
        with self.page.context.expect_page() as new_page_info:
            self.account_setup_link.click()
        return AccountSetupPage(new_page_info.value)

conftest的fixture只需要返回page即可:

@pytest.fixture(scope="function")
def accsetup(request, playwright):
    browser=playwright.chromium.launch()    
    context=browser.new_context()
    page=context.new_page()
    yield page
    context.close()
    browser.close()

测试用例也更简洁:

def test_account_setup(accsetup):
    home_page = HomePage(accsetup)
    account_setup_page = home_page.click_account_setup_link()
    account_setup_page.click_start_account()

这样就完全符合POM的设计思想了,把每个页面的操作都封装到对应的页面对象中,测试用例只负责业务流程的串联。

备注:内容来源于stack exchange,提问作者Subbu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 12:58:06