最佳做法是等待下拉列表并在JS中使用Selenium选择一个值



我有一个用 React 编写的网站(不是我写的),我目前正在使用 selenium 选择一个下拉列表并从中选择一个值

既然是 React,我不能只是等待 DOM 准备好(无论如何我都会这样做)。

所以,我写了那些行,实际上正在工作:

  • 点击下拉菜单的前 3 行
  • 最后 3 个从下拉列表中选择一个元素
/** Find dropdown and click on it */
await driver.wait(until.elementLocated(By.css('div#discipline')))
const dropdown = await driver.findElement(By.css('div#discipline'))
await dropdown.click()

/** Wait the list, find element to select and click on it */
const dropOpts = await driver.wait(until.elementLocated(By.css('div#menu-discipline > div > ul')))
await driver.wait(until.elementLocated(By.xpath('//li[contains(text(),"Infirmary")]')))
const choice = await dropOpts.findElement(By.xpath('//li[contains(text(),"Infirmary")]'))        
await choice.click()
  • 第一个问题是关于它是否真的正确(它运行但不一定正确!
  • 第二个问题是:第一个元素是否正确,等待然后找到它?还是我应该做相反的事情?
  • 第三个也是最重要的问题:最后 3 行代码呢? A) 等待下拉菜单的元素 B)等待下拉菜单出现 driver.wait C) 找到我想用findElement选择的元素吗?还是我应该先findElement然后等待它出现?

我对此有点困惑。

我最终创建了一个函数

  • 使用elementLocated,因为这个函数在自己的代码中使用findElement;
  • 使用elementIsVisible,因为它检查元素是否可见
  • 使用elementIsEnabled,因为它检查元素是否已启用(最后两个检查是检查元素是否确实存在于 DOM 中的标准方法,路易斯回答)

代码如下:

async function waitAndClickElement(driver, selectorType, selector) {
let element
try {
element = await driver.wait(until.elementLocated(By[selectorType](selector)), timeout)
await driver.wait(until.elementIsVisible(element), timeout)
await driver.wait(until.elementIsEnabled(element), timeout)
await element.click()
} catch (error) {
console.error('Something went wrong!n', error.stack, 'n')
throw error
}
return element
}

这样,您还可以使用首选选择器,只需在参数中插入selectorType作为string即可。

然后,我使用了这个函数两次:一个用于选择下拉列表,第二个用于选择一个元素:

/** Find dropdown 'test' and click on it */
await waitAndClickElement(driver, 'css', 'div#test')
/** Wait the list, find element to select and click on it */
await waitAndClickElement(
driver,
'xpath',
`//li[contains(text(),"myText")]`,
)

最新更新