Comment forcer Selenium WebDriver à cliquer sur un élément qui n'est pas actuellement visible?
j'utilise L'API Java de Selenium 2 avec FirefoxDriver. Lorsque je remplis un formulaire, des cases à cocher sont ajoutées à la page en fonction des entrées de formulaires.
j'aimerais simuler un clic sur ces cases à cocher en utilisant du sélénium. L'élément visible et utilisable dans un navigateur classique mais, sélénium affirme que les éléments ne sont pas visibles.
"Element is not currently visible and so may not be interacted with"
puis-je forcer le sélénium à ignorer l'état non visible des éléments? Comment puis-je forcer le sélénium à interagir avec l'élément non visible?
12 réponses
le sélénium détermine qu'un élément est visible ou non selon les critères suivants (utilisez un inspecteur DOM pour déterminer ce que la css s'applique à votre élément, assurez-vous de regarder computed style):
- visibilité != caché
- affichage != Aucune (est également cochée contre chaque élément parent)
- l'opacité != 0 (ceci n'est pas vérifié pour cliquer un élément)
- hauteur et largeur > 0
- pour une entrée, l'attribut type != 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 avec javascript (en allant supposer WebDriver puisque vous avez dit API Selenium2):
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);
mais cela ne va pas déclencher un événement javascript, si vous dépendez de l'événement de changement pour cette entrée, vous devrez le faire aussi (plusieurs façons de le faire, plus facile à utiliser quelle que soit la bibliothèque javascript chargée sur cette page).
la source de La visibilité de l'enregistrement
https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577
la spécification WebDriver qui définit ceci -
parfois, cela signifie qu'il y a plusieurs éléments sur une page qui ont la même propriété que vous essayez de rechercher et vous"parlez au mauvais".
si votre élément ne peut pas être identifié de façon unique par :id ou :name (ou :class), il peut être délicat.
parfois chercher l'élément par le :xpath aidera et dans certains cas, même cela n'est pas pratique.
dans ces cas, vous pouvez avoir tous les les éléments qui correspondent à vos critères et référencent le bon par l'index. C'est sale, mais ça fonctionne.
J'utilise Selenium / Watir de Ruby on Rails app, donc 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
Espérons que cette aide.
j'avais un problème similaire, mais il était lié à l'élément n'étant pas visible dans le viewport. J'ai pris une capture d'écran et réalisé la fenêtre du navigateur est trop étroite et l'élément ne pouvait pas être vu. J'en ai fait une et ça a marché:
driver.maximize_window()
ou vous pouvez utiliser la classe D'Action sélénium pour simuler l'interaction de l'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();
il y a aussi un autre cas où l'élément visible sera reconnu comme non visible:
- lorsque L'élément est css transformé
- lorsque L'élément Parent de L'élément est css transformé
pour vérifier si l'élément avec lequel vous ne voulez pas interagir est transformé css, sur CHROME faites ceci:
- ouvrir l'inspecteur
- trouver élément intéressant (ou plus probablement son élément parent, soi-disant élément div)
- sélectionnez "Computed" tab
- s'il y a un paramètre: webkit-transform: matrix( ... ) cela signifie que l'élément est css transformé, et ne peut pas être reconnu par le sélénium 2 comme un élément visible
l'invisibilité peut aussi être due au timing quand l'élément est censé apparaître lentement. Forcer le navigateur à attendre un peu peut aider dans ce cas.
voir, par exemple, la question sur le fait de laisser WebDriver attendre jusqu'à ce qu'un élément soit présent .
j'ai eu le même problème avec le sélénium 2 dans internet explorer 9, Mais mon correctif est vraiment étrange. Je n'ai pas pu cliquer dans les entrées de mon formulaire -> répétitions sélénium, elles ne sont pas visibles.
cela s'est produit quand ma forme avait des ombres courbées - > http://www.paulund.co.uk/creating-different-css3-box-shadows-effects : dans le béton " effet no. 2"
Je n'ai aucune idée, pourquoi et comment cette solution de pseudo élément a cessé des tests de sélénium, mais ça marche pour moi.
vous ne pouvez pas forcer l'accès/changement d'élément auquel l'utilisateur n'a normalement pas accès, car le sélénium est conçu pour imiter l'interaction de l'utilisateur.
si cette erreur se produit, cochez:
- élément est visible dans votre viewport, essayer de maximiser la fenêtre actuelle que webdriver utilise (par exemple
maximize()
dans noeud.js ,maximize_window()
en Python), - votre élément n'apparaît pas deux fois (sous le même sélecteur), et vous sélectionnez le mauvais,
- si votre élément est caché, alors envisagez de le rendre visible,
- si vous souhaitez accéder/changer la valeur de l'élément caché malgré la limitation, utilisez Javascript pour cela (par exemple
executeScript()
dans noeud.js ,execute_script()
en Python).
je viens de résoudre cette erreur en utilisant capybara dans le projet ror en ajoutant:
Capybara.ignore_elements = true
à features/support/env.rb
.
je viens de résoudre cette erreur en attente de l'élément de propriété d'affichage
waitFor() { element.displayed }
je reçois dans ElementNotVisibleException exception à l'aide de sélénium pour les tests fonctionnels sur un site django avec fichier d'amorce glyphicons comme des liens dans des modèles comme:
<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>
lors de mes tests fonctionnels, le style bootstrap n'est pas chargé, puis essayer de cliquer sur de tels liens soulèvera ElementNotVisibleException. J'arrive à les rendre cliquables en ajoutant juste un espace dans la balise, comme ça:
<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"> </span></a>
la réponse acceptée a fonctionné pour moi. Ci-dessous, un code pour trouver l'élément parent qui fait croire au sélénium 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'));