Implementación del proceso de carga de un archivo desde un contenedor con un navegador a un marco de prueba

Automatización de las pruebas End-2-End de un sistema de información integrado
Parte 2-2. Implementación del proceso de carga de un archivo desde un contenedor con un navegador a un marco de prueba. Busque el nombre del archivo descargado por el navegador


Autor: habr.com/us/users/anrad
Hubs:
Etiquetas: #autotest, #selenium, #selenoid, #headlessbrowser, #download


Cuando estábamos desarrollando las pruebas automáticas End-2-End para la interfaz de usuario, nos enfrentamos a la pregunta "Cómo obtener el nombre de la última carga ¿navegador de archivos de WebDriver? ", Google no obtuvo nada rápidamente. Por lo tanto, escribí este artículo, que al mismo tiempo decía qué teníamos exactamente un problema y cómo lo solucionamos.

Con este artículo, continuamos una serie de publicaciones sobre cómo automatizamos el proceso de pruebas manuales (en lo sucesivo denominadas pruebas automáticas) de un gran sistema de información (en adelante, Sistemas) en uno de los principales proyectos de LANIT y lo que surgió de él.

imagen
fuente


El artículo en sí completa el ciclo, a continuación hay un enlace a todas las partes anteriores:
Parte 1. Organizacional y gerencial. ¿Por qué necesitamos automatización? Organización del proceso de desarrollo y gestión. Organización de uso
Parte 2. Técnica. Arquitectura y pila técnica. Detalles de implementación y sorpresas técnicas
Parte 2-1. Implementación de clase base para todas las pruebas y JUnit RuleChain,

eso fue hace un año. Así que hoy puede no ser relevante. Escriba en los comentarios si sabe qué manera eficiente de procesar archivos con múltiples servidores de cuadrícula selenoide.

Al desarrollar las "pruebas automáticas", teníamos la tarea de descargar (descargar) archivos del sistema con un análisis posterior de sus contenidos. Para "cargar" archivos del sistema probado, utilizamos las siguientes soluciones:
  • para el modo de inicio "local" (se inicia directamente en la PC en funcionamiento): cuando se inicializa el navegador "local", el nombre de la carpeta local temporal se le pasa como un parámetro. A continuación, el archivo se lee directamente desde la carpeta local para su posterior análisis;
  • para el modo "remoto" (a través de Bamboo): el archivo fue "tomado" del contenedor con el navegador a través de la función del servidor de solenoide: selenoid-host.example.com : 4444 / download / {SESSION_ID} / {FILE_NAME}


Los detalles se describen en la documentación.

Para ambos modos, para acceder al archivo, tenía que saber su nombre. Esto fue una sorpresa. El problema de la falta de datos sobre el nombre del archivo de "descarga" fue el siguiente:
  • después de "hacer clic" en el botón "descargar archivo", el navegador descargó el archivo a la carpeta local correspondiente en el contenedor;
  • en este caso, el nombre del archivo se formó dinámicamente y, cómo determinarlo por adelantado, no pudimos encontrarlo. Esta fue una característica de nuestro sistema de prueba;
  • Además, este archivo debe "extraerse" del contenedor y debe llevarse a cabo la verificación comercial de su contenido;
  • para "extraer" el archivo, debe conocer su nombre, pero no lo sabíamos, ya que el nombre se generó dinámicamente y no había ningún valor en el enlace.


Además, la situación se agravó por el hecho de que, debido a la gran complejidad de algunas pruebas, varios archivos podrían descargarse durante la prueba como parte de diferentes scripts de prueba independientes de la composición de la prueba misma.
La mejor solución para nosotros fue el método en el que determinamos el último archivo descargado. Había varias formas de hacer esto:
  • . . , ;
  • Google Chrome javascript chrome://downloads/, html-. .




Analizar la composición de los archivos cargados por el navegador para el modo local es una tarea trivial.
Para el modo remoto, debe usar la función "no documentada" del servidor selenoid: selenoid-host.example.com : 4444 / download / {SESSION_ID} muestra una lista de todos los archivos descargados con éxito, donde SESSION_ID es una ID de sesión selenoide
En general, el esquema funciona bien con una excepción: nosotros Debe esperar un momento hasta que el archivo se descargue y aparezca en la lista. La espera se puede establecer a través de un ciclo de tiempo de espera, sin embargo, de esta manera no podemos obtener información sobre un posible error de carga de archivos. Solo podemos determinar que el archivo no se cargó en este circuito. Por lo tanto, al final, nos decidimos por el método para determinar el nombre del archivo a través de chrome: // downloads / page.

Obtener el nombre del archivo a través de Chrome: // descargas / página


Este método funciona igualmente bien en modo local y remoto. El esquema de trabajo es bastante simple:
  • Ejecute Java Script para abrir la ventana de Chrome: // Downloads /;
  • procesar datos en la ventana de la forma habitual. Espere hasta que se cargue el primer archivo de la lista y determine su nombre;
  • cierre la ventana chrome: // downloads / y devuelva el nombre del archivo que está buscando.


Buscamos en Google la idea de usar chrome: // downloads / y, a mi pesar, no puedo proporcionar un enlace a la fuente, ya que no estaba conservado. La implementación real de la clase para obtener el nombre del archivo se proporciona a continuación.

Clase para obtener el nombre del archivo descargado a través de Chrome: // descargas /
	private static final long DOWNLOADS_PAGE_LOAD_TIMEOUT = 5_000;
	private static final long MAX_GET_FILE_NAME_ATTEMPT = 5;
 
	public static String getLastDownloadedFilename() throws DownloaderException {
        String[] filename = new String[1];
        Exception[] ex = new Exception[1];
        WebDriver driver = WebDriverRunner.getWebDriver();
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        Utils.driver.openNewTabCheckAndClose(
                () -> {
                    executor.executeScript("window.open('','_blank');");
                },
                () -> {
                    driver.get("chrome://downloads/");
 
                    for (int i = 0; i < MAX_GET_FILE_NAME_ATTEMPT; i++) {
                    	ex[0] = null;
                        sleep();
                    	try {
                        	WebElement element = (WebElement) executor.executeScript(
                                    "return document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.getElementById('file-link')");
                        	filename[0] = element.getText();
                            LOGGER.info("Attempt get file name " + i + ". Name = '" + filename[0] + "'");
                    	} catch (WebDriverException e) {
                        	ex[0] = e;
                            LOGGER.info("Failed attempt "+ i + " to get filename text: " + e.getMessage());
                        	continue;
                    	}
                    	if (filename[0] != null && !filename[0].isEmpty()) {
                        	 //             
                         	executor.executeScript(
                                    "document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.getElementById('remove').click()");
                        	break;
                    	}
                    }
                }
    	);
 
    	if (filename[0] != null && !filename[0].isEmpty()) {
            return filename[0];
    	}
 
    	String message = "Timeout. Can not get last downloaded file name from chrome://downloads/. File name is '" + filename[0] + "'. Exception: " + ex[0].getMessage();
        LOGGER.warning(message);
    	throw new DownloaderException(message, ex[0]);
	}

All Articles