[英]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.