web-dev-qa-db-fra.com

Comment forcer Selenium WebDriver à cliquer sur un élément non visible actuellement?

J'utilise l'API Java Selenium 2 avec FirefoxDriver. Lorsque je remplis un formulaire, des cases à cocher sont ajoutées à la page en fonction des entrées de formulaire. 

J'aimerais simuler un clic sur ces cases à l'aide de Selenium . L'élément est visible et utilisable dans un navigateur standard, mais Selenium affirme que les éléments ne sont pas visibles.

"Element is not currently visible and so may not be interacted with"

Puis-je forcer Selenium à ignorer l'état non visible des éléments? Comment puis-je forcer Selenium à interagir avec l'élément non visible?

92
djondal

Selenium détermine si un élément est visible ou non en fonction des critères suivants (utilisez un inspecteur DOM pour déterminer quel css s'applique à votre élément, assurez-vous de regarder le style calculé):

  • visibilité! = caché
  • display! = none (est également vérifié pour chaque élément parent)
  • opacité! = 0 (cette option n'est pas activée pour cliquer sur un élément)
  • la hauteur et la largeur sont toutes deux> 0
  • pour une entrée, le type d'attribut! = caché

Votre élément correspond à l'un de ces critères. Si vous n'avez pas la possibilité de changer le style de l'élément, voici comment vous pouvez le faire avec force en javascript (en supposant que WebDriver soit utilisé depuis que vous avez dit Selenium2 API):

((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);

Mais cela ne déclenchera pas un événement javascript, si vous dépendez de l'événement change pour cette entrée, vous devrez également le déclencher (de nombreuses façons de le faire, il est plus simple d'utiliser la bibliothèque javascript chargée sur cette page).

La source du contrôle de visibilité -

https://github.com/SeleniumHQ/Selenium/blob/master/javascript/atoms/dom.js#L577

La spécification WebDriver qui définit ceci -

https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#widl-WebElement-isDisplayed-boolean

97
lukeis

Parfois, cela signifie que plusieurs éléments d'une page ont la même propriété que celle que vous essayez de rechercher et que vous "parlez au mauvais".

Si votre élément ne peut pas être identifié de manière unique par: id ou: name (ou: class), cela pourrait être délicat.

Parfois, la recherche de l'élément par: xpath peut aider et dans certains cas, cela n'est pas pratique.

Dans ces cas, vous devrez peut-être obtenir tous les éléments qui correspondent à vos critères et référencer le bon par l'index. C'est sale, mais ça marche.

J'utilise Selenium/Watir de l'application Ruby on Rails. Dans mon cas, l'exemple serait:

browser = Watir::Browser.new(:firefox, :profile => "default")       
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click

J'espère que cela t'aides.

26
ranktrackerpro

J'avais un problème similaire, mais il était lié au fait que l'élément n'était pas visible dans la fenêtre. J'ai pris une capture d'écran et me suis rendu compte que la fenêtre du navigateur était trop étroite et que l'élément ne pouvait pas être vu. J'ai fait un de ceux-ci et cela a fonctionné:

driver.maximize_window()

Voir: WebDriver.maximize_window ()

14
mynameistechno

Ou vous pouvez utiliser Selenium Action Class pour simuler une interaction utilisateur -- Par exemple

    WebDriver = new FirefoxDriver();

    WebElement menu = driver.findElement(By.xpath("")); // the triger event element

    Actions build = new Actions(driver); // heare you state ActionBuider
    build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
    WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
    m2m.click();
6
fil mihaylov

Il y a aussi un autre cas où un élément visible sera reconnu comme non visible:

  • Quand l'élément est transformé en CSS
  • Lorsque l'élément parent de l'élément est transformé par CSS

Afin de vérifier si un élément avec lequel vous ne voulez pas interagir est transformé par CSS, procédez comme suit:

  1. inspecteur ouvert
  2. Trouver un élément intéressant (ou plus probablement son élément parent, supposé élément div)
  3. Sélectionnez l'onglet 'Calculé'
  4. s'il existe un paramètre: webkit-transform: matrix (...), cela signifie que l'élément est transformé par CSS et peut ne pas être reconnu par Selenium 2 en tant qu'élément visible
6
justnpT

L’invisibilité peut également être due au moment où l’élément est censé apparaître lentement ..__ Le fait d’obliger le navigateur à attendre un peu peut aider dans ce cas.

Voir, par exemple, la question de laisser WebDriver attendre la présence d’un élément .

5
avandeursen

J'ai eu le même problème avec Selenium 2 dans Internet Explorer 9, mais ma solution est vraiment étrange. Je n'ai pas été en mesure de cliquer sur les entrées de ma fiche -> répétitions Sélénium, elles ne sont pas visibles. 

Cela se produisait lorsque ma forme avait des ombres courbes -> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects : dans le concret "Effet n ° 2"

Je ne sais pas du tout, pourquoi et comment cette solution de pseudo-éléments a interrompu les tests Selenium, mais cela fonctionne pour moi.

2
Agoreddah

Vous ne pouvez pas forcer l'accès/le changement d'élément auquel l'utilisateur n'a normalement pas accès, car Selenium est conçu pour imiter les interactions de l'utilisateur.

Si cette erreur se produit, vérifiez si:

  • l'élément est visible dans votre fenêtre, essayez de maximiser la fenêtre actuelle utilisée par webdriver (par exemple, maximize() in node.js, maximize_window() en Python),
  • votre élément n'apparaît pas deux fois (sous le même sélecteur), et vous choisissez le mauvais,
  • si votre élément est caché, envisagez de le rendre visible,
  • si vous souhaitez accéder à/changer la valeur de l'élément caché malgré la limitation, utilisez alors Javascript pour cela (par exemple executeScript() in node.js, execute_script() en Python).
2
kenorb

Je viens de résoudre cette erreur lors de l’utilisation de capybara in ror project en ajoutant:

Capybara.ignore_elements = true

à features/support/env.rb.

1
Zernel

Je viens de résoudre cette erreur en attendant la propriété d'affichage d'élément

waitFor() { element.displayed }
1
Suat Keskin

Je suis dans une exception ElementNotVisibleException en utilisant Selenium pour des tests fonctionnels sur un site Django avec des glyphiques bootstrap sous forme de liens dans des modèles tels que:

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>

Lors de mes tests fonctionnels, le style d'amorçage n'est pas chargé. Si vous essayez de cliquer sur ces liens, ElementNotVisibleException sera levé. Je parviens à les rendre cliquables juste en ajoutant un espace dans la balise, comme ça:

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger">&nbsp;</span></a>
1
jean pierre huart

La réponse acceptée a fonctionné pour moi. Vous trouverez ci-dessous un code pour trouver l’élément parent qui fait que Selenium pense qu’il n’est pas visible.

function getStyles(element){
	
	computedStyle = window.getComputedStyle(element);

	if(computedStyle.opacity === 0
	|| computedStyle.display === "none"
	|| computedStyle.visibility === "hidden"
	|| (computedStyle.height < 0 && computedStyle.height < 0)
	|| element.type === "hidden") {
		console.log("Found an element that Selenium will consider to not be visible")
		console.log(element);
		console.log("opacity: " + computedStyle.opacity);
		console.log("display: " + computedStyle.display);
		console.log("visibility: " + computedStyle.visibility);
		console.log("height: " + computedStyle.height);
		console.log("width: " + computedStyle.width);
	}

	if(element.parentElement){
		getStyles(element.parentElement);
	}
}

getStyles(document.getElementById('REPLACE WITH THE ID OF THE ELEMENT YOU THINK IS VISIBLE BUT Selenium CAN NOT FIND'));

0
starmer

Il y a beaucoup de bonnes réponses sur cette page.

  1. Généralement, je commence par maxim.window (). En fait, je le fais dans l’usine du pilote ou partout où vous initialisez votre pilote. C'est quelque chose de fait par défaut - toujours.
  2. C'est généralement une attente pour un élément en raison de certains délais javascript.

Les deux sont discutés dans divers détails ci-dessus. La réponse que je n'ai pas vue était ScrollToElement. On dirait que vous traitez une liste d’éléments, alors que vous traitez, vous créez plus d’éléments, des cases à cocher. Cela peut entraîner le déplacement d'éléments de votre liste de la page visible. Parfois, vous pouvez voir l'élément à l'œil nu, mais vous ne pouvez simplement pas cliquer dessus. Lors du traitement des listes, vous devez parfois interrompre le défilement.

  • Définissez un point de rupture et vérifiez si l'élément que vous utilisez se trouve dans la fenêtre Bord, en haut/en bas à droite/à gauche. Parfois, lorsque c'est le cas, vous ne pouvez pas y accéder via Selenium, mais vous pouvez cliquer manuellement avec votre souris.

Comme je me heurte à cela, j'ai créé un PageScroll.Java et y ai placé mes scripts de défilement. Voici quelques-unes des méthodes de cette classe:

public static void scrollToTop(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0,0)");
    }

    public static void scrollToBottom(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0, document.body.scrollHeight)");
    }

    public static void scrollToElementTop(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(true);", element);
    }

    public static void scrollToElementBottom(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(false);", element);
    }

voir Faites défiler l'élément dans la vue avec Selenium pour plus d'exemples

0
mancocapac

Pour ajouter mon grain de sable ici: si un élément réside derrière une div fixe, il sera considéré comme non visible et vous ne pourrez pas cliquer dessus; cela m'est arrivé récemment et je l'ai résolu en exécutant un script comme recommandé ci-dessus, ce qui fait:

document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);
0
Fernando Gabrieli