gpt4 book ai didi

Selenium WebDriver 无法单击 内的

转载 作者:行者123 更新时间:2023-12-04 09:04:21 24 4
gpt4 key购买 nike

我正在为 angular/clarity 应用程序编写自动化测试,我想先输入
一些文本进入输入字段,然后从数据列表中选择一个选项。
UI and HTML
将文本设置为输入字段工作正常,但是当尝试单击
选项元素我得到以下异常:

Caused by: org.openqa.selenium.JavascriptException: javascript error: option element is not in a select
我已经尝试过使用 selenium 和 javascript 单击它。下面是两者的代码。
@Override
public void click(String xpath, MouseButton button, ClickPosition position)
{
LOG.info("Clicking on element '{}' with Mouse Button '{}' on Position '{}'!", xpath, button, position);

final WebElement element = find(xpath);

//in case we have a standard click (left on center) we spare out the whole calculation and just use standard click
if (button == MouseButton.LEFT && position == ClickPosition.CENTER)
{
element.click();
}
else
{
final Dimension size = element.getSize();

// opposite to the javadoc, the Actions#moveToElement() method is relative to the center and not to the top left corner with selenium api version 3.14.0
// REMARK: there is an issue currently filed so may be changed back at some point
final Point relativePoint = position.calculateRelativePointFromCenter(size.width - 1, size.height - 1);

performActions(a -> {
try
{
a.moveToElement(element, relativePoint.x, relativePoint.y);
switch (button)
{
case LEFT:
a.click();
break;
case RIGHT:
a.contextClick();
break;
case MIDDLE:
default:
throw new UnsupportedOperationException("Unexpected click button: " + button);
}
}
catch (final WebDriverException e)
{
if (e.getMessage().contains("Element is not clickable"))
{
throw new ElementNotClickableException("Unable to click on element with XPath '" + xpath + "'",
e);
}
}
});
}
}
@Override
public void javascriptClick(String xpath)
{
LOG.info("Triggering click event on element '{}' via javascript!", xpath);
parent.executeJavascript("arguments[0].click();", find(xpath));
}
System info: host: 'XXX', ip: 'XXX', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_191'
Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities {browserName: chrome, browserVersion: 84.0.4147.125, chrome: {chromedriverVersion: 84.0.4147.30}
有没有人知道这里出了什么问题?

最佳答案

这是个好问题。 Datalistoption s 似乎很简单,但 selenium 不喜欢它们。我通读了数据列表和选项的 w3c 标准——它们是为自动完成支持而不是选择而设计的。
html living spec说:

The datalist element represents a set of option elements thatrepresent predefined options for other controls. In the rendering, thedatalist element represents nothing and it, along with its children,should be hidden


而对于 input field规范说:

When the user selects a suggestion, the input element's value must beset to the selected suggestion's value, as if the user had writtenthat value themself.


所以真的,这个数据列表只是用值填充输入......
我能够用一段非常简单的 html 重现你的错误:
<html>
<body>
<input id="input" list="datalist">
<datalist class="c" id="datalist">
<option value="AUTO00001TEST - AutoTestRequestPart" class="ng-star-inserted"></option>
</datalist>
</input
</body>
</html>
正如你所说的 - 一个正常的 Selenium 点击会引发一个 js 错误:

Javascript error: option element is not in a select


你也...
  • 无法将其转换为 Select 对象类型,因为它不接受数据列表标签
  • 无法直接单击数据列表,因为它会抛出 ElementNotIteractable
  • 无法使用移动到和单击操作 - 您会收到“无法在“文档”上执行“elementsFromPoint””
  • 不能使用操作键按下 + 键输入 - 只是不这样做
  • 无法使用 JS 执行器点击 - 什么都不做

  • 所以 - 剩下的就是重新创建规范所说的下拉菜单。
  • 在输入中键入您的部分文本。
  • 获取您的选项对象(确认弹出窗口存在)
  • 获取 value 属性
  • 清除并发送 key 到输入

  • 这段代码对我有用,可以输入完整值:
        var input = driver.findElement(By.id("input"));
    input.sendKeys("Auto");

    String optionValue = driver.findElement(By.xpath("//option[contains(@value,'TEST')]")).getAttribute("value");
    input.clear();
    input.sendKeys(optionValue);
    我知道这并不理想,但它是一种解决方法,也是一个开始。
    您还将看到我添加了一些简单的 ID 来简化我的代码。您需要将这些更新为您的标识符

    如果其他人有任何想法和尝试的东西,这是我尝试过的其他所有内容,但不适用于我的示例页面:
                       //JS error in question
    driver.findElement(By.xpath("//option[contains(@value,'TEST')]")).click();

    //can only create from select
    var select = new Select(driver.findElement(By.id("datalist")));
    select.selectByIndex(0); // only 1 option with specific text

    //element not interactable
    driver.findElement(By.id("datalist")).click();

    //This works!
    String optionValue = driver.findElement(By.xpath("//option[contains(@value,'TEST')]")).getAttribute("value");
    input.clear();
    input.sendKeys(optionValue);
    //potentially press enter if required.

    //Failed to execute 'elementsFromPoint' on 'Document': The provided double value is non-finite.
    var options = driver.findElement(By.xpath("//option[contains(@value,'TEST')]"));
    var actions = new Actions(driver);
    actions.moveToElement(options).click().build().perform();

    //does nothing!
    var options = driver.findElement(By.xpath("//option[contains(@value,'TEST')]"));
    var actions = new Actions(driver);
    actions.click(input).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ENTER).build().perform();

    //does nothing - doesn't click
    var options = driver.findElement(By.xpath("//option[contains(@value,'TEST')]"));
    JavascriptExecutor js = (JavascriptExecutor)driver;
    js.executeScript("arguments[0].click();",options);
    (重复相同的变量,因此一次使用一个)

    关于Selenium WebDriver 无法单击 <datalist> 内的 <option> 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63486374/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com