目前 puppeteer 已经成为了非常流行的 Node.js 的库,被广泛用于爬虫或 UI 测试。
我也很欢喜 puppeteer 这个库。然而,puppeteer 的几乎所有的 API 都是异步的,它返回的是一个 Promise
。
这就导致整个代码有点啰嗦,下面是官方的例子:
const puppeteer = require('puppeteer')
void (async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('http://example.com')
await page.screenshot({ path: 'example.png' })
await browser.close()
})()
如您所见,一堆的 await
关键字使得代码不太优雅。为了要使用 async/await
,您必须将代码放入一个立即执行函数(IIFE)里。
为此,我受到了 Laravel Dusk 的启发,写了 Rize
这个库。
上面的例子如果用 Rize 重写,将会是这个样子:
const Rize = require('rize')
const rize = new Rize()
rize
.goto('http://example.com')
.saveScreenshot('example.png')
.end()
代码简单得多了。另外,链式的 API 调用也是代码变得优雅。
除了提供基本的操作(如页面导航、对 DOM 操作、与表单进行交互),Rize 这个库还提供了一些断言方法。
为什么呢?因为我们经常利用 puppeteer 来进行 UI 测试。而 Rize 提供了一系列的 assertions,使得 UI 测试变得简单、方便,E2E 测试同样没有问题。
例如,您可以断言当前页面的 URL:
const rize = new Rize()
rize.assertUrlIs('http://example.com')
又或者断言指定的文本是否存在于页面上:
const rize = new Rize()
rize.assertSee('Some text')
还可以为 DOM 断言:
const rize = new Rize()
rize.assertClassHas('div', 'my-class')
上面这个函数可以断言指定的元素上是否存在指定的类名。更多的 API 可以参考 Rize 的文档(链接在下方)。
Rize 库的 GitHub 仓库:https://github.com/g-plane/rize (欢迎 star)
Rize 库的文档教程:https://rize.js.org/
Rize 库所有的 API 参考:https://rize.js.org/api/classes/index.rize.html
一堆的 await 关键字使得代码不太优雅…
不能苟同。
遇到需要异步处理的很多需求的时候。。。。
@anuxs 目前就除了获取数据这一部分不得不返回 Promise 之外(因为它们必须返回有效的数据),其它都是链式的,用起来就像 jQuery 那样。
如果业务操作很多,每一步以后都需要处理数据呢?await就显得很必要 自豪地采用 CNodeJS ionic
@lpbird 如果你是要获取数据(也就是 get 而不是 set),在这个库中仍然需要使用 await;但相反,如果是 set 或者是在做测试断言,完全不需要 await(除了在最后后退出浏览器可能需要 await)。