Executing JavascriptFromPoint element through Selenium driver

I am trying to implement an "object collector" on my Selenium based framework, as is the case with most commercial automation tools. To do this, I am using a Javascript command to find the element at the mouse location, but I am not getting the expected element.

If I use ChromeDriver or InternetExplorerDriver the script always returns a header object. No matter what web page I am looking at or the position of the mouse. Although it seems that the script is accepting coordinates 0, 0 instead of the mouse position, I have confirmed that Cursor.Position is sending the correct values.

If I use FirefoxDriver I get an exception:

"Argument 1 of Document.elementFromPoint is not a finite floating-point value. (UnexpectedJavaScriptError)"

      

Can anyone see what I am doing wrong?

    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) { }
        }
    }

      

Thank!

+2


source to share


2 answers


Actually about how you pass coordinates to script. Script arguments must be specified separately as separate arguments ExecuteScript()

. What was happening in your case is that you basically provided one argument x

, which made it think it y

should be considered the default 0

. And y=0

usually there is a headline.

Instead:

ele = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(
                        "return document.elementFromPoint(arguments[0], arguments[1])", 
                        new int[] { Cursor.Position.X, Cursor.Position.Y });

      



You should:

ele = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(
                        "return document.elementFromPoint(arguments[0], arguments[1])", 
                        Cursor.Position.X, Cursor.Position.Y);

      

+2


source


The code from alecxe works in most cases, but it will fail if the page contains frames or frames.

A lot more code to respect frames / frames as well.



/// <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);
}

      

This should be implemented in the WebDriver.

+1


source







All Articles