使用Puppeteer进行用户界面测试

Puppeteer是由Google Chrome 官方团队进行维护的一个Node库,提供了一组高级API, 通过DevTools协议控制无界面Chrome (headless chrome, 也就是无UI界面的chrome)。
简而言之,Puppeteer可以让用户界面测试变得很轻松。
什么是Puppeteer?
Puppeteer是一个用户界面自动化工具。 它组合了”Chrome无界面模式”和”DevTools协议”,通过提供一个更上层的API,让用户界面测试自动化变得轻而易举。
无界面Chrome是没有UI界面的Chrome。 它允许你从浏览器之外的环境(即命令行)与Chromium进行交互。
示例代码
我们通过一个示例,来探讨Puppeteer的使用方法:使用Puppeteer来访问百度, 源代码仓库地址请点击这里。
示例代码的安装、执行
在安装依赖、执行示例代码之前,请先安装最新版的Node.js。
# 建议使用cnpm进行安装,puppeteer需要下载Chromium (~170Mb Mac, ~282Mb Linux, ~280Mb Win)
sudo npm install -g cnpm
cnpm install
# 执行
npm start
# or npm run test
执行结果——无头
执行结果——有头
代码说明
/**
* 下面是使用 puppeteer 的一个例子
*/
const puppeteer = require('puppeteer');
(async() => {
// 1、打开 浏览器
const browser = await puppeteer.launch({headless: true});
// 2、打开 新页面
const page = await browser.newPage();
// 3、网址跳转到 百度
await page.goto('https://www.baidu.com');
// 4、在 百度的搜索框 输入 Puppeteer
await page.type('#kw', 'Puppeteer', {delay: 50});
// 5、点击 "百度一下" 按钮
await page.click('#su');
// 6、等待 1秒钟,等待百度传输结果
await page.waitFor(1000);
// 7、抽取所有结果的"标题"和"链接"
const links = await page.evaluate(() => {
const anchors = Array.from(document.querySelectorAll('.c-container h3.t a'));
return anchors.map(anchor => anchor.textContent);
});
// 8、期待有结果
console.log(links.join('\n'));
// 9、关闭浏览器
await browser.close();
})();
我们首先加载puppeteer
模块——require
是Node.js中用于加载模块的关键字。
然后我们将加载好的puppeteer
模块放到名称为puppeteer
的常量中——
const
是ES6中用于定义常量
的关键字
关于ES6,阮一峰写了一本免费、开源的电子书,点击这里查看。
/**
* 下面是使用 puppeteer 的一个例子
*/
const puppeteer = require('puppeteer');
接下来是一个匿名的立即执行函数
(IIFE,Immediately Invoked Function Expression),里面是我们需要执行的测试代码,
async
是ES7
中用于异步操作的关键字,表示内部是异步操作,返回一个异步操作的结果。
关于async
和await
的更详细的内容,参见阮一峰的开源电子书《ECMAScript 6 入门》
(电子书地址:http://es6.ruanyifeng.com/)
(async() => {
})();
1、打开 浏览器
// 1、打开 浏览器
const browser = await puppeteer.launch();
我们通过puppeteer
模块提供的launch
方法,打开一个浏览器。
在打开浏览器的同时,我们可以提供一些配置项,比如不使用无头浏览器(headless
设置为false
)。
await
是ES7
中用于异步操作的关键字,表示等待异步操作结束、得到返回的结果,await
只能用在异步函数async function
中。
打开浏览器
对Puppeteer
来说是一个异步操作(返回值是Promise
),
Puppeteer的其他API也是类似处理。
我们为了模拟人的输入方式、或者为了查看方便,我们还可以设置slowMo
为true
,这样浏览器会模拟人的输入方式、缓慢地进行输入。
// 1、打开 浏览器
const browser = await puppeteer.launch({headless: true, slowMo: true});
2、打开 新页面
// 2、打开 新页面
const page = await browser.newPage();
3、网址跳转到 百度
// 3、网址跳转到 百度
await page.goto('https://www.baidu.com');
4、在 百度的搜索框 输入 Puppeteer
// 4、在 百度的搜索框 输入 Puppeteer
await page.type('#kw', 'Puppeteer', {delay: 50});
百度的关键字”输入框”,是一个id
属性为kw
的’Input’,我们要在里面输入Puppeteer
字符串,
为了模拟人类的输入效果,各个字符之间、我们加了50毫秒的延迟。
<!-- 百度的搜索框,是一个`id`属性为`kw`的'Input' -->
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
5、点击 “百度一下” 按钮
// 5、点击 "百度一下" 按钮
await page.click('#su');
百度的”百度一下”按钮,是一个id
属性为su
的’Submit Button’。
<!-- 百度的"百度一下"按钮,是一个`id`属性为`su`的'Submit Button'。 -->
<input type="submit" id="su" value="百度一下" class="bg s_btn">
6、等待 1秒钟,等待百度传输结果
// 6、等待 1秒钟,等待百度传输结果
await page.waitFor(1000);
由于”根据关键字进行查询”需要花一段时间,所以我们等1秒(1s,也就是1000毫秒,1000 ms)。
7、抽取所有结果的”标题”和”链接”
// 7、抽取所有结果的"标题"和"链接"
const links = await page.evaluate(() => {
const anchors = Array.from(document.querySelectorAll('.c-container h3.t a'));
return anchors.map(anchor => anchor.textContent);
});
百度的搜索结果,是放在样式类为c-container
的Div
中,我们想要的是结果是——结果的标题——
这样我们只需要找到样式类为t
的h3
标签、然后找到里面的a
标签,取它的文本内容。
8、期待有结果
// 8、期待有结果
console.log(links.join('\n'));
9、关闭浏览器
// 9、关闭浏览器
await browser.close();
更多Puppeteer的API,请访问Puppeteer官方API地址。