Tomar capturas de pantalla con Selenium WebDriver

1. Información general

Cuando trabajamos con pruebas automatizadas usando Selenium, a menudo necesitamos tomar una captura de pantalla de una página web o parte de una página web. Esto puede ser útil, especialmente cuando se depuran fallas de prueba o cuando se verifica que el comportamiento de nuestra aplicación sea consistente en diferentes navegadores.

En este tutorial rápido, veremos un par de formas en las que podemos capturar capturas de pantalla utilizando Selenium WebDriver de nuestras pruebas JUnit . Para obtener más información sobre las pruebas con Selenium, consulte nuestra excelente guía de Selenium.

2. Dependencias y configuración

Comencemos agregando la dependencia de Selenium a nuestro pom.xml :

 org.seleniumhq.selenium selenium-java 3.141.59 

Como siempre, la última versión de este artefacto se puede encontrar en Maven Central.

Ahora configuremos nuestro controlador para usar Chrome desde nuestra prueba unitaria:

private static ChromeDriver driver; @BeforeClass public static void setUp() { System.setProperty("webdriver.chrome.driver", resolveResourcePath("chromedriver.mac")); Capabilities capabilities = DesiredCapabilities.chrome(); driver = new ChromeDriver(capabilities); driver.manage() .timeouts() .implicitlyWait(5, TimeUnit.SECONDS); driver.get("//www.google.com/"); }

Como podemos ver, esta es una configuración de Selenium bastante estándar para un ChromeDriver que nos permitirá controlar el navegador Chrome que se ejecuta en nuestra máquina local. También configuramos la cantidad de tiempo que el controlador debe esperar cuando busca un elemento en la página en cinco segundos.

Finalmente, antes de que se ejecute cualquiera de nuestras pruebas, abrimos una página web favorita, www.google.com , en la ventana actual del navegador.

3. Tome una captura de pantalla del área visible

En este primer ejemplo, echaremos un vistazo a la interfaz TakesScreenShot , que Selenium proporciona lista para usar . Como sugiere su nombre, podemos usar esta interfaz para tomar capturas de pantalla del área visible.

Creemos un método simple para tomar capturas de pantalla usando esta interfaz:

public void takeScreenshot(String pathname) throws IOException { File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(src, new File(pathname)); } 

En este método conciso, primero convertimos nuestro controlador en un TakesScreenshot usando un molde. Entonces podemos llamar al método getScreenshotAs , con el OutputType especificado para crear un archivo de imagen .

Después de eso, podemos copiar el archivo a cualquier ubicación deseada usando el método copyFile de Apache Commons IO . ¡Muy genial! En solo dos líneas podemos realizar capturas de pantalla .

Ahora veamos cómo podemos usar este método desde una prueba unitaria:

@Test public void whenGoogleIsLoaded_thenCaptureScreenshot() throws IOException { takeScreenshot(resolveTestResourcePath("google-home.png")); assertTrue(new File(resolveTestResourcePath("google-home.png")).exists()); }

En esta prueba unitaria, guardamos el archivo de imagen resultante en nuestra carpeta test / resources usando el nombre de archivo google-home.png antes de confirmar para ver si el archivo existe.

4. Captura de un elemento en la página

En la siguiente sección, veremos cómo podemos capturar una captura de pantalla de un elemento individual en la página. Para esto, usaremos una biblioteca llamada aShot, una biblioteca de utilidad de captura de pantalla que es compatible de forma nativa con Selenium 3 en adelante .

Dado que aShot está disponible en Maven Central, podemos incluirlo en nuestro pom.xml :

 ru.yandex.qatools.ashot ashot 1.5.4 

La biblioteca aShot proporciona una API fluida para configurar cómo exactamente queremos capturar las capturas de pantalla.

Ahora veamos cómo podemos capturar el logo de la página de inicio de Google de una de nuestras pruebas unitarias:

@Test public void whenGoogleIsLoaded_thenCaptureLogo() throws IOException { WebElement logo = driver.findElement(By.id("hplogo")); Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)) .coordsProvider(new WebDriverCoordsProvider()) .takeScreenshot(driver, logo); ImageIO.write(screenshot.getImage(), "jpg", new File(resolveTestResourcePath("google-logo.png"))); assertTrue(new File(resolveTestResourcePath("google-logo.png")).exists()); }

Comenzamos encontrando un WebElement en la página usando el id hplogo. Luego creamos una nueva instancia de AShot y establecemos una de las estrategias de disparo integradas: ShootingStrategies.viewportPasting (1000) . Esta estrategia desplazará la ventana gráfica mientras tomamos nuestra captura de pantalla durante un máximo de un segundo (1oooms) .

Ahora tenemos configurada la política de cómo queremos tomar nuestra captura de pantalla.

Cuando queremos capturar un elemento específico en la página, internamente, aShot buscará el tamaño y la posición de un elemento y recortará la imagen original. Para esto, llamamos al método coordsProvider y pasamos una clase WebDriverCoordsProvider que usará la API de WebDriver para encontrar las coordenadas.

Note that, by default, aShot uses jQuery for coordinate resolution. But some drivers have problems with Javascript.

Now we can call the takeScreenshot method passing our driver and logo element which will, in turn, give us a Screenshot object containing the result of our screen capture. As before, we finish our test by writing an image file and verifying its existence.

5. Conclusion

In this quick tutorial, we've seen two approaches to capturing screenshots using Selenium WebDriver.

In the first approach, we saw how to capture the whole screen using Selenium directly. Then we learned how to capture a specific element on the page using a great utility library called aShot.

Uno de los principales beneficios de usar aShot es que los diferentes WebDrivers se comportan de manera diferente al tomar capturas de pantalla. Usar aShot nos abstrae de esta complejidad y nos brinda resultados transparentes independientemente del controlador que estemos usando . Asegúrese de consultar la documentación completa para ver todas las funciones compatibles disponibles.

Como siempre, el código fuente completo del artículo está disponible en GitHub.