Selenium 无法使用无头浏览器单击元素,但相同的代码在 UI 浏览器中工作正常
Selenium unable to click on element using headless browser, but same code works fine with a UI browser
我有一个包含下拉菜单的页面(使用 'span' 和 'li' 元素创建)。下拉菜单有一些选项也有一个子菜单,当你点击父菜单时帽子是可见的(下面给出的代码)。当使用 UI 浏览器(chrome 或 firefox)时,我使用一个简单的:
webDriver.findElement(By.xpath("//span[contains(text(), '" + menuOption + "')]"));
上面的代码有效,但是当我在同一个浏览器的无头模式下使用相同的代码时,它不起作用并给出错误:
org.openqa.selenium.ElementNotInteractableException: element not interactable
我尝试使用以下方法 select 父节点,然后单击子节点,但结果相似:
webDriver.findElement(By.xpath("//span[contains(text(), '" + sItemActionMenu + "')]")).isSelected();
webDriver.findElement(By.xpath("//span[contains(text(), '" + menuOption + "')]"));
已经通过并检查了其他可用的解决方案,使用 JavascriptExecutor,等待元素可见等:
Unable to Click Button with Headless Selenium Browser
Click on hidden element Selenium webdriver(javascript)
Selenium - Unable to click on link from dropdown list
但是none给出了明确的答案,提供的解决方案并没有解决我的问题,甚至尝试使用JavascriptExecutor:
JavascriptExecutor js = (JavascriptExecutor) DriverFactory.getDriver();
WebElement weItemMenu = webDriver.findElement(By.xpath("//span[contains(text(), '" + menuOption + "')]"));
我尝试点击的代码是:
<div class="menu-panel-wrapper" style="top: 0px; left: 1384.83px;">
<ul class="menu menu-format-standard menu-regular" role="menu" id="pyNavi1614647592355" data-menu-id="-pyNavi1614647592355" style="display: block; top: 0px; left: 0px; max-height: 570px;">
<li class="menu-item menu-item-enabled" role="presentation" data-childnodesid="$pNavi1614647592355$pElements" id="menu-item-$pNavi1614647592355$pElements">
<a href="#" onclick="pd(event);" class="menu-item-anchor menu-item-expand" tabindex="0" role="menuitem" aria-haspopup="true">
<span class="menu-item-title-wrap" data-click=".">
<span class="menu-item-title" data-click="..">Parent MenuItem</span>
</span>
</a>
<div class="menu-panel-wrapper" style="top: 1px; left: 245.547px; border-left: 17px solid transparent;">
<ul class="menu menu-format-standard menu-regular" role="menu" id="$pNav1614647592355$pElements" data-menu-id="-2" style="display: none; max-height: 570px;">
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="0" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem1","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">MenuItem1</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled menu-item-active" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="0" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem2 ","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item 2</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem3","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item 3</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem4","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">MenuItem4</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem5","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">MenuItem5</span></span>
</a>
</li>
<li class="menu-item-separator" role="separator"> </li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem6","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item6</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem7","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item7</span></span>
</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
菜单看起来像这样(由于限制不能给出实际的,但代码是real/correct,名称已更改):
我什至尝试使用以下内容:
webDriver.findElement(By.xpath("//ul[@id=\"$pNavi1614647592355$pElements\"]//li//span[contains(text(), '" + menuOption + "')]")).click();
但这不适用于 UI 浏览器或无头浏览器。在以上所有示例中,'menuOption' 是一个变量,它被传递以确定名称(例如 MenuItem1、Menu Item 2、Menu Item3 等)
关于如何点击上述代码中的子菜单选项有什么建议吗?此选项最初似乎是 'hidden',当父选项在 UI 中被 select 编辑时,它会显示子选项。
如果我正确理解了您的操作:移动到第一个元素,然后移动到第二个元素并单击它。
尝试等到第一个元素可点击,然后像这样使用 Actions
class:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Click {
private final WebDriver driver;
private By parentMenu = By.xpath("//span[contains(text(), 'Parent MenuItem')]");
private By subMenu = By.xpath("//span[contains(text(), 'MenuItem5')]");
public Click(WebDriver driver) {
this.driver = driver;
}
public Click clickSubMenu() {
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(parentMenu));
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(parentMenu)).moveToElement(driver.findElement(subMenu)).click().build().perform();
return this;
}
}
如果 elementToBeClickable
不起作用 visibilityOfElementLocated
在这种情况下可能是更好的选择。
我有一个包含下拉菜单的页面(使用 'span' 和 'li' 元素创建)。下拉菜单有一些选项也有一个子菜单,当你点击父菜单时帽子是可见的(下面给出的代码)。当使用 UI 浏览器(chrome 或 firefox)时,我使用一个简单的:
webDriver.findElement(By.xpath("//span[contains(text(), '" + menuOption + "')]"));
上面的代码有效,但是当我在同一个浏览器的无头模式下使用相同的代码时,它不起作用并给出错误:
org.openqa.selenium.ElementNotInteractableException: element not interactable
我尝试使用以下方法 select 父节点,然后单击子节点,但结果相似:
webDriver.findElement(By.xpath("//span[contains(text(), '" + sItemActionMenu + "')]")).isSelected();
webDriver.findElement(By.xpath("//span[contains(text(), '" + menuOption + "')]"));
已经通过并检查了其他可用的解决方案,使用 JavascriptExecutor,等待元素可见等:
Unable to Click Button with Headless Selenium Browser
Click on hidden element Selenium webdriver(javascript)
Selenium - Unable to click on link from dropdown list
但是none给出了明确的答案,提供的解决方案并没有解决我的问题,甚至尝试使用JavascriptExecutor:
JavascriptExecutor js = (JavascriptExecutor) DriverFactory.getDriver();
WebElement weItemMenu = webDriver.findElement(By.xpath("//span[contains(text(), '" + menuOption + "')]"));
我尝试点击的代码是:
<div class="menu-panel-wrapper" style="top: 0px; left: 1384.83px;">
<ul class="menu menu-format-standard menu-regular" role="menu" id="pyNavi1614647592355" data-menu-id="-pyNavi1614647592355" style="display: block; top: 0px; left: 0px; max-height: 570px;">
<li class="menu-item menu-item-enabled" role="presentation" data-childnodesid="$pNavi1614647592355$pElements" id="menu-item-$pNavi1614647592355$pElements">
<a href="#" onclick="pd(event);" class="menu-item-anchor menu-item-expand" tabindex="0" role="menuitem" aria-haspopup="true">
<span class="menu-item-title-wrap" data-click=".">
<span class="menu-item-title" data-click="..">Parent MenuItem</span>
</span>
</a>
<div class="menu-panel-wrapper" style="top: 1px; left: 245.547px; border-left: 17px solid transparent;">
<ul class="menu menu-format-standard menu-regular" role="menu" id="$pNav1614647592355$pElements" data-menu-id="-2" style="display: none; max-height: 570px;">
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="0" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem1","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">MenuItem1</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled menu-item-active" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="0" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem2 ","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item 2</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem3","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item 3</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem4","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">MenuItem4</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem5","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">MenuItem5</span></span>
</a>
</li>
<li class="menu-item-separator" role="separator"> </li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem6","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item6</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor " tabindex="-1" role="menuitem" data-ctl="" data-click="[["setMobileTransition",["mobile.trans.NONE"]],["createNewWork",["GM-Work-Prog","","pStartCs","&ProcessType=MenuItem7","","","",{}]]]">
<span class="menu-item-title-wrap" data-click="."><span class="menu-item-title" data-click="..">Menu Item7</span></span>
</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
菜单看起来像这样(由于限制不能给出实际的,但代码是real/correct,名称已更改):
我什至尝试使用以下内容:
webDriver.findElement(By.xpath("//ul[@id=\"$pNavi1614647592355$pElements\"]//li//span[contains(text(), '" + menuOption + "')]")).click();
但这不适用于 UI 浏览器或无头浏览器。在以上所有示例中,'menuOption' 是一个变量,它被传递以确定名称(例如 MenuItem1、Menu Item 2、Menu Item3 等)
关于如何点击上述代码中的子菜单选项有什么建议吗?此选项最初似乎是 'hidden',当父选项在 UI 中被 select 编辑时,它会显示子选项。
如果我正确理解了您的操作:移动到第一个元素,然后移动到第二个元素并单击它。
尝试等到第一个元素可点击,然后像这样使用 Actions
class:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Click {
private final WebDriver driver;
private By parentMenu = By.xpath("//span[contains(text(), 'Parent MenuItem')]");
private By subMenu = By.xpath("//span[contains(text(), 'MenuItem5')]");
public Click(WebDriver driver) {
this.driver = driver;
}
public Click clickSubMenu() {
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(parentMenu));
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(parentMenu)).moveToElement(driver.findElement(subMenu)).click().build().perform();
return this;
}
}
如果 elementToBeClickable
不起作用 visibilityOfElementLocated
在这种情况下可能是更好的选择。