我正在尝试实现一个"对象选择器"在大多数商业自动化工具中常见的基于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) { }
}
}
谢谢!
答案 0 :(得分:2)
实际上是关于如何将坐标传递给脚本。 脚本参数必须单独指定为单独的"use strict";
describe("PFTs", function(){
it("cannot be created without a subjId", function(){
var testDate = new Date();
var invalidNewPFT = {pftDate: testDate}
var preinsertCount = PFTs.find().fetch().length;
// expect used here to swallow the msg sent to the browser by Collection2
expect( function(){ PFTs.insert(invalidNewPFT); }).toThrow;
// Verify that a record was not saved
expect( PFTs.find().fetch().length ).toEqual(preinsertCount);
});
});
参数。在您的情况下发生的事情是您基本上指定了一个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 });
答案 1 :(得分:1)
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中实现。
答案 2 :(得分:0)
我也遇到了这个问题。我发现它被抛出的原因是因为我试图获取其位置的元素是隐藏的(具有属性display:none)。因此没有位置。