Selenium, el proyecto para automatizar navegadores

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Selenium es un proyecto que alberga un abanico de herramientas y librerías que permiten y apoyan la automatización de navegadores web.

Proporciona extensiones que permiten emular las interacciones que realizan los usuarios con los navegadores, un servidor que permite distribuir la asignación de navegadores de forma escalable, y la infraestructura necesaria para las implementaciones de la especificación del WebDriver del W3C, el cual permite escribir código intercambiable para los navegadores web mas usados.

Este proyecto es posible gracias a los colaboradores voluntarios, los cuales han dedicado miles de horas de su propio tiempo haciendo así que el código fuente esté disponible de manera gratuita para que cualquiera pueda usarlo, disfrutarlo y mejorarlo.

Selenium conecta a proveedores de navegadores web, ingenieros y entusiastas para promover un debate abierto sobre la automatización de plataformas web. El proyecto organiza una conferencia anual con el fin de enseñar y nutrir a la comunidad.

El corazón de Selenium es el WebDriver, una interfaz que permite escribir conjuntos de instrucciones que se pueden ejecutar de manera indistinta en muchos navegadores.

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;
import java.time.Duration;

public class HelloSelenium {

    public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        try {
            driver.get("https://google.com/ncr");
            driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER);
            WebElement firstResult = wait.until(presenceOfElementLocated(By.cssSelector("h3")));
            System.out.println(firstResult.getAttribute("textContent"));
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import presence_of_element_located

#This example requires Selenium WebDriver 3.13 or newer
with webdriver.Firefox() as driver:
    wait = WebDriverWait(driver, 10)
    driver.get("https://google.com/ncr")
    driver.find_element(By.NAME, "q").send_keys("cheese" + Keys.RETURN)
    first_result = wait.until(presence_of_element_located((By.CSS_SELECTOR, "h3")))
    print(first_result.get_attribute("textContent"))
  
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;

class HelloSelenium {
  static void Main() {
    using(IWebDriver driver = new FirefoxDriver()) {
      WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
      driver.Navigate().GoToUrl("https://www.google.com/ncr");
      driver.FindElement(By.Name("q")).SendKeys("cheese" + Keys.Enter);
      wait.Until(webDriver => webDriver.FindElement(By.CssSelector("h3")).Displayed);
      IWebElement firstResult = driver.FindElement(By.CssSelector("h3"));
      Console.WriteLine(firstResult.GetAttribute("textContent"));
    }
  }
}
  
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox
wait = Selenium::WebDriver::Wait.new(timeout: 10)

begin
  driver.get 'https://google.com/ncr'
  driver.find_element(name: 'q').send_keys 'cheese', :return
  first_result = wait.until { driver.find_element(css: 'h3') }
  puts first_result.attribute('textContent')
ensure
  driver.quit
end
  
const {Builder, By, Key, until} = require('selenium-webdriver');

(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.google.com');

        // Enter text "cheese" and perform keyboard action "Enter"
        await driver.findElement(By.name('q')).sendKeys('cheese', Key.ENTER);

        let firstResult = await driver.wait(until.elementLocated(By.css('h3')), 10000);

        console.log(await firstResult.getAttribute('textContent'));
    }
    finally{
       await driver.quit();
    }
})();
  
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated
import org.openqa.selenium.support.ui.WebDriverWait
import java.time.Duration

fun main() {
    val driver = FirefoxDriver()
    val wait = WebDriverWait(driver, Duration.ofSeconds(10))
    try {
        driver.get("https://google.com/ncr")
        driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER)
        val firstResult = wait.until(presenceOfElementLocated(By.cssSelector("h3")))
        println(firstResult.getAttribute("textContent"))
    } finally {
        driver.quit()
    }
}
  

See the Overview to check the different project components and decide if Selenium is the right tool for you.

You should continue on to Getting Started to understand how you can install Selenium and successfully use it as a test automation tool, and scaling simple tests like this to run in large, distributed environments on multiple browsers, on several different operating systems.

1 - Overview

Is Selenium for you? See an overview of the different project components.

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Selenium no es solo una herramienta o API, sino que compone muchas herramientas.

WebDriver

Si está comenzando con la automatización de pruebas de sitios web de escritorio, entonces va a utilizar las API de WebDriver utiliza las API de automatización del navegador proporcionadas por los desarrolladores de los navegadores para controlar el navegador y ejecutar pruebas. Esto es como si un usuario real estuviera manipulando el navegador. Dado que el WebDriver no requiere que su API se compile con el código de la aplicación que va a probar, no es de naturaleza intrusiva. Por lo tanto, está probando la misma aplicación que está en vivo.

IDE

IDE (Integrated Development Environment) es la herramienta que usas para desarrollar tus casos de prueba con Selenium. Es una extensión para Chrome y Firefox muy sencilla de usar y es generalmente la forma mas eficiente de desarrollar casos de prueba. Esta graba las acciones del usuario en el navegador, usando los comandos existentes en Selenium, con parámetros definidos por el contexto de cada elemento. No solo sirve para ahorrar tiempo sino que también es una forma excelente de aprender la sintaxis de scripts de Selenium.

Grid

Selenium Grid te permite ejecutar casos de prueba en diferentes maquinas a través de diferentes plataformas. La gestión que desencadena las ejecuciones de los casos de prueba se realiza en la parte local, y cuando los casos de prueba se hayan disparado, automáticamente serán ejecutados en la parte remota.

Poco después del desarrollo de las pruebas de WebDriver, es posible que deba ejecutar sus pruebas en múltiples combinaciones de navegador y sistema operativo. Aquí es donde Grid viene al rescate.

1.1 - A Deeper Look

Selenium es un proyecto que alberga un catálogo de herramientas y librerías que permiten y sustentan la automatización de navegadores web.

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Selenium controla los navegadores web

Selenium significa muchas cosas pero en su núcleo, es un conjunto de herramientas para la automatización de navegadores web que utiliza las mejores técnicas disponibles para controlar remotamente las instancias de los navegadores y emular la interacción del usuario con el navegador.

Permite a los usuarios simular interacciones básicas realizadas por los usuarios finales; insertando texto en los campos, seleccionando valores de menús desplegables y casillas de verificación, y haciendo clics en los enlaces de los documentos. También provee muchos otros controles tales como el movimiento del mouse, la ejecución arbitraria de JavaScript, y mucho más.

A pesar de que es usado principalmente para pruebas de front-end de sitios webs, Selenium es en esencia una librería de agente de usuario para el navegador. Las interfaces son ubicuas a su aplicación, lo que fomenta la composición con otras librerías para adaptarse a su propósito.

Una interfaz para gobernarlos a todos

Uno de los principios fundamentales del proyecto es permitir una interfaz común para todas las tecnologías de los (principales) navegadores. Los navegadores web son aplicaciones increíblemente complejas y de mucha ingeniería, realizando operaciones completamente diferentes pero que usualmente se ven iguales al hacerlo. Aunque el texto se presente con las mismas fuentes, las imágenes se muestren en el mismo lugar y los enlaces te llevan al mismo destino. Lo que sucede por debajo es tan diferente como la noche y el día. Selenium abstrae estas diferencias, ocultando sus detalles y complejidades a la persona que escribe el código. Esto le permite escribir varias líneas de código para realizar un flujo de trabajo complicado, pero estas mismas líneas se ejecutarán en Firefox, Internet Explorer, Chrome y los demás navegadores compatibles.

Herramientas y soporte

El diseño minimalista de Selenium le da la versatilidad para que se pueda incluir como un componente en otras aplicaciones. La infraestructura proporcionada debajo del catálogo de Selenium te da las herramientas para que puedas ensamblar tu grid de navegadores de modo que tus pruebas se puedan ejecutar en diferentes navegadores a través de diferente sistemas operativos y plataformas.

Imagina un banco de computadores en tu sala de servidores o en un centro de datos, todos ejecutando navegadores al mismo tiempo e interactuando con los enlaces en tu sitio web, formularios, y tablas—probando tu aplicación 24 horas al día. A través de la sencilla interfaz de programación proporcionada para los lenguajes más comunes, estas pruebas se ejecutarán incansablemente en paralelo, reportando cuando ocurran errores.

Es un objetivo ayudar a que esto sea una realidad para ti, proporcionando a los usuarios herramientas y documentación para controlar no solo los navegadores pero también para facilitar la escalabilidad e implementación de tales grids.

Quien utiliza Selenium

Muchas de las empresas más importantes del mundo han adoptado Selenium para sus pruebas basadas en navegador, a menudo reemplazando esfuerzos de años que involucran otras herramientas propietarias. A medida que ha crecido en popularidad, también se han multiplicado sus requisitos y desafíos.

A medida que la web se vuelve más complicada y se agregan nuevas tecnologías a los sitios web, la misión de este proyecto es mantenerse al día con ellos siempre que sea posible. Siendo un proyecto de código abierto, este apoyo se sustenta a través de la donación generosa de tiempo de muchos voluntarios, cada uno de los cuales tiene un “trabajo diurno”.

Otra misión del proyecto es alentar a más voluntarios a participar en este esfuerzo, y construir una comunidad fuerte para que el proyecto pueda seguir el ritmo de las tecnologías emergentes y seguir siendo una plataforma dominante para la automatización de pruebas funcionales.

2 - Empezando

If you are new to Selenium, we have a few resources that can help you get up to speed right away.

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Selenium permite la automatización de todos los principales navegadores del mercado mediante el uso de WebDriver. WebDriver es una API y un protocolo que define una interfaz de idioma neutral para controlar el comportamiento de los navegadores web. Cada navegador está respaldado por una implementación específica de WebDriver, llamada controlador. El controlador es el componente responsable de delegar en el navegador, y maneja la comunicación hacia y desde Selenium y el navegador.

Esta separación es parte de un esfuerzo consciente para hacer que los proveedores de navegadores asuman la responsabilidad de la implementación para sus navegadores. Selenium utiliza estos controladores de terceros cuando es posible, pero también proporciona sus propios controladores mantenidos por el proyecto para los casos en que esto no es una realidad.

El framework de Selenium unifica todas estas piezas a través de una interfaz orientada al usuario que habilita que los diferentes backends de los navegadores sean utilizados de forma transparente, permitiendo la automatización cruzada entre navegadores y plataformas diferentes.

La configuración de Selenium es bastante diferente de la configuración de otras herramientas comerciales. Para usar Selenium en tu proyecto de automatización, necesitas instalar las librerías de enlace de tu lenguaje de preferencia. Además necesitarás los binarios de WebDriver para los navegadores en los que deseas automatizar y ejecutar pruebas.

Installing Selenium can be divided in three steps:

  1. Installing the Selenium library for your desired programming language
  2. Set up the browser driver to automate your browser (e.g. GeckoDriver for Firefox)
  3. (Optional) Set up and configure Selenium Grid if you want to scale up your tests

If you wish to start with a low-code/record and playback tool, please check Selenium IDE

After completing the setup, you can run the code snippet shown at the starting page in our docs. Then head to the WebDriver section to learn more about browser automation with Selenium.

2.1 - Installing Selenium libraries

Setting up the Selenium library for your favourite programming language.

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

First you need to install the Selenium bindings for your automation project. The installation process for libraries depends on the language you choose to use.

Java

Installation of Selenium libraries for Java can be done using Maven. Add the selenium-java dependency in your project pom.xml:

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
  <version>4.X</version>
</dependency>

The selenium-java dependency supports running your automation project with all Selenium supported browsers. If you want to run tests only in a specific browser, you can add the dependency for that browser in your pom.xml file. For example, you should add following dependency in your pom.xml file to run your tests only in Firefox:

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-firefox-driver</artifactId>
  <version>4.X</version>
</dependency>

In a similar manner, if you want to run tests only in Chrome, you should add the following dependency:

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-chrome-driver</artifactId>
  <version>4.X</version>
</dependency>

Python

Installation of Selenium libraries for Python can be done using pip:

pip install selenium

Alternatively you can download the PyPI source archive (selenium-x.x.x.tar.gz) and install it using setup.py:

python setup.py install

C#

Installation of Selenium libraries for C# can be done using NuGet:

# Using package manager
Install-Package Selenium.WebDriver
# or using .Net CLI
dotnet add package Selenium.WebDriver

Ruby

Installation of Selenium libraries for Ruby can be done using gem:

gem install selenium-webdriver

JavaScript

Installation of Selenium libraries for JavaScript can be done using npm:

npm install selenium-webdriver

Kotlin

Due to missing native language bindings for Kotlin, you have to use the Java Bindings, e.g. with maven Java

2.2 - Installing browser drivers

Setting up your browser to be automated.

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

A través del WebDriver, Selenium es capaz de soportar los navegadores mas usados en el mercado como Chrom(ium), Firefox, Internet Explorer, Edge, Opera y Safari. WebDriver maneja los navegadores, cuando es posible, apoyándose en las propias funciones que el navegador incorpora para la automatización.

La finalidad del WebDriver es emular las interacciones de los usuarios reales. Esto es posible en diversos niveles en diferentes navegadores.

Aunque todos los controladores comparten una única interfaz orientada al usuario para manejar los navegadores, todos ellos tienen diferentes formas de establecer las sesiones. Ya que muchas de estas implementaciones son realizadas por terceras personas y no están incluidas en la distribución estándar de Selenium.

La instanciación del controlador, el tratamiento de perfiles y algunos ajustes específicos de cada navegador son ejemplos de parámetros que tienen diferentes requisitos dependiendo del navegador.

Esta sección explica los requisitos básicos para comenzar a trabajar con diferentes navegadores.

Añadiendo los ejecutables al PATH del sistema

La gran mayoría de controladores necesitan de un ejecutable extra para que Selenium pueda comunicarse con el navegador. Puedes especificar manualmente donde esta ubicado el ejecutable antes lanzar el WebDriver, pero esto hará que tus tests sean menos portables, ya que los ejecutables necesitan estar en el mismo lugar en todas las maquinas, o que este incluido en el repositorio.

Añadir una carpeta que contenga los binarios del WebDriver a tu sistema, permitirá a Selenium localizar los binarios necesarios adicionales sin la necesidad de tener que incluir en el código de los tests la ruta exacta.

  • Crea un directorio para almacenar los ejecutables en el, como C:\WebDriver\bin o /opt/WebDriver/bin
  • Añade el directorio al PATH del sistema:
    • En Windows - Abre una terminal de comando como administrador y ejecuta el siguiente comando para añadir permanentemente el directorio a tu PATH para todos los usuarios de tu maquina:
setx /m path "%path%;C:\WebDriver\bin\"
  • En macOS y Linux ejecutar el siguiente comando en una terminal:
export PATH=$PATH:/opt/WebDriver/bin >> ~/.profile
  • Ahora puedes probar los cambios. Para ello cierra todas las terminales de comando y abre una nueva Escribe el nombre de uno de los binarios que has añadido en la carpeta en el paso previo. p. ej.:

    chromedriver
    
  • Si tu PATH ha sido configurado correctamente, verás una salida relacionada con la puesta en marcha del controlador:

Starting ChromeDriver 2.25.426935 (820a95b0b81d33e42712f9198c215f703412e1a1) on port 9515
Only local connections are allowed.

Puedes recuperar el control de la consola de comandos pulsando Ctrl + C

Referencia Rápida

NavegadorSO SoportadosMantenido porDescargasIssues
Chromium/ChromeWindows/macOS/LinuxGoogleDescargasIncidentes
FirefoxWindows/macOS/LinuxMozillaDescargasIncidentes
EdgeWindows 10MicrosoftDescargasIncidentes
Internet ExplorerWindowsProyecto de SeleniumDescargasIncidentes
SafarimacOS El Capitan and newerAppleIntegradoIncidentes
OperaWindows/macOS/LinuxOperaDescargasIncidentes

Chromium/Chrome

Para controlar Chrome o Chromium, tienes que descargar chromedriver y almacenarlo en una carpeta que esté en el PATH del sistema.

En Linux y en macOS esto significa que tienes que modificar la variable de entorno PATH.

Puedes ver que directorios están incluidos en esta variable, los directorios se separan mediante dos puntos.

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Para incluir el chromedriver en el PATH si no lo estuviera, hay que asegurarse que incluimos la ruta donde se almacena el binario del chromedriver. Recuerda que puedes fijar la ruta al ejecutable del chromedriver usando la siguiente linea, esto te permitirá añadir el contenido actual del PATH mas una ruta adicional después de los dos puntos:

$ export PATH="$PATH:/path/to/chromedriver"

Cuando el chromedriver este en el PATH este podrá ser ejecutado desde cualquier directorio. Para instanciar una sesión de Chrome/Chromium puedes hacer lo siguiente:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

WebDriver driver = new ChromeDriver();
  
#Asignación simple
from selenium.webdriver import Chrome

driver = Chrome()

#Como gestor de contexto
from selenium.webdriver import Chrome

with Chrome() as driver:
    #your code inside this indent
  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

IWebDriver driver = new ChromeDriver();
  
require "selenium-webdriver"

driver = Selenium::WebDriver.for :chrome
  
const {Builder} = require('selenium-webdriver');

(async function myFunction() {
    let driver = await new Builder().forBrowser('chrome').build();
    //your code inside this block
})();
  
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver

val driver: WebDriver = ChromeDriver()
  

Recuerda que tienes que fijar la ruta al ejecutable del chromedriver. Lo puedes hacer de la siguiente forma:

System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
  
Chrome(executable_path='/path/to/chromedriver')
  
new ChromeDriver("/path/to/chromedriver");
  
Selenium::WebDriver::Chrome.driver_path = "/path/to/chromedriver"
  
chrome.setDefaultService(new chrome.ServiceBuilder('path/to/chromedriver').build());
  
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver")
  

El chromedriver esta implementado como un servidor remoto el cual expone la interfaz del proxy para la automatización de chrome, enseñando asi al navegador que hacer.

Firefox

Con la salida de Selenium 3, Mozilla se ha encargado de la implementación del controlador de Firefox, a través del geckodriver. Este nuevo controlador se llama geckodriver y funciona a partir de la versión 48 de Firefox. Como este controlador sigue en desarrollo, cuanto mas nueva sea la versión de Firefox mas respaldo tendrá por parte de Mozilla.

Como geckodriver es la nueva forma por defecto de lanzar Firefox, puedes instanciar Firefox de la misma forma en Selenium 2:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

WebDriver driver = new FirefoxDriver();
  
#Asignación simple
from selenium.webdriver import Firefox

driver = Firefox()
#Como gestor de contexto
from selenium.webdriver import Firefox

with Firefox() as driver:
   #El código con este nivel de tabulación
  
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

IWebDriver driver = new FirefoxDriver();
  
require "selenium-webdriver"

driver = Selenium::WebDriver.for :firefox
  
const {Builder} = require('selenium-webdriver');

(async function myFunction() {
   let driver = await new Builder().forBrowser('firefox').build();
   //your code inside this block
})();
  
import org.openqa.selenium.WebDriver
import org.openqa.selenium.Firefox.FirefoxDriver

val driver: WebDriver = FirefoxDriver()
  

Si no quisieras fijar la ruta del geckodriver en el PATH, puedes fijar la ruta del ejecutable como propiedad del sistema:

System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");
  
Firefox(executable_path='/path/to/geckodriver')
  
new FirefoxDriver("/path/to/geckodriver");
  
Selenium::WebDriver::Firefox.driver_path = "/path/to/geckodriver"
  
const firefox = require('selenium-webdriver/firefox');

const serviceBuilder = new firefox.ServiceBuilder("/path/to/geckodriver");

(async function myFunction() {
    let driver = await new Builder()
        .forBrowser('firefox')
        .setFirefoxService(serviceBuilder)
        .build();
        //your code inside this block
})();
  
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver")
  

En ciertos lenguajes de programación también es posible fijar la propiedad en tiempo de ejecución:

mvn test -Dwebdriver.gecko.driver=/path/to/geckodriver

Actualmente también es posible revertir al controlador antiguo de Firefox, el cual es un controlador mas completo, instalando la versión 47.0.1 o 45 ESR y especificando la capacidad deseada del controlador marionette como false. Las ultimas versiones de Firefox ya no son compatibles con este controlador.

Edge

Edge es el navegador mas nuevo de Microsoft, incluido en Windows 10 y Microsoft Server 2016. Las actualizaciones de Edge están incluidas en las actualizaciones principales de Windows, es por eso que necesitaras descargar el binario que coincida con la versión que tengas en ese momento instalada de Windows. La web de desarrolladores de Edge contiene los enlaces a todos los binarios disponibles.

Los bugs de la implementación del EdgeDriver se pueden encontrar en Microsoft.

Si deseas lanzar los tests contra Edge pero tu sistema operativo no es Windows 10, Microsoft ofrece maquinas virtuales en la web de desarrolladores de Edge.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

WebDriver driver = new EdgeDriver();
  
#Asignación simple
from selenium.webdriver import Edge

driver = Edge()
#Como gestor de contexto:
from selenium.webdriver import Edge

with Edge() as driver:
   #El código con este nivel de tabulación
  
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;

IWebDriver driver = new EdgeDriver();
  
require "selenium-webdriver"

driver = Selenium::WebDriver.for :edge
  
const {Builder} = require('selenium-webdriver');

(async function myFunction() {
   let driver = await new Builder().forBrowser('MicrosoftEdge').build();
   //your code inside this block
})();
  
import org.openqa.selenium.WebDriver
import org.openqa.selenium.edge.EdgeDriver

val driver: WebDriver = EdgeDriver()
  

Si el controlador de Edge no esta presente en el PATH, puedes añadirlo con el siguiente comando:

System.setProperty("webdriver.edge.driver", "C:/path/to/MicrosoftWebDriver.exe");
  
Edge(executable_path='/path/to/MicrosoftWebDriver.exe')
  
new EdgeDriver("/path/to/MicrosoftWebDriver.exe");
  
Selenium::WebDriver::Edge.driver_path = "C:/path/to/MicrosoftWebDriver.exe"
  
const {Builder} = require("selenium-webdriver");
const edge = require('selenium-webdriver/edge');
let service = new edge.ServiceBuilder("/path/to/msedgedriver.exe");
(async function test() {
    let driver = await new Builder()
                .setEdgeService(service)
                .forBrowser('MicrosoftEdge')
                .build();
})();
  
System.setProperty("webdriver.edge.driver", "C:/path/to/MicrosoftWebDriver.exe")
  

Internet Explorer

Internet Explorer era el navegador por defecto hasta la salida de Windows 10, aunque todavía esta incluido en Windows 10. El controlador de Internet Explorer es el único que Selenium tiene como objetivo admitir las mismas versiones que Microsoft considera como actuales. Las versiones anteriores pueden funcionar pero no serán mantenidas.

A pesar de que Selenium proporciona los binarios para las versiones de 32 y 64 bits de Internet Explorer existen algunas limitaciones respecto a las versiones 10 y 11 para el controlador de 64-bits, en cambio el controlador de 32-bits funciona correctamente. Hay que tener en cuenta que las preferencias de Internet Explorer se guardan en la cuenta del usuario conectado, ademas es necesario realizar configuraciones adicionales

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;

WebDriver driver = new InternetExplorerDriver();
  
#Asignación simple
from selenium.webdriver import Ie

driver = Ie()
#Como gestor de contexto
from selenium.webdriver import Ie

with Ie() as driver:
   #El código con este nivel de tabulación
  
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

IWebDriver driver = new InternetExplorerDriver();
  
require "selenium-webdriver"

driver = Selenium::WebDriver.for :internet_explorer
  
const {Builder} = require('selenium-webdriver');

(async function myFunction() {
   let driver = await new Builder().forBrowser('internet explorer').build();
   //your code inside this block
})();
  
import org.openqa.selenium.WebDriver
import org.openqa.selenium.ie.InternetExplorerDriver

val driver: WebDriver = InternetExplorerDriver()
  

Si el controlador de Internet Explorer no esta presente en el PATH, puedes añadirlo usando la siguiente linea:

System.setProperty("webdriver.ie.driver", "C:/path/to/IEDriver.exe");
  
Ie(executable_path='/path/to/IEDriverServer.exe')
  
new InternetExplorerDriver("C:/path/to/IEDriver.exe");
  
Selenium::WebDriver::IE.driver_path = "C:/path/to/IEDriver.exe"
  
const {Builder} = require("selenium-webdriver");
const ie = require('selenium-webdriver/ie');
let service = new ie.ServiceBuilder("/path/to/IEDriverServer.exe");
(async function test() {
    let driver = await new Builder()
                .setIeService(service)
                .forBrowser('internet explorer')
                .build();
})();
  
System.setProperty("webdriver.ie.driver", "C:/path/to/IEDriver.exe")
  

Microsoft tambien ofrece un binario para Internet Explorer 11 en Windows 7 y 8.1. El cual no ha sido actualizado desde 2014 y está basado en una versión preeliminar de la especificación del W3C. Jim Evans hizo un informe excelente sobre la implementación del controlador.

Opera

Las versiones actuales de Opera están construidas con el motor de Chromium, y WebDriver ahora es soportado a través del controlador de código propietario de Opera el cual puede ser añadido al PATH o configurado como propiedad del sistema.

Instanciar una sesión del controlador es similar a como se hace el Firefox y Chromium:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.opera.OperaDriver;

WebDriver driver = new OperaDriver();
  
#Asignación simple
from selenium.webdriver import Opera

driver = Opera()
#Como gestor de contexto
from selenium.webdriver import Opera

with Opera() as driver:
   #El código con este nivel de tabulación
  
using OpenQA.Selenium;
using OpenQA.Selenium.Opera;

IWebDriver driver = new OperaDriver();
  
require "selenium-webdriver"

driver = Selenium::WebDriver.for :opera
  
const {Builder} = require("selenium-webdriver");
const opera = require('selenium-webdriver/opera');
(async function test() {
    let driver = await new Builder()
        .forBrowser('opera')
        .build();
})();
  
import org.openqa.selenium.WebDriver
import org.openqa.selenium.opera.OperaDriver

val driver: WebDriver = OperaDriver()
  

Safari

Para las versiones High Sierra y superiores:

  • Al Lanzar el siguiente comando desde la terminal por primera vez se debe escribir la contraseña para autorizar al WebDriver
safaridriver --enable

Para El Capitan y Sierra:

  • Activar el menú desarrollador desde las preferencias de Safari
  • Seleccionar la opción Permitir automatización desde el menú del desarrollador
  • Ejecutar el siguiente comando desde la terminal y escribir la contraseña para autorizar al WebDriver
/usr/bin/safaridriver -p 1337</

Una vez realizar podrás comenzar una sesión usando:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;

WebDriver driver = new SafariDriver();
  
#Asignación simple
from selenium.webdriver import Safari

driver = Safari()
#Como gestor de contexto
from selenium.webdriver import Safari

with Safari() as driver:
   #El código con este nivel de tabulación
  
using OpenQA.Selenium;
using OpenQA.Selenium.Safari;

IWebDriver driver = new SafariDriver();
  
require "selenium-webdriver"

driver = Selenium::WebDriver.for :safari
  
const {Builder} = require('selenium-webdriver');

(async function myFunction() {
   let driver = await new Builder().forBrowser('safari').build();
   //your code inside this block
})();
  
import org.openqa.selenium.WebDriver
import org.openqa.selenium.safari.SafariDriver

val driver: WebDriver = SafariDriver()
  

Aquellos que busquen automatizar Safari en iOS deberían echarle un vistazo al proyecto de Appium Aunque antes Safari estuviera disponible en Windows, Apple hace tiempo que dejo de mantenerlo, convirtiendo así a Windows en una pobre elección para la automatización de pruebas sobre Safari

HtmlUnit

HtmlUnit es un navegador sin interfaz grafica para programas basados en Java. Modela documentos HTML y proporciona un API que permite invocar las paginas, rellanar formularios, hacer clic en enlaces, etc. Soporta JavaScript y es capaz de funcionar con librerías AJAX, simulando Chrome, Firefox o Internet Explorer dependiendo de la configuración usada. Se ha migrado a una nueva web. El código fuente es mantenido con de snv.

PhantomJS

PhantomJS is un navegador sin interfaz grafica basado en Webkit, aunque la versión en la que se basa es mucho mas antigua que las usadas por Chrome o Safari. A pesar de que históricamente ha sido una elección popular actualmente no es una elección muy sabia. Ya que el proyecto esta sin soporte desde el 5 de gosto, cuando Google anunció que Chrome tendría la capacidad de ser un navegador sin interfaz grafica, algo que también ha ofrecido Firefox.

2.3 - How to upgrade to Selenium 4

Interested in Selenium 4? Check this guide that will help you upgrade to the latest release!

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Upgrading to Selenium 4 should be a painless process if you are using one of the officially supported languages (Ruby, JavaScript, C#, Python, and Java). There might be some cases where a few issues can happen, and this guide will help you to sort them out. We will go through the steps to upgrade your project dependencies and understand the major deprecations and changes the version upgrade brings.

These are the steps we will follow to upgrade to Selenium 4:

  • Preparing our test code
  • Upgrading dependencies
  • Potential errors and deprecation messages

Note: while Selenium 3.x versions were being developed, support for the W3C WebDriver standard was implemented. Both this new protocol and the legacy JSON Wire Protocol were supported. Around version 3.11, Selenium code became compliant with the level W3C 1 specification. The W3C compliant code in the latest version of Selenium 3 will work as expected in Selenium 4.

Preparing our test code

Selenium 4 removes support for the legacy protocol and uses the W3C WebDriver standard by default under the hood. For most things, this implementation will not affect end users. The major exceptions are Capabilities and the Actions class.

Capabilities

If the test capabilities are not structured to be W3C compliant, may cause a session to not be started. Here is the list of W3C WebDriver standard capabilities:

  • browserName
  • browserVersion (replaces version)
  • platformName (replaces platform)
  • acceptInsecureCerts
  • pageLoadStrategy
  • proxy
  • timeouts
  • unhandledPromptBehavior

An up-to-date list of standard capabilities can be found at W3C WebDriver.

Any capability that is not contained in the list above, needs to include a vendor prefix. This applies to browser specific capabilities as well as cloud vendor specific capabilities. For example, if your cloud vendor uses build and name capabilities for your tests, you need to wrap them in a cloud:options block (check with your cloud vendor for the appropriate prefix).

Before

DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), capabilities);
caps = Selenium::WebDriver::Remote::Capabilities.firefox
caps[:platform] = 'Windows 10'
caps[:version] = '92'
caps[:build] = my_test_build
caps[:name] = my_test_name
driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)

After

FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), options);
options = Selenium::WebDriver::Options.firefox
options.browser_version = 'latest'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options[:build] = my_test_build
cloud_options[:name] = my_test_name
options.add_option('cloud:options', cloud_options)
driver = Selenium::WebDriver.for :remote, url: cloud_url, capabilities: options
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)

Find element(s) utility methods in Java

The utility methods to find elements in the Java bindings (FindsBy interfaces) have been removed as they were meant for internal use only. The following code samples explain this better.

Finding a single element with findElement*

Before

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");

After

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));

Finding a multiple elements with findElements*

Before

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");

After

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));

Upgrading dependencies

Check the subsections below to install Selenium 4 and have your project dependencies upgraded.

Java

The process of upgrading Selenium depends on which build tool is being used. We will cover the most common ones for Java, which are Maven and Gradle. The minimum Java version required is still 8.

Maven

Before

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>

After

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.0.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>

After making the change, you could execute mvn clean compile on the same directory where the pom.xml file is.

Gradle

Before

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}

After

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.0.0'
}
test {
    useJUnitPlatform()
}

After making the change, you could execute ./gradlew clean build on the same directory where the build.gradle file is.

To check all the Java releases, you can head to MVNRepository.

C#

The place to get updates for Selenium 4 in C# is NuGet. Under the Selenium.WebDriver package you can get the instructions to update to the latest version. Inside of Visual Studio, through the NuGet Package Manager you can execute:

PM> Install-Package Selenium.WebDriver -Version 4.0.0

Python

The most important change to use Python is the minimum required version. Selenium 4 will require a minimum Python 3.7 or higher. More details can be found at the Python Package Index. To upgrade from the command line, you can execute:

pip install selenium==4.0.0

Ruby

The update details for Selenium 4 can be seen at the selenium-webdriver gem in RubyGems. To install the latest version, you can execute:

gem install selenium-webdriver

To add it to your Gemfile:

gem 'selenium-webdriver', '~> 4.0.0'

JavaScript

The selenium-webdriver package can be found at the Node package manager, npmjs. Selenium 4 can be found here. To install it, you could either execute:

npm install selenium-webdriver

Or, update your package.json and run npm install:

{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.0.0"
  }
}

Potential errors and deprecation messages

Here is a set of code examples that will help to overcome the deprecation messages you might encounter after upgrading to Selenium 4.

Java

Waits and Timeout

The parameters received in Timeout have switched from expecting (long time, TimeUnit unit) to expect (Duration duration).

Before

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

After

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));

Waits are also expecting different parameters now. WebDriverWait is now expecting a Duration instead of a long for timeout in seconds and milliseconds. The withTimeout and pollingEvery utility methods from FluentWait have switched from expecting (long time, TimeUnit unit) to expect (Duration duration).

Before

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);

After

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);

Merging capabilities is no longer changing the calling object

It was possible to merge a different set of capabilities into another set, and it was mutating the calling object. Now, the result of the merge operation needs to be assigned.

Before

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

As a result, the options object was getting modified.

After

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

The result of the merge call needs to be assigned to an object.

Firefox Legacy

Before GeckoDriver was around, the Selenium project had a driver implementation to automate Firefox (version <48). However, this implementation is not needed anymore as it does not work in recent versions of Firefox. To avoid major issues when upgrading to Selenium 4, the setLegacy option will be shown as deprecated. The recommendation is to stop using the old implementation and rely only on GeckoDriver. The following code will show the setLegacy line deprecated after upgrading.

FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);

BrowserType

The BrowserType interface has been around for a long time, however it is getting deprecated in favour of the new Browser interface.

Before

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);

After

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);

C#

AddAdditionalCapability is deprecated

Instead of it, AddAdditionalOption is recommended. Here is an example showing this:

Before

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);

After

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);

Summary

We went through the major changes to be taken into consideration when upgrading to Selenium 4. Covering the different aspects to cover when test code is prepared for the upgrade, including suggestions on how to prevent potential issues that can show up when using the new version of Selenium. To finalize, we also covered a set of possible issues that you can bump into after upgrading, and we shared potential fixes for those issues.

This was originally posted at https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4

3 - WebDriver

WebDriver drives a browser natively, learn more about it.

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

WebDriver controla un navegador de forma nativa, como lo haría un usuario, ya sea localmente o en una máquina remota utilizando el servidor Selenium, marca un salto adelante en términos de automatización de navegadores.

Selenium WebDriver se refiere tanto a los enlaces de lenguajes como también a las implementaciones individuales del código controlador del navegador. Esto se conoce comúnmente solo como WebDriver.

Selenium WebDriver es una Recomendación W3C

  • WebDriver está diseñado como una interfaz de programación simple y más concisa.

  • WebDriver es una API compacta orientada a objetos.

  • Controla el navegador de manera efectiva.

3.1 - Entendiendo los componentes

Construir una suite de test usando WebDriver requerirá que entiendas y uses de forma efectiva diferentes componentes. Como con todo en el desarrollo de software, la gente usa diferentes términos para la misma idea. A continuación hay un desglose de cómo los términos son usados en esa descripción.

Terminología

  • API: Interfaz de Programación de Aplicaciones. Es un conjunto de “comandos” que se utilizan para manipular el WebDriver.
  • Library: Un módulo de código que contiene las APIs y el código necesario para implementarlos. Las librerías son específicas para cada lenguaje, por ejemplo ficheros .jar en Java, ficheros .dll para .NET, etc.
  • Driver: El responsable de controlar el navegador actual. La mayoría de los drivers son creados por los vendors del navegador. Los Drivers son generalmente módulos ejecutables que corren en el sistema con el propio navegador, no en el sistema ejecutando la suite de test. (Aunque esos pueden ser el mismo sistema.) NOTE: Algunas personas se refieren a los drivers como proxies.
  • Framework: Una librería adicional usada como un soporte para la suites de WebDriver. Estos frameworks pueden ser test frameworks como JUnit o NUnit. También pueden ser frameworks soportando lenguaje natural como Cucumber o Robotium. Los frameworks también pueden ser escritos y usados para cosas como la manipulación o configuración del sistema bajo la prueba, creación de datos, test oracles, etc

Las Partes y las Piezas

Como mínimo, el WebDriver habla con un navegador a través del driver. La comunicación es bidireccional: el WebDriver pasa comandos al navegador a través del driver, y recibe la información de vuelta por la misma ruta.

Basic Communication

El driver es específico para el navegador, como es ChromeDriver para Chrome/Chromium de Google, GeckoDriver para Mozilla Firefox, etc. El driver corre en el mismo sistema que el browser. Esto puede, o no puede ser, el mismo sistema donde los tests se están ejecutando.

Este simple ejemplo anterior es de comunicación directa. La comunicación con el navegador puede ser remota a través de Selenium Server o RemoteWebdriver. Éste último corre en el mismo sistema que el driver y el browser.

Remote Communication

La comunicación remota puede también hacerse usando Selenium Server o Selenium Grid, ambos a su vez hablan con el driver en el sistema anfitrión.

Remote Communication with Grid

Dónde encaja el Framework

El WebDriver tiene un trabajo y solo un trabajo: comunicarse con el navegador a través de uno de los métodos nombrados. El WebDriver no tiene que saber nada sobre testing: no sabe cómo comparar cosas, asegurar un pass o fail, y ciertamente no sabe nada acerca de reportes o sobre la gramática Given/When/Then.

Aquí es donde varios frameworks entran en juego. Como mínimo necesitarás un framework de test que compare los enlaces de idiomas, por ejempolo NUnit para .NET, JUnit para Java, RSpec para Ruby, etc.

El framework de test es responsable de correr y ejecutar tu WebDriver y los pasos de tus tests. Como tal, puedes pensar que se parece a la siguiente imagen.

Test Framework

Los frameworks o herramientas de lenguage natural como Cucumber pueden existir como parte de la caja de Test Framework de la figura de arriba, o envolver totalmente el Test Framework en su propia implementación.

3.2 - Manipulación de Navegadores

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Ruby

Ruby no esta instalado por defecto en Windows. Puedes descargar la ultima versión y ejecutar el instalador. Puedes dejar todos los parámetros de configuración con los valores por defecto excepto el parámetro Add Ruby executables to your PATH de la pantalla de Installation Destination and Optional Tasks. Para manejar cualquier navegador tienes que instalar la gema de Ruby selenium-webdriver. Para instalarla abre una consola de comando y ejecuta el siguiente comando.

gem install selenium-webdriver

O si usas Bundler añade esta linea al Gemfile de tu aplicación:

gem "selenium-webdriver"

Y después ejecuta el siguiente comando en el terminal:

bundle install

Internet Explorer

Internet Explorer viene instalado por defecto en Windows, por lo que no es necesario realizar ninguna instalación. Para manejar Internet Explorer en Windows tienes que descargar la ultima versión del driver de Internet Explorer y añadirlo a un directorio que este incluido en el PATH del sistema. Para saber que directorios están incluidos en el PATH escribe el comando echo %PATH% en el terminal.

$ echo %PATH%
C:\Ruby200\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem

Por ejemplo el directorio C:\Ruby200\bin parece un buen lugar. Descomprime el archivo IEDriverServer y mueve el ejecutable IEDriverServer.exe a esta carpeta.

Las lineas que se muestran a continuación deberían abrir una nueva ventana de Internet Explorer.

require "selenium-webdriver"
driver = Selenium::WebDriver.for :internet_explorer

Manejo de los navegadores web

La primera cosa que querrás hacer después de levantar un navegador es abrir una pagina web. Esto se puede lograr en una sola linea:

//Forma adecuada
driver.get("https://selenium.dev");

//Forma extensa
driver.navigate().to("https://selenium.dev");
  
driver.get("https://selenium.dev")
  
driver.Navigate().GoToUrl(@"https://selenium.dev");
  
//Forma adecuada
driver.get 'https://selenium.dev'

//Forma extensa
driver.navigate.to 'https://selenium.dev'
  
await driver.get('https://selenium.dev');
  
//Forma adecuada
driver.get("https://selenium.dev")

//Forma extensa
driver.navigate().to("https://selenium.dev")
  

Obtener la URL actual

Puedes leer la URL actual desde la barra de direcciones del navegador usando:

driver.getCurrentUrl();
driver.current_url
driver.Url;
driver.current_url
await driver.getCurrentUrl();
driver.currentUrl

Retroceder

Presionando el botón de retroceder del navegador:

driver.navigate().back();
driver.back()
driver.Navigate().Back();
driver.navigate.back
await driver.navigate().back();
driver.navigate().back() 

Avanzar

Presionando el botón de avanzar del navegador:

driver.navigate().forward();
driver.forward()
driver.Navigate().Forward();
driver.navigate.forward
await driver.navigate().forward();
driver.navigate().forward()

Actualizar

Recargando la pagina actual:

driver.navigate().refresh();
driver.refresh()
driver.Navigate().Refresh();
driver.navigate.refresh
await driver.navigate().refresh();
driver.navigate().refresh()

Obtener el título

Puedes leer el título de la pagina actual desde el navegador:

driver.getTitle();
driver.title
driver.Title;
driver.title
await driver.getTitle();
driver.title

Ventanas y pestañas

Obtener el controlador de ventanas

El WebDriver no hace distinción entre ventanas y pestañas. Si tu sitio web abre una nueva pestaña o ventana, Selenium te permitirá trabajar con ella usando un controlador de ventanas. Cada ventana tiene un identificador único el cual persiste en una sola sesión. Puedes obtener el controlador de la ventana de la ventana actual usando:

driver.getWindowHandle();
driver.current_window_handle
driver.CurrentWindowHandle;
driver.window_handle
await driver.getWindowHandle();
driver.windowHandle

Cambiar entre ventanas o pestañas

Haciendo clic en un enlace el cual abre una nueva ventana cambiará el foco a la nueva ventana o pestaña en la pantalla, pero el WebDriver no sabrá que ventana el sistema operativo considera activa. Para trabajar con la nueva ventana necesitaras cambiar a ella. Si solo tienes dos ventanas o pestañas abiertas y sabes en cual empezaste, por proceso de eliminación, puede recorrer las ventanas o pestañas que ve el WebDriver y cambiar a una de ellas que no sea la original.

Sin embargo Selenium 4 proporciona una nueva API NewWindow la cual crea una nueva pestaña o ventana y automáticamente cambia a ella.

//Almacena el ID de la ventana original
String originalWindow = driver.getWindowHandle();

//Comprueba que no existen otras ventanas abiertas previamente
assert driver.getWindowHandles().size() == 1;

//Haz clic en el enlace el cual abre una nueva ventana
driver.findElement(By.linkText("new window")).click();

//Espera a la nueva ventana o pestaña
wait.until(numberOfWindowsToBe(2));

//Recorrelas hasta encontrar el controlador de la nueva ventana
for (String windowHandle : driver.getWindowHandles()) {
    if(!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle);
        break;
    }
}

//Espera a que la nueva ventana cargue su contenido
wait.until(titleIs("Selenium documentation"));
  
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Instancia el driver
with webdriver.Firefox() as driver:
    # Abre la URL
    driver.get("https://seleniumhq.github.io")

    # Configura una espera para despues
    wait = WebDriverWait(driver, 10)

    # Almacena el ID de la ventana original
    original_window = driver.current_window_handle

    # Comprueba que no existen otras ventanas abiertas previamente
    assert len(driver.window_handles) == 1

    # Haz clic en el enlace el cual abre una nueva ventana
    driver.find_element(By.LINK_TEXT, "new window").click()

    # Espera a la nueva ventana o pestaña
    wait.until(EC.number_of_windows_to_be(2))

    # Recorrelas hasta encontrar el controlador de la nueva ventana
    for window_handle in driver.window_handles:
        if window_handle != original_window:
            driver.switch_to.window(window_handle)
            break

    # Espera a que la nueva ventana carge su contenido
    wait.until(EC.title_is("SeleniumHQ Browser Automation"))
  
//Almacena el ID de la ventana original
string originalWindow = driver.CurrentWindowHandle;

//Comprueba que no existen otras ventanas abiertas previamente
Assert.AreEqual(driver.WindowHandles.Count, 1);

//Haz clic en el enlace el cual abre una nueva ventana
driver.FindElement(By.LinkText("new window")).Click();

//Espera a la nueva ventana o pestaña
wait.Until(wd => wd.WindowHandles.Count == 2);

//Recorrelas hasta encontrar el controlador de la nueva ventana
foreach(string window in driver.WindowHandles)
{
    if(originalWindow != window)
    {
        driver.SwitchTo().Window(window);
        break;
    }
}
//Espera a que la nueva ventana cargue su contenido
wait.Until(wd => wd.Title == "Selenium documentation");
  
#Almacena el ID de la ventana original
original_window = driver.window_handle

#Comprueba que no existen otras ventanas abiertas previamente
assert(driver.window_handles.length == 1, 'Expected one window')

#Haz clic en el enlace el cual abre una nueva ventana
driver.find_element(link: 'new window').click

#Espera a la nueva ventana o pestaña
wait.until { driver.window_handles.length == 2 }

#Recorrelas hasta encontrar el controlador de la nueva ventana
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

#Espera a que la nueva ventana carge su contenido
wait.until { driver.title == 'Selenium documentation'}
  
//Almacena el ID de la ventana original
const originalWindow = await driver.getWindowHandle();

//Comprueba que no existen otras ventanas abiertas previamente
assert((await driver.getAllWindowHandles()).length === 1);

//Haz clic en el enlace el cual abre una nueva ventana
await driver.findElement(By.linkText('new window')).click();

//Espera a la nueva ventana o pestaña
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Recorrelas hasta encontrar el controlador de la nueva ventana
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Espera a que la nueva ventana cargue su contenido
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
//Almacena el ID de la ventana original
val originalWindow = driver.getWindowHandle()

//Comprueba que no existen otras ventanas abiertas previamente
assert(driver.getWindowHandles().size() === 1)

//Haz clic en el enlace el cual abre una nueva ventana
driver.findElement(By.linkText("new window")).click()

//Espera a la nueva ventana o pestaña
wait.until(numberOfWindowsToBe(2))

//Recorrelas hasta encontrar el controlador de la nueva ventana
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Espera a que la nueva ventana cargue su contenido
wait.until(titleIs("Selenium documentation"))

  

Crea una nueva ventana o pestaña y cambia a ella

Crea una nueva ventana o pestaña y cambia el foco de la pantalla a la nueva ventana o pestaña. No necesitas cambiar el controlador para poder trabajar sobre la nueva ventana o pestaña. Si tienes mas de dos ventanas o pestañas abiertas diferentes de la nueva puedes recorrerlas y cambiar a la que no sea la original.

Nota: Esta funcionalidad es específica de Selenium 4 y versiones posteriores.

// Abre una nueva pestaña y cambia el controlador a ella
driver.switchTo().newWindow(WindowType.TAB);

// Abre una nueva ventana y cambia el controlar a ella
driver.switchTo().newWindow(WindowType.WINDOW);
  
# Abre una nueva pestaña y cambia el controlador a ella
driver.switch_to.new_window('tab')

# Abre una nueva ventana y cambia el controlar a ella
driver.switch_to.new_window('window')
  
// Abre una nueva pestaña y cambia el controlador a ella
driver.SwitchTo().NewWindow(WindowType.Tab)

// Abre una nueva ventana y cambia el controlar a ella
driver.SwitchTo().NewWindow(WindowType.Window)
  
# Nota: El API new_window en Ruby solo abre una nueva pestaña o ventana pero no
# cambiará el controlador automáticamente, el usuario tiene forzar el cambio a
# la nueva pestaña o ventana

# Abre una nueva pestaña
driver.manage.new_window(:tab)

# Abre una nueva ventana
driver.manage.new_window(:window)
  
// Abre una nueva pestaña y cambia el controlador a ella
await driver.switchTo().newWindow('tab');

// Abre una nueva ventana y cambia el controlar a ella
await driver.switchTo().newWindow('window');

  
// Abre una nueva pestaña y cambia el controlador a ella
driver.switchTo().newWindow(WindowType.TAB)

// Abre una nueva ventana y cambia el controlar a ella
driver.switchTo().newWindow(WindowType.WINDOW)
  

Cerrando una ventana o pestaña

Cuando hayas acabado con una ventana o una pestaña y no sea la única ventana o pestaña abierta en el navegador, debes cerrarla y cambiar el controlador de vuelta a la ventana o pestaña que usabas con anterioridad. Asumiendo que has seguido los ejemplos de código de la sección anterior dispondrás de una ventana almacenada en una variable. Si le añades el siguiente código obtendrás un ejemplo:

//Cierra una ventana o pestaña
driver.close();

//Cambia el controlador a la ventana o pestaña original
driver.switchTo().window(originalWindow);
  
#Cierra una ventana o pestaña
driver.close()

#Cambia el controlador a la ventana o pestaña original
driver.switch_to.window(original_window)
  
//Cierra una ventana o pestaña
driver.Close();

//Cambia el controlador a la ventana o pestaña original
driver.SwitchTo().Window(originalWindow);
  
#Cierra una ventana o pestaña
driver.close

#Cambia el controlador a la ventana o pestaña original
driver.switch_to.window original_window
  
//Cierra una ventana o pestaña
await driver.close();

//Cambia el controlador a la ventana o pestaña original
await driver.switchTo().window(originalWindow);
  
//Cierra una ventana o pestaña
driver.close()

//Cambia el controlador a la ventana o pestaña original
driver.switchTo().window(originalWindow)

  

Si te olvidas de cambiar el controlador de vuelta a otra ventana después de cerrarla dejará al WebDriver ejecutando una ventana o pestaña cerrada, esto devolverá la excepción No Such Window Exception. Debes de cambiar el controlador de vuelta a una ventana o pestaña valida para continuar la ejecución.

Saliendo del navegador al final de una sesión

Cuando hayas acabado una sesión del navegador debes llamar al método salir en lugar de cerrar:

driver.quit();
driver.quit()
driver.Quit();
driver.quit
await driver.quit();
driver.quit()
  • Salir hará:
    • Cerrará todas las ventanas y pestañas asociadas a esa sesión del WebDriver.
    • Cerrará el proceso de navegador.
    • Cerrará el proceso en segundo plano del driver.
    • Notificará al Grid de Selenium que el navegador ya no esta en uso y que puede ser usado por otra sesión del Grid de Selenium.

Un fallo en la llamada del método salir dejará procesos corriendo en segundo plano y puertos abiertos en tu maquina lo que podría llevar a problemas en un futuro.

Algunos frameworks de pruebas ofrecen métodos y anotaciones a las cuales puedes llamar para salir de una sesión al finalizar las pruebas.

/**
 * Ejemplo usando JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
# Ejemplo usando unittest
# https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
/*
    Ejemplo usando UnitTesting de Visual Studio
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
# Ejemplo usando UnitTest
# https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
/**
 * Ejemplo usando Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
/**
 * Ejemplo usando JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  

Si no estas ejecutando el WebDriver en un contexto que no es de tests, puedes considerar el usar try / finally los cuales son soportadas por la gran mayoría de lenguajes de programacion de esta manera cuando aparezca una excepción la sesión del WebDriver saldrá correctamente.

try {
    //Código del WebDriver aquí...
} finally {
    driver.quit();
}
  
try:
    #Código del WebDriver aquí...
finally:
    driver.quit()
  
try {
    //Código del WebDriver aquí...
} finally {
    driver.Quit();
}
  
begin
    #Código del WebDriver aquí...
ensure
    driver.quit
end
  
try {
    //Código del WebDriver aquí...
} finally {
    await driver.quit();
}
  
try {
    //Código del WebDriver aquí...
} finally {
    driver.quit()
}
  

El WebDriver de Python ahora es soportado como gestor de contexto, lo que permite ser usado con la palabra clave with para que automáticamente se cierre al final de la ejecución.

with webdriver.Firefox() as driver:
  # Codigo del WebDriver aqui...

# El WebDriver saldrá automaticamente despues de la indentacion

Frames e Iframes

El uso de frames esta desaprobado, estos se basaban en construir sitios desde múltiples documentos en el mismo dominio. Es poco probable que trabajes con esto a menos que estés desarrollando una aplicación web previa a la versión de HTML5. Los iframes te permiten la inserción de un documento desde un dominio diferente y aun son usados de manera común.

Si necesitas trabajar con iframes o frames, el WebDriver te permite hacerlo de la misma forma. Considera un iframe que contiene un botón. Si inspeccionamos el elemento usando las herramientas de desarrollo del navegador podríamos ver lo siguiente:

<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>

Si no fuera por el iframe haríamos clic en el botón de una forma como esta:

//Esto no funcionará
driver.findElement(By.tagName("button")).click();
  
# Esto no funcionará
driver.find_element(By.TAG_NAME, 'button').click()
  
//Esto no funcionará
driver.FindElement(By.TagName("button")).Click();
  
# Esto no funcionará
driver.find_element(:tag_name,'button').click
  
// Esto no funcionará
await driver.findElement(By.css('button')).click();
  
//Esto no funcionará
driver.findElement(By.tagName("button")).click()
  

Sin embargo, como no existirían botones fuera del iframe obtendríamos una excepción del tipo no such element. Esto ocurriría por que Selenium solo esta al tanto de los elementos en los niveles superiores del documento. Para interactuar con el botón primero necesitaremos cambiar el foco al iframe, de una forma similar a lo que ocurría con las ventanas y pestañas. El WebDriver ofrece tres formas de cambiar el foco a un iframe.

Usando un WebElement

Cambiar usando un WebElement es la forma mas flexible de todas. Puedes encontrar el iframe usando tu selector preferido y después cambiar el foco a el.

//Almacena el elemento web
WebElement iframe = driver.findElement(By.cssSelector("#modal>iframe"));

//Cambia el foco al iframe
driver.switchTo().frame(iframe);

//Ahora podemos hacer clic en el botón
driver.findElement(By.tagName("button")).click();
  
# Almacena el elemento web
iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")

# Cambia el foco al iframe
driver.switch_to.frame(iframe)

# Ahora podemos hacer clic en el botón
driver.find_element(By.TAG_NAME, 'button').click()
  
//Almacena el elemento web
IWebElement iframe = driver.FindElement(By.CssSelector("#modal>iframe"));

//Cambia el foco al iframe
driver.SwitchTo().Frame(iframe);

//Ahora podemos hacer clic en el botón
driver.FindElement(By.TagName("button")).Click();
  
# Almacena el elemento web
iframe = driver.find_element(:css,'#modal > iframe')

# Cambia el foco al iframe
driver.switch_to.frame iframe

# Ahora podemos hacer clic en el botón
driver.find_element(:tag_name,'button').click
  
// Almacena el elemento web
const iframe = driver.findElement(By.css('#modal > iframe'));

// Cambia el foco al iframe
await driver.switchTo().frame(iframe);

// Ahora podemos hacer clic en el botón
await driver.findElement(By.css('button')).click();
  
//Almacena el elemento web
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Cambia el foco al iframe
driver.switchTo().frame(iframe)

//Ahora podemos hacer clic en el botón
driver.findElement(By.tagName("button")).click()
  

Usando el nombre o el ID

Si tu iframe o frame dispone de un atributo id o un nombre estos pueden ser usados para ello. Si los nombres o el id no fuesen únicos en la pagina este método cambiará el foco al primer iframe o frame que encuentre.

//Usando el ID
driver.switchTo().frame("buttonframe");

//O usando el atributo nombre
driver.switchTo().frame("myframe");

//Ahora podemos hacer clic en el botón
driver.findElement(By.tagName("button")).click();
  
# Usando el ID
driver.switch_to.frame('buttonframe')

# Ahora podemos hacer clic en el botón
driver.find_element(By.TAG_NAME, 'button').click()
  
//Usando el ID
driver.SwitchTo().Frame("buttonframe");

//O usando el atributo nombre
driver.SwitchTo().Frame("myframe");

//Ahora podemos hacer clic en el botón
driver.FindElement(By.TagName("button")).Click();
  
# Usando el ID
driver.switch_to.frame 'buttonframe'

# Ahora podemos hacer clic en el botón
driver.find_element(:tag_name,'button').click
  
//Usando el ID
await driver.switchTo().frame('buttonframe');

// O usando el atributo nombre
await driver.switchTo().frame('myframe');

// Ahora podemos hacer clic en el botón
await driver.findElement(By.css('button')).click();
  
//Usando el ID
driver.switchTo().frame("buttonframe")

//O usando el atributo nombre
driver.switchTo().frame("myframe")

//Ahora podemos hacer clic en el botón
driver.findElement(By.tagName("button")).click()
  

Por indice

También es posible usar el indice del iframe para cambiar el foco a el, los indices pueden ser consultados utilizando la query de JavaScript window.frames.

// Cambia el foco al segundo frame
driver.switchTo().frame(1);
  
# Cambia el foco al segundo frame
driver.switch_to.frame(1)
  
// Cambia el foco al segundo frame
driver.SwitchTo().Frame(1);
  
# Cambia el foco al segundo frame
iframe = driver.find_elements_by_tag_name('iframe')[1]

# Cambia el foco al iframe seleccionado
driver.switch_to.frame(iframe)
  
//Cambia el foco al segundo frame
await driver.switchTo().frame(1);
  
// Cambia el foco al segundo frame
driver.switchTo().frame(1)
  

Saliendo de un frame

Para salir de un iframe o un frame y volver el foco al contenido original:

// Vuelve al nivel superior
driver.switchTo().defaultContent();
  
# Vuelve al nivel superior
driver.switch_to.default_content()
  
// Vuelve al nivel superior
driver.SwitchTo().DefaultContent();
  
# Vuelve al nivel superior
driver.switch_to.default_content
  
// Vuelve al nivel superior
await driver.switchTo().defaultContent();
  
// Vuelve al nivel superior
driver.switchTo().defaultContent()
  

Manejo de las ventanas

La resolución de las pantallas puede impactar en como tu aplicación se renderiza es por eso que el WebDriver provee de mecanismos para mover y cambiar el tamaño de la ventana del navegador.

Obtener el tamaño de la ventana

Obtiene el tamaño de la ventana del navegador en pixeles.

//Accede a cada dimensión individualmente
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//O almacénalas para acceder a ellas mas tarde
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
# Accede a cada dimensión individualmente
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

# O almacénalas para acceder a ellas mas tarde
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
//Accede a cada dimensión individualmente
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//O almacénalas para acceder a ellas mas tarde
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
# Accede a cada dimensión individualmente
width = driver.manage.window.size.width
height = driver.manage.window.size.height

# O almacénalas para acceder a ellas mas tarde
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
// Accede a cada dimensión individualmente
const { width, height } = await driver.manage().window().getRect();

// O almacénalas para acceder a ellas mas tarde
const rect = await driver.manage().window().getRect();
const width1 = rect.width;
const height1 = rect.height;
  
//Accede a cada dimensión individualmente
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//O almacénalas para acceder a ellas mas tarde
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  

Fija el tamaño de la ventana

Recupera la ventana y fija el tamaño de esta.

driver.manage().window().setSize(new Dimension(1024, 768));
driver.set_window_size(1024, 768)
driver.Manage().Window.Size = new Size(1024, 768);
driver.manage.window.resize_to(1024,768)
await driver.manage().window().setRect({ width: 1024, height: 768 });
driver.manage().window().size = Dimension(1024, 768)

Obten la posicion de la ventana

Obtiene la posiciones de las coordernadas en el sistema arriba izquierda de la ventana del navegador.

// Accede a cada dimensión individualmente
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// O almacénalas para acceder a ellas mas tarde
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
# Accede a cada dimensión individualmente
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

# O almacénalas para acceder a ellas mas tarde
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
//Accede a cada dimensión individualmente
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//O almacénalas para acceder a ellas mas tarde
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
#Accede a cada dimensión individualmente
x = driver.manage.window.position.x
y = driver.manage.window.position.y

# O almacénalas para acceder a ellas mas tarde
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
// Accede a cada dimensión individualmente
const { x, y } = await driver.manage().window().getRect();

// O almacénalas para acceder a ellas mas tarde
const rect = await driver.manage().window().getRect();
const x1 = rect.x;
const y1 = rect.y;
  
// Accede a cada dimensión individualmente
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// O almacénalas para acceder a ellas mas tarde
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  

Fija la posición de la ventana

Mueve la ventana a la posición deseada.

// Mueve la ventana arriba izquierda del monitor principal
driver.manage().window().setPosition(new Point(0, 0));
  
# Mueve la ventana arriba izquierda del monitor principal
driver.set_window_position(0, 0)
  
// Mueve la ventana arriba izquierda del monitor principal
driver.Manage().Window.Position = new Point(0, 0);
  
driver.manage.window.move_to(0,0)
  
// Mueve la ventana arriba izquierda del monitor principal
await driver.manage().window().setRect({ x: 0, y: 0 });
  
// Mueve la ventana arriba izquierda del monitor principal
driver.manage().window().position = Point(0,0)
    

Maximizar la ventana

Maximiza la ventana. Para la gran mayoría de sistemas operativos, la ventana rellenará la pantalla, sin bloquear los menús propios y barras de herramientas de los sistemas operativos.

driver.manage().window().maximize();
driver.maximize_window()
driver.Manage().Window.Maximize();
driver.manage.window.maximize
await driver.manage().window().maximize();
driver.manage().window().maximize()

Minimizar la ventana

Minimiza la ventana del actual contexto del navegador. El comportamiento exacto de este comando es especifico individualmente de cada gestor de ventanas.

Minimizar la ventana típicamente oculta la ventana en la bandeja del sistema.

Nota: Esta funcionalidad es específica de Selenium 4 y versiones posteriores.

driver.manage().window().minimize();
driver.minimize_window()
driver.Manage().Window.Minimize();
driver.manage.window.minimize
await driver.manage().window().minimize();
driver.manage().window().minimize()

Modo pantalla completa

Llena la pantalla completamente, similar a presionar la tecla F11 en la gran mayoria de navegadores.

driver.manage().window().fullscreen();
driver.fullscreen_window()
driver.Manage().Window.FullScreen();
driver.manage.window.full_screen
await driver.manage().window().fullscreen();
driver.manage().window().fullscreen()

TakeScreenshot

Used to capture screenshot for current browsing context. The WebDriver endpoint screenshot returns screenshot which is encoded in Base64 format.

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
from selenium import webdriver

driver = webdriver.Chrome()

# Navigate to url
driver.get("http://www.example.com")

# Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");
    Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
    screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
   
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

  # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
let {Builder} = require('selenium-webdriver');
let fs = require('fs');

(async function example() {
    let driver = await new Builder()
      .forBrowser('chrome')
      .build();

    await driver.get('https://www.example.com');
    // Returns base64 encoded string
    let encodedString = await driver.takeScreenshot();
    await fs.writeFileSync('./image.png', encodedString, 'base64');
    await driver.quit();
}())
  
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  

TakeElementScreenshot

Used to capture screenshot of an element for current browsing context. The WebDriver endpoint screenshot returns screenshot which is encoded in Base64 format.

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

# Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

# Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
# Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

  # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
const {Builder, By} = require('selenium-webdriver');
let fs = require('fs');

(async function example() {
   let driver = await new Builder()
       .forBrowser('chrome')
       .build();

   await driver.get('https://www.example.com');
   let ele = await driver.findElement(By.css("h1"));
   // Captures the element screenshot
   let encodedString = await ele.takeScreenshot(true);
   await fs.writeFileSync('./image.png', encodedString, 'base64');
   await driver.quit();
}())
  
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  

Execute Script

Executes JavaScript code snippet in the current context of a selected frame or window.

    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
# Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

# Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
    //creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
# Stores the header element
header = driver.find_element(css: 'h1')

# Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

# Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
// Stores the header element
let header = await driver.findElement(By.css('h1'));

// Executing JavaScript to capture innerText of header element
let text = await driver.executeScript('return arguments[0].innerText', header);
  
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  

Prints the current page within the browser

Note: This requires Chromium Browsers to be in headless mode

   import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
    // code sample not available please raise a PR
  
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
  const {Builder} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  let opts = new chrome.Options();
  let fs = require('fs');
  (async function example() {
    let driver = new Builder()
      .forBrowser('chrome')
      .setChromeOptions(opts.headless())
      .build();
    await driver.get('https://www.selenium.dev');
    try {
      let base64 = await driver.printPage({pageRanges:["1-2"]});
      await fs.writeFileSync('./test.pdf', base64, 'base64');
    } catch (e) {
    console.log(e)
    }
    await driver.quit();
  })();
  
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  

3.3 - Localizando elementos

Localizando un elemento

Una de las técnicas más fundamentales para aprender al usar WebDriver es cómo encontrar elementos en la página. WebDriver ofrece varios tipos de selectores integrados, entre ellos encontrar un elemento por su atributo ID:

WebElement cheese = driver.findElement(By.id("cheese"));
  
driver.find_element(By.ID, "cheese")
  
IWebElement element = driver.FindElement(By.Id("cheese"));
  
cheese = driver.find_element(id: 'cheese')
  
const cheese = driver.findElement(By.id('cheese'));
  
val cheese: WebElement = driver.findElement(By.id("cheese"))
  

Como se ve en el ejemplo, localizar elementos en WebDriver se realiza en la instancia del objeto WebDriver. El método findElement(By) devuelve otro tipo de objeto fundamental, el WebElement.

  • WebDriver representa el navegador
  • WebElement representa un nodo particular del DOM (un control, por ejemplo un enlace o campo de entrada, etc.)

Una vez que tengas una referencia a un elemento web que se ha “encontrado”, puedes reducir el alcance de tu búsqueda utilizando la misma llamada en la instancia de ese objeto:

WebElement cheese = driver.findElement(By.id("cheese"));
WebElement cheddar = cheese.findElement(By.id("cheddar"));
  
cheese = driver.find_element(By.ID, "cheese")
cheddar = cheese.find_elements_by_id("cheddar")
  
IWebElement cheese = driver.FindElement(By.Id("cheese"));
IWebElement cheddar = cheese.FindElement(By.Id("cheddar"));
  
cheese = driver.find_element(id: 'cheese')
cheddar = cheese.find_element(id: 'cheddar')
  
const cheese = driver.findElement(By.id('cheese'));
const cheddar = cheese.findElement(By.id('cheddar'));
  
val cheese = driver.findElement(By.id("cheese"))
val cheddar = cheese.findElement(By.id("cheddar"))
  

Puedes hacer esto porque los tipos WebDriver y WebElement implementan la interfaz SearchContext. En WebDriver, esto se conoce como interfaz basada en roles. Las interfaces basadas en roles te permiten determinar si la implementación del controlador admite una característica dada. Estas interfaces están claramente definidas y tratan de cumplir con tener un solo rol de responsabilidad. Puede leer más sobre el diseño de WebDriver y qué roles son compatibles con qué controladores en Otra sección.

En consecuencia, la interfaz By utilizada anteriormente también permite una serie de estrategias adicionales de localización. Una búsqueda anidada podría no ser la estrategia mas efectiva para localizar cheese ya que requiere dos comandos que se emitirán al navegador; primero buscando en el DOM un elemento con ID “cheese”, luego una búsqueda de “cheddar” en un contexto reducido.

Para mejorar ligeramente el rendimiento, deberíamos intentar utilizar un localizador más específico: WebDriver permite buscar elementos por localizadores CSS, lo que nos permite combinar los dos localizadores anteriores en una sola búsqueda:

driver.findElement(By.cssSelector("#cheese #cheddar"));
  
cheddar = driver.find_element_by_css_selector("#cheese #cheddar")
  
driver.FindElement(By.CssSelector("#cheese #cheddar"));
  
driver.find_element(css: '#cheese #cheddar')
  
const cheddar = driver.findElement(By.css('#cheese #cheddar'));
  
driver.findElement(By.cssSelector("#cheese #cheddar"))
  

Localizando múltiples elementos

Es posible que el documento con el que estamos trabajando contenga una lista ordenada del queso que más nos gusta:

<ol id=cheese>
 <li id=cheddar><li id=brie><li id=rochefort><li id=camembert></ol>

Dado que más queso es indiscutiblemente mejor, y sería engorroso tener que recuperar cada uno de los elementos individualmente, una técnica superior para recuperar cheese es hacer uso de la versión pluralizada findElements(By). Este método devuelve una colección de elementos web. Si solo se encuentra un elemento, aún devolverá una colección (de un elemento). Si ningún elemento coincide con el localizador, se devolverá la lista vacía.

List<WebElement> muchoCheese = driver.findElements(By.cssSelector("#cheese li"));
  
mucho_cheese = driver.find_elements_by_css_selector("#cheese li")
  
IReadOnlyList<IWebElement> muchoCheese = driver.FindElements(By.CssSelector("#cheese li"));
  
mucho_cheese = driver.find_elements(css: '#cheese li')
  
const muchoCheese = driver.findElements(By.css('#cheese li'));
  
val muchoCheese: List<WebElement>  = driver.findElements(By.cssSelector("#cheese li"))
  

Estrategias de localización de elementos

Hay ocho estrategias diferentes de ubicación de elementos integradas en WebDriver:

LocalizadorDescripción
class nameLocaliza elementos en el que el nombre de su clase contiene el valor de la búsqueda (no se permiten nombres de clase compuestos)
css selectorLocaliza elementos que coinciden con un selector CSS
idLocaliza elementos cuyo atributo ID coincide con el valor de la búsqueda
nameLocaliza elementos cuyo atributo NAME coincide con el valor de la búsqueda
link textLocaliza elementos de anclaje cuyo texto visible coincide con el valor de búsqueda
partial link textLocaliza elementos de anclaje cuyo texto visible coincide con el valor de búsqueda. Si varios elementos coinciden, solo se seleccionará el primero.
tag nameLocaliza elementos cuyo nombre de etiqueta (tagName) coincide con el valor de búsqueda
xpathLocaliza elementos que coinciden con una expresión XPath

Consejos sobre el uso de selectores

En general, si los ID del HTML están disponibles, son únicos y consistentemente predecibles, son el método preferido para ubicar un elemento en una página. Tienden a trabajar muy rápido y renuncian al mucho procesamiento que viene con recorridos DOM complicados.

Si las ID únicas no están disponibles, un selector CSS bien escrito es el método preferido para localizar un elemento. XPath funciona tan bien como los selectores CSS, pero la sintaxis es complicada y con frecuencia difícil de depurar. Aunque los selectores XPath son muy flexibles, generalmente su desempeño no es probado por lo proveedores de navegadores y tienden a ser bastante lentos.

Las estrategias de selección basadas en enlaces de texto y enlaces de texto parciales tienen el inconveniente en que solo funcionan en elementos de enlace. Además, internamente en WebDriver llaman a los selectores XPath.

El nombre de la etiqueta puede ser una forma peligrosa de localizar elementos. Existen frecuentemente múltiples elementos con la misma etiqueta presentes en la página. Esto es mayormente útil cuando se llama al método findElements(By) que devuelve una colección de elementos.

La recomendación es mantener tus localizadores tan compactos y legibles como sea posible. Pedirle a WebDriver que atraviese la estructura del DOM es una operación costosa, y cuanto más se pueda reducir el alcance de tu búsqueda, mejor.

Relative Locators

Selenium 4 brings Relative Locators which are previously called as Friendly Locators. This functionality was added to help you locate elements that are nearby other elements. The Available Relative Locators are:

  • above
  • below
  • toLeftOf
  • toRightOf
  • near

The findElement method accepts a new method with(By) which returns a RelativeLocator. Users can pick a locator of their choice like By.id, By.cssSelector, etc.

How does it work

Selenium uses the JavaScript function getBoundingClientRect() to find the relative elements. This function returns properties of an element such as right, left, bottom, and top.

Let us consider the below example for understanding the relative locators.

Relative Locators

above()

Returns the WebElement, which appears above to the specified element

import static org.openqa.selenium.support.locators.RelativeLocator.with;

WebElement passwordField = driver.findElement(By.id("password"));
WebElement emailAddressField = driver.findElement(with(By.tagName("input"))
.above(passwordField));
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

passwordField = driver.find_element(By.ID, "password")
emailAddressField = driver.find_element(locate_with(By.TAG_NAME, "input").above(passwordField))
using static OpenQA.Selenium.RelativeBy;

IWebElement passwordField = driver.FindElement(By.Id("password"));
IWebElement emailAddressField = driver.FindElement(RelativeBy(By.TagName("input")).Above(passwordField));
password_field= driver.find_element(:id, "password")
email_address_field = driver.find_element(relative: {tag_name: 'input', above:password_field})
let passwordField = driver.findElement(By.id('password'));
let emailAddressField = await driver.findElement(locateWith(By.tagName('input')).above(passwordField));
val passwordField = driver.findElement(By.id("password"))
val emailAddressField = driver.findElement(with(By.tagName("input")).above(passwordField))

below()

Returns the WebElement, which appears below to the specified element

import static org.openqa.selenium.support.locators.RelativeLocator.with;

WebElement emailAddressField = driver.findElement(By.id("email"));
WebElement passwordField = driver.findElement(with(By.tagName("input"))
.below(emailAddressField));
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

emailAddressField = driver.find_element(By.ID, "email")
passwordField = driver.find_element(locate_with(By.TAG_NAME, "input").below(emailAddressField))
using static OpenQA.Selenium.RelativeBy;

IWebElement emailAddressField = driver.FindElement(By.Id("email"));
IWebElement passwordField = driver.FindElement(RelativeBy(By.TagName("input")).Below(emailAddressField));
email_address_field = driver.find_element(:id, "email")
password_field = driver.find_element(relative: {tag_name: 'input', below: email_address_field})
let emailAddressField = driver.findElement(By.id('email'));
let passwordField = await driver.findElement(locateWith(By.tagName('input')).below(emailAddressField));
val emailAddressField = driver.findElement(By.id("email"))
val passwordField = driver.findElement(with(By.tagName("input")).below(emailAddressField))

toLeftOf()

Returns the WebElement, which appears to left of specified element

import static org.openqa.selenium.support.locators.RelativeLocator.with;

WebElement submitButton = driver.findElement(By.id("submit"));
WebElement cancelButton = driver.findElement(with(By.tagName("button"))
.toLeftOf(submitButton));
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

submitButton = driver.find_element(By.ID, "submit")
cancelButton = driver.find_element(locate_with(By.TAG_NAME, "button").
to_left_of(submitButton))
using static OpenQA.Selenium.RelativeBy;

IWebElement submitButton = driver.FindElement(By.Id("submit"));
IWebElement cancelButton = driver.FindElement(RelativeBy(By.TagName("button")).LeftOf(submitButton));
submit_button= driver.find_element(:id, "submit")
cancel_button = driver.find_element(relative: {tag_name: 'button', left:submit_button})
let submitButton = driver.findElement(By.id('submit'));
let cancelButton = await driver.findElement(locateWith(By.tagName('button')).toLeftOf(submitButton));
val submitButton = driver.findElement(By.id("submit"))
val cancelButton = driver.findElement(with(By.tagName("button")).toLeftOf(submitButton))

toRightOf()

Returns the WebElement, which appears to right of the specified element

import static org.openqa.selenium.support.locators.RelativeLocator.with;

WebElement cancelButton = driver.findElement(By.id("cancel"));
WebElement submitButton = driver.findElement(with(By.tagName("button")).toRightOf(cancelButton));
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

cancelButton = driver.find_element(By.ID, "cancel")
submitButton = driver.find_element(locate_with(By.TAG_NAME, "button").
to_right_of(cancelButton))
using static OpenQA.Selenium.RelativeBy;

IWebElement cancelButton = driver.FindElement(By.Id("cancel"));
IWebElement submitButton = driver.FindElement(RelativeBy(By.TagName("button")).RightOf(cancelButton));
cancel_button = driver.find_element(:id, "cancel")
submit_button = driver.find_element(relative: {tag_name: 'button', right:cancel_button})
let cancelButton = driver.findElement(By.id('cancel'));
let submitButton = await driver.findElement(locateWith(By.tagName('button')).toRightOf(cancelButton));
val cancelButton = driver.findElement(By.id("cancel"))
val submitButton = driver.findElement(with(By.tagName("button")).toRightOf(cancelButton))

near()

Returns the WebElement, which is at most 50px away from the specified element.

import static org.openqa.selenium.support.locators.RelativeLocator.with;

WebElement emailAddressLabel = driver.findElement(By.id("lbl-email"));
WebElement emailAddressField = driver.findElement(with(By.tagName("input")).near(emailAddressLabel));
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

emailAddressLabel = driver.find_element(By.ID, "lbl-email")
emailAddressField = driver.find_element(locate_with(By.TAG_NAME, "input").
near(emailAddressLabel))
using static OpenQA.Selenium.RelativeBy;

IWebElement emailAddressLabel = driver.FindElement(By.Id("lbl-email"));
IWebElement emailAddressField = driver.FindElement(RelativeBy(By.TagName("input")).Near(emailAddressLabel));
email_address_label = driver.find_element(:id, "lbl-email")
email_address_field = driver.find_element(relative: {tag_name: 'input', near: email_address_label})
let emailAddressLabel = driver.findElement(By.id("lbl-email"));
let emailAddressField = await driver.findElement(locateWith(By.tagName("input")).near(emailAddressLabel));
val emailAddressLabel = driver.findElement(By.id("lbl-email"))
val emailAddressField = driver.findElement(with(By.tagName("input")).near(emailAddressLabel))

3.4 - Waits

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

WebDriver can generally be said to have a blocking API. Because it is an out-of-process library that instructs the browser what to do, and because the web platform has an intrinsically asynchronous nature, WebDriver does not track the active, real-time state of the DOM. This comes with some challenges that we will discuss here.

From experience, most intermittent issues that arise from use of Selenium and WebDriver are connected to race conditions that occur between the browser and the user’s instructions. An example could be that the user instructs the browser to navigate to a page, then gets a no such element error when trying to find an element.

Consider the following document:

<!doctype html>
<meta charset=utf-8>
<title>Race Condition Example</title>

<script>
  var initialised = false;
  window.addEventListener("load", function() {
    var newElement = document.createElement("p");
    newElement.textContent = "Hello from JavaScript!";
    document.body.appendChild(newElement);
    initialised = true;
  });
</script>

The WebDriver instructions might look innocent enough:

driver.get("file:///race_condition.html");
WebElement element = driver.findElement(By.tagName("p"));
assertEquals(element.getText(), "Hello from JavaScript!");
  
driver.navigate("file:///race_condition.html")
el = driver.find_element(By.TAG_NAME, "p")
assert el.text == "Hello from JavaScript!"
  
driver.Navigate().GoToUrl("file:///race_condition.html");
IWebElement element = driver.FindElement(By.TagName("p"));
assertEquals(element.Text, "Hello from JavaScript!");
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
begin
  # Navigate to URL
  driver.get 'file:///race_condition.html'

  # Get and store Paragraph Text
  search_form = driver.find_element(:css,'p').text

  "Hello from JavaScript!".eql? search_form
ensure
  driver.quit
end
  
await driver.get('file:///race_condition.html');
const element = driver.findElement(By.css('p'));
assert.strictEqual(await element.getText(), 'Hello from JavaScript!');
  
driver.get("file:///race_condition.html")
val element = driver.findElement(By.tagName("p"))
assert(element.text == "Hello from JavaScript!")
  

The issue here is that the default page load strategy used in WebDriver listens for the document.readyState to change to "complete" before returning from the call to navigate. Because the p element is added after the document has completed loading, this WebDriver script might be intermittent. It “might” be intermittent because no guarantees can be made about elements or events that trigger asynchronously without explicitly waiting—or blocking—on those events.

Fortunately, the normal instruction set available on the WebElement interface—such as WebElement.click and WebElement.sendKeys—are guaranteed to be synchronous, in that the function calls will not return (or the callback will not trigger in callback-style languages) until the command has been completed in the browser. The advanced user interaction APIs, Keyboard and Mouse, are exceptions as they are explicitly intended as “do what I say” asynchronous commands.

Waiting is having the automated task execution elapse a certain amount of time before continuing with the next step.

To overcome the problem of race conditions between the browser and your WebDriver script, most Selenium clients ship with a wait package. When employing a wait, you are using what is commonly referred to as an explicit wait.

Explicit wait

Explicit waits are available to Selenium clients for imperative, procedural languages. They allow your code to halt program execution, or freeze the thread, until the condition you pass it resolves. The condition is called with a certain frequency until the timeout of the wait is elapsed. This means that for as long as the condition returns a falsy value, it will keep trying and waiting.

Since explicit waits allow you to wait for a condition to occur, they make a good fit for synchronising the state between the browser and its DOM, and your WebDriver script.

To remedy our buggy instruction set from earlier, we could employ a wait to have the findElement call wait until the dynamically added element from the script has been added to the DOM:

WebDriver driver = new ChromeDriver();
driver.get("https://google.com/ncr");
driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER);
// Initialize and wait till element(link) became clickable - timeout in 10 seconds
WebElement firstResult = new WebDriverWait(driver, Duration.ofSeconds(10))
        .until(ExpectedConditions.elementToBeClickable(By.xpath("//a/h3")));
// Print the first result
System.out.println(firstResult.getText());
  
from selenium.webdriver.support.ui import WebDriverWait
def document_initialised(driver):
    return driver.execute_script("return initialised")

driver.navigate("file:///race_condition.html")
WebDriverWait(driver).until(document_initialised)
el = driver.find_element(By.TAG_NAME, "p")
assert el.text == "Hello from JavaScript!"
  
driver = new ChromeDriver();
driver.Url = "https://www.google.com/ncr";
driver.FindElement(By.Name("q")).SendKeys("cheese" + Keys.Enter);
            
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement firstResult = wait.Until(e => e.FindElement(By.XPath("//a/h3")));

Console.WriteLine(firstResult.Text);
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
wait = Selenium::WebDriver::Wait.new(:timeout => 10)

def document_initialised(driver)
  driver.execute_script('return initialised')
end

begin
  driver.get 'file:///race_condition.html'
  wait.until{document_initialised driver}
  search_form = driver.find_element(:css,'p').text
  "Hello from JavaScript!".eql? search_form
ensure
  driver.quit
end
  
const documentInitialised = () =>
    driver.executeScript('return initialised');

await driver.get('file:///race_condition.html');
await driver.wait(() => documentInitialised(), 10000);
const element = driver.findElement(By.css('p'));
assert.strictEqual(await element.getText(), 'Hello from JavaScript!');
  
driver.get("https://google.com/ncr")
driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER)
// Initialize and wait till element(link) became clickable - timeout in 10 seconds
val firstResult = WebDriverWait(driver, Duration.ofSeconds(10))
      .until(ExpectedConditions.elementToBeClickable(By.xpath("//a/h3")))
// Print the first result
println(firstResult.text)
  

We pass in the condition as a function reference that the wait will run repeatedly until its return value is truthy. A “truthful” return value is anything that evaluates to boolean true in the language at hand, such as a string, number, a boolean, an object (including a WebElement), or a populated (non-empty) sequence or list. That means an empty list evaluates to false. When the condition is truthful and the blocking wait is aborted, the return value from the condition becomes the return value of the wait.

With this knowledge, and because the wait utility ignores no such element errors by default, we can refactor our instructions to be more concise:

WebElement foo = new WebDriverWait(driver, Duration.ofSeconds(3))
          .until(driver -> driver.findElement(By.name("q")));
assertEquals(foo.getText(), "Hello from JavaScript!"); 
  
from selenium.webdriver.support.ui import WebDriverWait

driver.navigate("file:///race_condition.html")
el = WebDriverWait(driver).until(lambda d: d.find_element_by_tag_name("p"))
assert el.text == "Hello from JavaScript!"
  
   using (var driver = new FirefoxDriver())
    {
        var foo = new WebDriverWait(driver, TimeSpan.FromSeconds(3))
                        .Until(drv => drv.FindElement(By.Name("q")));
        Debug.Assert(foo.Text.Equals("Hello from JavaScript!"));
    }
  
  driver.get 'file:///race_condition.html'
  wait = Selenium::WebDriver::Wait.new(:timeout => 10)
  ele = wait.until { driver.find_element(css: 'p')}
  foo = ele.text
  assert_match foo, 'Hello from JavaScript'
  
let ele = await driver.wait(until.elementLocated(By.css('p')),10000);
let foo = await ele.getText();
assert(foo == "Hello from JavaScript");
  
driver.get("file:///race_condition.html")
val ele = WebDriverWait(driver, Duration.ofSeconds(10))
            .until(ExpectedConditions.presenceOfElementLocated(By.tagName("p")))
assert(ele.text == "Hello from JavaScript!")
  

In that example, we pass in an anonymous function (but we could also define it explicitly as we did earlier so it may be reused). The first and only argument that is passed to our condition is always a reference to our driver object, WebDriver. In a multi-threaded environment, you should be careful to operate on the driver reference passed in to the condition rather than the reference to the driver in the outer scope.

Because the wait will swallow no such element errors that are raised when the element is not found, the condition will retry until the element is found. Then it will take the return value, a WebElement, and pass it back through to our script.

If the condition fails, e.g. a truthful return value from the condition is never reached, the wait will throw/raise an error/exception called a timeout error.

Options

The wait condition can be customised to match your needs. Sometimes it is unnecessary to wait the full extent of the default timeout, as the penalty for not hitting a successful condition can be expensive.

The wait lets you pass in an argument to override the timeout:

new WebDriverWait(driver, Duration.ofSeconds(3)).until(ExpectedConditions.elementToBeClickable(By.xpath("//a/h3")));
  
WebDriverWait(driver, timeout=3).until(some_condition)
  
new WebDriverWait(driver, TimeSpan.FromSeconds(3)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a/h3")));
  
wait = Selenium::WebDriver::Wait.new(:timeout => 10)

wait.until { driver.find_element(:id, 'message').displayed? }
  
  await driver.wait(until.elementLocated(By.id('foo')), 30000);
  
WebDriverWait(driver, Duration.ofSeconds(3)).until(ExpectedConditions.elementToBeClickable(By.xpath("//a/h3")))
  

Expected conditions

Because it is quite a common occurrence to have to synchronise the DOM and your instructions, most clients also come with a set of predefined expected conditions. As might be obvious by the name, they are conditions that are predefined for frequent wait operations.

The conditions available in the different language bindings vary, but this is a non-exhaustive list of a few:

  • alert is present
  • element exists
  • element is visible
  • title contains
  • title is
  • element staleness
  • visible text

You can refer to the API documentation for each client binding to find an exhaustive list of expected conditions:

Implicit wait

There is a second type of wait that is distinct from explicit wait called implicit wait. By implicitly waiting, WebDriver polls the DOM for a certain duration when trying to find any element. This can be useful when certain elements on the webpage are not available immediately and need some time to load.

Implicit waiting for elements to appear is disabled by default and will need to be manually enabled on a per-session basis. Mixing explicit waits and implicit waits will cause unintended consequences, namely waits sleeping for the maximum time even if the element is available or condition is true.

Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0, meaning disabled. Once set, the implicit wait is set for the life of the session.

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
  
driver = Firefox()
driver.implicitly_wait(10)
driver.get("http://somedomain/url_that_delays_loading")
my_dynamic_element = driver.find_element(By.ID, "myDynamicElement")
  
IWebDriver driver = new ChromeDriver();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement dynamicElement = driver.FindElement(By.Name("dynamicElement"));
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.manage.timeouts.implicit_wait = 10

begin
  driver.get 'http://somedomain/url_that_delays_loading'
  search_form = driver.find_element(:id,'dynamic_element')
ensure
  driver.quit
end
  
(async function(){

// Apply timeout for 10 seconds
await driver.manage().setTimeouts( { implicit: 10000 } );

// Navigate to url
await driver.get('http://somedomain/url_that_delays_loading');

let webElement = driver.findElement(By.id("myDynamicElement"));

}());
  
val driver = FirefoxDriver()
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
driver.get("http://somedomain/url_that_delays_loading")
val myDynamicElement = driver.findElement(By.id("myDynamicElement"))
  

FluentWait

FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition.

Users may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementException when searching for an element on the page.

// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
  public WebElement apply(WebDriver driver) {
    return driver.findElement(By.id("foo"));
  }
});
  
driver = Firefox()
driver.get("http://somedomain/url_that_delays_loading")
wait = WebDriverWait(driver, 10, poll_frequency=1, ignored_exceptions=[ElementNotVisibleException, ElementNotSelectableException])
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div")))
  
using (var driver = new FirefoxDriver())
{
  WebDriverWait wait = new WebDriverWait(driver, timeout: TimeSpan.FromSeconds(30))
  {
      PollingInterval = TimeSpan.FromSeconds(5),
  };
  wait.IgnoreExceptionTypes(typeof(NoSuchElementException));

  var foo = wait.Until(drv => drv.FindElement(By.Id("foo")));
}
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
exception = Selenium::WebDriver::Error::NoSuchElementError

begin
  driver.get 'http://somedomain/url_that_delays_loading'
  wait = Selenium::WebDriver::Wait.new(timeout: 30, interval: 5, message: 'Timed out after 30 sec', ignore: exception)
  foo = wait.until { driver.find_element(id: 'foo')}
ensure
  driver.quit
end
  
const {Builder, until} = require('selenium-webdriver');

(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    await driver.get('http://somedomain/url_that_delays_loading');
    // Waiting 30 seconds for an element to be present on the page, checking
    // for its presence once every 5 seconds.
    let foo = await driver.wait(until.elementLocated(By.id('foo')), 30000, 'Timed out after 30 seconds', 5000);
})();
  
val wait = FluentWait<WebDriver>(driver)
        .withTimeout(Duration.ofSeconds(30))
        .pollingEvery(Duration.ofSeconds(3))
        .ignoring(NoSuchElementException::class.java)

val foo = wait.until {it.findElement(By.id("foo")) }
  

3.5 - Alertas, avisos y confirmaciones de JavaScript

WebDriver proporciona una API para trabajar con los tres tipos nativos de mensajes emergentes ofrecidos por JavaScript. Estas ventanas emergentes están diseñadas por el navegador y ofrecen personalización limitada.

Alertas

El más simple de estos se conoce como alerta, que muestra unmensaje personalizado y un solo botón que descarta la alerta, etiquetado en la mayoría de los navegadores como OK. También se puede descartar en la mayoría de los navegadores presionando el botón de cerrar, pero esto siempre hará lo mismo que el presionar botón OK. Esto es una alerta de ejemplo.

WebDriver puede obtener el texto de la ventana emergente y aceptar o descartar estas alertas.

// Haz clic en el enlace para activar la alerta 
driver.findElement(By.linkText("See an example alert")).click();

// Espera a que se muestre la alerta y almacenala en una variable
Alert alert = wait.until(ExpectedConditions.alertIsPresent());

// Almacena el texto de la alerta en una variable
String text = alert.getText();

// Presiona el botón OK
alert.accept();
  
# Haz clic en el enlace para activar la alerta
driver.find_element(By.LINK_TEXT, "See an example alert").click()

# Espera a que se muestre la alerta y almacenala en una variable
alert = wait.until(expected_conditions.alert_is_present())

# Almacena el texto de la alerta en una variable
text = alert.text

# Presiona el botón OK
alert.accept()
  
// Haz clic en el enlace para activar la alerta
driver.FindElement(By.LinkText("See an example alert")).Click();

// Espera a que se muestre la alerta y almacenala en una variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

// Almacena el texto de la alerta en una variable
string text = alert.Text;

// Presiona el botón OK
alert.Accept();
  
#  Haz clic en el enlace para activar la aler
driver.find_element(:link_text, 'See an example alert').click

# Almacena la referencia de la alertta en una variable
alert = driver.switch_to.alert

# Almacena el texto de la alerta en una variable
alert_text = alert.text

# Presiona el botón OK
alert.accept
  
// Haz clic en el enlace para activar la alerta
await driver.findElement(By.linkText('See an example alert')).click();

// Espera a que se muestre la alerta
await driver.wait(until.alertIsPresent());

// Almacena la alerta en una variable
let alert = await driver.switchTo().alert();

// Almacena el texto de la alerta en una variable
let alertText = await alert.getText();

// Presiona el botón OK
await alert.accept();

// Nota: Para usar await, el código mostrado arriba debe estar en una función async
  
// Haz clic en el enlace para activar la alerta
driver.findElement(By.linkText("See an example alert")).click()

// Espera a que se muestre la alerta y almacenala en una variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

// Almacena el texto de la alerta en una variable
val text = alert.getText()

// Presiona el botón OK
alert.accept()
  

Confirm

Un cuadro de confirmación es similar a una alerta, excepto que el usuario también puede elegir cancelar el mensaje. Esto es un confirm de ejemplo.

Este ejemplo también muestra un enfoque diferente para almacenar una alerta:

// Haz clic en el enlace para activar la alerta
driver.findElement(By.linkText("See a sample confirm")).click();

// Espera a que se muestre la alerta
wait.until(ExpectedConditions.alertIsPresent());

// Almacena la alerta en una variable
Alert alert = driver.switchTo().alert();

// Almacena la alerta en una variable para poder reusarla
String text = alert.getText();

// Presiona el botón cancelar
alert.dismiss();
  
#  Haz clic en el enlace para activar la alerta
driver.find_element(By.LINK_TEXT, "See a sample confirm").click()

# Espera a que se muestre la alerta
wait.until(expected_conditions.alert_is_present())

# Almacena la alerta en una variable para poder reusarla
alert = driver.switch_to.alert

# Almacena el texto de la alerta en una variable
text = alert.text

# Presiona el botón cancelar
alert.dismiss()
  
// Haz clic en el enlace para activar la alerta
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Espera a que se muestre la alerta
wait.Until(ExpectedConditions.AlertIsPresent());

// Almacena la alerta en una variable
IAlert alert = driver.SwitchTo().Alert();

// Almacena la alerta en una variable para poder reusarla
string text = alert.Text;

// Presiona el botón cancelar
alert.Dismiss();
  
#  Haz clic en el enlace para activar la alerta
driver.find_element(:link_text, 'See a sample confirm').click

# Almacena la referencia de la alertta en una variable
alert = driver.switch_to.alert

# Almacena el texto de la alerta en una variable
alert_text = alert.text

# Presiona el botón cancelar
alert.dismiss
  
// Haz clic en el enlace para activar la alerta
await driver.findElement(By.linkText('See a sample confirm')).click();

// Espera a que se muestre la alerta
await driver.wait(until.alertIsPresent());

// Almacena la alerta en una variable
let alert = await driver.switchTo().alert();

// Almacena el texto de la alerta en una variable
let alertText = await alert.getText();

// Presiona el botón cancelar
await alert.dismiss();

// Nota: Para usar await, el código mostrado arriba debe estar en una función async
  
// Haz clic en el enlace para activar la alerta
driver.findElement(By.linkText("See a sample confirm")).click()

//Espera a que se muestre la alerta
wait.until(ExpectedConditions.alertIsPresent())

// Almacena la alerta en una variable
val alert = driver.switchTo().alert()

// Almacena la alerta en una variable para poder reusarla
val text = alert.text

//Presiona el botón cancelar
alert.dismiss()
  

Prompt

Los prompts son similares a los cuadros de confirmación, excepto que también incluyen una entrada de texto. Similar a trabajar con elementos de los formularios, puedes usar el sendKeys de WebDriver para completar una respuesta. Esto reemplazará completamente el texto por defecto. Al presionar el botón cancelar esto hará que no se envie ningún texto. Esto es un prompt de ejemplo.

// Haz clic en el enlace para activar la alerta
driver.findElement(By.linkText("See a sample prompt")).click();

// Espera a que se muestre la alerta y almacenala en una variable
Alert alert = wait.until(ExpectedConditions.alertIsPresent());

// Inserta tu mensaje
alert.sendKeys("Selenium");

// Presiona el botón OK
alert.accept();
  
#  Haz clic en el enlace para activar la alerta
driver.find_element(By.LINK_TEXT, "See a sample prompt").click()

# Espera a que se muestre la alerta
wait.until(expected_conditions.alert_is_present())

# Almacena la alerta en una variable para poder reusarla
alert = Alert(driver)

# Inserta tu mensaje
alert.send_keys("Selenium")

# Presiona el botón OK
alert.accept()
  
// Haz clic en el enlace para activar la alerta
driver.FindElement(By.LinkText("See a sample prompt")).Click();

// Espera a que se muestre la alerta y almacenala en una variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

// Inserta tu mensaje
alert.SendKeys("Selenium");

// Presiona el botón OK
alert.Accept();
  
#  Haz clic en el enlace para activar la alerta
driver.find_element(:link_text, 'See a sample prompt').click

# Almacena la referencia de la alerta en una variable
alert = driver.switch_to.alert

# Inserta tu mensaje
alert.send_keys("selenium")

# Presiona el botón OK
alert.accept
  
// Haz clic en el enlace para activar la alerta
await driver.findElement(By.linkText('See a sample prompt')).click();

// Espera a que se muestre la alerta
await driver.wait(until.alertIsPresent());

// Almacena la alerta en una variable
let alert = await driver.switchTo().alert();

// Inserta tu mensaje
await alert.sendKeys("Selenium");

// Presiona el botón OK
await alert.accept();

// Nota: Para usar await, el código mostrado arriba debe estar en una función async
  
// Haz clic en el enlace para activar la alerta
driver.findElement(By.linkText("See a sample prompt")).click()

// Espera a que se muestre la alerta y almacenala en una variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

// Inserta tu mensaje
alert.sendKeys("Selenium")

// Presiona el botón OK
alert.accept()
  

3.6 - Proxies Http

Un servidor proxy actúa como intermediario para solicitudes entre un cliente y un servidor. En forma simple, el tráfico fluye a través del servidor proxy en camino a la dirección solicitada y de regreso.

Un servidor proxy para scripts de automatización con Selenium podría ser útil para:

  • Captura el tráfico de la red
  • Simular llamadas de backend realizadas por el sitio web
  • Accede al sitio web requerido bajo topologías de red complejas o restricciones/políticas corporativas estrictas.

Si te encuentras en un entorno corporativo, y un navegador no puede conectarse a una URL, esto es muy probablemente porque el ambiente necesita un proxy para acceder.

Selenium WebDriver proporciona una via para configurar el proxy:

import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class proxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
  
from selenium import webdriver

PROXY = "<HOST:PORT>"
webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
    "httpProxy": PROXY,
    "ftpProxy": PROXY,
    "sslProxy": PROXY,
    "proxyType": "MANUAL",

}

with webdriver.Firefox() as driver:
    # Open URL
    driver.get("https://selenium.dev")

  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
  public static void Main() {
    ChromeOptions options = new ChromeOptions();
    Proxy proxy = new Proxy();
    proxy.Kind = ProxyKind.Manual;
    proxy.IsAutoDetect = false;
    proxy.SslProxy = "<HOST:PORT>";
    options.Proxy = proxy;
    options.AddArgument("ignore-certificate-errors");
    IWebDriver driver = new ChromeDriver(options);
    driver.Navigate().GoToUrl("https://www.selenium.dev/");
  }
}
  
# this code was written with Selenium 4

proxy = Selenium::WebDriver::Proxy.new(http: '<HOST:PORT>')
cap   = Selenium::WebDriver::Remote::Capabilities.chrome(proxy: proxy)

driver = Selenium::WebDriver.for(:chrome, capabilities: cap)
driver.get('http://google.com')
  
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
  opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
  let driver = new webdriver.Builder()
    .forBrowser('chrome')
    .setChromeOptions(opts)
    .build();
  try {
    await driver.get("https://selenium.dev");
  }
  finally {
   await driver.quit();
  }
}());
  
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
    fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
  

3.7 - Page loading strategy

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

Defines the current session’s page loading strategy. By default, when Selenium WebDriver loads a page, it follows the normal pageLoadStrategy. It is always recommended to stop downloading additional resources (like images, css, js) when the page loading takes lot of time.

The document.readyState property of a document describes the loading state of the current document. By default, WebDriver will hold off on responding to a driver.get() (or) driver.navigate().to() call until the document ready state is complete

In SPA applications (like Angular, React, Ember) once the dynamic content is already loaded (I.e once the pageLoadStrategy status is COMPLETE), clicking on a link or performing some action within the page will not make a new request to the server as the content is dynamically loaded at the client side without a full page refresh.

SPA applications can load many views dynamically without any server requests, So pageLoadStrategy will always show COMPLETE status until we do a new driver.get() and driver.navigate().to()

WebDriver pageLoadStrategy supports the following values:

normal

This will make Selenium WebDriver to wait for the entire page is loaded. When set to normal, Selenium WebDriver waits until the load event fire is returned.

By default normal is set to browser if none is provided.

import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;

public class pageLoadStrategy {
    public static void main(String[] args) {
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
        WebDriver driver = new ChromeDriver(chromeOptions);
        try {
            // Navigate to Url
            driver.get("https://google.com");
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'normal'
driver = webdriver.Chrome(options=options)
# Navigate to url
driver.get("http://www.google.com")
driver.quit()

  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace pageLoadStrategy {
  class pageLoadStrategy {
    public static void Main(string[] args) {
      var chromeOptions = new ChromeOptions();
      chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try {
        driver.Navigate().GoToUrl("https://example.com");
      } finally {
        driver.Quit();
      }
    }
  }
}
  
require 'selenium-webdriver'
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps.page_load_strategy='normal'

driver = Selenium::WebDriver.for :chrome, :desired_capabilities => caps
driver.get('https://www.google.com')
  
const {Builder, Capabilities} = require('selenium-webdriver');
const caps = new Capabilities();
caps.setPageLoadStrategy("normal");
(async function example() {
    let driver = await new Builder().
                withCapabilities(caps).
                forBrowser('chrome').
                build();
    try {
        // Navigate to Url
        await driver.get('https://www.google.com');
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
    val chromeOptions = ChromeOptions()
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
    val driver = ChromeDriver(chromeOptions)
    try {
        driver.get("https://www.google.com")
    }
    finally {
        driver.quit()
    }
}
  

eager

This will make Selenium WebDriver to wait until the initial HTML document has been completely loaded and parsed, and discards loading of stylesheets, images and subframes.

When set to eager, Selenium WebDriver waits until DOMContentLoaded event fire is returned.

import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;

public class pageLoadStrategy {
    public static void main(String[] args) {
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
        WebDriver driver = new ChromeDriver(chromeOptions);
        try {
            // Navigate to Url
            driver.get("https://google.com");
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'eager'
driver = webdriver.Chrome(options=options)
# Navigate to url
driver.get("http://www.google.com")
driver.quit()
  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace pageLoadStrategy {
  class pageLoadStrategy {
    public static void Main(string[] args) {
      var chromeOptions = new ChromeOptions();
      chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try {
        driver.Navigate().GoToUrl("https://example.com");
      } finally {
        driver.Quit();
      }
    }
  }
}
  
require 'selenium-webdriver'
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps.page_load_strategy='eager'

driver = Selenium::WebDriver.for :chrome, :desired_capabilities => caps
driver.get('https://www.google.com')
  
const {Builder, Capabilities} = require('selenium-webdriver');
const caps = new Capabilities();
caps.setPageLoadStrategy("eager");
(async function example() {
    let driver = await new Builder().
                withCapabilities(caps).
                forBrowser('chrome').
                build();
    try {
        // Navigate to Url
        await driver.get('https://www.google.com');
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
    val chromeOptions = ChromeOptions()
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
    val driver = ChromeDriver(chromeOptions)
    try {
        driver.get("https://www.google.com")
    }
    finally {
        driver.quit()
    }
}
  

none

When set to none Selenium WebDriver only waits until the initial page is downloaded.

import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;

public class pageLoadStrategy {
    public static void main(String[] args) {
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
        WebDriver driver = new ChromeDriver(chromeOptions);
        try {
            // Navigate to Url
            driver.get("https://google.com");
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'none'
driver = webdriver.Chrome(options=options)
# Navigate to url
driver.get("http://www.google.com")
driver.quit()
  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace pageLoadStrategy {
  class pageLoadStrategy {
    public static void Main(string[] args) {
      var chromeOptions = new ChromeOptions();
      chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try {
        driver.Navigate().GoToUrl("https://example.com");
      } finally {
        driver.Quit();
      }
    }
  }
}
  
require 'selenium-webdriver'
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps.page_load_strategy='none'

driver = Selenium::WebDriver.for :chrome, :desired_capabilities => caps
driver.get('https://www.google.com')
  
const {Builder, Capabilities} = require('selenium-webdriver');
const caps = new Capabilities();
caps.setPageLoadStrategy("none");
(async function example() {
    let driver = await new Builder().
                withCapabilities(caps).
                forBrowser('chrome').
                build();
    try {
        // Navigate to Url
        await driver.get('https://www.google.com');
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
    val chromeOptions = ChromeOptions()
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
    val driver = ChromeDriver(chromeOptions)
    try {
        driver.get("https://www.google.com")
    }
    finally {
        driver.quit()
    }
}
  

3.8 - Web element

Page being translated from English to Spanish. Do you speak Spanish? Help us to translate it by sending us pull requests!

WebElement represents a DOM element. WebElements can be found by searching from the document root using a WebDriver instance, or by searching under another WebElement.

WebDriver API provides built-in methods to find the WebElements which are based on different properties like ID, Name, Class, XPath, CSS Selectors, link Text, etc.

Find Element

It is used to find an element and returns a first matching single WebElement reference, that can be used for future element actions

WebDriver driver = new FirefoxDriver();

driver.get("http://www.google.com");

// Get search box element from webElement 'q' using Find Element
WebElement searchBox = driver.findElement(By.name("q"));

searchBox.sendKeys("webdriver");
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

driver.get("http://www.google.com")

# Get search box element from webElement 'q' using Find Element
search_box = driver.find_element(By.NAME, "q")

search_box.send_keys("webdriver")
  
IWebDriver driver = new FirefoxDriver();

driver.Url = "http://www.google.com";

// Get search box element from webElement 'q' using Find Element
IWebElement searchbox = driver.FindElement(By.Name("q"));

searchbox.SendKeys("webdriver");
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
begin
  # Navigate to URL
  driver.get 'https://google.com'

  # Get search box element from webElement 'q' using Find Element
  search_bar = driver.find_element(name: 'q')

  # Perform action using WebElement
  search_bar.send_keys 'Webdriver'
ensure
  driver.quit
end
  
let {Builder, By} = require('selenium-webdriver');
driver = new Builder().forBrowser('firefox').build();

(async function test(){

//Navigate to url
await driver.get('http://www.google.com');

// Get search box element from webElement 'q' using Find Element
let searchBar = driver.findElement(By.name('q'));

//Perform action using WebElement
await searchBar.sendKeys('Webdriver');

})();
  
val driver = FirefoxDriver()

driver.get("http://www.google.com")

// Get search box element from webElement 'q' using Find Element
val searchBox = driver.findElement(By.name("q"))

searchBox.sendKeys("webdriver")
  

Find Elements

Similar to ‘Find Element’, but returns a list of matching WebElements. To use a particular WebElement from the list, you need to loop over the list of elements to perform action on selected element.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.util.List;

public class findElementsExample {
    public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        try {
            driver.get("https://example.com");
            // Get all the elements available with tag name 'p'
            List<WebElement> elements = driver.findElements(By.tagName("p"));
            for (WebElement element : elements) {
                System.out.println("Paragraph text:" + element.getText());
            }
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

# Navigate to Url
driver.get("https://www.example.com")

# Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
begin
  # Navigate to URL
  driver.get 'https://www.example.com'

  # Get all the elements available with tag name 'p'
  elements = driver.find_elements(:tag_name,'p')

  elements.each { |e|
    puts e.text
  }
ensure
  driver.quit
end
  
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  

Find Element From Element

It is used to find a child element within the context of parent element. To achieve this, the parent WebElement is chained with ‘findElement’ to access child elements

WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
WebElement searchForm = driver.findElement(By.tagName("form"));
WebElement searchBox = searchForm.findElement(By.name("q"));
searchBox.sendKeys("webdriver");
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()
driver.get("http://www.google.com")
search_form = driver.find_element(By.TAG_NAME, "form")
search_box = search_form.find_element(By.NAME, "q")
search_box.send_keys("webdriver")
  
IWebDriver driver = new FirefoxDriver();
driver.Url = "http://www.google.com";
IWebElement searchForm = driver.FindElement(By.TagName("form"));
IWebElement searchbox = searchForm.FindElement(By.Name("q"));
searchbox.SendKeys("webdriver");
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
begin
  # Navigate to URL
  driver.get 'https://google.com'

  # Get and store DOM element '<form>'
  search_form = driver.find_element(name: 'f')

  # Get search box element from webElement 'form'
  search_bar = search_form.find_element(name: 'q')

  # Perform action using WebElement
  search_bar.send_keys 'Webdriver'
ensure
  driver.quit
end
  
let {Builder, By} = require('selenium-webdriver');
driver = new Builder().forBrowser('firefox').build();

(async function test(){

//Navigate to url
await driver.get('http://www.google.com');

//Get and store DOM element '<form>'
let searchForm = driver.findElement(By.name('f'));

//Get search box element from webElement 'form'
let searchBar = searchForm.findElement(By.name('q'));

//Perform action using WebElement
await searchBar.sendKeys('Webdriver');

})();
  
val driver = FirefoxDriver()
driver.get("http://www.google.com")
val searchForm = driver.findElement(By.tagName("form"))
val searchBox = searchForm.findElement(By.name("q"))
searchBox.sendKeys("webdriver")
  

Find Elements From Element

It is used to find the list of matching child WebElements within the context of parent element. To achieve this, the parent WebElement is chained with ‘findElements’ to access child elements

  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")

# Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

# Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)
  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
  require 'selenium-webdriver'
  driver = Selenium::WebDriver.for :chrome
  begin
    # Navigate to URL
    driver.get 'https://www.example.com'

    # Get element with tag name 'div'
    element = driver.find_element(:tag_name,'div')

    # Get all the elements available with tag name 'p'
    elements = element.find_elements(:tag_name,'p')

    elements.each { |e|
      puts e.text
    }
  ensure
    driver.quit
  end
  
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  

Get Active Element

It is used to track (or) find DOM element which has the focus in the current browsing context.

  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

  # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
  require 'selenium-webdriver'
  driver = Selenium::WebDriver.for :chrome
  begin
    driver.get 'https://www.google.com'
    driver.find_element(css: '[name="q"]').send_keys('webElement')

    # Get attribute of current active element
    attr = driver.switch_to.active_element.attribute('title')
    puts attr
  ensure
    driver.quit
  end
  
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  

Is Element Enabled

This method is used to check if the connected Element is enabled or disabled on a webpage. Returns a boolean value, True if the connected element is enabled in the current browsing context else returns false.

  //navigates to url
  driver.get("https://www.google.com/");

  //returns true if element is enabled else returns false
  boolean value = driver.findElement(By.name("btnK")).isEnabled();
  
# Navigate to url
driver.get("http://www.google.com")

# Returns true if element is enabled else returns false
value = driver.find_element(By.NAME, 'btnK').is_enabled()
  
// Navigate to Url
driver.Navigate().GoToUrl("https://google.com");

// Store the WebElement
IWebElement element = driver.FindElement(By.Name("btnK"));

// Prints true if element is enabled else returns false
System.Console.WriteLine(element.Enabled);
  
# Navigate to url
driver.get 'http://www.google.com/'

# Returns true if element is enabled else returns false
ele = driver.find_element(name: 'btnK').enabled?
  
// Navigate to url
await driver.get('https://www.google.com');

// Resolves Promise and returns boolean value
let element =  await driver.findElement(By.name("btnK")).isEnabled();
  
 //navigates to url
 driver.get("https://www.google.com/")

 //returns true if element is enabled else returns false
 val attr = driver.findElement(By.name("btnK")).isEnabled()
  

Is Element Selected

This method determines if the referenced Element is Selected or not. This method is widely used on Check boxes, radio buttons, input elements, and option elements.

Returns a boolean value, True if referenced element is selected in the current browsing context else returns false.

 //navigates to url
 driver.get("https://the-internet.herokuapp.com/checkboxes");

 //returns true if element is checked else returns false
 boolean value = driver.findElement(By.cssSelector("input[type='checkbox']:first-of-type")).isSelected();
  
# Navigate to url
driver.get("https://the-internet.herokuapp.com/checkboxes")

# Returns true if element is checked else returns false
value = driver.find_element(By.CSS_SELECTOR, "input[type='checkbox']:first-of-type").is_selected()
  
// Navigate to Url
driver.Navigate().GoToUrl("https://the-internet.herokuapp.com/checkboxes");

// Returns true if element ins checked else returns false
bool value = driver.FindElement(By.CssSelector("input[type='checkbox']:last-of-type")).Selected;
  
# Navigate to url
driver.get 'https://the-internet.herokuapp.com/checkboxes'

# Returns true if element is checked else returns false
ele = driver.find_element(css: "input[type='checkbox']:last-of-type").selected?
  
// Navigate to url
await driver.get('https://the-internet.herokuapp.com/checkboxes');

// Returns true if element ins checked else returns false
let res = await driver.findElement(By.css("input[type='checkbox']:last-of-type")).isSelected();
  
 //navigates to url
 driver.get("https://the-internet.herokuapp.com/checkboxes")

 //returns true if element is checked else returns false
 val attr =  driver.findElement(By.cssSelector("input[type='checkbox']:first-of-type")).isSelected()
  

Get Element TagName

It is used to fetch the TagName of the referenced Element which has the focus in the current browsing context.

 //navigates to url
 driver.get("https://www.example.com");

 //returns TagName of the element
 String value = driver.findElement(By.cssSelector("h1")).getTagName();
  
# Navigate to url
driver.get("https://www.example.com")

# Returns TagName of the element
attr = driver.find_element(By.CSS_SELECTOR, "h1").tag_name
  
// Navigate to Url
driver.Navigate().GoToUrl("https://www.example.com");

// Returns TagName of the element
string attr = driver.FindElement(By.CssSelector("h1")).TagName;
  
# Navigate to url
driver.get 'https://www.example.com'

# Returns TagName of the element
attr = driver.find_element(css: "h1").tag_name
  
// Navigate to URL
await driver.get('https://www.example.com');

// Returns TagName of the element
let value = await driver.findElement(By.css('h1')).getTagName();
  
 //navigates to url
 driver.get("https://www.example.com")

 //returns TagName of the element
 val attr =  driver.findElement(By.cssSelector("h1")).getTagName()
  

Get Element Rect

It is used to fetch the dimensions and coordinates of the referenced element.

The fetched data body contain the following details:

  • X-axis position from the top-left corner of the element
  • y-axis position from the top-left corner of the element
  • Height of the element
  • Width of the element
// Navigate to url
driver.get("https://www.example.com");

// Returns height, width, x and y coordinates referenced element
Rectangle res =  driver.findElement(By.cssSelector("h1")).getRect();

// Rectangle class provides getX,getY, getWidth, getHeight methods
System.out.println(res.getX());
  
# Navigate to url
driver.get("https://www.example.com")

# Returns height, width, x and y coordinates referenced element
res = driver.find_element(By.CSS_SELECTOR, "h1").rect
  
// Navigate to Url
driver.Navigate().GoToUrl("https://example.com");

var res = driver.FindElement(By.CssSelector("h1"));
// Return x and y coordinates referenced element
System.Console.WriteLine(res.Location);
// Returns height, width
System.Console.WriteLine(res.Size);
  
# Navigate to url
driver.get 'https://www.example.com'

# Returns height, width, x and y coordinates referenced element
res = driver.find_element(css: "h1").rect
  
// Navigate to url
await driver.get('https://www.example.com');

// Returns height, width, x and y coordinates referenced element
let element =  await driver.findElement(By.css("h1")).getRect();
  
// Navigate to url
driver.get("https://www.example.com")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.cssSelector("h1")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
  

Get Element CSS Value

Retrieves the value of specified computed style property of an element in the current browsing context.

// Navigate to Url
driver.get("https://www.example.com");

// Retrieves the computed style property 'color' of linktext
String cssValue = driver.findElement(By.linkText("More information...")).getCssValue("color");

  
# Navigate to Url
driver.get('https://www.example.com')

# Retrieves the computed style property 'color' of linktext
cssValue = driver.findElement(By.LINK_TEXT, "More information...").value_of_css_property('color')

  
// Navigate to Url
driver.Navigate().GoToUrl("https://www.example.com");

// Retrieves the computed style property 'color' of linktext
String cssValue = driver.FindElement(By.LinkText("More information...")).GetCssValue("color");

  
# Navigate to Url
driver.get 'https://www.example.com'

# Retrieves the computed style property 'color' of linktext
cssValue = driver.find_element(:link_text, 'More information...').css_value('color')

  
// Navigate to Url
await driver.get('https://www.example.com');

// Retrieves the computed style property 'color' of linktext
let cssValue = await driver.findElement(By.linkText("More information...")).getCssValue('color');

    
// Navigate to Url
driver.get("https://www.example.com")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.linkText("More information...")).getCssValue("color")

  

Get Element Text

Retrieves the rendered text of the specified element.

// Navigate to url
driver.get("https://example.com");

// Retrieves the text of the element
String text = driver.findElement(By.cssSelector("h1")).getText();
  
# Navigate to url
driver.get("https://www.example.com")

# Retrieves the text of the element
text = driver.find_element(By.CSS_SELECTOR, "h1").text
  
// Navigate to url
driver.Url="https://example.com";

// Retrieves the text of the element
String text = driver.FindElement(By.CssSelector("h1")).Text;
  
# Navigate to url
driver.get 'https://www.example.com'

# Retrieves the text of the element
text = driver.find_element(:css, 'h1').text
  
// Navigate to URL
await driver.get('http://www.example.com');

// retrieves the text of the element
let text = await driver.findElement(By.css('h1')).getText();
    
// Navigate to URL
driver.get("https://www.example.com")

// retrieves the text of the element
val text = driver.findElement(By.cssSelector("h1")).getText()
  

3.9 - Teclado

Keyboard representa un evento del teclado. Las acciones del teclado se realizan mediante el uso de una interfaz de bajo nivel que nos permite proporcionar entradas de un dispositivo virtualizado al navegador web.

sendKeys

El sendKeys escribe una secuencia de teclas en el elemento del DOM incluso si se encuentra una secuencia de teclas modificadoras. Here are the list of possible keystrokes that WebDriver Supports.

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class HelloSelenium {
  public static void main(String[] args) {
    WebDriver driver = new FirefoxDriver();
    try {
      // Navega a la URL
      driver.get("https://google.com");

      // Inserta el texto "q" y ejecuta la accion del teclado "Enter"
      driver.findElement(By.name("q")).sendKeys("q" + Keys.ENTER);
    } finally {
      driver.quit();
    }
  }
}
  
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()

# Navega a la URL
driver.get("http://www.google.com")

# Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
driver.find_element(By.NAME, "q").send_keys("webdriver" + Keys.ENTER)
  
using (var driver = new FirefoxDriver())
{
  //  Navega a la URL
  driver.Navigate().GoToUrl("https://google.com");

  // Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
  driver.FindElement(By.Name("q")).SendKeys("webdriver" + Keys.Enter);
}
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
begin
  #  Navega a la URL
  driver.get 'https://google.com'

  # Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
  driver.find_element(name: 'q').send_keys 'webdriver', :return

ensure
  driver.quit
end
  
const {Builder, By, Key} = require('selenium-webdriver');

(async function example() {
  let driver = await new Builder().forBrowser('firefox').build();

  try {
    //  Navega a la URL
    await driver.get('https://www.google.com');

    // Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
    await driver.findElement(By.name('q')).sendKeys('webdriver', Key.ENTER);
  }
  finally {
    await driver.quit();
  }
})();
  
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
  val driver = FirefoxDriver()
  try {
    // Navega a la URL
    driver.get("https://google.com")

    // Inserta el texto "q" y ejecuta la accion del teclado "Enter"
    driver.findElement(By.name("q")).sendKeys("q" + Keys.ENTER)
  } finally {
    driver.quit()
  }
}
  

keyDown

KeyDown se usa para simular la acción de presionar una tecla modificadora (CONTROL, SHIFT, ALT)

WebDriver driver = new ChromeDriver();
try {
  //  Navega a la URL
  driver.get("https://google.com");

  // Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
  driver.findElement(By.name("q")).sendKeys("webdriver" + Keys.ENTER);

  Actions actionProvider = new Actions(driver);
  Action keydown = actionProvider.keyDown(Keys.CONTROL).sendKeys("a").build();
  keydown.perform();
} finally {
  driver.quit();
}
  
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()

#  Navega a la URL
driver.get("http://www.google.com")

# Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
driver.find_element(By.NAME, "q").send_keys("webdriver" + Keys.ENTER)

# Ejecuta la acción ctrl + A (modificador CONTROL + Alfabeto A) para seleccionar la página
webdriver.ActionChains(driver).key_down(Keys.CONTROL).send_keys("a").perform()
  
IWebDriver driver = new ChromeDriver();
try
{
  //  Navega a la URL
  driver.Navigate().GoToUrl("https://google.com");

  // Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
  driver.FindElement(By.Name("q")).SendKeys("webdriver" + Keys.Enter);

  // Ejecuta la acción ctrl + A (modificador CONTROL + Alfabeto A) para seleccionar la página
  Actions actionProvider = new Actions(driver);
  IAction keydown = actionProvider.KeyDown(Keys.Control).SendKeys("a").Build();
  keydown.Perform();
}
finally
{
  driver.Quit();
}
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome
begin
  #  Navega a la URL
  driver.get 'https://google.com'

  # Inserta el texto "Webdriver" y ejecuta la accion del teclado "ENTER"
  driver.find_element(name: 'q').send_keys 'webdriver', :return

  # Ejecuta la acción ctrl + A (modificador CONTROL + Alfabeto A) para seleccionar la página
  driver.action.key_down(:control).send_keys('a').perform

ensure
  driver.quit
end
  
const {Builder, By, Key