通过 Selenium 驱动程序执行 Javascript elementFromPoint
Posted
技术标签:
【中文标题】通过 Selenium 驱动程序执行 Javascript elementFromPoint【英文标题】:Executing Javascript elementFromPoint through Selenium driver 【发布时间】:2015-11-01 20:02:11 【问题描述】:我正在尝试在我的基于 Selenium 的框架中实现一个“对象选择器”,这在大多数商业自动化工具中很常见。为此,我使用 javascript 命令在鼠标位置查找元素,但没有得到我期望的元素。
如果我使用的是 ChromeDriver 或 InternetExplorerDriver,脚本总是返回标头对象。无论我看什么网页或鼠标的位置。虽然听起来脚本使用坐标 0、0 而不是鼠标位置,但我已经确认 Cursor.Position 正在发送正确的值。
如果我使用的是 FirefoxDriver,我会遇到异常:
"Argument 1 of Document.elementFromPoint is not a finite floating-point value. (UnexpectedJavaScriptError)"
谁能看出我做错了什么?
private void OnHovering()
if (Control.ModifierKeys == System.Windows.Forms.Keys.Control)
IWebElement ele = null;
try
// Find the element at the mouse position
if (driver is IJavaScriptExecutor)
ele = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(
"return document.elementFromPoint(arguments[0], arguments[1])",
new int[] Cursor.Position.X, Cursor.Position.Y );
// Select the element found
if (ele != null)
SelectElement(ele);
catch (Exception)
谢谢!
【问题讨论】:
如何将鼠标实际移动到元素上?谢谢。 另外,页面上是否有 iframe 元素? 使用鼠标 ;-) 该功能发生在计时器滴答声中。如果用户按住 ctrl,则鼠标下的元素被选中 我不是网页的开发者,但我尝试了很多不同的网页... www.nab.com.au, www.microsoft.com, www.google.com。无论网站是什么,我都会返回标题。 Cursor.Position.X 和 Cursor.Position.Y 是正确的值,只是似乎我没有正确地将它们传递给“ExecuteScript”方法。 是的,谢谢我刚刚使用 Python 绑定和 SO 站点作为目标重现了该问题 - 无论坐标是什么,都会返回标题元素。 【参考方案1】:我也遇到了这个问题。我发现它被抛出的原因是因为我试图获取位置的元素被隐藏(具有属性 display:none)。因此没有位置。
【讨论】:
【参考方案2】:alecxe 的代码在大多数情况下都有效,但如果页面包含框架或 iframe,它将失败。
还需要更多代码来尊重框架/iframe。
/// <summary>
/// Get the element at the viewport coordinates X, Y
/// </summary>
static public RemoteWebElement GetElementFromPoint(RemoteWebDriver i_Driver, int X, int Y)
while (true)
String s_Script = "return document.elementFromPoint(arguments[0], arguments[1]);";
RemoteWebElement i_Elem = (RemoteWebElement)i_Driver.ExecuteScript(s_Script, X, Y);
if (i_Elem == null)
return null;
if (i_Elem.TagName != "frame" && i_Elem.TagName != "iframe")
return i_Elem;
Point p_Pos = GetElementPosition(i_Elem);
X -= p_Pos.X;
Y -= p_Pos.Y;
i_Driver.SwitchTo().Frame(i_Elem);
/// <summary>
/// Get the position of the top/left corner of the Element in the document.
/// NOTE: RemoteWebElement.Location is always measured from the top of the document and ignores the scroll position.
/// </summary>
static public Point GetElementPosition(RemoteWebElement i_Elem)
String s_Script = "var X, Y; "
+ "if (window.pageYOffset) " // supported by most browsers
+ " "
+ " X = window.pageXOffset; "
+ " Y = window.pageYOffset; "
+ " "
+ "else " // Internet Explorer 6, 7, 8
+ " "
+ " var Elem = document.documentElement; " // <html> node (IE with DOCTYPE)
+ " if (!Elem.clientHeight) Elem = document.body; " // <body> node (IE in quirks mode)
+ " X = Elem.scrollLeft; "
+ " Y = Elem.scrollTop; "
+ " "
+ "return new Array(X, Y);";
RemoteWebDriver i_Driver = (RemoteWebDriver)i_Elem.WrappedDriver;
IList<Object> i_Coord = (IList<Object>) i_Driver.ExecuteScript(s_Script);
int s32_ScrollX = Convert.ToInt32(i_Coord[0]);
int s32_ScrollY = Convert.ToInt32(i_Coord[1]);
return new Point(i_Elem.Location.X - s32_ScrollX,
i_Elem.Location.Y - s32_ScrollY);
这应该在 WebDriver 中实现。
【讨论】:
【参考方案3】:这实际上是关于如何将坐标传递到脚本中。 脚本参数必须单独指定为单独的ExecuteScript()
参数。在您的情况下发生的情况是,您基本上指定了一个 x
参数,这使得它认为 y
应该被视为默认的 0
值。在y=0
通常有一个标题。
代替:
ele = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(
"return document.elementFromPoint(arguments[0], arguments[1])",
new int[] Cursor.Position.X, Cursor.Position.Y );
你应该这样做:
ele = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(
"return document.elementFromPoint(arguments[0], arguments[1])",
Cursor.Position.X, Cursor.Position.Y);
【讨论】:
谢谢alecxe,你说得对,这就是问题所在。但是 C# 的文档是object IJavaScriptExecuter.ExecuteScript(string script, params object[] args)
。文档是错误的还是我读错了?对我来说,这意味着第二个参数应该是一个参数数组。
@Scotty 是的,我同意这很令人困惑。以上是关于通过 Selenium 驱动程序执行 Javascript elementFromPoint的主要内容,如果未能解决你的问题,请参考以下文章
Docker selenium自动化 - 执行程序没反应不执行原因,强制处理之前失败的进程,“... requests waiting for a slot to be free“问题解决
Docker selenium自动化 - 执行程序没反应不执行原因,强制处理之前失败的进程,“... requests waiting for a slot to be free“问题解决