使用puppeteer 實現對Antd Select 組件自動化測試

問題描述

項目須要使用jest+puppeteer 實現對Antd組件庫中的Select組件進行操做,選中其中的某一項的值。測試頁面爲Antd Selectgit

使用puppeteer Recorder錄製出來的測試代碼以下所示
圖片描述github

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測試,常常會在這段代碼timeoutapi

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

如點擊了上述的下拉列表以後,纔會出現下圖所示的代碼,也就意味着antd的Select 的實現下拉和列表項是分離的。
圖片描述
使用puppeteer recorder錄製以後的代碼其實是正確的。可是仔細看這段代碼中選中的selector的值中有一個#\31 55fc83a-09de-47b7-a57e-a6042a0e3a5b。這是一個div的id,很不幸的是每次刷新頁面以後這個id就要從新生成,因此就形成了puppeteer recorder錄製以後的代碼在進行測試以後沒法執行,每次都是timeout。async

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:最粗暴的辦法是在編碼時,須要每個列表項一個不重複的idsvg

<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>

測試代碼ui

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來模擬實現this

相關文章
相關標籤/搜索