Faire défiler l’élément avec le selenium

Est-il possible de faire défiler la fenêtre du navigateur dans Selenium 1.x ou 2.x pour qu’un élément particulier identifié par un XPath soit visible par le navigateur? Il existe une méthode de focus dans Selenium, mais elle ne semble pas faire défiler physiquement la vue dans FireFox. Quelqu’un at-il des suggestions sur la façon de le faire?

La raison pour laquelle j’en ai besoin est que je teste le clic d’un élément sur la page. Malheureusement, l’événement ne semble pas fonctionner à moins que l’élément ne soit visible. Je n’ai pas le contrôle du code qui se déclenche lorsque l’utilisateur clique sur l’élément. Je ne peux donc pas le déboguer ni y apporter de modifications. Par conséquent, la solution la plus simple consiste à faire défiler l’élément à vue.

Ont essayé beaucoup de choses en ce qui concerne le défilement, mais le code ci-dessous a fourni de meilleurs résultats.

Cela fera défiler jusqu’à ce que l’élément soit en vue:

WebElement element = driver.findElement(By.id("id_of_element")); ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element); Thread.sleep(500); //do anything you want with the element 

Vous pouvez utiliser la classe org.openqa.selenium.interactions.Actions pour org.openqa.selenium.interactions.Actions à un élément:

 WebElement element = driver.findElement(By.id("my-id")); Actions actions = new Actions(driver); actions.moveToElement(element); actions.perform(); 
 JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("javascript:window.scrollBy(250,350)"); 

Vous voudrez peut-être essayer ceci.

Si vous souhaitez faire défiler la fenêtre de Firefox à l’aide du pilote Web Selenium, vous pouvez utiliser JavaScript dans le code Java. Le code JavaScript pour faire défiler (vers le bas de la page Web) est le suivant:

 JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("window.scrollTo(0, Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight));"); 

Le selenium 2 essaie de faire défiler l’élément, puis cliquez dessus. Cela est dû au fait que Selenium 2 n’interagira pas avec un élément à moins qu’il ne le pense visible.

Faire défiler jusqu’à l’élément se produit implicitement, il vous suffit donc de trouver l’élément puis de travailler avec lui.

 webElement = driver.findElement(By.xpath("bla-bla-bla")); ((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", webElement); 

Pour plus d’exemples, allez ici . Tout en russe, mais le code Java est interculturel 🙂

Cibler n’importe quel élément et envoyer des clés (ou haut / gauche / droite) semble fonctionner également. Je sais que c’est un peu un piratage, mais je ne suis pas vraiment intéressé par l’idée d’utiliser JavaScript pour résoudre le problème de défilement.

D’après mon expérience, Selenium Webdriver ne fait pas défiler automatiquement un élément lorsqu’il y a plus d’une section déroulante sur la page (ce qui est assez fréquent).

J’utilise Ruby, et pour mon AUT, j’ai dû associer le patch à la méthode click comme suit:

 class Element # # Alias the original click method to use later on # alias_method :base_click, :click # Override the base click method to scroll into view if the element is not visible # and then retry click # def click begin base_click rescue Selenium::WebDriver::Error::ElementNotVisibleError location_once_scrolled_into_view base_click end end 

La méthode ‘location_once_scrolled_into_view’ est une méthode existante sur la classe WebElement.

J’avoue que vous n’utilisez peut-être pas Ruby, mais cela devrait vous donner quelques idées.

Vous pouvez utiliser cet extrait de code pour faire défiler:

C #

 var element = Driver.FindElement(By.Id("element-id")); Actions actions = new Actions(Driver); actions.MoveToElement(element).Perform(); 

Voilà

Utilisez le pilote pour envoyer des clés telles que la clé pagedown ou downarrow pour afficher l’élément. Je sais que c’est une solution trop simple et peut ne pas être applicable dans tous les cas.

Cela a fonctionné pour moi:

 IWebElement element = driver.FindElements(getApplicationObject(currentObjectName, currentObjectType, currentObjectUniqueId))[0]; ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element); 

Dans Selenium, nous devons prendre l’aide d’un exécuteur JavaScript pour faire défiler un élément ou faire défiler la page:

 je.executeScript("arguments[0].scrollIntoView(true);", element); 

Dans la déclaration ci-dessus, l’ element est l’élément exact où vous devez faire défiler.

J’ai essayé le code ci-dessus et cela a fonctionné pour moi.

J’ai un post complet et une vidéo à ce sujet:

http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver/

Parfois, j’ai aussi fait face au problème du défilement avec Selenium. J’ai donc utilisé javaScriptExecuter pour y parvenir.

Pour faire défiler vers le bas:

 WebDriver driver = new ChromeDriver(); JavascriptExecutor js = (JavascriptExecutor)driver; js.executeScript("window.scrollBy(0, 250)", ""); 

Ou aussi

 js.executeScript("scroll(0, 250);"); 

Pour faire défiler vers le haut:

 js.executeScript("window.scrollBy(0,-250)", ""); 

Ou,

 js.executeScript("scroll(0, -250);"); 

Si vous pensez que les autres réponses étaient trop piratées, celle-ci l’est aussi, mais aucune injection JavaScript n’est impliquée.

Lorsque le bouton est hors de l’écran, il se casse et y accède, réessayez donc … ¯ \ _ (ツ) _ / ¯

 try { element.Click(); } catch { element.Click(); } 

J’ai utilisé cette méthode pour faire défiler l’élément et cliquer sur:

 List image = state.getDriver().findElements(By.xpath("//*[contains(@src,'image/plus_btn.jpg')]")); for (WebElement clickimg : image) { ((JavascriptExecutor) state.getDriver()).executeScript("arguments[0].scrollIntoView(false);", clickimg); clickimg.click(); } 
 def scrollToElement(element: WebElement) = { val location = element.getLocation driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});") } 

Le script Ruby pour faire défiler un élément dans la vue est comme ci-dessous.

 $driver.execute_script("arguments[0].scrollIntoView(true);", element) sleep(3) element.click 

Vous pouvez visiter la page Éléments Web Scroll et la page Web – Selenium WebDriver avec Javascript :

 public static void main(Ssortingng[] args) throws Exception { // TODO Auto-generated method stub FirefoxDriver ff = new FirefoxDriver(); ff.get("http://toolsqa.com"); Thread.sleep(5000); ff.executeScript("document.getElementById('text-8').scrollIntoView(true);"); } 

Selenium peut faire défiler automatiquement certains éléments de la barre de défilement pour une interface utilisateur simple, mais pour l’interface utilisateur paresseuse, scrollToElement est toujours nécessaire.

Ceci est mon implémentation en Java avec JavascriptExecutor. Vous pouvez trouver plus de détails dans le code source de Satix: http://www.binpress.com/app/satix-seleniumbased-automation-testing-in-xml/1958

 public static void perform(WebDriver driver, Ssortingng Element, Ssortingng ElementBy, By by) throws Exception { try{ //long start_time = System.currentTimeMillis(); SsortingngBuilder js = new SsortingngBuilder(); Ssortingng browser = "firefox"; if (ElementBy.equals("id")) { js.append("var b = document.getElementById(\"" + Element + "\");"); } else if (ElementBy.equals("xpath")) { if (!"IE".equals(browser)) { js.append("var b = document.evaluate(\"" + Element + "\", document, null, XPathResult.ANY_TYPE, null).iterateNext();"); } else { throw new Exception("Action error: xpath is not supported in scrollToElement Action in IE"); } } else if (ElementBy.equals("cssSelector")) { js.append("var b = document.querySelector(\"" + Element + "\");"); } else { throw new Exception("Scroll Action error"); } Ssortingng getScrollHeightScript = js.toSsortingng()+ "var o = new Array(); o.push(b.scrollHeight); return o;"; js.append("b.scrollTop = b.scrollTop + b.clientHeight;"); js.append("var tmp = b.scrollTop + b.clientHeight;"); js.append("var o = new Array(); o.push(tmp); return o;"); int sortinges = 1; Ssortingng scrollTop = "0"; while (sortinges > 0){ try{ Ssortingng scrollHeight = ((JavascriptExecutor)driver).executeScript(getScrollHeightScript).toSsortingng(); if (scrollTop.equals(scrollHeight)) { break; } else if (driver.findElement(by).isDisplayed()) { break; } Object o = ((JavascriptExecutor)driver).executeScript(js.toSsortingng()); scrollTop = o.toSsortingng(); Thread.sleep(interval); sortinges ++; }catch(Exception e){ throw new Exception("Action error:" + " javascript execute error : " + e.getMessage() + ", javascript : " + js.toSsortingng()); } } }catch (Exception e) { try { ScreenshotCapturerUtil.saveScreenShot(driver, CLASSNAME); } catch (IOException e1) { throw new Exception("Save screenshot error!", e1); } throw e; } } 

Le comportement par défaut de Selenium nous permet de faire défiler afin que l’élément soit à peine visible en haut de la fenêtre. En outre, tous les navigateurs n’ont pas exactement le même comportement. C’est très décevant. Si vous enregistrez des vidéos des tests de votre navigateur, comme je le fais, vous voulez que l’élément défile dans la vue et soit centré verticalement .

Voici ma solution pour Java:

 public List getBoundedRectangleOfElement(WebElement we) { JavascriptExecutor je = (JavascriptExecutor) driver; List bounds = (ArrayList) je.executeScript( "var rect = arguments[0].getBoundingClientRect();" + "return [ '' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height) ]", we); System.out.println("top: " + bounds.get(1)); return bounds; } 

Et puis, pour faire défiler, vous l’appelez comme ceci:

 public void scrollToElementAndCenterVertically(WebElement we) { List bounds = getBoundedRectangleOfElement(we); Long totalInnerPageHeight = getViewPortHeight(driver); JavascriptExecutor je = (JavascriptExecutor) driver; je.executeScript("window.scrollTo(0, " + (Integer.parseInt(bounds.get(1)) - (totalInnerPageHeight/2)) + ");"); je.executeScript("arguments[0].style.outline = \"thick solid #0000FF\";", we); } 

Voici comment je le fais avec PHP WebDriver pour Selenium. Il fonctionne pour le serveur autonome Selenium 2.39.0 + https://github.com/Element-34/php-webdriver + Firefox 25.0

 $element=$session->welement("xpath", "//input[@value='my val']"); $element->click(); $element=$session->welement("xpath", "//input[@value='ma val2']"); $element->location_in_view(); // < -- this is the candy $element->click(); 

Remarque: J’utilise une version personnalisée du composant PHP-webdriver Element34. Mais il n’y a pas de changement dans le kernel. J’utilise juste mon “welement” au lieu de “element”. Mais cela n’a aucune influence sur le cas en question. L’auteur du pilote dit “permettre à presque tous les appels d’API d’être une transformation directe de ce qui est défini dans le protocole WebDriver lui-même.” Donc, vous ne devriez avoir aucun problème avec les autres langages de programmation.

Un simple clic ne fonctionnera pas dans ma configuration. Il fera défiler au lieu de cliquer, donc je devais cliquer deux fois sans appeler “location_in_view ()”.

Remarque: Cette méthode fonctionne pour des éléments pouvant être visualisés, comme une entrée de type.

Jetez un oeil à: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location

La description de JsonWireProtocol # suggère l’utilisation de location + moveto, car location _in_view est une méthode interne.

Quelque chose qui a fonctionné pour moi était d’utiliser la méthode Browser.MoveMouseToElement sur un élément au bas de la fenêtre du navigateur. Par miracle, cela a fonctionné dans Internet Explorer, Firefox et Chrome.

J’ai choisi cette technique plutôt que la technique d’injection JavaScript simplement parce qu’elle semblait moins piratée.

J’ai fait des tests avec des composants ADF et vous devez avoir une commande séparée pour faire défiler si le chargement paresseux est utilisé. Si l’object n’est pas chargé et que vous essayez de le trouver en utilisant Selenium, Selenium lancera une exception d’élément non trouvé.

Si rien ne fonctionne, essayez ceci avant de cliquer sur:

 public void mouseHoverJScript(WebElement HoverElement) { Ssortingng mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}"; ((JavascriptExecutor) driver).executeScript(mouseOverScript, HoverElement); } 

En Java, nous pouvons faire défiler en utilisant JavaScript, comme dans le code suivant:

 driver.getEval("var elm = window.document.getElementById('scrollDiv'); if (elm.scrollHeight > elm.clientHeight){elm.scrollTop = elm.scrollHeight;}"); 

Vous pouvez affecter une valeur souhaitée à la variable “elm.scrollTop”.

Une solution est:

 public void javascriptclick(Ssortingng element) { WebElement webElement = driver.findElement(By.xpath(element)); JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].click();", webElement); System.out.println("javascriptclick" + " " + element); } 

Ceci est une solution répétée avec JavaScript, mais avec une attente supplémentaire pour l’élément.

Sinon, ElementNotVisibleException peut apparaître si une action est en cours sur l’élément.

 this.executeJavaScriptFunction("arguments[0].scrollIntoView(??true);", elementToBeViewable); WebDriverWait wait = new WebDriverWait(getDriver(), 5); wait.until(ExpectedConditions.visibilityOf(elementToBeViewab??le)); 

Ce code fonctionne pour moi:

 JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("javascript:window.scrollBy(250, 350)"); 

Je suis d’accord avec tout le monde ici, qui dit “Selenium a une option de défilement implicite”. Aussi, si vous étiez dans Selenium 1 et que vous vous êtes mis à niveau vers Selenium 2 et que vous recherchez les commandes de la version précédente, vous pouvez utiliser la commande:

 Seleniumbackeddriver. WebDriver driver = new FirefoxDriver(); public void setUp() throws Exception { Ssortingng baseUrl = "http://www.google.co.in/"; selenium = new WebDriverBackedSelenium(driver, baseUrl); } 

Vous pouvez les utiliser et utiliser les commandes des deux versions.

Faites un clic au hasard sur la page:

 driver.findElement(By.id("ID of a web element present below")).click 

Effectuez ensuite ce que vous voulez faire.