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 *