Élément de défilement en vue avec le sélénium
Existe-t-il un moyen quelconque dans L'un ou l'autre sélénium 1.x ou 2.x pour faire défiler la fenêtre du navigateur de sorte qu'un élément particulier identifié par un XPath soit en vue du navigateur? Il y a une méthode focus dans le sélénium, mais elle ne semble pas faire défiler physiquement la vue dans FireFox. Quelqu'un a-t-il des suggestions à faire?
la raison pour laquelle j'ai besoin de cela 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 soit visible. Je n'ai pas le contrôle du code qui démarre lorsque l'élément est cliqué, donc je ne peux pas le déboguer ou y apporter des modifications, donc, solution la plus simple, Faites défiler l'élément en vue.
30 réponses
ont essayé beaucoup de choses en ce qui concerne le défilement, mais le code ci-dessous a fourni de meilleurs résultats.
ceci 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 passer à 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)");
essayez ceci.
si vous voulez faire défiler la fenêtre Firefox en utilisant le webdriver Selenium, une des façons est D'utiliser JavaScript dans le code Java. Le code JavaScript à faire défiler vers le bas (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));");
Sélénium 2 essaie de faire défiler jusqu'à l'élément, puis cliquez sur. C'est parce que le sélénium 2 n'interagira pas avec un élément à moins qu'il ne pense qu'il est visible.
défiler vers l'élément se produit implicitement donc vous avez juste besoin de trouver l'élément et puis travailler avec elle.
webElement = driver.findElement(By.xpath("bla-bla-bla"));
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", webElement);
pour plus d'exemples, allez ici . Tous en russe, mais le code Java est multi-culturelle :)
ciblant tout élément et envoyant des clés (ou Haut/Gauche/Droite) semble fonctionner aussi. Je sais que c'est un peu un piratage, mais je ne suis pas vraiment à l'idée d'utiliser JavaScript pour résoudre le problème de défilement soit.
d'après mon expérience, Selenium Webdriver ne fait pas défiler automatiquement un élément sur un clic quand il y a plus d'une section scrollable sur la page (ce qui est assez courant).
j'utilise Ruby, et pour mon AUT, j'ai dû patcher la méthode de clic de singe 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 de la classe WebElement.
j'apprécie que vous n'utilisiez pas Ruby mais il devrait vous donner quelques idées.
vous pouvez utiliser ce code pour faire défiler:
c#
var element = Driver.FindElement(By.Id("element-id"));
Actions actions = new Actions(Driver);
actions.MoveToElement(element).Perform();
Là vous l'avez
utilisez le pilote pour envoyer des clés comme la clé pagedown ou downarrow pour mettre l'élément en vue. Je sais que c'est une solution trop simple et pourrait 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 sélénium nous avons besoin de l'aide D'un exécuteur de JavaScript pour faire défiler un élément ou faire défiler la page:
je.executeScript("arguments[0].scrollIntoView(true);", element);
dans l'énoncé ci-dessus element
est l'élément exact où nous devons faire défiler.
j'ai essayé le code ci-dessus, et ça a marché pour moi.
j'ai un post complet et vidéo sur ce:
http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver /
parfois, j'ai également fait face au problème de défilement avec du sélénium. J'ai donc utilisé javaScriptExecuter pour réaliser ceci.
pour 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 hacky, celle-ci l'est aussi, mais il n'y a pas d'injection JavaScript impliqué.
quand le bouton est éteint, il se brise et se défile vers lui, alors réessayez... \_ (Gent) _ /
try
{
element.Click();
}
catch {
element.Click();
}
j'ai utilisé cette façon pour défiler l'élément et cliquer:
List<WebElement> 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 défiler un élément en vue est comme ci-dessous.
$driver.execute_script("arguments[0].scrollIntoView(true);", element)
sleep(3)
element.click
Vous pouvez visiter la page Défilement d'éléments Web et la page Web - Selenium WebDriver à l'aide de Javascript :
public static void main(String[] 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);");
}
sélénium peut faire défiler vers un élément de la barre de défilement automatiquement pour une interface simple, mais pour l'interface paresseuse, scrollToElement est encore nécessaire.
C'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, String Element, String ElementBy, By by) throws Exception {
try{
//long start_time = System.currentTimeMillis();
StringBuilder js = new StringBuilder();
String 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");
}
String getScrollHeightScript = js.toString()+ "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 tries = 1;
String scrollTop = "0";
while (tries > 0){
try{
String scrollHeight = ((JavascriptExecutor)driver).executeScript(getScrollHeightScript).toString();
if (scrollTop.equals(scrollHeight)) {
break;
} else if (driver.findElement(by).isDisplayed()) {
break;
}
Object o = ((JavascriptExecutor)driver).executeScript(js.toString());
scrollTop = o.toString();
Thread.sleep(interval);
tries ++;
}catch(Exception e){
throw new Exception("Action error:"
+ " javascript execute error : " + e.getMessage() + ", javascript : " + js.toString());
}
}
}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 du sélénium nous faire défiler de sorte que l'élément est à peine en vue au sommet du viewport. Aussi, tous les navigateurs ont exactement le même comportement. C'est très dis-satisfaisant. Si vous enregistrez des vidéos de vos tests de navigateur, comme je le fais, ce que vous voulez, c'est que l'élément soit affiché et centré verticalement .
voici ma solution pour Java:
public List<String> getBoundedRectangleOfElement(WebElement we)
{
JavascriptExecutor je = (JavascriptExecutor) driver;
List<String> bounds = (ArrayList<String>) 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 défiler, vous l'appelez comme ceci:
public void scrollToElementAndCenterVertically(WebElement we)
{
List<String> 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 fais avec PHP webDriver pour le sélénium. Il fonctionne pour Selenium stand-alone server 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();
Note: j'utilise une version personnalisée de L'Element34 PHP-webdriver. Mais il n'y a aucun changement dans le noyau. 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 "d'autoriser presque toutes les API appelle à être une transformation directe de ce qui est défini dans le protocole WebDriver lui-même."Vous ne devriez donc pas avoir de problème avec d'autres langages de programmation.
juste en cliquant ne fonctionnera pas dans mon installation. Il va faire un scroll au lieu de cliquer, donc j'ai dû cliquer deux fois sans appeler "location_in_view()".
Note: cette méthode fonctionne pour les éléments qui peuvent être visualisés, comme un bouton d'entrée de type.
regardez: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location
la description de JsonWireProtocol # suggère l'utilisation de location + moveto, parce que location _in_view est une méthode interne.
quelque chose qui a fonctionné pour moi était d'utiliser le navigateur.Méthode MoveMouseToElement sur un élément en bas de la fenêtre du navigateur. Miraculeusement Il a fonctionné dans Internet Explorer, Firefox, et Chrome.
j'ai choisi ceci plutôt que la technique D'injection JavaScript juste parce qu'il se sentait moins hacky.
j'ai fait des tests avec des composants ADF et vous devez avoir une commande séparée pour défiler si le chargement paresseux est utilisé. Si l'objet n'est pas chargé et que vous tentez de le trouver en utilisant le sélénium, le sélénium lancera une exception element-not-found.
si rien ne fonctionne, essayez ceci avant de cliquer:
public void mouseHoverJScript(WebElement HoverElement) {
String 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 attribuer une valeur désirée au" elm.scrollTop" à la variable.
une solution est:
public void javascriptclick(String element)
{
WebElement webElement = driver.findElement(By.xpath(element));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", webElement);
System.out.println("javascriptclick" + " " + element);
}
il s'agit d'une solution répétée avec JavaScript, mais avec un élément ajouté en attente.
sinon ElementNotVisibleException
peut apparaître si une action sur l'élément est en cours.
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 que"le sélénium a une option de défilement implicite". Aussi si vous étiez dans Selenium 1 et maintenant vous avez mis à jour vous - même dans Selenium 2 et cherchez les commandes de la version précédente, vous pouvez utiliser la commande connue sous le nom de:
Seleniumbackeddriver.
WebDriver driver = new FirefoxDriver();
public void setUp() throws Exception {
String baseUrl = "http://www.google.co.in/";
selenium = new WebDriverBackedSelenium(driver, baseUrl);
}
vous pouvez utiliser ces commandes et utiliser les commandes des deux versions.
Cliquez au hasard sur la page:
driver.findElement(By.id("ID of a web element present below")).click
alors, faites ce que vous voulez.