项目需要使用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来模拟实现