Executing Javascript elementFromPoint through Selenium driver

前端 未结 3 1946
暗喜
暗喜 2021-01-15 02:28

I am trying to implement an \"object picker\" to my Selenium based framework as is common on most commercial automation tools. To do this I am using a Javascript command to

相关标签:
3条回答
  • 2021-01-15 03:11

    I was having this issue as well. The reason it was being thrown I found out was because the element I was trying to get the location of was hidden (had the attribute display:none). And therefore didn't have a location.

    0 讨论(0)
  • 2021-01-15 03:17

    It's actually about how you are passing the coordinates into the script. Script arguments has to be specified separately as separate ExecuteScript() arguments. What was happening in your case is that you have basically specified one x argument which made it think that y should be considered a default 0 value. And at y=0 there is usually a header.

    Instead of:

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

    You should do:

    ele = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(
                            "return document.elementFromPoint(arguments[0], arguments[1])", 
                            Cursor.Position.X, Cursor.Position.Y);
    
    0 讨论(0)
  • 2021-01-15 03:22

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

    Much more code is required to respect also frames / iframes.

    /// <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.

    0 讨论(0)
提交回复
热议问题