这个解决方案中要求node
版本大于v7.6.0
,因为puppeteer
要求最低版本是v6.4.0
,但是官方实例中大量使用async
await
新特性,所以需要使用v7.6.0
或更高版本的node
。
wept
是一个微信小程序web端实时运行工具。它的后台使用 node 提供服务完全动态生成小程序,前端实现了 view 层、service 层和控制层之间的相关通讯逻辑。支持 Mac, Window 以及 Linux。
Chrome团队出品的一款更友好的Headless Chrome Node API ,用于代替用户在页面上面点击、拖拽、输入等多种操作,常见的使用场景还是应用到UI自动化测试,puppeteer可以对页面进行截图保存为图片或者PDF,解决爬虫无法实现的一些操作(异步加载页面内容) 。
其他类似的工具:
在puppeteer
出来以后,phantomjs
即宣布不再继续开发维护,而puppeteer
的使用更简单,功能更丰富,所以这里选择了puppeteer
。
Jest
是 Facebook 出品的一个测试框架,相对其他测试框架,其一大特点就是就是内置了常用的测试工具,比如自带断言、测试覆盖率工具,实现了开箱即用。
其他类似的工具:
npm i -g wept
npm i --save-dev puppeteer jest
在安装puppeteer
有可能会出现以下报错:
ERROR: Failed to download Chromium r508693! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download.
Error: Download failed: server returned code 502. URL: https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/508693/chrome-win32.zip
at ClientRequest.https.get.response (D:\chromium\node_modules\puppeteer\utils\ChromiumDownloader.js:197:21)
at Object.onceWrapper (events.js:316:30)
at emitOne (events.js:115:13)
at ClientRequest.emit (events.js:210:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:116:23)
at Socket.socketOnData (_http_client.js:454:20)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at ClientRequest.onsocket (D:\chromium\node_modules\https-proxy-agent\index.js:181:14)
原因是安装puppeteer
时,都会下载Chromium,然而墙内网络环境不友好可能会导致下载失败。
安装puppeteer
时直接跳过Chromium的下载:
npm install puppeteer --ignore-scripts
手动下载chrome开发版,Win平台下载链接是https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/508693/chrome-win32.zip
翻开仓库源码可以得知其他下载地址:
const downloadURLs = {
linux: 'https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip',
mac: 'https://storage.googleapis.com/chromium-browser-snapshots/Mac/%d/chrome-mac.zip',
win32: 'https://storage.googleapis.com/chromium-browser-snapshots/Win/%d/chrome-win32.zip',
win64: 'https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/%d/chrome-win32.zip',
};
选择对应平台,将%d
替换成具体编号下载即可。
直接在小程序根目录执行wept
,然后打开chrome访问http://localhost:3000/#!pages/index/index ,就可以看到小程序运行在chrome上了
新建一个/test
目录,并增加一个hello.test.js
测试,直接上代码:
const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
(async () => {
try {
const browser = await puppeteer.launch({
// 如果是手动下载chromium则需要制定chromium所在目录的地址
// executablePath: '/chromium/chrome.exe'
headless: false
});
// 新建选项卡
const page = await browser.newPage();
// 设置展示设备
await page.emulate(devices['iPhone 6']);
// waitUnitil参数为了保证截图不是白屏
await page.goto('http://localhost:3000/#!pages/index/index', { waitUntil: 'networkidle2' });
// 截图
// await page.screenshot({path: 'example.png'});
// 根据iframe的name属性来获取正确的iframe
const frames = await page.frames();
const weChatFrame = frames.find(f => f.name() === 'view-0');
const outerText = await weChatFrame.evaluate(() => {
const anchors = Array.from(document.querySelectorAll('.container'));
return anchors.map(anchor => anchor.textContent);
});
console.log('the outerText: ', outerText);
// 关闭页面
await browser.close();
} catch (e) {
console.log(e);
}
})();
完整代码:
const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
test('should return "Hello WorldHello World"', () => {
(async () => {
try {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.emulate(devices['iPhone 6']);
await page.goto('http://localhost:3000/#!pages/index/index', { waitUntil: 'networkidle2' });
const frames = await page.frames();
const weChatFrame = frames.find(f => f.name() === 'view-0');
const outerText = await weChatFrame.evaluate(() => {
const anchors = Array.from(document.querySelectorAll('.container'));
return anchors.map(anchor => anchor.textContent);
});
console.log('the outerText: ', outerText);
expect(outerText[0]).toBe('Hello WorldHello World');
await browser.close();
} catch (e) {
console.log(e);
}
})();
})
运行效果:
此套方案的优点是易于set up,无需代理,支持目前所有的小程序API,可使用Chrome调试。缺点是wept项目作者不再继续维护,并且测试环境和正式环境有一定差异。
另外小程序官方也有一个云测试,但是一个开发者24小时内只能提交一次。