写点什么

如何成为 Puppeteer 大师

  • 2017-09-24
  • 本文字数:2031 字

    阅读完需:约 7 分钟

对程序进行测试有很多方法。从微型的单元测试开始,到更大型的用户界面测试 Puppeteer 绝对属于后一种。

Puppeteer 宣传自己是

一个 Node 库,它提供了一组高级 API,通过 DevTools 协议控制无界面 Chrome。

简而言之,基于 Chrome Devtools 协议,Puppeteer 可以让用户界面测试变得很轻松。而所有这一切都是免费的。

什么是 Puppeteer?

Puppeteer 是一个用户界面自动化工具。它通过使用 Chrome 无界面模式和 DevTools 协议的组合来实现这一点。正如上面的引用所言,它使用一个更上层的 API 来封装其功能,让用户界面测试自动化变得轻而易举。

人们基于 Chrome DevTools 协议开发了一系列 Google Chrome 工具。你在浏览器中点击更多工具 -> 开发工具,打开的就是 DevTools 。DevTools 协议是 DevTools 的动力基础,我们现在可以使用 Chrome 中的 DevTools 来做更多的事情。

无界面Chrome 是没有Chrome 的Chrome。是的,你没看错。它允许你从浏览器之外的环境(即命令行)与Chromium 进行交互。

将Chromium 和 Blink 渲染引擎带入命令行使得很多事情变得可行,比如自动化测试。

安装

安装很简单,可以通过 yarn npm 来完成。只需运行下面的命令:

复制代码
yarn add pupeeter
# or "npm i puppeteer"

之后可以像其它 nodejs 程序一样用 node 来运行。

创建截图

有时你想测试像 CSS 这样的东西,确保网站观感没有出现回退。

譬如,对我的博客首页进行截图:

复制代码
const puppeteer = require("puppeteer");
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("http://jackhiston.com/");
await page.screenshot({ path: "jackhiston-blog.png" });
browser.close();
})();

首先我们要引用 puppeteer 作为依赖包。有了这个,你可以启动一个浏览器实例,它实际上也可以在屏幕上加载浏览器,如下所示:

复制代码
const browser = await puppeteer.launch({ headless: false });

注意 headless 选项。

这样你就可以在浏览页面时创建一个全新的页面,然后你可以“转到”一个特定的网址(在这个例子里会转到我的主页)。

然后,我们可以使用内建的屏幕截图功能来保存页面截图。

爬取网页

另外一个应用场景是用 Puppeteer 爬取网站的内容。在下面的例子里,我将浏览骇客新闻并从第一页上取得所有新闻的链接:

复制代码
const puppeteer = require("puppeteer");
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on("console", (...args) => console.log("PAGE LOG:", ...args));
await page.goto("https://news.ycombinator.com", { waitUntil: "networkidle" });
const links = await page.evaluate(() => {
const anchors = Array.from(document.querySelectorAll(".storylink"));
return anchors.map(anchor => anchor.textContent);
});
console.log(links.join("\n"));
browser.close();
})();

这里需要注意的是 page.evaluate 功能。它允许我们检查当前所在的页面 ,就像我们在 Chrome 的 DevTools 里做的那样。

点击链接并浏览

我想展示的最后一个用例是导航。在下面的例子中,我展示了你如何点击页面链接并等待页面加载,并将结果记录下来:

复制代码
const puppeteer = require("puppeteer");
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://news.ycombinator.com", { waitUntil: "networkidle" });
await page.click("a.storylink");
var response = await page.waitForNavigation({ waitUntil: "networkidle" });
console.log(await page.title());
console.log(page.url());
browser.close();
})();

在这里, page.waitForNavigation 是一个很关键的功能。我们可以等到页面加载完毕,因为 promise 只会在点击事件完成后结束。

这对于浏览导航来说非常有用,并且可以进行全面的 UI 用户体验测试。

总结

Puppeteer 的重点是提供 API 来展现 DevTools 协议的功能。

Selenium 这样的工具更加成熟,并提供跨浏览器测试。Puppeteer 不属于 Selenium 这类应用。

Puppeteer 只是许多无界面 Chrome 的应用中的一种。在撰写本文时,已经有很多项目在使用无界面 Chrome。Ken Soh 的博客很好地介绍了这方面的内容。其他使用DevTools 协议的项目可以在这里找到。

Puppeteer 由 Chrome DevTools 团队维护,他们正在寻求各种人才为社区作贡献。因此,你可以通过加入 Puppeteer 开源项目来推动无界面 Chrome 自动化测试。

谢谢阅读。请与朋友分享。

有用的链接

查看英文原文 Making a Master Puppeteer


感谢薛命灯对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-09-24 19:007775
用户头像

发布了 322 篇内容, 共 147.6 次阅读, 收获喜欢 148 次。

关注

评论

发布
暂无评论
发现更多内容

阿里Java岗面试必备JVM指南:内存分配+垃圾回收+调优+类加载器等

Java架构之路

Java 程序员 架构 面试 编程语言

架构师训练营 1 期 -- 第十三周作业

曾彪彪

极客大学架构师训练营

原创 | 使用JPA实现DDD持久化-O/R映射元数据-值属性映射

编程道与术

Java hibernate 编程 mybatis jpa

eCharts -- 如何修改柱状图中相关数据的顺序?如何在鼠标悬浮时增加百分比信息?如何为柱状图设置分组?

Geek_de9857

柱状图 eCharts 修改数据顺序 百分比提示信息 设置分组

第九周作业

Griffenliu

阿里Java研发第2面,都会问什么?斩获阿里P6+的“他”告诉你答案

Java架构之路

Java 程序员 架构 面试 编程语言

原创 | 使用JPA实现DDD持久化-启动JPA程序+通过JPA原生API访问数据

编程道与术

Java hibernate 编程 mybatis jpa

终于有人把性能优化讲清楚了!阿里架构师推荐的Java性能权威指南可太强了

Java架构之路

Java 程序员 架构 面试 编程语言

一周信创舆情观察(12.7~12.13)

统小信uos

原创 | 使用JPA实现DDD持久化-O/R映射元数据-关联属性映射

编程道与术

Java hibernate 编程 mybatis jpa

去 DeepMind 面试是怎样一种体验?

故胤道长

人工智能 面试 谷歌Google 硅谷 移动开发

原创 | 使用JPA实现DDD持久化-O/R映射元数据-值和关联的比较+继承映射

编程道与术

Java hibernate 编程 mybatis jpa

自从看了百度强推的“Spring源码笔记”我从渣渣成功逆袭成为钢铁侠!

比伯

Java 架构 程序人生 计算机 spring源码

盘点 2020 | 感悟总结

idonkeyliu

盘点2020

滴滴DoKit阶段性成果汇报之一机多控

工具 滴滴开源 DoKit

【涂鸦物联网足迹】用煲仔饭来说明IaaS/PaaS/SaaS的区别

IoT云工坊

云计算 IaaS PaaS SaaS 云平台

阿里云容器服务入选云原生边缘「领导力企业TOP3」,推动「原生云边」基础设施标准建立

阿里巴巴云原生

阿里云 容器 开发者 云原生 边缘计算

第九周学习总结

Griffenliu

原创 | 使用JPA实现DDD持久化-通过Spring Data JPA访问数据

编程道与术

Java hibernate 编程 mybatis jpa

架构师训练营第四周命题作业

Geek_xq

佛萨奇Forsage系统开发,智能合约dapp技术

薇電13242772558

智能合约 dapp

15年华为云视频架构师采访实录:揭秘未来音视频行业的科技趋势!

华为云开发者联盟

直播 视频 华为云

Java程序员还没有掌握SpringBoot?这一份文档你真应该好好学学!

Java架构之路

Java 程序员 架构 面试 编程语言

flink 使用curl,通过RESTful api,上传和删除jar包

Geek_de9857

flink RESTful curl 上传jar 删除jar

Mysql中,1=1和 1=1=1 和 -1=-1 和 -1=-1=-1 和 5=5 和 5=5=5 有什么区别

Geek_de9857

MySQL sql 返回值 1=1=1 -1=1=1

JavaScript中,if判断未生效的一些特殊情况

Geek_de9857

js 1 if 0 不生效

读《全球创新投资:经济大变局中的财富新机遇》

邓瑞恒Ryan

创业 读书笔记 企业 企业管理 产业竞争

LeetCode题解:127. 单词接龙,双向BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

一文详解激活函数

书豪

Hive中,同时存在map、array、struct这三种格式,应如何在建表语句中指定分隔符?

Geek_de9857

hive struct map array 分隔符

基于区块链的政务平台设计探索

华为云开发者联盟

区块链 架构 安全

如何成为Puppeteer大师_软件工程_Jack Histon_InfoQ精选文章