Exécution d’un élément Javascript depuis un point par le pilote Selenium

J’essaie d’implémenter un “sélecteur d’object” dans mon framework basé sur Selenium, comme cela est courant dans la plupart des outils d’automatisation commerciaux. Pour ce faire, j’utilise une commande Javascript pour trouver l’élément à l’emplacement de la souris, mais je ne reçois pas l’élément que j’attends.

Si j’utilise ChromeDriver ou InternetExplorerDriver, le script renvoie toujours l’object en-tête. Peu importe la page Web que je regarde ou la position de la souris. Bien que le script prenne les coordonnées 0, 0 au lieu de la position de la souris, j’ai confirmé que Cursor.Position envoie les valeurs correctes.

Si j’utilise FirefoxDriver, je reçois une exception:

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

Quelqu’un peut-il voir ce que je fais mal?

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

Merci!

C’est en fait sur la façon dont vous passez les coordonnées dans le script. Les arguments de script doivent être spécifiés séparément en tant qu’arguments ExecuteScript() distincts . Ce qui se passait dans votre cas, c’est que vous avez essentiellement spécifié un argument x qui lui a fait penser que y devrait être considérée comme une valeur par défaut de 0 . Et à y=0 il y a généralement un en-tête.

Au lieu de:

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

Tu devrais faire:

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

Le code de alecxe fonctionne dans la plupart des cas, mais il échouera si la page contient des frameworks ou des iframes.

Beaucoup plus de code est nécessaire pour respecter également les frameworks / iframes.

 ///  /// Get the element at the viewport coordinates X, Y ///  static public RemoteWebElement GetElementFromPoint(RemoteWebDriver i_Driver, int X, int Y) { while (true) { Ssortingng 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); } } ///  /// 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. ///  static public Point GetElementPosition(RemoteWebElement i_Elem) { Ssortingng 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; " //  node (IE with DOCTYPE) + " if (!Elem.clientHeight) Elem = document.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 i_Coord = (IList) 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); } 

Cela devrait être implémenté dans le WebDriver.