高等前端进阶
本日给大家带来的主题是2023年PhantomJS的几个可行替代方案,希望大家有须要的时候能够想起来利用它们。话不多说,直接开始!
以前用过 PhantomJS,研究几天后创造 PhantomJS 虽然在业内有一定的影响力,但后继乏力,紧张还是缺少掩护职员,导致项目依赖的 chrome 内核版本太低,无人办理的 BUG 太多,现在已经越来越知足不了真实的前端仿照以及各种新的特性需求(比如高版本 Chrome 的实行环境特性,比如 JS 实行和渲染等都相差很大)。

图片来自:Marko Anastasov
目前PhantomJS的项目官网已经发出了停滞掩护的关照,关于后续是否会连续不得而知。因此本文将带着大家细数那些可行的替代方案!
2.PhantomJS可行的替代方案2.1 puppeteer什么是puppeteer
谷歌浏览器在 17 年开拓了 Chrome Headless 特性,并同时推出了 puppeteer,可以理解成日常利用的 Chrome 的无界面版本以及对其进行操控的 js 接口套装。 借助 puppeteer,实际上是通过调用 Chrome DevTools 开放的接口与 Chrome 通信,Chrome DevTools 的接口很繁芜,但 puppeteer 对其进行了封装,开拓者调用起来还是很方便的。
大多数可以在浏览器中手动完成的事情都可以利用 Puppeteer 完成,比如:
天生页面的屏幕截图和 PDF。抓取 SPA(单页运用程序)并天生预渲染内容(即SSR做事器端渲染)。自动化表单提交、UI 测试、键盘输入等。利用最新的 JavaScript 和浏览器功能创建自动化测试环境。捕获站点的韶光线跟踪以帮助诊断性能问题。测试 Chrome 扩展。puppeteer示例以下示例在 developer.chrome.com 中搜索带有文本“automate beyond recorder”的博文,单击第一个结果并打印博文的完全标题。
import puppeteer from 'puppeteer';(async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://developer.chrome.com/'); // 设置屏幕大小 await page.setViewport({width: 1080, height: 1024}); // 输入框添补内容 await page.type('.search-box__input', 'automate beyond recorder'); // 等待和点击第一个结果 const searchResultSelector = '.search-box__link'; await page.waitForSelector(searchResultSelector); await page.click(searchResultSelector); //利用唯一字符串找到完全标题 const textSelector = await page.waitForSelector( 'text/Customize and automate' ); const fullTitle = await textSelector.evaluate(el => el.textContent); // 打印完全标题 console.log('The title of this blog post is "%s".', fullTitle); await browser.close();})();
目前 puppeteer 在Github上有82.4k的star、8.9k的fork、超过312k的项目依赖它,代码贡献者人数超过450+。从NPM的利用数据来看,最近周下载量也达到了4156k旁边,而且基本坚持稳定。
2.2 Playwright2.2.1 什么是PlaywrightPlaywright 是一个用于 Web 测试和自动化的框架。它许可利用单个 API 测试 Chromium、Firefox 和 WebKit。Playwright具有以下显著特色:
任何浏览器 • 任何平台 • 一个 API跨浏览器:Playwright 支持所有当代渲染引擎,包括 Chromium、WebKit 、 Firefox。跨平台:在 Windows、Linux 和 macOS 上进行本地测试或在 CI 上进行无/有头测试。跨措辞:在 TypeScript、JavaScript、Python、.NET、Java 中利用 Playwright API。测试移动网络:适用于 Android 和 Mobile Safari 的 Google Chrome 浏览器的本机移动仿真, 相同的渲染引擎适用于桌面和云端。弹性 • 保持测试稳定自动等待:Playwright在实行动作之前等待元素可操作, 同时还具有一组丰富的内置事宜。 两者的结合肃清了人为超时的可能性,这是不稳定测试的紧张缘故原由。Web优先断言: Playwright断言是专门为动态网络创建的,检讨会自动重试,直到知足必要的条件。追踪: 配置测试重试策略,捕获实行跟踪、视频、屏幕截图以肃清薄片。没有权衡 • 没有限定浏览器在不同进程中运行属于不同来源的 Web 内容:Playwright 与当代浏览器架构保持同等,并在进程外运行测试。 这使得 Playwright 摆脱了范例的进程内测试运行器的限定。Multiple everything: 跨多个选项卡、多个来源和多个用户的测试场景。 为不同的用户创建具有不同高下文的场景,并在做事器上运行它们,所有这些都在一次测试中完成。可信事宜:悬停元素,与动态控件交互,产生可信事宜。 Playwright 利用与真实用户无法区分的真实浏览器输入管道。测试框架,穿透 Shadow DOM: Playwright选择器穿透影子 DOM 并许可无缝地输入帧。完备隔离 • 快速实行浏览器高下文: Playwright 为每个测试创建一个浏览器高下文, 浏览器高下文相称于一个全新的浏览器配置文件。 这供应了零开销的完备测试隔离,创建一个新的浏览器高下文只须要几毫秒。登录一次: 保存高下文的身份验证状态并在所有测试中重用它, 这绕过了每个测试中的重复登录操作,但供应了独立测试的完备隔离。强大的工具代码天生器: 通过记录操作来天生测试, 许可将测试结果保存为任何措辞。Playwright 检测: 检讨页面、天生选择器、逐步实行测试、查看点击、探索实行日志。跟踪查看器: 捕获所有信息以调查测试失落败缘故原由, Playwright 跟踪包含测试实行截屏、实时 DOM 快照、动作资源管理器、测试源等等。2.2.2 Playwright示例
下面代码片段导航到 whatsmyuseragent.org 并保存屏幕截图。
import { test } from '@playwright/test';test('Page Screenshot', async ({ page }) => { await page.goto('http://whatsmyuseragent.org/'); await page.screenshot({ path: `example.png` });});
下面代码段在给定地理位置的设备上仿照 Mobile Safari,导航到 maps.google.com,实行操作并截取屏幕截图。
import { test, devices } from '@playwright/test';test.use({ ...devices['iPhone 13 Pro'], locale: 'en-US', geolocation: { longitude: 12.492507, latitude: 41.889938 }, permissions: ['geolocation'],})test('Mobile and geolocation', async ({ page }) => { await page.goto('https://maps.google.com'); await page.locator('text="Your location"').click(); await page.waitForRequest(/.preview\/pwa/); await page.screenshot({ path: 'colosseum-iphone.png' });});
下面代码片段导航到 example.com,并在页面高下文中实行脚本。
import { test } from '@playwright/test';test('Evaluate in browser context', async ({ page }) => { await page.goto('https://www.example.com/'); const dimensions = await page.evaluate(() => { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight, deviceScaleFactor: window.devicePixelRatio } }); console.log(dimensions);});
下面代码片段为页面设置要求路由以记录所有网络要求。
import { test } from '@playwright/test';test('Intercept network requests', async ({ page }) => { // Log and continue all network requests await page.route('', route => { console.log(route.request().url()); route.continue(); }); await page.goto('http://todomvc.com');});
目前 playwright 在Github上有48.9k的star、2.4k的fork、超过24.5k的项目依赖它,代码贡献者人数超过380+。从NPM的利用数据来看,最近周下载量也达到了1316k旁边,而且基本坚持稳定。
2.3 Selenium2.3.1 什么是SeleniumSelenium 是一个综合项目,封装了各种支持 Web 浏览器自动化的工具和库。 Selenium 专门为 W3C WebDriver 规范供应了一个根本举动步伐,即一个与所有主流浏览器兼容的平台和措辞中立的编码接口。
该项目是由志愿贡献者供应的,捐赠了数千小时用于代码开拓和掩护。Selenium 的源代码在 Apache 2.0 容许证下可用。
Selenium是最广泛利用的开源Web UI(用户界面)自动化测试套件之一,支持跨不同浏览器,平台和编程措辞的自动化能力。优点是:支持多款主流浏览器,供应了功能丰富的API 接口。
但是Selenium比较于其他方案也有不少问题,比如:
速率太慢、对版本配置哀求严苛,最麻烦是常常要更新对应的驱动。保护机制不许可跨域 cookies 保存,登录的时候必须先打开网页然后加载 cookies 再刷新的办法很不友好2.3.2 如何利用Selenium下面的示例和其他示例包含在exmaple目录,还包含 selenium-webdriver 的测试信息。
const {Builder, By, Key, until} = require('selenium-webdriver');(async function example() { let driver = await new Builder().forBrowser('firefox').build(); try { await driver.get('http://www.google.com/ncr'); await driver.findElement(By.name('q'));.sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); } finally { await driver.quit(); }})();
Builder 类是配置新 WebDriver 实例的一站式store, 构建器许可在一个流程中设置所有选项。 当调用 Builder#build() 时,与所选浏览器无关的所有选项都将被删除:
const webdriver = require('selenium-webdriver');const chrome = require('selenium-webdriver/chrome');const firefox = require('selenium-webdriver/firefox');let driver = new webdriver.Builder() .forBrowser('firefox') .setChromeOptions(/ ... /) .setFirefoxOptions(/ ... /) .build();
目前 Selenium 在Github上有26.1k的star、7.5k的fork、超过191k的项目依赖它,代码贡献者人数超过660+。从NPM的利用数据来看,最近周下载量也达到了2280k旁边,而且基本坚持稳定。
2.4 Cypress什么是CypressCypress 是一个开源测试实行实用程序,可让开发者对代码进行测试。 由于它利用 JavaScript,因此吸引了大多数开拓职员和测试自动化工程师。
端到端测试工具许可创建脚本并高速运行, 还可以将鼠标悬停在特定命令上以查看详细信息并截取特定屏幕截图。
因此,借助 Cypress,开拓者可以轻松为当代 Web 运用程序创建测试、可视化调试它们,并在持续集成构建中自动运行。
Cypress紧张特点如下:
具有自己的 IDE,可进行全面的运用程序测试利用 JavaScript 编程措辞支持多种浏览器进行网络测试和自动化端到端测试更随意马虎实行,速率更快关于如何利用Cypress,本文不再连续展开,可以参考文末的资料。目前 Cypress 在Github上有43k的star、2.8k的fork、超过748k的项目依赖它,代码贡献者人数超过230+。从NPM的利用数据来看,最近周下载量也达到了4874k旁边,而且基本坚持稳定。
2.5 webdriverio2.5.1 什么是webdriverio下面是webdriverio对付自己的定位,即用于 Node.js 的下一代浏览器和移动自动化测试框架。
Next-gen browser and mobile automation test framework for Node.js
webdriverio在 WebDriver 规范之上供应了一个易于管理的 API 和大量语法糖。 开拓者可以将 WebdriverIO 作为独立包利用,也可以利用 @wdio/cli 通过测试运行器利用。
WebdriverIO 许可利用 WebDriver 或 Chrome DevTools 协议在本地运行测试,以及利用 Sauce Labs 等云供应商的远程用户代理。
WebdriverIO具有以下明显特性:
真实环境测试 :WebdriverIO 许可在用户利用的实际浏览器或移动设备中进行测试。多功能支持:利用 WebdriverIO 在浏览器中进行完全的 e2e 或单元和组件测试。自动等待 :WebdriverIO 在与元素交互之前自动等待元素涌现。基于Web标准 :通过 WebDriver 和 WebDriver Bidi 自动化实现跨浏览器支持。本机支持 :通过 Appium 在真实的移动设备、智能电视或其他物联网设备上运行 WebdriverIO。设计支持 :运行一个拥有超过 8000 名成员的支持渠道和丰富的社区掩护插件生态系统。2.5.2 如何利用WebdriverIOWebdriverIO 默认利用 Puppeteer 来自动化浏览器,如 Chrome、Firefox 或 Chromium Edge。 因此,如果安装了 Chrome,以下脚本该当会自动启动浏览器并获取页面标题:
import { remote } from 'webdriverio'let browser;(async () => { browser = await remote({ capabilities: { browserName: 'chrome' } }) await browser.navigateTo('https://www.google.com/ncr') const searchInput = await browser.$('#lst-ib') await searchInput.setValue('WebdriverIO') const searchBtn = await browser.$('input[value="Google Search"]') await searchBtn.click() console.log(await browser.getTitle()) // outputs "WebdriverIO - Google Search" await browser.deleteSession()})().catch((err) => { console.error(err) return browser.deleteSession()})
目前 WebdriverIO 在Github上有8k的star、2.3k的fork、超过50k的项目依赖它,代码贡献者人数超过480+。从NPM的利用数据来看,最近周下载量也达到了1320k旁边,而且基本坚持稳定。
3.6 其他方案nightwatchjsNightwatch 是由 Node.js 供应支持并利用 W3C Webdriver API 的集成测试框架。 它是 BrowserStack 开拓的完全测试办理方案,可用于:
☑️ Web 运用程序和网站的端到端测试☑️ 隔离组件测试(React / Vue)☑️ Node.js 单元和 API 测试目前 Nightwatch 在Github上有11.3k的star、1.1k的fork、超过141k的项目依赖它,代码贡献者人数超过100+。从NPM的利用数据来看,最近周下载量也达到了268k旁边。
Zombie.jsZombie.js是利用 Node.js 进行快速、无头的全栈测试工具。Zombie.js 是一个轻量级框架,用于在仿照环境中测试客户端 JavaScript 代码而无需浏览器。
const Browser = require('zombie');// We're going to make requests to http://example.com/signup// Which will be routed to our test server localhost:3000Browser.localhost('example.com', 3000);describe('User visits signup page', function() { const browser = new Browser(); before(function(done) { browser.visit('/signup', done); }); describe('submits form', function() { before(function(done) { browser .fill('email', 'zombie@underworld.dead') .fill('password', 'eat-the-living') .pressButton('Sign Me Up!', done); }); it('should be successful', function() { browser.assert.success(); }); it('should see welcome page', function() { browser.assert.text('title', 'Welcome To Brains Depot'); }); });});
目前 Zombie 在Github上有5.6k的star、560+的fork。从NPM的利用数据来看,最近周下载量也达到了6k旁边,值得持续关注!
QUnitQUnit 是一个功能强大、易于利用的 JavaScript 测试框架。 它最初是为 jQuery 项目开拓的,后来发展到可以测试任何客户端或做事器真个 JavaScript 代码。 QUnit 没有依赖性,支持 Node.js、SpiderMonkey 和所有紧张的网络浏览器。
目前 QUnit 在Github上有4k的star、800+的fork、超过63.5k的项目依赖它,代码贡献者人数超过100+。从NPM的利用数据来看,最近周下载量也达到了192k旁边。
3.本文总结本文紧张和大家先容下PhantomJS停滞掩护后,2023年3个可行的替代品。相信通过本文的比较,大家对puppeteer、Playwright、Selenium、Cypress、WebdriverIO、nightwatchjs 、Zombie 、QUnit都会有一个初步的理解。不才次真实的项目中也能有一个充分的、择优的考量!
由于篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页连续阅读,同时文末的参考资料供应了大量精良文档以供学习。末了,欢迎大家点赞、评论、转发、收藏!
参考资料
https://github.com/puppeteer/puppeteer/tree/main
https://github.com/Microsoft/playwright
https://playwright.dev/
https://github.com/SeleniumHQ/selenium
https://www.npmjs.com/package/selenium-webdriver
https://www.selenium.dev/
https://blog.csdn.net/weixin_38235865/article/details/122838410
https://github.com/casperjs/casperjs
https://github.com/cypress-io/cypress
https://docs.cypress.io/guides/getting-started/installing-cypress
https://github.com/webdriverio/webdriverio
https://testsigma.com/blog/puppeteer-alternatives/
https://github.com/qunitjs/qunit
https://qunitjs.com/intro/#browser-support