使用puppeteer-实现对Antd-Select-组件自动化测试

41次阅读

共计 2338 个字符,预计需要花费 6 分钟才能阅读完成。

问题描述

项目需要使用 jest+puppeteer 实现对 Antd 组件库中的 Select 组件进行操作,选中其中的某一项的值。测试页面为 Antd Select

使用 puppeteer Recorder 录制出来的测试代码如下所示

const puppeteer = require('puppeteer');
(async () => {const browser = await puppeteer.launch()
  const page = await browser.newPage()
  
  await page.goto('https://ant.design/components/select-cn/')
  
  await page.setViewport({width: 1154, height: 586})
  
  await page.waitForSelector('.ant-select-focused > .ant-select-selection > .ant-select-arrow > .anticon > svg')
  await page.click('.ant-select-focused > .ant-select-selection > .ant-select-arrow > .anticon > svg')
  
  await page.waitForSelector('div > .ant-select-dropdown > #\31 55fc83a-09de-47b7-a57e-a6042a0e3a5b > .ant-select-dropdown-menu > .ant-select-dropdown-menu-item-active')
  await page.click('div > .ant-select-dropdown > #\31 55fc83a-09de-47b7-a57e-a6042a0e3a5b > .ant-select-dropdown-menu > .ant-select-dropdown-menu-item-active')
  
  await browser.close()})()

使用这段代码进行 E2E 测试,经常会在这段代码 timeout

await page.waitForSelector('div > .ant-select-dropdown > #\31 55fc83a-09de-47b7-a57e-a6042a0e3a5b > .ant-select-dropdown-menu > .ant-select-dropdown-menu-item-active')

原因分析

puppeteer 中的 page 对象实际上有一个 select 方法对下拉列表框来进行操作。但是这个方法只能针对原生标签

  <select>
  <option value ="volvo">Volvo</option>
  <option value ="saab">Saab</option>
  <option value="opel">Opel</option>
  <option value="audi">Audi</option>
  </select>
     

antd 中的 select 的实现不是采用原生的 select 这个标签来实现的。使用浏览器控制台来获取它的源代码如下

在这段代码中根本没有下拉选项的代码。其下拉选项的代码出现在页面最底端,并且只有点击了下拉列表框之后才会出现。

如点击了上述的下拉列表之后,才会出现下图所示的代码,也就意味着 antd 的 Select 的实现下拉和列表项是分离的。

使用 puppeteer recorder 录制之后的代码实际上是正确的。但是仔细看这段代码中选中的 selector 的值中有一个#\31 55fc83a-09de-47b7-a57e-a6042a0e3a5b。这是一个 div 的 id,很不幸的是每次刷新页面之后这个 id 就要重新生成,所以就造成了 puppeteer recorder 录制之后的代码在进行测试之后无法执行,每次都是 timeout。

await page.waitForSelector('div > .ant-select-dropdown > #\31 55fc83a-09de-47b7-a57e-a6042a0e3a5b > .ant-select-dropdown-menu > .ant-select-dropdown-menu-item-active')

antd select 标签不是调用的原生的 select 标签, 标签下拉和列表项是分离的

解决方案

方法 1: 最粗暴的办法是在编码时,需要每一个列表项一个不重复的 id

<Select onChange={this.beginYearChange}>
   {yearArr.map(year=><Option key={year}>{year}</Option>)}
</Select>

修改后的代码

<Select onChange={this.beginYearChange}>
   {yearArr.map(year=><Option id={year} key={year}>{year}</Option>)}
</Select>

测试代码

 await page.waitForSelector('.ant-select-focused > .ant-select-selection > .ant-select-arrow > .anticon > svg')
  await page.click('.ant-select-focused > .ant-select-selection > .ant-select-arrow > .anticon > svg')
  
  await page.waitForSelector('ul #具体的 id 值')
  await page.click('ul #具体的 id 值')

方法 2:
使用 page.evaluate 来模拟实现

正文完
 0