使用 Selenium 单击伪元素
Click on pseudo element using Selenium
我正在尝试使用 Selenium 单击 ::after 伪元素。我意识到这不能直接通过 WebDriver 完成,但似乎无法找到使用 Javascript.
的方法
这是 DOM 的样子:
<em class="x-btn-split" unselectable="on" id="ext-gen161">
<button type="button" id="ext-gen33" class=" x-btn-text">
<div class="mruIcon"></div>
<span>Accounts</span>
</button>
::after
</em>
这就是上面元素的样子。对象的左侧是 'button' 元素,右侧是带箭头的 :after 元素,单击该箭头会弹出下拉菜单。正如您所看到的,右侧没有任何标识符,这在一定程度上使这很难做到。
我在 Whosebug 中看到了这两个链接,并试图将答案结合起来形成我的解决方案,但无济于事。
使用 JavaScript 单击 Selenium WebDriver 中的元素
Locating pseudo element in Selenium WebDriver using JavaScript
这是我的尝试之一:
string script = "return window.getComputedStyle(document.querySelector('#ext-gen33'),':before')";
IJavaScriptExecutor js = (IJavaScriptExecutor) Session.Driver;
js.ExecuteScript("arguments[0].click(); ", script);
其中出现此错误:
System.InvalidOperationException: 'unknown error: arguments[0].click is not a function
(Session info: chrome=59.0.3071.115)
(Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 6.1.7601 SP1 x86_64)'
我也试过使用 Selenium 中的 Actions class 来参考左侧移动鼠标,这也类似于 this answer。我想这可能是因为我不知道偏移量是用什么来衡量的,而且文档似乎也没有给出任何指示。我认为它是以像素为单位的??
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(235, 15).Click().Build().Perform();
这次尝试似乎点击了某个地方,因为它没有给出任何错误,但我不太确定在哪里。
如果有帮助,我正在尝试在 c# 中自动化 Salesforce(服务云)。
也许有人可以提供解决方案?
我在为 Salesforce 编写 Selenium 测试时遇到了同样的问题,并设法通过使用 Actions 直接控制鼠标来解决它。
此按钮的包装器 table 的硬编码宽度为 250 像素,您已经发现了这一点。要定位鼠标的位置,您可以使用 contextClick()
方法而不是 Click().
它模拟鼠标右键,因此它将始终打开浏览器菜单。
如果你这样做:
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).ContextClick().Build().Perform();
您会发现鼠标移动到 WebElement 的中间,而不是左上角(我认为它也是)。由于该元素的宽度是恒定的,我们只需将鼠标向右移动 250 / 2 - 1
就可以了:)
代码:
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(124, 0).Click().Build().Perform();
对于那些在Python中尝试这样做的人,解决方案如下:
elem= driver.<INSERT THE PATH TO ELEMENT HERE>
ActionChains(driver).move_to_element_with_offset(elem,249,1).click().perform()
基本上我是在 DOM 中找到我的元素并分配给 WebElement。然后将 WebElement 作为参数传递给方法 move_to_element_with_offset。
我从开发人员工具中获得了元素的 px 值。
PS:使用这个 import- from selenium.webdriver.common.action_chains import ActionChains
您可以在此处阅读有关 动作链 class 及其方法 move_to_element_with_offset 的更多信息:http://selenium-python.readthedocs.io/api.html.
希望对您有所帮助。
上面的 Maciej 答案适用于 WebDriver,但不适用于针对 Firefox V.56 的 RemoteWebDriver (Selenium 3.12.0)。我们需要一个适用于本地和远程的解决方案。最后使用键盘快捷键调用导航菜单下拉菜单。作为一个额外的好处,这也消除了使用偏移量的需要。
String navigationMenuDropdownShortcutKeys = Keys.chord(Keys.ESCAPE, "v");
new Actions(driver)
.sendKeys(navigationMenuDropdownShortcutKeys)
.perform();
我将提供一种可能适用于某些场景的替代方案,至少它对我有用,并且相对容易通过 JS 脚本使用 selenium 在任何语言中实现。
在我的场景中,有一个包含按钮功能的 ::after 伪元素。此按钮包含在相对于其下的另一个元素的位置。
所以我做了以下事情:
- 我能得到的元素,在这个问题场景中就是那个跨度。
- 获取元素的坐标。
- 计算相对于您要单击的伪元素的那个元素的坐标。
- 点击那些坐标。
这是我使用 perl 编写的代码,但我相信您可以使用任何语言执行相同的操作:
my $script="
function click_function(x, y)
{
console.log('Clicking: ' + x + ' ' + y);
var ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
});
var el = document.elementFromPoint(x, y);
el.dispatchEvent(ev);
}
var element = document.getElementById('here_put_your_id'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?
document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
console.log('Coordiantes: ' + elementLeft + ' ' + elementTop)
click_function(elementLeft*1.88, elementTop*1.045) // here put yor relative coordiantes
";
$driver->execute_script($script);
在阅读了大量文章和博客后,我找到了确定如何在 Selenium 中检测 DOM 中的伪元素的方法。并根据特定条件验证是否存在。
步骤 1
找到伪元素组成的父元素的路径,在findElement下传递如下图
WebElement pseudoEle = driver.findElement(path);
步骤 2
String display = ((JavascriptExecutor)getWebDriver()).executeScript("return window.getComputedStyle(arguments[0], ':after').getPropertyValue('display');",pseudoEle).toString();
在上面的代码行中,在“:after”的位置传递所需的伪代码(在我的例子中,我正在寻找 'after')和 属性 值,该值正在根据伪代码是否存在(在我的例子中是 'display')。
注意:当存在伪元素时 javascript 代码 return 'Block' 我又将其保存在 显示中 字段。并根据场景使用。
为您的案例确定正确 属性 价值的步骤
- 检查元素。
- 导航到伪代码的父元素。
- 在“样式”选项卡下找出伪代码存在和不存在时其值会发生变化的字段(绿色)。
我相信这会对您有很大帮助。请喜欢和支持,会鼓励我post更多这样的解决方案。
谢谢!
我正在尝试使用 Selenium 单击 ::after 伪元素。我意识到这不能直接通过 WebDriver 完成,但似乎无法找到使用 Javascript.
的方法这是 DOM 的样子:
<em class="x-btn-split" unselectable="on" id="ext-gen161">
<button type="button" id="ext-gen33" class=" x-btn-text">
<div class="mruIcon"></div>
<span>Accounts</span>
</button>
::after
</em>
这就是上面元素的样子。对象的左侧是 'button' 元素,右侧是带箭头的 :after 元素,单击该箭头会弹出下拉菜单。正如您所看到的,右侧没有任何标识符,这在一定程度上使这很难做到。
我在 Whosebug 中看到了这两个链接,并试图将答案结合起来形成我的解决方案,但无济于事。
使用 JavaScript 单击 Selenium WebDriver 中的元素
Locating pseudo element in Selenium WebDriver using JavaScript
这是我的尝试之一:
string script = "return window.getComputedStyle(document.querySelector('#ext-gen33'),':before')";
IJavaScriptExecutor js = (IJavaScriptExecutor) Session.Driver;
js.ExecuteScript("arguments[0].click(); ", script);
其中出现此错误:
System.InvalidOperationException: 'unknown error: arguments[0].click is not a function
(Session info: chrome=59.0.3071.115)
(Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 6.1.7601 SP1 x86_64)'
我也试过使用 Selenium 中的 Actions class 来参考左侧移动鼠标,这也类似于 this answer。我想这可能是因为我不知道偏移量是用什么来衡量的,而且文档似乎也没有给出任何指示。我认为它是以像素为单位的??
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(235, 15).Click().Build().Perform();
这次尝试似乎点击了某个地方,因为它没有给出任何错误,但我不太确定在哪里。
如果有帮助,我正在尝试在 c# 中自动化 Salesforce(服务云)。
也许有人可以提供解决方案?
我在为 Salesforce 编写 Selenium 测试时遇到了同样的问题,并设法通过使用 Actions 直接控制鼠标来解决它。
此按钮的包装器 table 的硬编码宽度为 250 像素,您已经发现了这一点。要定位鼠标的位置,您可以使用 contextClick()
方法而不是 Click().
它模拟鼠标右键,因此它将始终打开浏览器菜单。
如果你这样做:
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).ContextClick().Build().Perform();
您会发现鼠标移动到 WebElement 的中间,而不是左上角(我认为它也是)。由于该元素的宽度是恒定的,我们只需将鼠标向右移动 250 / 2 - 1
就可以了:)
代码:
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(124, 0).Click().Build().Perform();
对于那些在Python中尝试这样做的人,解决方案如下:
elem= driver.<INSERT THE PATH TO ELEMENT HERE>
ActionChains(driver).move_to_element_with_offset(elem,249,1).click().perform()
基本上我是在 DOM 中找到我的元素并分配给 WebElement。然后将 WebElement 作为参数传递给方法 move_to_element_with_offset。
我从开发人员工具中获得了元素的 px 值。
PS:使用这个 import- from selenium.webdriver.common.action_chains import ActionChains
您可以在此处阅读有关 动作链 class 及其方法 move_to_element_with_offset 的更多信息:http://selenium-python.readthedocs.io/api.html.
希望对您有所帮助。
上面的 Maciej 答案适用于 WebDriver,但不适用于针对 Firefox V.56 的 RemoteWebDriver (Selenium 3.12.0)。我们需要一个适用于本地和远程的解决方案。最后使用键盘快捷键调用导航菜单下拉菜单。作为一个额外的好处,这也消除了使用偏移量的需要。
String navigationMenuDropdownShortcutKeys = Keys.chord(Keys.ESCAPE, "v");
new Actions(driver)
.sendKeys(navigationMenuDropdownShortcutKeys)
.perform();
我将提供一种可能适用于某些场景的替代方案,至少它对我有用,并且相对容易通过 JS 脚本使用 selenium 在任何语言中实现。
在我的场景中,有一个包含按钮功能的 ::after 伪元素。此按钮包含在相对于其下的另一个元素的位置。
所以我做了以下事情:
- 我能得到的元素,在这个问题场景中就是那个跨度。
- 获取元素的坐标。
- 计算相对于您要单击的伪元素的那个元素的坐标。
- 点击那些坐标。
这是我使用 perl 编写的代码,但我相信您可以使用任何语言执行相同的操作:
my $script="
function click_function(x, y)
{
console.log('Clicking: ' + x + ' ' + y);
var ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
});
var el = document.elementFromPoint(x, y);
el.dispatchEvent(ev);
}
var element = document.getElementById('here_put_your_id'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?
document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
console.log('Coordiantes: ' + elementLeft + ' ' + elementTop)
click_function(elementLeft*1.88, elementTop*1.045) // here put yor relative coordiantes
";
$driver->execute_script($script);
在阅读了大量文章和博客后,我找到了确定如何在 Selenium 中检测 DOM 中的伪元素的方法。并根据特定条件验证是否存在。
步骤 1
找到伪元素组成的父元素的路径,在findElement下传递如下图
WebElement pseudoEle = driver.findElement(path);
步骤 2
String display = ((JavascriptExecutor)getWebDriver()).executeScript("return window.getComputedStyle(arguments[0], ':after').getPropertyValue('display');",pseudoEle).toString();
在上面的代码行中,在“:after”的位置传递所需的伪代码(在我的例子中,我正在寻找 'after')和 属性 值,该值正在根据伪代码是否存在(在我的例子中是 'display')。
注意:当存在伪元素时 javascript 代码 return 'Block' 我又将其保存在 显示中 字段。并根据场景使用。
为您的案例确定正确 属性 价值的步骤
- 检查元素。
- 导航到伪代码的父元素。
- 在“样式”选项卡下找出伪代码存在和不存在时其值会发生变化的字段(绿色)。
我相信这会对您有很大帮助。请喜欢和支持,会鼓励我post更多这样的解决方案。
谢谢!