zl程序教程

您现在的位置是:首页 >  工具

当前栏目

PlayWright VS Porsche实战 - 启坑

vs 实战 Playwright
2023-06-13 09:15:50 时间

这是一个新坑的开始,弃坑的事情其实也做过,当年考虑把Jmeter用7天速成宝典的方式重新写一遍,最后也不了了之了,毕竟一旦这事情做起来没乐趣了,也就少了动力了。

而起这个坑的关键是工作中遇到了React开发的组件需要规划自动化的方案选型,考虑到团队的小伙伴都很忙,作为SM的我还是自己先踩一下坑然后给团队分享下这个可行性吧。

其实谈到UI自动化基本上就是WebDriver的天下,毕竟基于浏览器的DOM架构体系不可能撼动,曾经的各种富媒体技术(Flex&SliverLight)也相继倒下,还是HTML+CSS+JavaScript的天下。所以压根也没想到当前的技术架构使用WebDriver竟然出现了诸多问题,才有了现在PlayWright的这篇系列文章。

在开始下面的内容前,我相信读者也和我一样有着不可思议的心态,竟然还有WebDriver搞不定的东西?那么请先

Show me code,WebDriver VS Porsche

业务逻辑也不麻烦,打开保时捷中国首页,点击顶端的911车型,然后访问菜单中的Turbo Cabriolet车型,最后提取911 Turbo S的当前价格即可。

如果在30分钟内完成这个基于WebDriver的自动化脚本,请给我指教让我深刻反省自己的自动化认知障碍,如果和我一样百思不得其解的话,那么接着就和我一起进入Playwright的世界,把WebDriver丢出大脑。

框架的说明很简单,微软做的Web Testing and Automaition工具,支持各种浏览器和API,也就是既可以做UI自动化也可以做API接口自动化。

GitHub - microsoft/playwright: Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.

在GitHub上也可以发现这个框架87%是基于TypeScript实现的,冥冥之中这玩意不太一样!

能搜索到的中文介绍有一般如下:

  • Playwright 支持当前所有主流浏览器,包括 Chrome 和 Edge(基于 Chromium)、Firefox、Safari(基于 WebKit) ,提供完善的自动化控制的 API。
  • Playwright 支持移动端页面测试,使用设备模拟技术可以使我们在移动 Web 浏览器中测试响应式 Web 应用程序。
  • Playwright 支持所有浏览器的 Headless 模式和非 Headless 模式的测试。
  • Playwright 的安装和配置非常简单,安装过程中会自动安装对应的浏览器和驱动,不需要额外配置 WebDriver 等。
  • Playwright 提供了自动等待相关的 API,当页面加载的时候会自动等待对应的节点加载,大大简化了 API 编写复杂度。

当然我觉得比较好的地方是,Playwright不是直接操作DOM对象操作的,所以对于React这种响应式刷新会更好的兼容,不会出现WebDriver驱动了无效的尴尬情况。

官网Playwright.dev也提到了对Shadow DOM的穿透支持,这也是WebDriver不支持React很多问题的本质原因。

Fast and reliable end-to-end testing for modern web apps | Playwright Java

shadow DOM视为“DOM中的DOM”。它是自己独立的DOM树,具有自己的元素和样式,与原始DOM完全隔离。

废话不多说,直接开始Playwright的世界,这里我是用的是IDEA的Maven构建(Python早就忘的不认识了),为了考虑后面的框架与研发配合,可能会改成Gradle构建。

安装很简单,pom.xm依赖即可

      <!-- https://mvnrepository.com/artifact/com.microsoft.playwright/playwright -->
        <dependency>
            <groupId>com.microsoft.playwright</groupId>
            <artifactId>playwright</artifactId>
            <version>1.26.0</version>
        </dependency>

新建一个测试类,这里我使用了Junit5

 @Test
void playwright()
{
}

初始化一个playwright

 @Test
 void playwright()
    {
        try(Playwright playwright=Playwright.create()){
            Browser browser=playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false).setSlowMo(200));
            Page page=browser.newPage();
            page.navigate("https://www.porsche.cn/china/zh/");
        }
    }

这里需要注意的是通过

new BrowserType.LaunchOptions().setHeadless(false).setSlowMo(200)

将浏览器设置为有头模式(如果不设置运行的时候浏览器不会弹出),并且设置执行速度降速。然后就是新建一个页面,并且把页面导航到首页。

*注意,这里不需要配置任何浏览器,在第一次使用的时候,会自动下载所有浏览器的支持组件,包括Chrome体系、Firefox和WebKit三种。

接着就是定位操作对象的核心功能了locator()

  page.locator("[aria-label=\"Porsche Model Series 911\"]").click();

page.locator是核心方法,其参数推荐使用css,但是也支持xpath或者别的语法,而且定位模式还有很多模糊的内容,官方文档也没完全写清楚,等后续章节踩坑梳理。

上面的代码定位对应了首页上的这个元素

<button class="sc-phn-menu-button" aria-expanded="false" aria-haspopup="true" aria-label="Porsche Model Series 911" role="menuitem">
<div class="content-wrapper sc-phn-menu-button sc-phn-menu-button-s">
<phn-car-series class="sc-phn-menu-desktop-level-1 sc-phn-car-series-h sc-phn-car-series-s hydrated">
<img srcset="https://nav.porsche.com/00BC524/series-assets/1366/911.jpg, https://nav.porsche.com/00BC524/series-assets/1366/911@2x.jpg 2x" alt="" class="sc-phn-car-series" style="">
<p class="car-series-text sc-phn-car-series">911</p>
</phn-car-series>
</div>
</button>

看起来很有Xpath的那种@属性=值的感觉

在解决了定位的问题后,接着核心的功能是pause()

page.pause();

暂停调试功能,一旦运行后,你就会爱上它。以前我们常常吐槽WebDriver缺乏动态调试功能,发现错误了要自己一点点的检查定位等,而在Playwright中提供了和Cypress一样的调试模式,就是可以直接在浏览上跟着操作,但是没有办法和Cypress一样完全自由,毕竟工作模式还是有些区别。

执行到这条命令的时候会弹出一个调试窗口,在里面可以录制操作代码,生成对应的脚本,也可以选择对象获取Playwright推荐的定位信息(可惜这里的定位不能自己设置规则)

而Explore功能就是那个选哪里的定位功能

这个定位一看就是CSS的选择ID,对应代码如下

在解决了浏览器启动,对象选择,调试功能后,最后就是断言的支持,在Playwright中提供了属性操作的诸多选择,例如基本的getAttribute,当然也有InnerHTML、InnerText等,这里就不详细介绍了,可以自己看一下page对象下的可用方法列表。

最后代码如下

 @Test
    void playwright()
    {
        try(Playwright playwright=Playwright.create()){
            Browser browser=playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false).setSlowMo(200));
            Page page=browser.newPage();
            page.setViewportSize(1920,1080);
            page.navigate("https://www.porsche.cn/china/zh/");
            page.locator("[aria-label=\"Porsche Model Series 911\"]").click();
            page.locator("text=Turbo Cabriolet 车型 >> a").click();
            String price=page.locator(".m-364-module-headline--copy>>nth=0").innerText();
            System.out.println(price);
            page.pause();
        }
    }

这个代码里面有两个比较有趣的内容,一个是:

page.setViewportSize(),用来强行定义页面渲染大小,为什么要这样做大家可以猜测一下,自己写一下就明白了。这里强调下,Playwright是没有最大化浏览器的功能的,为什么其实和要强行定义渲染大小是一个道理。

另外一个是".m-364-module-headline--copy>>nth=0"这句CSS定位,如果熟悉的朋友应该知道>>nth=0是用来说明该定位的一次出现项。在Playwright中没有对象集合的概念,就是locator出来的一定是唯一的,否则会出现定位错误的问题,至于为什么不能像WebDriver一样来个findElements(),等我继续往下踩坑。

好了今天的内容先到这里,毕竟回顾视频内容还是很累的,所有踩坑的过程和问题的解决过程都被更新到了:

https://www.bilibili.com/video/BV1iN4y1K7Bt/

也可以点击访问原文链接跳转。

关于职业发展可以参考和CKL聊的:从自动化到性能再到研发效能之路