Puppeteer 初探之前端自动化测试

导语: Most things that you can do manually in the browser can be done using Puppeteer!

初识puppeteer

puppeteer 翻译是操纵木偶的人,利用这个工具,我们能做一个操纵页面的人。puppeteer是一个nodejs的库,支持调用Chrome的API来操纵Web,相比较Selenium或是PhantomJs,它最大的特点就是它的操作Dom可以完全在内存中进行模拟既在V8引擎中处理而不打开浏览器,而且关键是这个是Chrome团队在维护,会拥有更好的兼容性和前景。

puppeteer功能

1.利用网页生成PDF、图片 2.爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染) 3.可以从网站抓取内容 4.自动化表单提交、UI测试、键盘输入等 5.帮你创建一个最新的自动化测试环境(chrome),可以直接在此运行测试用例 6.捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题

安装 puppeteer

yarn add puppeteer
# or "npm i puppeteer"

可能会遇到 无法下载Chromium 问题

是因为在执行安装的过程中需要执行install.js,这里会下载Chromium,官网建议是进行跳过,我们可以执行 —ignore-scripts 忽略这个js执行

./node/npm i --save puppeteer --ignore-scripts

接下来我们需要去下载Chromium,windows的版本我这里已经下载好了,直接解压缩附件中的到 node_modules/puppeteer中就可以了。

执行下,我们创建一个文件index.js,文件内容

const puppeteer = require('puppeteer');

(async () => {
      const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://y.qq.com');
    await page.screenshot({path: 'yqq.png'});
    browser.close();
})();

这段代码会打开 https://y.qq.com 并截图,我们运行

node  index.js

如果看到目录下有生成图片y.qq.png的话,恭喜你,我们可以开始继续往下学习puppeteer了。

体验第一个demo,数字专辑自动购买的UI自动化测试

这里测试的功能是自动拉登录购买一张数字专辑,并在购买成功后跳转到铭牌页,先看下整个流程吧。

首先我们先创建一个设备,文档中(https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js) 我们能看到,默认支持的设备数量还是很多的,除了这些默认的设备之外,我们还可以自定义自己的设备,后面在调用emulate方法时会提到:

我们这里暂时先创建系统提供的iphone6设备,完了我们定义一个延时的timeout函数

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];
let timeout = function (delay) {
     return new Promise((resolve, reject) => {   
           setTimeout(() => {   
                  try {
                      resolve(1)
                  } catch (e) {
                      reject(0)
                   }
           }, delay);
     })
 }

接下来我们创建一个浏览器实例,并打开一个页面,细心的你一定发现在创建浏览器的时候我们传了headless参数,如果设为true的话就能可以在不打开外部浏览器的情况下完全利用v8引擎来进行页面的测试,简单说就是页面以及Dom完全在内存中,就连浏览器事件也是在内存中去模拟触发。

 const browser = await puppeteer.launch({
      headless:false //这里我设置成false主要是为了让大家看到效果,设置为true就不会打开浏览器
 });

 const page = await browser.newPage();

创建好浏览器实例之后我们需要让页面模拟成iphone6,这里的emulate函数的参数你也可以自定义参数

await page.emulate(iPhone);
参数:
 {
    'name': 'Galaxy S5', //设备名
    'userAgent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36', //UA
    'viewport': {
      'width': 360,//屏幕宽度
      'height': 640,//屏幕高度
      'deviceScaleFactor': 3,//缩放比例
      'isMobile': true,//是否是移动设备
      'hasTouch': true,//是否支持touch事件
      'isLandscape': false//是否横屏
    }
  }

好接下来我们就可以写我们的测试步骤了。

第一步:我们打开页面,考虑到有数据需要异步加载,我们在延迟1000ms后调用screenshot方法截图留作日志。

console.log("进入页面");
await page.goto('https://y.qq.com/m/digitalbum/gold/index.html?_video=true&id=2210323&g_f=tuijiannewupload#index/fans');
await timeout(1000);
await page.screenshot({
     path: '1.png'
 });

第二步: 模拟触发点击 立即购买按钮,这时候会因为没有登录态而打开QQ登录。

console.log("点击立即购买按钮");
await page.tap('.js_sale_buyalbum');
await page.screenshot({
    path: '2.png'
 });

第三步:在输入框中输入帐号密码,模拟输入需要我们先调用tap方法模拟点击输入框,tap参数就是元素selector,再用type方法进行输入,输入完了之后在模拟点击登录按钮,登录完了之后我们延迟一段时间截图,顺利的话我们就能重新回到之前的售卖页首页,而底下usrbar因为有了登录态也展示了出来。

console.log("登录");
await page.tap("#u"); //直接操作dom选择器,是不是很方便
await page.type("521017853");

await page.tap("#p");
await page.type("*********");//这里密码就不展示了哈

await page.tap("#go");

await timeout(3000);

await page.screenshot({
     path: '3.png'
});

console.log("登录成功");

第四步:跟第一步一样,点击立即购买按钮,这里会出现一个购买选择浮层,然后我们点击立即支付之后需要加载米大师,故这里我们延迟5000ms。

//点击购买
console.log("点击立即购买按钮");
await page.tap('.js_sale_buyalbum');

await page.screenshot({
    path: '4.png'
});

console.log("点击支付浮层上的立即支付");
await page.tap(".js_buyalbum_pay");

await timeout(5000);

第五步:在拉起米大师支付浮层之后,我们需要去点击提示中的确定按钮,由于米大师是在iframe中打开的,所以我们需要先获取到我们当前页frame,这个可以调用刚创建的页面实例page的mainFrame()方法即可获得,如果我们需要获取子frame的话也只需要调用childFrames来进行获取。在获取到米大师对应的frame之后就可以调用midas_frame.$(selector)类jquery的方法进行元素的获取,之后再模拟点击。

console.log("进入 米大师支付浮层")
await page.screenshot({
     path: '5.png'
});

let $frame = page.mainFrame();
let midas_frame = $frame.childFrames()[0];//获取到midas对应的frame

console.log("点击确定 米大师支付浮层测试环境提示 的确认按钮");
let $dom = await midas_frame.$(".fusion-pm-fl-wrapper .fpm-default");
await $dom.tap();

await page.screenshot({
    path: '6.png'
});

第六步:点击Q币支付

console.log("点击 米大师支付浮层 确认支付按钮");
$dom = await midas_frame.$("#wrap .fpm-default");
await $dom.tap();

await timeout(5000);

await page.screenshot({
    path: '7.png'
});

第七步:点击完成进入铭牌页,测试完毕,关闭浏览器实例

console.log("点击 米大师支付浮层 支付完成");
$dom = await midas_frame.$("#wrap .btn-primary");
await $dom.tap();

await timeout(2000);

console.log("已购铭牌页");
await page.screenshot({
     path: '8.png'
});
browser.close();

最后在项目目录中,我们看到,各个步骤的截图都已生成。

体验第二个demo,页面性能检测 Puppeteer Trace API

Trace API 主要是利用Chrome Performance,生成页面性能追踪的文件 trace.json,在Chrome 开发者工具中上传该文件,就可以对里面的火焰图去做分析。 事例代码:

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];

(async () => {
        const browser = await puppeteer.launch();

        const page = await browser.newPage();

        await page.emulate(iPhone);

        await page.tracing.start({path: './trace.json'});
        await page.goto('https://y.qq.com/m/digitalbum/gold/index.html?_video=true&id=2210323&g_f=tuijiannewupload#index/fans');
        await page.tracing.stop();

        browser.close();
    } catch (e) {
        console.log(e.message);
    }
})();

首先,这段代码执行的是模拟iphone6打开林俊杰的《丹宁执着》数专售卖页,并进行性能的分析。主要使用 tracing.start,stop生成trace.json文件

trace.json

接下来我们打开Chrome的开发者工具,进入到Performance栏目下,把刚才的trace.json拖上去就能看到数据了

总结

通过上面两个例子,我们看到了puppeteer可以做UI自动化测试和页面性能检测,其实他的功能远远不止于此,比如还可以做爬虫,去爬取github的文章或是掘金上的博客,总之,自己也是初次尝试,肯定会有更多的功能能够被挖掘出来,希望大家多多交流。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏社区的朋友们

一个 RNN 调研引发的点评推荐血案

在这篇文章里,作者基于用户的评论内容,评估了十多种不同的 RNN 框架。这些 RNN 框架包括多层双向 GRU 和 LSTM,同时有 attention-bas...

1.8K00
来自专栏社区的朋友们

机器学习概念总结笔记(一)

本部分介绍了机器学习算法的四大分类,即:监督学习、半监督学习、无监督学习和增强学习以及包括最小二乘回归、岭回归、LASSO回归、LARS回归在内的26大常见算法...

1.6K40
来自专栏Star先生的专栏

Tensorflow 术语表

本文主要简要介绍了广播操作、Graph(图)、Session(会话)、Tensor 等13个 Tensorflow 术语表。希望对大家了解学习 Tensorfl...

1.2K10
来自专栏腾讯AI实验室的专栏

腾讯AI Lab斩获知识图谱顶级赛事KBP 2017世界冠军

感谢阅读腾讯AI Lab微信号文章,恭喜知识图谱团队首次出战KBP大赛就获得实体发现与链接任务三语总分第一名好成绩!

18410
来自专栏腾讯AI实验室的专栏

腾讯AI Lab斩获知识图谱顶级赛事KBP 2017世界冠军

谢阅读腾讯AI Lab微信号文章,恭喜知识图谱团队首次出战KBP大赛就获得实体发现与链接任务三语总分第一名好成绩!

12410
来自专栏吕晟的专栏

机器学习库初探之 Caffe

Caffe 是一个清晰而高效的深度学习框架,其作者是博士毕业于 UC Berkeley 的贾扬清,目前在 Facebook 工作。Caffe 是纯粹的 C++/...

1.5K20
来自专栏利炳根的专栏

学习笔记DL001 : 数学符号、深度学习的概念

深度学习是机器学习拉出的分支,它试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。本文主要介绍深度学习中的数学符号、数和数组。

59500
来自专栏程飞翔的专栏

XGBoost 源码阅读笔记(2):树构造之 Exact Greedy Algorithm

本篇将继续向大家介绍 XGBoost 源码是如何构造一颗回归树,不过在分析源码之前,还是有必要先和大家一起推导下 XGBoost 的目标函数。

1.1K10
来自专栏腾讯移动品质中心TMQ的专栏

Tensorflow 的 word2vec 详细解释:basic篇

Word2Vec即Word to vector(词汇转向量)。我们希望词义相近的两个单词,在映射之后依然保持相近,词义很远的单词直接则保持很远的映射距离。

1.6K40
来自专栏织云平台团队的专栏

腾讯赵建春:AI浪潮下的高效运维思考及实践

腾讯 SNG 助理总经理、GOPS 金牌讲师赵建春老师受邀出席大会,并带来精彩演讲《AI 浪潮下的高效运维思考与实践》。

79810

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励