Mostrando las entradas con la etiqueta webdriver. Mostrar todas las entradas
Mostrando las entradas con la etiqueta webdriver. Mostrar todas las entradas

viernes, 25 de mayo de 2018

Page Object

 ¿Qué es un Page Object?

Page Object es un patrón de diseño con el cual buscamos crear un objeto que sirva como una capa de abstracción para las interacciones que se pueden efectuar en una página web. Es decir, un page object debe proveer una manera simple para interactuar con una página web encapsulando sus funcionalidades y características.



¿Por qué usar page objects?

Los page objects nos entregan una manera sencilla de interactuar con las páginas web que queremos verificar en nuestros tests. Esto le quita mucha complejidad a nuestros tests, ya que nosotros para realizar acciones u obtener datos de la página web, solamente debemos llamar los métodos del objeto. Esto reducirá dramáticamente la cantidad de código en nuestros tests. Disminuyendo sus complejidad, mantenimiento y facilitando el patrón AAA (Arrange, Act y Assert.).

Consejos para el manejo de elementos.

Campo de texto (Input text y text areas).

Usualmente los campos de texto son elementos html que aceptan texto libre en su interior.

Extracción de datos.

Se debe tener un método para extraer el contenido de dicho campo y retornarlo como un String.

Asignación de datos.

Se debe tener un método para poder ingresar datos a ese campo. Lo ideal es que este método reciba un String como parámetro

Radio buttons.

Los radio buttons son un conjunto de elementos que comparten el atributo name y se diferencian entre ellos por el valor que ellos contienen.

Extracción de datos.

Se debe tener un método que retorne el valor del botón seleccionado de la familia.

Asignación de datos.

Se debe tener un método que debería ser capaz de seleccionar el elemento de la familia mediante un parámetro de texto que concuerde con uno de los elementos de la familia.

Checkboxes.

Los checkboxes son elementos que pueden ser clickeados para  cambiar su estado a 'checked'.

Extracción de datos.

Se debe tener un método que retorne True o False.

Asignación de datos.

Se debe terner un método que asigne mediante un parámetro booleano para cambiar la selección de dicho objecto. True para que pase a estar 'checked' y False para remover remover el atributo 'checked'.

Listas desplegables (Selects).

Las listas deplegables son elementos que contienen opciones para ser seleccionadas por el usuario. Las opciones tienen dos principales características, una es el texto visible y la otra es el valor de la opción. Dichas características no siempre comparten valor.

Extracción de datos.

Se debe tener métodos que retornen el valor, texto o índice de la opción seleccionado en la lista desplegable.

Asignación de datos.

Se debe tener métodos para poder seleccionar la opción por valor, texto o indice.

Conclusión.

El page object es un patrón de diseño que nos ayudarás a disminuir la complejidad de nuestros tests. Debido a que nos entregará menos código por mantener, mayor abstracción en nuestras pruebas y una complejidad menor en nuestros tests.

sábado, 23 de diciembre de 2017

Guía para utilizar WebElementHighlighter

WebElementHighlighter es una librería python que nos permite resaltar WebElements de Selenium. La principal finalidad de esta librería es poder mostrar al tester que elementos de una página están fallando.

Sus funcionalidades actuales son:

  • Hacer parpadear WebElements.
  • Cambiar estilos como fondo y bordes de WebElements.

Instalación.

pip install webelement_highlighter

Ejemplo de uso.

from webelement_highlighter import WebElementHighlighter
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.w3schools.com/js/default.asp")

wh = WebElementHighlighter(driver)

we = driver.find_element_by_id("topnavbtn_references")
wes = driver.find_elements_by_class_name("w3-col")

wh.make_it_blink(we)
wh.make_them_blink(wes, times=20)

wh.highlight_element(we)
wh.highlight_elements(wes, stop=True)

Nota.

Para ejecutar el ejemplo es necesario tener instalada la librería selenium.

Enlaces.

Repositorio: https://github.com/rtorres90/webelement_highlighter

martes, 6 de junio de 2017

Configuración de webdriver para manejar descarga de PDFs.

Uno de los grandes problemas al momento de crear tests para una aplicación web que entregue PDFs como resultado en algunas de sus funcionalidades,  es controlar el comportamiento por defecto que tendrá el navegador frente a dichos archivos. Según mi experiencia como QA de automatización los principales problemas son los siguientes:

  • Ventanas de confirmación de descarga. ¡Un verdadero dolor de cabeza!, es imposible interactuar con ellas porque son parte del navegador y no de la página web.
  • Ubicación del archivo a descargar. Un gran problema si no es manejado en la configuración de tu driver porque el navegador por defecto intentará usar sus carpetas ocultas en los lugares más oscuros de tu pc, ten en cuenta que además las rutas para dichos directorios son diferentes por sistema operativo, por lo tanto buscar manualmente o hardcodear una ruta es casi imposible sin previa investigación.
  • Plugins por defecto del navegador. Actualmente los navegadores son capaces de leer los PDFs sin ningún tipo de plugin de terceros. Esto es un problema bastante recurrente, intentas descargar un pdf, pero ¡pum! el navegador mágicamente lo abre, rompiendo totalmente con el flujo de tu test.


Para poder resolver estos problemas es necesario modificar las configuración de los navegadores y guardar estos cambios dentro de un perfil.

A continuación listaré y explicaré los pasos para crear estos perfiles con sus configuraciones necesarias para los drivers de Firefox y Chrome utilizando Python.

Firefox.

profile = webdriver.FirefoxProfile() #1

profile.set_preference("browser.download.folderList", 2)#2
profile.set_preference("browser.download.dir", cfg.temp_pdf)#3
profile.set_preference("browser.download.useDownloadDir", True)#4
profile.set_preference("browser.download.manager.showWhenStarting", False)#5
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")#6
profile.set_preference("browser.download.manager.showAlertOnComplete", False)#7
profile.set_preference("browser.download.manager.useWindow", False)#7
profile.set_preference("pdfjs.disabled", True)#9
self.driver = webdriver.Firefox(profile)#10

Configuración para firefox.

  1. Se crea un perfil de firefox vacío.
  2. Con el número 2 le indicamos a firefox que debe utilizar la carpeta especificada en el paso 3.
  3. Acá le proporcionaremos a firefox la carpeta que queremos utilizar como directorio de descarga.
  4. Ahora activamos el uso del directorio asignado en el paso 3.
  5. Apagamos la animación de comienzo de descarga. (Opcional)
  6. Este paso es muy importante, acá le pasaremos como parámetro los MIME type que queremos descargar sin preguntar. Más info sobre MIME types.
  7. Desactivamos animación de descarga completa. (Opcional)
  8. Deshabilitamos la ventana de descarga de firefox.
  9. Apagamos el plugin por defecto de firefox para leer archivos PDF.
  10. Instanciamos el driver de Firefox pasando como parámetro nuestro profile recién creado.

Chrome
chrome_profile = webdriver.ChromeOptions()#1
profile = {"download.default_directory": cfg.temp_pdf,
           "download.prompt_for_download": False,
           "download.directory_upgrade": True,
           "safebrowsing.enabled": True,
           "plugins.always_open_pdf_externally": True}#2
chrome_profile.add_experimental_option("prefs", profile)#3
chrome_profile.add_argument("--disable-extensions")#4
chrome_profile.add_argument("--disable-print-preview")#5
self.driver = webdriver.Chrome(chrome_options=chrome_profile)#6

Configuración para Chrome.

  1. Se crea un perfil de chrome vacío.
  2. Acá creamos un diccionario con las siguientes configuraciones.
    1. Directorio por defecto para las descargas de chrome.
    2. Acá apagamos  la ventana que pregunta donde ubicar y como llamar el archivo por descargar.
    3. Opción para que chrome pueda crear la ruta de descarga si es que no existe.
    4. Navegación segura activada. (Opcional)
    5. Para abrir el pdf externamente.
  3. Se añade el diccionario recién creado como las preferencias del perfil.
  4. Desactiva todas las extensiones de Chrome para evitar que algún plugin del navegador intente abrir los archivos PDF.
  5. Acá desactivamos la vista de impresión para evitar nuevamente que algo intente abrir los PDFs.
  6. Finalmente instanciamos el chromedriver pasando como parámetros el perfil de chrome recién creado.
Tal como pudimos apreciar, la configuración para evitar la interrupción de tests que contengan PDFs es un tanto compleja, ya que se debe tener en consideración muchas variables como lugar de descarga, desactivación de plugins, etc. Como comentario profesional siempre recomiendo descargar los pdfs utilizando código para no crear tests completamente dependientes de la máquina en que se están corriendo los tests, debido a que estos tipos de tests no van a funcionar al 100% en drivers provistos por saucelabs.

sábado, 15 de octubre de 2016

Downgrade de Firefox para no perder la compatibilidad con webdriver.


Uno de los últimos grandes problemas que me he enfrentado como QA de automatización ha sido el problema de compatibilidad de webdriver con Firefox. A partir de la versión 47 de Firefox,  no será posible utilizar webdriver con este navegador. Es decir, ya no podremos simplemente llamar a webdriver.Firefox() para hacer uso de él.

Las solución actual ante esto es instalar marionette. Suena fácil, pero créanme que no lo es. Es necesario hacer diferentes tipos de instalaciones por sistema operativo, lo cual no es lo ideal si estamos trabajando en testing multiplataforma.

Como notaran por mis palabras, no fui capaz de instalar marionette en el framework de automatización en el que trabajo. Me niego rotundamente a hacer una instalación ad hoc para cada sistema operativo, esto rompe totalmente la filosofía de mi trabajo. Por lo tanto, decidí hacer un downgrade de Firefox y esperar por una mejor solución al instalar marionette.

En sistemas operativos como OSX o Windows se puede desactivar las actualizaciones fácilmente mediante las opciones de configuración de Firefox. Por lo tanto, ahora compartiré la solución que utilicé para Ubuntu. Dicha solución es la siguiente:

1. Abrir un terminal.

2. Después debes correr este comando para instalar la versión 45 de Firefox:
sudo apt-get install firefox=45.0.2+build1-0ubuntu1
Nota: Puede que el sistema te advierta de que se llevará a cabo un downgrade, da tu consentimiento para continuar. 3. Para mantener la versión de Firefox sin permitir updates, se debe usar este comando:
sudo apt-mark hold firefox
Nota: Esto excluirá Firefox de cualquier actualización. Si quieres remover este cambio, es decir, volver a aceptar actualizaciones en Firefox, utiliza estos comandos para revertir el estado actual.
sudo apt-mark unhold firefox
sudo apt-get upgrade
Conclusión. Con estos cambios Firefox no volverá a ser actualizado, por lo cual podremos continuar usando sin problemas webdriver con Firefox, mientras esperamos por una versión más madura de marionette.

Como activar el comando python en el CMD de windows 10.

Un problema bastante común para los novatos de python que usan windows 10 es correr scripts en la linea de comando. Generalmente este proble...