[英]Executing Javascript elementFromPoint through Selenium driver
我正在尝试为我的基于 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) { }
}
}
谢谢!
这实际上是关于您如何将坐标传递到脚本中。 脚本参数必须单独指定为单独的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 的代码在大多数情况下都可以工作,但如果页面包含框架或 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 中实现。
我也遇到了这个问题。 我发现它被抛出的原因是因为我试图获取位置的元素被隐藏(具有属性 display:none)。 因此没有位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.