Automatizaci贸n del navegador web con Selenium y Java

    Introducci贸n

    Varias herramientas pueden manejar el navegador web de la forma en que a un usuario real le gustar铆a navegar a diferentes p谩ginas, interactuar con los elementos de la p谩gina y capturar algunos datos. Este proceso se denomina Automatizaci贸n del navegador web. Lo que puede hacer con la automatizaci贸n del navegador web depende totalmente de su imaginaci贸n y sus necesidades.

    Algunos de los casos de uso comunes de la automatizaci贸n del navegador web podr铆an ser:

    • Automatizar las pruebas manuales en una aplicaci贸n web
    • Automatizar las tareas repetitivas como eliminar informaci贸n de sitios web
    • Llenar los formularios HTML, realizar algunos trabajos administrativos, etc.

    En este tutorial exploraremos una de las herramientas de automatizaci贸n de navegadores web m谩s populares: Selenium . Conoceremos sus caracter铆sticas, la API y c贸mo podemos usarla con Java para automatizar cualquier sitio web.

    驴Qu茅 es el selenio?

    Selenium es una colecci贸n de herramientas que incluye Selenium IDE, Selenium RC y Selenium WebDriver.

    Selenium IDE es puramente una herramienta de reproducci贸n de grabaciones que se presenta como un complemento de Firefox y una extensi贸n de Chrome. Selenium RC era la herramienta heredada que ahora est谩 depreciada. Selenium WebDriver es la herramienta m谩s reciente y m谩s utilizada.

    Nota : Los t茅rminos Selenium, Selenium WebDriver o simplemente WebDriver se utilizan indistintamente para referirse a Selenium WebDriver.

    Es importante se帽alar aqu铆 que Selenium est谩 dise帽ado para interactuar solo con componentes web. Entonces, si encuentra alg煤n componente basado en el escritorio como un cuadro de di谩logo de Windows, Selenium por s铆 solo no puede interactuar con ellos. Existen otros tipos de herramientas como AutoIt o Automa que se pueden integrar con Selenium para estos fines.

    驴Por qu茅 usar selenio?

    El selenio es una de las herramientas de automatizaci贸n de navegadores m谩s populares. No depende de un lenguaje de programaci贸n en particular y es compatible con Java, Python, C #, Ruby, PHP, Perl, etc. Tambi茅n puede escribir su implementaci贸n para el lenguaje si a煤n no es compatible.

    En este tutorial, aprenderemos c贸mo usar los enlaces Java de Selenium WebDriver. Tambi茅n exploraremos la API de WebDriver.

    El 茅xito de Selenium tambi茅n se puede atribuir al hecho de que las especificaciones de WebDriver se han convertido en la recomendaci贸n del W3C para los navegadores.

    Prerrequisitos:

    WebDriver proporciona enlace para todos los idiomas populares como se describe en la secci贸n anterior. Dado que estamos usando el entorno Java, necesitamos descargar e incluir enlaces Java en la ruta de compilaci贸n. Adem谩s, casi todos los navegadores populares proporcionan un controlador que se puede usar con Selenium para controlar ese navegador.

    En este tutorial, manejaremos Google Chrome.

    WebDriver

    Antes de seguir adelante, es 煤til comprender algunos conceptos que generan confusi贸n entre los principiantes. WebDriverno es una clase, es una interfaz.

    Todos los conductores depende del explorador como ChromeDriver, FirefoxDriver, InternetExplorerDriverson clases Java que implementan la WebDriverinterfaz. Esta informaci贸n es importante porque si desea ejecutar su programa en un navegador diferente, no necesita cambiar un mont贸n de su c贸digo para que funcione, solo necesita cambiarlo WebDriverpor el navegador que desee.

    Primero, especifiquemos la ruta al controlador del navegador. A continuaci贸n, crearemos una instancia del “controlador correcto” para ese navegador, ChromeDriveren nuestro caso:

    System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
    WebDriver driver = new ChromeDriver();
    

    Como podemos ver, drivercontiene una referencia a ChromeDrivery, por lo tanto, se puede utilizar para controlar el navegador. Cuando se ejecute la declaraci贸n anterior, deber铆a ver una nueva ventana del navegador abierta en su sistema. Pero el navegador a煤n no ha abierto ning煤n sitio web. Necesitamos indicarle al navegador que lo haga.

    Nota : Para utilizar uno diferente WebDriver, debe especificar la ruta del controlador en el sistema de archivos y luego crear una instancia. Por ejemplo, si desea utilizar IE, esto es lo que debe hacer:

    System.setProperty("webdriver.ie.driver", "path/to/IEDriver");
    WebDriver driver = new InternetExplorerDriver();
    

    De aqu铆 en adelante, el c贸digo ser谩 exactamente el mismo para todos los navegadores. Para mantener nuestros aprendizajes enfocados, automatizaremos Pharos.sh.com.

    Como se mencion贸 anteriormente, primero debemos navegar a nuestro sitio web de destino. Para hacer esto, simplemente enviamos una solicitud GET a la URL del sitio web:

    driver.get("http://Pharos.sh.com");
    

    WebElement

    El primer paso en la automatizaci贸n del navegador web es ubicar los elementos de la p谩gina web con los que queremos interactuar, como un bot贸n, entrada, lista desplegable, etc.

    La representaci贸n de Selenium de dichos elementos HTML es WebElement. Al igual que WebDriverel WebElementtambi茅n es una interfaz Java. Una vez que nos hacemos con un WebElementpodemos realizar cualquier operaci贸n sobre ellos que pueda hacer un usuario final, como hacer clic, teclear, seleccionar, etc.

    Es obvio que intentar realizar operaciones no v谩lidas, como intentar ingresar texto en un elemento de bot贸n, resultar谩 en una excepci贸n.

    Podemos utilizar los atributos HTML de un elemento como id, classy namepara localizar un elemento. Si no hay tales atributos presentes, podemos usar algunas t茅cnicas de localizaci贸n avanzadas como Selectores CSS y XPath .

    Para verificar los atributos HTML de cualquier elemento, podemos abrir el sitio web en nuestro navegador Chrome (otros navegadores tambi茅n lo admiten), haga clic derecho sobre el elemento que desea seleccionar y haga clic en Inspeccionar elemento. Esto deber铆a abrir las herramientas de desarrollo y mostrar los atributos HTML de ese elemento:

    Como podemos ver, el elemento tiene una <input>etiqueta y m煤ltiples atributos como id, class, etc.

    WebDriver admite 8 localizadores diferentes para localizar elementos:

    • id
    • className
    • name
    • tagName
    • linkText
    • partialLinkText
    • cssSelector*
    • xpath

    Exploremos todos ellos uno por uno automatizando los diferentes elementos en nuestro sitio web objetivo.

    Ubicaci贸n de elementos a trav茅s de id

    Si inspeccionamos el cuadro de entrada del bolet铆n de nuestro sitio web de destino, podemos encontrar que tiene un idatributo:

    <input type="email" id="email" value name="email" class="required email input-lg" placeholder="Enter your email...">
    

    Podemos localizar este elemento usando el idlocalizador:

    WebElement newsletterEmail = driver.findElement(By.id("email"));
    

    Ubicaci贸n de elementos a trav茅s de className

    Si inspeccionamos el mismo cuadro de entrada, podemos ver que tambi茅n tiene un classatributo.

    Podemos localizar este elemento usando el classNamelocalizador:

    WebElement newsletterEmail = driver.findElement(By.className("required email input-lg"));
    

    Nota : El nombre del localizador es className, no class. Pero el atributo HTML s铆 lo es class.

    Ubicaci贸n de elementos por nombre

    Para este ejemplo, imaginemos una lista desplegable, donde un usuario debe seleccionar su rango de edad. La lista desplegable tiene un nameatributo, que podemos buscar:

    <select name="age">
        <option value="Yet to born">Not Born</option>
        <option value="Under 20">Under 20</option>
        <option value="20 to 29">Under 30</option>
        <option value="30 to 39">Under 40</option>
        <option value="40 to 50">Under 50</option>
        <option value="Over 50">Above 60</option>
        <option value="Ghost">Not Defined</option>
    </select>
    

    Podemos localizar este elemento usando el namelocalizador:

    WebElement age = driver.findElement(By.name("age"));
    

    Ubicaci贸n de elementos a trav茅s de xpath

    A veces, sin embargo, estos enfoques son obsoletos, ya que hay varios elementos con el mismo atributo:

    <p>
        <input name="gender" type="Radio" value="Female">Female<br>
        <input name="gender" type="Radio" value="Male">Male<br>
        <input name="gender" type="Radio" value="donotknow">Still Exploring
    </p>
    

    En este ejemplo podemos ver que los tres inputelementos tienen el mismo namearttribute, “gener”, pero no todos tienen el mismo valor. A veces, los atributos b谩sicos como id, classo nameno son 煤nicos, en cuyo caso necesitamos una forma de definir exactamente qu茅 elemento nos gustar铆a buscar.

    En estos casos, podemos utilizar localizadores XPath. Los XPath son localizadores muy poderosos y son un tema completo por s铆 mismos. El siguiente ejemplo puede darle una idea de c贸mo construir un XPath para los fragmentos de HTML anteriores:

    WebElement gender = driver.findElement(By.xpath("//input[@value="Female"]"));
    

    Ubicaci贸n de elementos a trav茅s de cssSelector

    Nuevamente, imaginemos una lista de casillas de verificaci贸n donde el usuario selecciona su lenguaje de programaci贸n preferido:

    <p>
        <input name="language_java" type="Checkbox" value="java">Java<br>
        <input name="language_python" type="Checkbox" value="python">Python<br>
        <input name="language_c#" type="Checkbox" value="c#">C#<br>
        <input name="language_c" type="Checkbox" value="c">C<br>
        <input name="language_vbs" type="Checkbox" value="vbscript">Vbscript
    </p>
    

    T茅cnicamente, para este fragmento de HTML, podemos usar f谩cilmente el namelocalizador, ya que tienen valores distintos. Sin embargo, en este ejemplo, usaremos cssSelectorspara ubicar este elemento, que se usa ampliamente en el front-end con bibliotecas como jQuery.

    El siguiente ejemplo puede darle una idea de c贸mo construir selectores de CSS para el fragmento de HTML anterior:

    WebElement languageC = driver.findElement(By.cssSelector("input[value=c]"));
    WebElement languageJava = driver.findElement(By.cssSelector("input[value=java]"));
    

    Evidentemente, es muy similar al enfoque XPath.

    Ubicaci贸n de elementos mediante linkText

    Si el elemento es un enlace, es decir, tiene una <a>etiqueta, podemos localizarlo utilizando su texto. Por ejemplo, el enlace “Abuso de pila”:

    <a href="/">Stack Abuse</a>
    

    Podemos localizar el enlace usando su texto:

    WebElement homepageLink = driver.findElement(By.linkText("Stack Abuse"));
    

    Ubicaci贸n de elementos a trav茅s de partialLinkText

    Digamos que tenemos un enlace con el texto: “texto-aleatorio-xyz-i-no cambiar茅-d铆gito-aleatorio-123”. Como se mostr贸 anteriormente, podemos ubicar este elemento usando el linkTextlocalizador.

    Sin embargo, la API de WebDriver ha proporcionado otro m茅todo partialLinkText. A veces, una parte del texto del enlace puede ser din谩mico y cambia cada vez que recargas la p谩gina, por ejemplo, “Pedido # XYZ123”.

    En estos casos podemos el partialLinkTextlocalizador:

    WebElement iWontChangeLink = driver.findElement(By.partialLinkText("i-wont-change"));
    

    El c贸digo anterior seleccionar谩 correctamente nuestro enlace “texto-aleatorio-xyz-i-wont-change-random-digit-123” ya que nuestro selector contiene una subcadena del enlace.

    Ubicaci贸n de elementos mediante tagName

    Tambi茅n podemos encontrar un elemento mediante el uso de su nombre de la etiqueta, por ejemplo <a>, <div>, <input>, <select>, etc Usted debe utilizar este localizador con precauci贸n. Como puede haber varios elementos con el mismo nombre de etiqueta y el comando siempre devuelve el primer elemento coincidente en la p谩gina:

    WebElement tagNameElem = driver.findElement(By.tagName("select"));
    

    Esta forma de encontrar un elemento suele ser m谩s 煤til cuando se llama al findElementm茅todo en otro elemento y no en todo el documento HTML. Esto reduce su b煤squeda y le permite encontrar elementos usando localizadores simples.

    Interactuar con los elementos

    Hasta ahora hemos localizado los elementos HTML en la p谩gina y podemos obtener los correspondientes WebElement. Sin embargo, todav铆a no hemos interactuado con esos elementos como lo har铆a un usuario final: hacer clic, escribir, seleccionar, etc. Exploraremos algunas de estas acciones simples en las pr贸ximas secciones.

    Hacer clic en Elementos

    Realizamos la operaci贸n de clic utilizando el click()m茅todo. Podemos usar esto en cualquiera WebElementsi se puede hacer clic. Si no, lanzar谩 una excepci贸n.

    En este caso, hagamos clic en homepageLink:

    homepageLink.click();
    

    Dado que esto realmente realiza el clic en la p谩gina, su navegador web seguir谩 el enlace en el que se hizo clic mediante programaci贸n.

    Ingresando texto

    Ingresemos algo de texto en el newsletterEmailcuadro de entrada:

    newsletterEmail.sendkeys("[email聽protected]");
    

    Seleccionar botones de radio

    Dado que simplemente se hace clic en los botones de radio, usamos el click()m茅todo para seleccionar uno:

    gender.click();
    

    Seleccionar casillas de verificaci贸n

    Lo mismo ocurre con la selecci贸n de casillas de verificaci贸n, aunque en este caso, podemos seleccionar varias casillas de verificaci贸n. Si seleccionamos otro bot贸n de radio, se deseleccionar谩 el anterior:

    languageC.click();
    languageJava.click();
    

    Seleccionar elementos de un men煤 desplegable

    Para seleccionar un elemento de la lista desplegable, tendr铆amos que hacer dos cosas:

    Primero, necesitamos crear una instancia Selecty pasarle el elemento de la p谩gina:

    Select select = new Select(age);
    

    Es importante se帽alar aqu铆 que Selectes una clase Java que implementa la ISelectinterfaz.

    A continuaci贸n, podemos seleccionar un elemento usando su:

    Texto mostrado :

    select.selectByVisibleText("Under 30");
    

    Valor (el valueatributo):

    select.selectByValue("20 to 30");
    

    脥ndice (comienza con 0):

    select.selectByIndex(2);
    

    Si la aplicaci贸n admite la selecci贸n m煤ltiple, podemos llamar a uno o m谩s de estos m茅todos varias veces para seleccionar diferentes elementos.

    Para comprobar si la aplicaci贸n permite m煤ltiples selecciones podemos ejecutar:

    select.isMultiple();
    

    Hay muchas otras operaciones 煤tiles que podemos realizar en la lista desplegable:

    • Obteniendo la lista de opciones:
    java.util.List<WebElement> options = select.getOptions();
    
    • Obteniendo la lista de opciones seleccionadas:
    java.util.List<WebElement> options = select.getAllSelectedOptions();
    
    • Obtener la primera opci贸n seleccionada
    java.util.List<WebElement> options = select.getFirstSelectedOption();
    
    • Deseleccionar todas las opciones
    select.deselectAll();
    
    • Deseleccionar por el texto mostrado:
    select.deselectByVisibleText("Under 30");
    
    • Deseleccionar por valor:
    select.deselectByValue("20 to 30");
    
    • Deseleccionar por 铆ndice:
    select.deselectByIndex(2);
    

    Nota : Tambi茅n podemos combinar los dos pasos de encontrar el elemento e interactuar con ellos en una sola declaraci贸n a trav茅s del encadenamiento. Por ejemplo, podemos encontrar y hacer clic en el bot贸n Enviar como este:

    driver.findElement(By.id("submit_htmlform")).click();
    

    Tambi茅n podemos hacer esto con Select:

    Select select = new Select(driver.findElement(By.name("age")));
    

    Obtener valores de atributo

    Para obtener el valor de un atributo particular en un elemento:

    driver.findElement(By.id("some-id")).getAttribute("class")
    

    Establecer valores de atributo

    Tambi茅n podemos establecer el valor de un atributo particular en un elemento. Podr铆a ser 煤til donde queramos habilitar o deshabilitar cualquier elemento:

    driver.findElement(By.id("some-id")).setAttribute("class", "enabled")
    

    Interactuar con el mouse y el teclado

    La API de WebDriver ha proporcionado la Actionsclase para interactuar con el mouse y el teclado.

    Primero, necesitamos crear una instancia Actionsy pasarle la WebDriverinstancia:

    Actions builder = new Actions(driver);
    

    Mover el mouse

    A veces, es posible que necesitemos colocar el cursor sobre un elemento del men煤 que hace que aparezca el elemento del submen煤:

    WebElement elem = driver.findElement(By.id("some-id"));
    builder.moveToElement(elem).build().perform();
    

    Arrastrar y soltar

    Arrastrar un elemento sobre otro elemento:

    WebElement sourceElement = driver.findElement(By.id("some-id"));
    WebElement targetElement = driver.findElement(By.id("some-other-id"));
    builder.dragAndDrop(sourceElement, targetElement).build().perform();
    

    Arrastrar un elemento por algunos p铆xeles (por ejemplo, 200 px en horizontal y 0 px en vertical):

    WebElement elem = driver.findElement(By.id("some-id"));
    builder.dragAndDropBy(elem, 200, 0).build().perform();
    

    Pulsando teclas

    Mantenga presionada una tecla en particular mientras escribe un texto como la Shifttecla:

    WebElement elem = driver.findElement(By.id("some-id"));
    builder.keyDown(Keys.SHIFT)
        .sendKeys(elem,"some value")
        .keyUp(Keys.SHIFT)
        .build()
        .perform();
    

    Realizar operaciones como Ctrl+a, Ctrl+c, Ctrl+v, y TAB:

    // Select all and copy
    builder.sendKeys(Keys.chord(Keys.CONTROL,"a"),Keys.chord(Keys.CONTROL,"c")).build().perform();
    
    // Press the tab to focus on the next field
    builder.sendKeys(Keys.TAB).build().perform();
    
    // Paste in the next field
    builder.sendKeys(Keys.chord(Keys.CONTROL,"v")).build().perform();
    

    Interactuar con el navegador

    Obtener la fuente de la p谩gina

    Lo m谩s probable es que use esto para las necesidades de raspado web:

    driver.getPageSource();
    

    Obtener el t铆tulo de la p谩gina

    driver.getPageTitle();
    

    Maximizar el navegador

    driver.manage().window().maximize();
    

    Salir del controlador

    Es importante salir del controlador al final del programa:

    driver.quit();
    

    Nota : WebDriver API tambi茅n proporciona un close()m茅todo y, a veces, esto confunde a los principiantes. El close()m茅todo simplemente cierra el navegador y se puede volver a abrir en cualquier momento. No destruye el WebDriverobjeto. El quit()m茅todo es m谩s apropiado cuando ya no necesita el navegador.

    Toma de capturas de pantalla

    Primero, tenemos que convertir WebDrivera TakesScreenshottipo que es una interfaz. A continuaci贸n, podemos llamar getScreenshotAs()y pasar OutputType.FILE.

    Finalmente, podemos copiar el archivo en el sistema de archivos local con las extensiones apropiadas como * .jpg, * .png, etc.

    File fileScreenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    
    // Copy screenshot in local file system with *.png extension
    FileUtils.copyFile(fileScreenshot, new File("path/MyScreenshot.png"));
    

    Ejecutando JavaScript

    Tambi茅n podemos inyectar o ejecutar cualquier pieza v谩lida de JavaScript a trav茅s de Selenium WebDriver. Esto es muy 煤til ya que le permite hacer muchas cosas que no est谩n integradas directamente en Selenium.

    Primero, necesitamos lanzar WebDriveral tipo JavaScriptExecutor:

    JavaScriptExecutor js = (JavaScriptExecutor)driver;
    

    Podr铆a haber varios casos de uso relacionados con JavaScriptExecutor:

    • Realizar operaciones de la forma natural de hacerlo si la API de WebDriver falla, como un click()o sendKeys().
    js.executeScript("driver.getElementById('some-id').click();");
    

    Tambi茅n podemos encontrar primero el elemento usando localizadores WebDriver y pasar ese elemento al executeScript()como segundo argumento. Es la forma m谩s natural de utilizar JavaScriptExecutor:

    // First find the element by using any locator
    WebElement element = driver.findElement(By.id("some-id"));
    
    // Pass the element to js.executeScript() as the 2nd argument
    js.executeScript("arguments[0].click();", element);
    

    Para establecer el valor de un campo de entrada:

    String value = "some value";
    WebElement element = driver.findElement(By.id("some-id"));
    js.executeScript("arguments[0].value=arguments[1];", element, value);
    
    • Desplazamiento de la p谩gina a la parte inferior de la ventana:
    js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
    
    • Desplazamiento del elemento para llevarlo a la ventana gr谩fica:
    WebElement element = driver.findElement(By.id("some-id"));
    
    // If the element is at the bottom pass true, otherwise false 
    js.executeScript("arguments[0].scrollIntoView(true);", element);
    
    • Alterando la p谩gina (agregando o quitando algunos atributos de un elemento):
    WebElement element = driver.findElement(By.id("some-id"));
    js.executeScript("arguments[0].setAttribute('myattr','myvalue')", element);
    

    Acceso a cookies

    Dado que muchos sitios web utilizan cookies para almacenar el estado del usuario u otros datos, puede resultarle 煤til acceder a ellos mediante programaci贸n utilizando Selenium. Algunas operaciones comunes de cookies se describen a continuaci贸n.

    Obtener todas las cookies:

    driver.manage().getCookies();
    

    Obtenga una cookie espec铆fica:

    driver.manage().getCookieNamed(targetCookie);
    

    Agrega una cookie:

    driver.manage().addCookie(mySavedCookie);
    

    Eliminar una cookie:

    driver.manage().deleteCookie(targetCookie);
    

    Conclusi贸n

    Hemos cubierto todas las caracter铆sticas principales de Selenium WebDriver que es posible que necesitemos usar al automatizar un navegador web. Selenium WebDriver tiene una API muy extensa y cubrir todo est谩 m谩s all谩 del alcance de este tutorial.

    Es posible que haya notado que Selenium WebDriver tiene muchos m茅todos 煤tiles para simular casi todas las interacciones de los usuarios. Dicho esto, las aplicaciones web modernas son realmente inteligentes. Si quieren restringir su uso automatizado, hay varias formas de hacerlo, como usar captcha. Desafortunadamente, Selenium no puede omitir el captcha. Utilice esta herramienta teniendo en cuenta los T茅rminos de uso del sitio web de destino.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *