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
相关产品推荐
相关产品推荐

