哈哈
无头Chrome在Chrome 59中发布。这是在无头环境中运行Chrome浏览器的一种方式。 基本上,运行没有Chrome的Chrome! 它将Chromium和Blink渲染引擎提供的所有现代Web平台功能引入命令行。
那么这个浏览器可以用来干嘛?
想象一下每次在发版前,测试人员都需要测试系统的功能,重复且乏味。于是你决定让程序自动测试界面上的功能。你不需要浏览器有GUI界面,想通过编程的方法来驱动浏览器进行各种操作,并且希望能在服务器端运行,这样每次发版前就可以自动测试相关功能,提高测试效率。
以上只是一个应用场景,Headless浏览器可以理解为没有GUI界面的浏览器程序。由于没有界面,所以在速度上比普通浏览器稍快,它可以在自动化测试、性能检查、获取元数据(例如爬虫)和网页截图等方面发挥用途。
Puppeteer 是一个 Node 库,它提供了高级的 API 并通过 DevTools 协议来控制 Chrome(或Chromium)。通俗来说就是一个 headless chrome 浏览器 (也可以配置成有 UI 的,默认是没有的)
Puppeteer API可用于截取屏幕截图,创建PDF,导航页面以及从页面获取信息等.
Puppeteer API 官方参考链接: https://pptr.dev/, Puppeteer API 中文版参考链接: https://zhaoqize.github.io/puppeteer-api-zh_CN/
了解了无头浏览器与Puppeteer, 本文主要介绍Puppeteer的安装使用以及结合我们现有的网站如何实现自动化测试.
以上我们了解了Puppeteer是一个Node库, 所以在安装puppeteer之前, 你需要先安装NodeJs. 我建议安装NodeJs官方最新版本
在项目中安装puppeteer , Note: 当你安装 Puppeteer 时,它会下载最新版本的Chromium(~170MB Mac,~282MB Linux,~280MB Win),以保证可以使用 API。 如果想要跳过下载,请阅读环境变量。
npm install puppeteer
puppeteer-core
自1.7版本以后,这个包默认不会下载chromium, puppeteer-core
是一个轻量级的Puppeteer版本, 用于启动现有浏览器安装或连接到远程安装
npm install puppeteer-core
Note: Puppeteer 至少需要 Node v6.4.0,下面的示例使用 async / await,它们仅在 Node v7.6.0 或更高版本中被支持。
Puppeteer 使用起来和其他测试框架类似。你需要创建一个 Browser 实例,打开页面,然后使用 Puppeteer 的 API。
Example - 跳转到 https://example.com 并保存截图至 example.png:
文件为 example.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
在命令行中执行
node example.js
Puppeteer 初始化的屏幕大小默认为 800px x 600px。但是这个尺寸可以通过 Page.setViewport() 设置。
LiveWire是一个提供给不同国家的用户通过booking页面提交个人信息预定试驾电动车的系统. 功能逻辑简单,每个地区只有三个页面: 表单页面, 确认页面和错误页面以及确认邮件.
[以检查 Footer Social Link 为例]
LiveWire包含很多国家和地区, 一共有26个Locale, 不同local的Social Link个数不同, 链接也不同, 正常测试流程我们会打开每一个locale网站, 分别一一对比soical link个数与链接是否正确.
这个时候可能使用自动测试就会很方便, Social Link位置固定, 改变的是网站地址信息, 使用Puppeteer取出每个locale的social link, 打印出来,再与Marketing Matrix对比, 就非常快速与高效.
以LiveWire DEV测试环境为例, 编写自动测试脚本 : http://livewire.xxx.com/en_GB
const puppeteer = require('puppeteer');
//All locales
const locales = ["en_CA", "fr_CA", "es_ES", "de_AT", "nl_BE", "fr_BE", "cs_CZ", "da_DK", "fi_FI", "fr_FR", "de_DE", "hu_HU", "en_IE", "it_IT", "fr_LU", "nl_NL", "no_NO", "pl_PL", "pt_PT", "sv_SE", "de_CH", "fr_CH", "it_CH", "en_GB"];
const base_url = "http://livewire.xxx.com";
headless: fasle
就是正常运行浏览器, 在本地测试使用. 如果使用headless mode
需要设置为true.defaultVidewport
设置窗口大小,默认为:800x600const chromeOptions = {
headless:false,
defaultViewport: {width: 1366, height: 768}
};
const browser = await puppeteer.launch(chromeOptions);
const page = await browser.newPage();
await page.authenticate({username:`${user}`, password: `${pass}`});
for(locale of locales){
//拼接locale url
const locale_url = base_url + "/" + locale;
//打印url
console.log(locale_url);
//打开locale页面
await page.goto(locale_url);
//此处填写业务逻辑代码...
}
打开网站并检查元素,得出div.footer div.common_sections div.footer_icon-container
下所有A链接即是所有social link. 如下图:
取出所有social link 并打印. 代码如下:
const socialHrefs = await page.$$eval(".footer .common_sections .footer_icon-container a", el => [].map.call(el, a => a.href));
for (const a of socialHrefs){
console.log('\t', a);
}
完整代码如下:
const puppeteer = require('puppeteer');
//测试网站基本认证用户名与密码
const user = 'xxx';
const pass = 'xxx';
//all
const locales = ["es_ES", "de_AT", "nl_BE", "fr_BE", "en_CA", "fr_CA", "cs_CZ", "da_DK", "fi_FI", "fr_FR", "de_DE", "hu_HU", "en_IE", "it_IT", "fr_LU", "nl_NL", "no_NO", "pl_PL", "pt_PT", "sv_SE", "de_CH", "fr_CH", "it_CH", "en_GB"];
const base_url = "http://livewire.xxx.com";
const chromeOptions = {
headless:false,
defaultViewport: {width: 1366, height: 768}
};
(async() => {
const browser = await puppeteer.launch(chromeOptions);
const page = await browser.newPage();
await page.authenticate({username:`${user}`, password: `${pass}`});
for(locale of locales){
//拼接locale url
const locale_url = base_url + "/" + locale;
//打印url
console.log(locale_url);
//打开locale页面
await page.goto(locale_url);
const socialHrefs = await page.$$eval(".footer .common_sections .footer_icon-container a", el => [].map.call(el, a => a.href));
for (const a of socialHrefs){
console.log('\t', a);
}
}
await browser.close();
})();
上一节, 我们以Footer Social Link 为例详细分析了编写自动测试脚本代码. 其它业务逻辑可在些基础之上继续添加, 比如: Footer Links.
const footerLinks = await page.$$eval(".footer .footer_links-container a", el => [].map.call(el, a => a.href));
//Show Footer Links
console.log('FOOTER LINKS:')
for (const a of footerLinks){
console.log('\t', a);
}
把上面代码添加到与"Footer Social Link "并列位置即可打印每个locale的footer link.
其它更复杂的业务也和这差不多, 只是编写更多的业务逻辑代码. 如自动提交表单, 自动截图用来检查文字是否重叠, 通过设置 defaultViewport
来检查手机端文字样式等等.
更多Puppeteer API 语法, 请参考在线文档: https://zhaoqize.github.io/puppeteer-api-zh_CN/
testing