lmk123 / blog

个人技术博客,博文写在 Issues 里。
https://github.com/lmk123/blog/issues
623 stars 35 forks source link

尝试用 Puppeteer 测试扩展程序 #107

Open lmk123 opened 2 years ago

lmk123 commented 2 years ago

《自动化测试 JavaScript》中,我提到我想用 Puppeteer 测试划词翻译。今天花了一些时间尝试了一下。

搭建测试工具

首先需要安装 puppeteer 和 jest-puppeteer。在安装 puppeteer 前,记得先将 puppeteer_download_host=https://npm.taobao.org/mirrors 写进 .npmrc 文件以加快下载速度。

另外,划词翻译已经用 Jest 写了单元测试了。为了能单独运行集成测试,所以我在 jest.config.js 里用到了 projects 选项将测试分为了两个部分:

module.exports = {
  projects: [
    {
      displayName: '单元测试',
      collectCoverage: true,
      coverageDirectory: 'coverage',
      preset: 'ts-jest',
    },
    {
      displayName: '集成测试',
      preset: 'jest-puppeteer',
      testMatch: ['**/__integration__/**/*.[jt]s?(x)']
    },
  ],
}

这样就可以通过 jest --selectProjects 集成测试 来单独运行指定的测试了。

最后,还需要通过 jest-puppeteer.config.js 来加载扩展程序文件夹:

const pathToExtension = require('path').join(__dirname, 'path/to/extension')

module.exports = {
  launch: {
    headless: false,
    args: [
      `--disable-extensions-except=${pathToExtension}`,
      `--load-extension=${pathToExtension}`,
    ],
  },
}

相关阅读 - Puppeteer working with chrome extensions

这样一来,测试工具就搭建好了,现在就可以开始写测试了,但是在写第一个测试的过程中,我就发现了 Puppeteer 的一个不足之处:无法真实模拟用户的操作。

我想要测试用户在划词后,划词翻译的按钮是否正常隐藏,那么首先我得模拟用户的划词操作,但是我发现这做不到,并且不止是划词,包括 Ctrl + A 全选、Ctrl + F 弹出搜索框、双击选中单词、打开邮件菜单等操作都不行。相关的问题有:

Puppeteer 给出的回答基本是让用户用 page.evaluate() 来执行 JavaScript 来模拟这些操作,但本质上这并不是用户的真实操作,而且有些操作是无法模拟的,例如选择右键菜单里的选项。

而另一方面,根据上面这些 issue 里的反馈,Selenium 似乎是能模拟用户的真实操作的,以下是选择右键菜单的问题里一个用户的回复:

https://github.com/puppeteer/puppeteer/issues/1575#issuecomment-449015605

No, I dropped Puppeteer and just used Selenium, and did what I needed to do with flags to Chrome.

所以,我决定改为用 Selenium 来做测试了 :joy:


了解了一圈之后,发现做端到端测试的工具除了 Selenium 还有很多别的。

相关阅读 - Which Automation Tool is the Best: Selenium Web Driver | Cypress | WebdriverIO | TestCafe | Playwright

也了解到了这些工具操纵浏览器的两种方式:WebDrivier 和 Devtools。Puppeteer 使用的就是 Devtools。

但是经过一番调查,这两种方式似乎都不支持选择浏览器的右键菜单。按照 Puppeteer 的说法,浏览器的右键菜单属于操作系统层面的了。

双击鼠标选中文字似乎也无法实现。

换句话说,WebDrivier 和 Devtools 触发事件时就只是用了 EventTarget.dispatchEvent() 一样,并不等同于用户的真实操作。

看来我最终只能用 Puppeteer 做一些简单的测试了。

nst909 commented 2 years ago

不错的