java - saber - WebDriver: ¿Cómo comprobar si existe un elemento web de objeto de página?
saber si existe elemento jquery (8)
El problema es el propio patrón. Utiliza la anotación @FindBy (utilizada por PageFactory para iniciar los campos que debe incluir el Proxy) que reemplaza los elementos estándar con sus instancias de proxy que contienen InvocationHandler.
Cada vez que intenta acceder a un campo, anotado con @FindBy, el controlador de invocación intenta encontrar el elemento utilizando el ElementLocator predeterminado. El problema es que el método ElementLocator.findElement () lanza una excepción TimeoutException / NoSuchElementException si no hay elementos presentados en el DOM.
public WebElement findElement(SearchContext context) {
List<WebElement> allElements = findElements(context);
if (allElements == null || allElements.isEmpty())
throw new NoSuchElementException("Cannot locate an element using "
+ toString());
return allElements.get(0);
}
Por lo tanto, cada vez que necesite comprobar si un elemento se muestra o no, debe buscar una Lista de elementos y verificar su tamaño.
@FindBy(css = "div.custom")
private List<WebElement> elements
...
public isElementPresented(){
return elements != null && elements.size > 0
}
Otra forma de resolver este problema es crear su propia implementación de LocatingElementHandler y ElementLocator
Por lo tanto, si necesita su propio método isDisplayed () para devolver false en lugar de Exception, debe reemplazar el método findElement () en ElementLocator con algo así:
...
List<WebElement> elements = searchContext.findElements(by)
if(elements != null && elements.size() > 0){
List<WebElement> visibleElements = []
elements.each {
if(it.displayed){
visibleElements.add(it)
}
}
if(visibleElements.size() > 0){
return visibleElements.get(0)
}
}
return null
...
Y añada nuevas condiciones a LocatingElementHandler.invoke ()
Algo como:
element = locator.findElement()
if(element == null){
if(method.name == "isDisplayed"){
return false
}
}
Cómo verificar si existe un elemento, cuando se usan objetos de página con webdriver.
Hasta ahora lo estoy haciendo de esta manera.
DefaultPage defaultPage = PageFactory.initElements(this.driver,
DefaultPage.class);
assertTrue(defaultPage.isUserCreateMenuLinkPresent());
Objeto de página:
public class DefaultPage {
@FindBy(id = "link_i_user_create")
private WebElement userCreateMenuLink;
public boolean isUserCreateMenuLinkPresent() {
try {
this.userCreateMenuLink.getTagName();
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}
Pero no puedo creer que este intento / captura sea la forma en que uno debería hacerlo. Entonces, ¿cuál sería una mejor manera de verificar si los elementos salen (con el uso de objetos de página)?
Estoy usando este patrón, funciona bien para mí:
public void login()
{
if (!loginButton.isDisplayed())
{
throw new IllegalStateException("Login button is not displayed!");
} else
{
loginButton.click();
}
}
o:
public boolean loginButtinIsDisplayed() {
try {
this.loginButton.getTagName();
return true;
} catch (NoSuchElementException e) {
e.printStackTrace();
return false;
}
}
Hace poco me encontré con este viejo post y creo que he encontrado una solución.
Estaba probando una página que tenía un botón Add User
. Cuando se hizo clic en el botón, aparecieron varios campos de texto editables (para Nombre, Apellido, Correo electrónico, etc.) y un solo menú desplegable.
Cuando se hizo clic en el botón Cancel
, los campos desaparecieron y ya no existían. El uso de WebDriverWait
con ExpectedConditions.visibilityOf()
no funcionaría ya que los elementos ya no existían en el DOM
.
Descubrí que @FindAll
era una solución para mí, aunque debo admitir que mi prueba fue notablemente lenta en la afirmación de mi lista.
Para su código, algo como esto:
public class DefaultPage {
@FindAll({@FindBy(id = "link_i_user_create")}) List<WebElement> userCreateMenuLink;
public boolean isUserCreateMenuLinkPresent() {
if (this.userCreateMenuLink.isEmpty()) fail("Link does not exist");}
Sin embargo, puedo usar algo similar en mis propias pruebas, y parece ser una forma confiable de eludir la excepción ''No existe tal elemento''. Es básicamente una adaptación de objeto de página de afirmar: driver.findElements(By.locator).size() < 1
.
Intenta esto es definitivamente trabajar en pom
public boolean isPrebuiltTestButtonVisible() {
try {
if (preBuiltTestButton.isEnabled()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Esto definitivamente funcionará en el modelo de objeto de página surround con try catch
Usando enlaces de C #:
using System.Collections.Generic;
using System.Linq;
public class DefaultPage
{
[FindsBy(How = How.Id, Using = "link_i_user_create")]
private IList<IWebElement> userCreateMenuLink;
public bool isUserCreateMenuLinkPresent()
{
return userCreateMenuLink.Any();
}
}
Le está diciendo a Selenium que tome todos los elementos que coincidan con esa identificación y los ponga en una lista de IWebElement
de IWebElement
. Luego llama a .Any()
en la lista que se evalúa como verdadera si se encontró al menos un elemento IWebElement
.
Webdriver está diseñado para lanzar una excepción si no se encuentra un elemento, por lo que no hay ningún método para verificar la presencia de un elemento en Webdriver.
Marque esto: http://groups.google.com/group/webdriver/browse_thread/thread/909a9b6cb568e341
Arquillian ha implementado esa característica en la extensión Graphene .
Compruebe la función ElementLocatorConditionFactory.isPresent()
.
Más o menos hacen lo que escribiste en tu pregunta (de ExpectedConditions.findElement
en selenium-support.jar ):
try {
return driver.findElement(by);
} catch (NoSuchElementException e) {
throw e;
} catch (WebDriverException e) {
// [...] some log
throw e;
}
@Ralph : Lo hago de la misma manera: prueba / captura. Nunca he encontrado otra manera. Podría intercambiar el bloque try / catch en una súper clase y diseñarlo genérico . En otras palabras: podría escribir un método que espere un objeto de tipo WebElement . Este método contiene el bloque try / catch y devuelve true / false ...
Así que escribí el siguiente método público en la súper clase del marco de prueba y ahora puedo usarlo en cada objeto de página :
public boolean isElementExisting(WebElement we) {
try {
we.isDisplayed();
return true;
} catch(NoSuchElementException e) {
LOGGER.severe("Element does not exist.");
return false;
}
}
No sé por qué esto no está implementado en WebDriver ...
De lo contrario, podría utilizar WebDriverWait .