@findby xpath selenium examples
Selenium @FindBy vs driver.findElement() (4)
¿Por qué debería usar @FindBy
vs WebDriver#findElement()
?
@FindBy
me obliga a mover todas mis variables a un nivel de clase (cuando la mayoría de ellas solo necesitan estar en el nivel de método). Lo único que parece comprarme es que puedo llamar a PageFactory.initElements()
, que se encarga de la inicialización perezosa para mí.
¿Qué me estoy perdiendo?
En términos generales, @FindBy
es solo una forma alternativa de encontrar elementos (la "forma habitual" es driver.findElement()
como dijiste).
Sin embargo, la gran ventaja de esa anotación no es en sí misma. Se usa mejor para soportar el patrón PageObject .
En pocas palabras, el patrón PageObject le indica que cree una clase para cada página del sistema que está intentando usar / probar.
Entonces, en lugar de tener (el driver.findElement()
usual de driver.findElement()
):
public class TestClass {
public void testSearch() {
WebDriver driver = new HtmlUnitDriver();
driver.get("http://www.google.com/");
Element searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys("stringToSearch");
searchBox.submit();
// some assertions here
}
}
@FindBy
una clase para la página (con la anotación @FindBy
para los elementos utilizados):
public class GooglePage {
@FindBy(how = How.NAME, using = "q")
private WebElement searchBox;
public void searchFor(String text) {
searchBox.sendKeys(text);
searchBox.submit();
}
}
Y utilízalo como:
public class TestClass {
public void testSearch() {
WebDriver driver = new HtmlUnitDriver();
driver.get("http://www.google.com/");
GooglePage page = PageFactory.initElements(driver, GooglePage.class);
page.searchFor("stringToSearch");
// some assertions here
}
}
Ahora, sé que esto puede parecer detallado al principio, pero solo dale un momento y considera tener varios casos de prueba para esa página. ¿Qué pasa si cambia el nombre del searchBox
? (Desde el name
"q"
a un id
, diga query
?)
¿En qué código habría más cambios para que vuelva a funcionar? ¿El que tiene o el que no tiene los objetos de página (y @FindBy
)? Si una página cambia mucho su estructura, ¿en qué código sería más fácil el mantenimiento?
Hay algunas otras ventajas, como anotaciones adicionales como:
@FindBy(name = "q")
@CacheLookup
private WebElement searchBox;
Ese @CacheLookup
hace que la búsqueda del elemento ocurra solo una vez. Después de eso, se almacenará en la variable y será accesible mucho más rápido.
Espero que esto ayude. Para obtener más detalles, asegúrese de verificar PageFactory y el patrón PageObject .
No me gustan las anotaciones de @FindBy porque, a continuación, IntelliJ ya no detecta si se está utilizando esa variable, por lo que es una tarea de limpieza.
Una de las ventajas de usar Page Factory es que puede evitar StaleElementException . Por favor vea el siguiente enlace:
¿Cómo Page Object Model resuelve StaleElementReferenceException?
Extractos del enlace de arriba:
Verá que los programas se ejecutan bien cuando usamos el patrón de diseño de objetos de página. Nunca obtendrás la Excepción de referencia de elementos obsoletos. Cuando usamos la anotación FindBy en POM, webdriver localiza el elemento y la referencia de actualización cada vez que se realiza una acción al respecto. Puedes usar el elemento web sin reubicar en ninguna parte. Esta es una gran ventaja de usar el modelo de objetos de página.
Cómo luchar y evitar los elementos pasados.
Extractos del enlace de arriba:
Cómo luchar y evitar los elementos pasados.
Hay muchas formas de lidiar con la Excepción de elementos antiguos en la web. Aquí reuní las que personalmente me resultan más útiles.
Una buena práctica es usar la anotación @FindBy debido a la Inicialización perezosa. De esta manera, los elementos se inicializarán justo antes del uso real. Ejemplo: @FindBy (xpath = ”someXpath”) public WebElement someElement;
Use métodos de espera para JavaScript, Ajax, Jquery, etc. Esto resolverá la "Condición de carrera" que causa esta excepción.
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class CommonPageForStudent {
@FindBy(name="usname")
private WebElement Studentusername;
@FindBy(name="pass")
private WebElement Studentpassword;
@FindBy(xpath="//button[@type=''submit'']")
private WebElement StudentLetmein;
@FindBy(id="logoutLink")
private WebElement StudentlogoutLnk;
public void loginToStudent(String username , String password ){
Studentusername.sendKeys(username);
Studentpassword.sendKeys(password);
StudentLetmein.click();
}
//when you call this methods from another class write this 2 line code that class
//CommonPageForStudent page = PageFactory.initElements(driver, CommonPageForStudent.class);
// page.loginToStudent("","");
public void logOut(){
StudentlogoutLnk.click();
}
//page.logOut(); method call
}`