Existe-t-il un moyen, dans Selenium 1.x ou 2.x, de faire défiler la fenêtre du navigateur de sorte qu'un élément particulier identifié par un XPath soit visible par le navigateur? Il existe une méthode de mise au point 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 procéder?
La raison pour laquelle j'ai besoin de cela est que je teste le clic d'un élément de 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 corriger ni le modifier. Par conséquent, la solution la plus simple consiste à faire défiler l'élément à la vue.
J'ai essayé beaucoup de choses en ce qui concerne le défilement, mais le code ci-dessous a donné de meilleurs résultats.
Cela défilera jusqu'à ce que l'élément soit visible:
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.
Java:
WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();
Python:
from Selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(driver.sl.find_element_by_id('my-id')).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 Firefox à l'aide du WebDriver Selenium, vous pouvez notamment utiliser JavaScript dans le code Java. Le code JavaScript à faire défiler (en 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));");
Selenium 2 essaie de faire défiler jusqu'à l'élément puis de cliquer dessus. En effet, le sélénium 2 n'interagira pas avec un élément s'il ne pense pas qu'il est visible.
Le défilement de l'élément s'effectue implicitement, il vous suffit donc de rechercher l'élément, puis de le manipuler.
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 tout élément et envoyer les clés (ou haut/gauche/droite) semble également fonctionner. Je sais que c'est un peu un bidouillage, mais je ne suis pas vraiment dans l'idée d'utiliser JavaScript pour résoudre le problème du défilement.
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 comme le pagedown ou downarrow clé pour mettre l'élément en vue. Je sais que c'est une solution trop simple et peut ne pas être applicable dans tous les cas.
D'après mon expérience, Selenium Webdriver ne fait pas automatiquement défiler vers un élément au clic lorsqu'il y a plus d'une section défilable sur la page (ce qui est assez courant).
J'utilise Ruby, et pour mon AUT, je devais appliquer la méthode du clic à la méthode des clics 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'apprécie que vous n'utilisiez pas Ruby, mais cela devrait vous donner quelques idées.
Dans Selenium, nous avons besoin de l'aide d'un exécutant 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, element
est l'élément exact où nous devons 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/
Cela a fonctionné pour moi:
IWebElement element = driver.FindElements(getApplicationObject(currentObjectName, currentObjectType, currentObjectUniqueId))[0];
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element);
Le script Ruby permettant de 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
Si vous pensez que d'autres réponses étaient trop compliquées, celle-ci l'est aussi, mais aucune injection de JavaScript n'est impliquée.
Lorsque le bouton est éteint, il se casse et défile jusqu'à celui-ci, alors essayez à nouveau ...
try
{
element.Click();
}
catch {
element.Click();
}
Parfois, je rencontrais aussi le 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);");
Vous souhaiterez peut-être visiter la page faire défiler les é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);");
}
J'ai utilisé cette méthode pour faire défiler l'élément et cliquez sur:
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 comportement par défaut de Selenium nous permet de faire défiler l'élément de manière à ce qu'il 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<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 faire 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);
}
J'ai déjà testé des composants ADF et vous devez disposer d'une commande distincte pour le défilement si un chargement différé est utilisé. Si l'objet n'est pas chargé et que vous essayez de le trouver à l'aide de Selenium, Selenium lève une exception d'élément introuvable.
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);
}
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".
C'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));
Dans la plupart des cas de défilement, ce code fonctionnera.
WebElement element = driver.findElement(By.xpath("xpath_Of_Element"));
js.executeScript("arguments[0].click();",element);
Ce code fonctionne pour moi:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250, 350)");
Selenium peut faire défiler automatiquement un élément de la barre de défilement pour une interface utilisateur simple, mais pour une interface utilisateur à chargement paresseux, scrollToElement est toujours nécessaire.
Ceci est mon implémentation en Java avec JavascriptExecutor. Vous trouverez plus de détails dans le code source de Satix: http://www.binpress.com/app/satix-selenium-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;
}
}
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);
}
Quelque chose qui a fonctionné pour moi a été d’utiliser la méthode Browser.MoveMouseToElement sur un élément en bas de la fenêtre du navigateur. Miraculeusement, cela fonctionnait dans Internet Explorer, Firefox et Chrome.
J'ai choisi cette méthode plutôt que la technique d'injection JavaScript, simplement parce que je me sentais moins mal.
Voici comment je le fais avec PHP webDriver for Selenium. Cela 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();
Note: J'utilise une version personnalisée du web-driver PHP Element34. Mais il n'y a pas de changement dans le noyau. Je viens d'utiliser mon "welement" au lieu de "élément". Mais cela n’influence pas le cas en question. L'auteur du pilote dit "permettre à presque tous les appels d'API de transformer directement ce qui est défini dans le protocole WebDriver lui-même". Vous ne devriez donc 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, alors je devais cliquer deux fois sans appeler "location_in_view ()".
Remarque: cette méthode fonctionne pour les éléments pouvant être visualisés, comme une entrée de type.
Consultez: 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.