Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use playwright for e2e test #5663

Closed
wants to merge 21 commits into from
Closed

chore: use playwright for e2e test #5663

wants to merge 21 commits into from

Conversation

xiaoiver
Copy link
Contributor

@xiaoiver xiaoiver commented Oct 19, 2023

使用 Playwright 进行截图测试,代替原有的 node-canvas / headless-gl,好处如下:

  • 易于安装。node-canvas 和 headless-gl 都需要下载后本地编译,Playwright 只需要下载 Chrome / Firefox / Edge 无需编译
  • 可以截取 HTML 内容,例如包含 tooltip 的示例
  • 使用最新的 Chrome 可以支持 WebGL 1/2 甚至 WebGPU
  • 官方直接提供了 toHaveScreenshot 这样的断言,内置像素级对比,失败后在 report 中展示 diff
  • 支持 sharding 在 CI 上支持多机器并行,每个机器又可以开启多线程。例如我们使用 4 个机器,每个机器开 10 个 worker 并行:
Running 73 tests using 10 workers, shard 1 of 4

需要注意该方案并不能完全代替已有的 node-canvas / headless-gl / JSDOM 服务端渲染方案,只是更适合做 e2e 测试。
另外也不能代替 Jest 做单元测试以及统计代码覆盖率。

详细方案如下:

  1. 启动 Vite 开发服务器
  2. 访问各个测试页面并截图
  3. 上传截图结果报告
  4. 动画测试
  5. 交互测试

启动开发服务器

Playwright 提供了test-webserver 用于在测试开始前启动服务器

webServer: {
  command: 'npm run dev',
  url: 'http://127.0.0.1:8080',
  reuseExistingServer: !process.env.CI,
  stdout: 'ignore',
  stderr: 'pipe',
},
use: {
  baseURL: 'http://127.0.0.1:8080',
},

访问页面并截图

在测试用例中截取 <canvas>,与基准图片进行对比:

await expect(page.locator('canvas')).toHaveScreenshot(
  'static-scoreByItemAreaRadar.png',
);

为了确保截图时机准确,例如渲染完成后立刻触发截图,使用 exposeFunction 向页面中 window 对象挂载 screenshot 方法:

await context.exposeFunction('screenshot', async () => {
  resolveReadyPromise();
});

这样在浏览器的测试页面中就可以随时调用该方法,例如渲染完成后:

// __tests__/main.ts
async function plot() {
  const render = tests[selectChart.value];
  render && render(currentContainer); // 渲染图表
  (await window.screenshot) && window.screenshot(); // 通知 Playwright 的测试用例进行截图
}

上传截图结果报告

跑 e2e.yml 后回上传 Playwright 的截图测试报告到 artifact 中:

动画测试

核心思路还是使用 G 提供的 Animation API 精确控制动画流程,需要在页面中 window 对象上挂载 goTo 方法,然后在测试用例中调用。Playwright 提供了 evaluate 方法用于执行页面中的方法:

问题记录

import ESM 报错

Playwright 设计成只允许执行 CJS,也不提供 ESM -> CJS 的转译,因此没有提供类似 Jest 的 transformIgnorePatterns
这就导致测试用例中类似 d3-* 这样的依赖会报错:

Error: require() of ES Module /Users/panyuqi/Documents/ant/G2/node_modules/_d3-random@3.0.1@d3-random/src/index.js from /Users/panyuqi/Documents/ant/G2/__tests__/plots/static/cars2-point-jitterY.ts not supported.

目前的解决方式来自:microsoft/playwright#7121 (comment)

paths: {
    'd3-*': [
        './stub.js'
    ],
}

截图高度 1px 误差

关于基准图片生成,由于 Chrome 在不同操作系统环境下截图存在不一致现象(例如高度多 1px),甚至官方也推荐在 CI 环境截图

我自己测试下来造成截图 1px 误差的原因来自 <canvas> 在页面中的位置坐标不为整数,设置上面的一排 UI 高度为整数可以解决:

const $wrapper = document.createElement('div');
$wrapper.style.height = '50px'; // 设置一个固定的整数高度
app.append($wrapper);
$wrapper.append(selectChart);
$wrapper.append(searchInput);
$wrapper.append(selectRenderer);
$wrapper.append(span);

@coveralls
Copy link

coveralls commented Oct 20, 2023

Pull Request Test Coverage Report for Build 6584873773

  • 3 of 3 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.001%) to 88.172%

Totals Coverage Status
Change from base Build 6572218518: 0.001%
Covered Lines: 10043
Relevant Lines: 11027

💛 - Coveralls

@xiaoiver
Copy link
Contributor Author

xiaoiver commented Nov 3, 2023

Playwright 在不同环境下还是会有差异,尤其是文本,下图为本地和 CI 的 diff:
alphabetIntervalHtmlLabel-actual
alphabetIntervalHtmlLabel-diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants