Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusUpload de archivos con sendKeys()
El upload de archivos en aplicaciones web es una funcionalidad crítica que requiere un manejo específico en las pruebas automatizadas. Selenium WebDriver proporciona un mecanismo directo y eficiente para manejar esta interacción a través del método sendKeys()
aplicado a elementos <input type="file">
.
A diferencia de otros elementos web que requieren clics o interacciones complejas, los campos de archivo funcionan de manera especial: no necesitamos abrir el explorador de archivos del sistema operativo, sino que podemos enviar directamente la ruta del archivo al elemento input correspondiente.
Mecánica básica del upload
La implementación fundamental del upload se basa en localizar el elemento input de tipo file y utilizar sendKeys()
con la ruta absoluta del archivo:
@Test
void deberiaSubirArchivoBasico() {
WebElement inputArchivo = driver.findElement(By.id("archivo"));
String rutaArchivo = Paths.get("src/test/resources/documento.pdf")
.toAbsolutePath()
.toString();
inputArchivo.sendKeys(rutaArchivo);
// Verificar que el archivo se ha seleccionado
String valorInput = inputArchivo.getAttribute("value");
assertTrue(valorInput.contains("documento.pdf"));
}
Es fundamental utilizar rutas absolutas ya que Selenium requiere la ubicación completa del archivo en el sistema de archivos. La clase Paths
de Java proporciona una forma moderna y multiplataforma de construir estas rutas.
Validación de tipos de archivo
Las aplicaciones web frecuentemente restringen los tipos de archivo que pueden subirse. Podemos implementar validaciones previas en nuestros tests para simular estos escenarios:
@Test
void deberiaValidarTipoArchivoPermitido() {
WebElement inputArchivo = driver.findElement(By.cssSelector("input[accept='.pdf,.doc,.docx']"));
var archivosValidos = List.of(
"documento.pdf",
"reporte.doc",
"presentacion.docx"
);
archivosValidos.forEach(nombreArchivo -> {
String ruta = obtenerRutaArchivoTest(nombreArchivo);
inputArchivo.clear();
inputArchivo.sendKeys(ruta);
// Validar que no aparece mensaje de error
assertTrue(driver.findElements(By.className("error-tipo-archivo")).isEmpty());
});
}
private String obtenerRutaArchivoTest(String nombreArchivo) {
return Paths.get("src/test/resources/archivos-test", nombreArchivo)
.toAbsolutePath()
.toString();
}
Upload múltiple de archivos
Cuando el elemento input tiene el atributo multiple
, podemos subir varios archivos simultáneamente separando las rutas con el carácter de nueva línea (\n
):
@Test
void deberiaSubirMultiplesArchivos() {
WebElement inputMultiple = driver.findElement(By.cssSelector("input[type='file'][multiple]"));
var rutasArchivos = Stream.of("imagen1.jpg", "imagen2.png", "documento.pdf")
.map(this::obtenerRutaArchivoTest)
.collect(Collectors.joining("\n"));
inputMultiple.sendKeys(rutasArchivos);
// Verificar que se han seleccionado múltiples archivos
String valor = inputMultiple.getAttribute("value");
long cantidadArchivos = valor.chars()
.filter(ch -> ch == '\\' || ch == '/')
.count();
assertTrue(cantidadArchivos >= 3);
}
Manejo de elementos ocultos
Muchas implementaciones modernas ocultan el input de archivo real y muestran botones personalizados. En estos casos, necesitamos interactuar directamente con el elemento input subyacente:
@Test
void deberiaSubirArchivoConInputOculto() {
// El input real está oculto con display: none o visibility: hidden
WebElement inputOculto = driver.findElement(By.id("archivo-oculto"));
// Usar JavaScript para hacer visible temporalmente el elemento si es necesario
if (!inputOculto.isDisplayed()) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].style.display = 'block';", inputOculto);
}
String rutaArchivo = obtenerRutaArchivoTest("imagen.jpg");
inputOculto.sendKeys(rutaArchivo);
// Verificar que el nombre del archivo aparece en la interfaz
WebElement nombreArchivo = driver.findElement(By.className("nombre-archivo-seleccionado"));
assertEquals("imagen.jpg", nombreArchivo.getText());
}
Validación de restricciones de tamaño
Las limitaciones de tamaño son comunes en uploads. Podemos crear archivos de test de diferentes tamaños para validar estas restricciones:
@Test
void deberiaRechazarArchivoDemasiadoGrande() throws IOException {
// Crear archivo temporal de prueba con tamaño específico
Path archivoGrande = crearArchivoTemporal("archivo-grande.txt", 10 * 1024 * 1024); // 10MB
WebElement inputArchivo = driver.findElement(By.id("archivo-limitado"));
inputArchivo.sendKeys(archivoGrande.toString());
// Intentar enviar el formulario
driver.findElement(By.id("btn-enviar")).click();
// Verificar mensaje de error por tamaño excedido
WebElement mensajeError = driver.findElement(By.className("error-tamaño"));
assertTrue(mensajeError.getText().contains("demasiado grande"));
// Limpiar archivo temporal
Files.deleteIfExists(archivoGrande);
}
private Path crearArchivoTemporal(String nombre, long tamaño) throws IOException {
Path archivo = Paths.get(System.getProperty("java.io.tmpdir"), nombre);
try (var canal = FileChannel.open(archivo, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
canal.truncate(tamaño);
}
return archivo;
}
Esperas y sincronización
Los uploads pueden requerir tiempo para procesarse, especialmente con archivos grandes. Es importante implementar esperas adecuadas:
@Test
void deberiaEsperarProcesamientoUpload() {
WebElement inputArchivo = driver.findElement(By.id("archivo"));
String rutaArchivo = obtenerRutaArchivoTest("documento-grande.pdf");
inputArchivo.sendKeys(rutaArchivo);
driver.findElement(By.id("btn-subir")).click();
// Esperar hasta que desaparezca el indicador de carga
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("cargando")));
// Verificar mensaje de éxito
WebElement mensajeExito = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.className("upload-exitoso"))
);
assertTrue(mensajeExito.isDisplayed());
}
La gestión eficiente de uploads requiere considerar aspectos como la ubicación de archivos de test, el manejo de rutas multiplataforma y la validación tanto de éxitos como de fallos esperados en el proceso de subida.
Downloads automáticos y configuración de carpetas
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
El manejo de descargas en pruebas automatizadas presenta desafíos únicos que requieren configuración específica del navegador para evitar ventanas emergentes y dirigir archivos a ubicaciones predecibles. Selenium WebDriver permite configurar tanto Chrome como Firefox para realizar descargas automáticas sin intervención del usuario.
La configuración de descargas debe establecerse antes de inicializar el WebDriver, modificando las opciones del navegador para controlar el comportamiento de descarga por defecto.
Configuración de Chrome para descargas automáticas
Chrome requiere configuración específica de preferencias para manejar descargas automáticas y establecer carpetas de destino personalizadas:
@BeforeEach
void configurarNavegadorParaDescargas() {
String carpetaDescarga = Paths.get("target/downloads-test")
.toAbsolutePath()
.toString();
// Crear carpeta si no existe
crearCarpetaDescarga(carpetaDescarga);
ChromeOptions opciones = new ChromeOptions();
// Configurar preferencias para descargas automáticas
Map<String, Object> preferencias = Map.of(
"download.default_directory", carpetaDescarga,
"download.prompt_for_download", false,
"download.directory_upgrade", true,
"safebrowsing.enabled", true
);
opciones.setExperimentalOption("prefs", preferencias);
driver = new ChromeDriver(opciones);
}
Configuración avanzada de tipos MIME
Para controlar tipos específicos de archivo, podemos configurar el comportamiento de descarga para diferentes tipos MIME:
private ChromeOptions configurarTiposMimeChrome(String carpetaDescarga) {
ChromeOptions opciones = new ChromeOptions();
Map<String, Object> preferencias = Map.of(
"download.default_directory", carpetaDescarga,
"download.prompt_for_download", false,
"plugins.always_open_pdf_externally", true, // PDFs se descargan en lugar de abrirse
"profile.default_content_settings.popups", 0,
"profile.default_content_setting_values.automatic_downloads", 1
);
opciones.setExperimentalOption("prefs", preferencias);
return opciones;
}
Configuración de Firefox para descargas
Firefox utiliza un sistema de preferencias diferente pero igualmente efectivo para controlar las descargas automáticas:
@Test
void configurarFirefoxParaDescargas() {
String carpetaDescarga = Paths.get("target/downloads-firefox")
.toAbsolutePath()
.toString();
FirefoxOptions opciones = new FirefoxOptions();
FirefoxProfile perfil = new FirefoxProfile();
// Configurar carpeta de descarga
perfil.setPreference("browser.download.dir", carpetaDescarga);
perfil.setPreference("browser.download.folderList", 2); // 2 = carpeta personalizada
// Desactivar ventanas emergentes de descarga
perfil.setPreference("browser.download.useDownloadDir", true);
perfil.setPreference("browser.helperApps.neverAsk.saveToDisk",
"application/pdf,text/csv,application/vnd.ms-excel,application/zip");
// Deshabilitar vista previa de PDFs
perfil.setPreference("pdfjs.disabled", true);
opciones.setProfile(perfil);
driver = new FirefoxDriver(opciones);
}
Manejo de múltiples tipos de archivo
Las aplicaciones web modernas ofrecen diversos formatos de descarga. Podemos configurar el navegador para manejar automáticamente los tipos más comunes:
private void configurarTiposArchivoFirefox(FirefoxProfile perfil) {
var tiposMime = List.of(
"application/pdf",
"text/csv",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/zip",
"image/jpeg",
"image/png"
);
String tiposUnidos = String.join(",", tiposMime);
perfil.setPreference("browser.helperApps.neverAsk.saveToDisk", tiposUnidos);
perfil.setPreference("browser.download.manager.showWhenStarting", false);
}
Configuración de descargas con timeout personalizado
Para archivos grandes o conexiones lentas, podemos ajustar los timeouts de descarga:
@Test
void configurarTimeoutDescarga() {
ChromeOptions opciones = new ChromeOptions();
Map<String, Object> preferencias = Map.of(
"download.default_directory", obtenerCarpetaDescarga(),
"download.prompt_for_download", false,
"profile.default_content_settings.popups", 0,
// Configurar timeout extendido (en milisegundos)
"download.extensions_to_open", "",
"safebrowsing_for_trusted_sources_enabled", false
);
opciones.setExperimentalOption("prefs", preferencias);
opciones.addArguments("--disable-popup-blocking");
driver = new ChromeDriver(opciones);
}
Configuración multiplataforma de carpetas
El manejo de rutas debe ser compatible con diferentes sistemas operativos:
private String configurarCarpetaDescargaMultiplataforma() {
String sistemaOperativo = System.getProperty("os.name").toLowerCase();
Path carpetaBase;
if (sistemaOperativo.contains("win")) {
carpetaBase = Paths.get(System.getProperty("user.home"), "Downloads", "selenium-test");
} else if (sistemaOperativo.contains("mac")) {
carpetaBase = Paths.get(System.getProperty("user.home"), "Downloads", "selenium-test");
} else {
carpetaBase = Paths.get("/tmp", "selenium-downloads");
}
try {
Files.createDirectories(carpetaBase);
} catch (IOException e) {
throw new RuntimeException("No se pudo crear la carpeta de descargas: " + carpetaBase, e);
}
return carpetaBase.toString();
}
Configuración de Edge y Safari
Para navegadores adicionales, la configuración sigue patrones similares pero con APIs específicas:
private EdgeOptions configurarEdgeDescargas(String carpetaDescarga) {
EdgeOptions opciones = new EdgeOptions();
Map<String, Object> preferencias = Map.of(
"download.default_directory", carpetaDescarga,
"download.prompt_for_download", false,
"profile.default_content_settings.popups", 0
);
opciones.setExperimentalOption("prefs", preferencias);
opciones.addArguments("--disable-popup-blocking");
return opciones;
}
Configuración de seguridad y restricciones
Las políticas de seguridad modernas requieren configuración adicional para descargas automáticas:
private void configurarSeguridadDescargas(ChromeOptions opciones) {
opciones.addArguments(
"--disable-web-security",
"--allow-running-insecure-content",
"--disable-extensions",
"--no-sandbox",
"--disable-dev-shm-usage"
);
Map<String, Object> preferenciasSeguridad = Map.of(
"safebrowsing.enabled", false,
"safebrowsing.disable_download_protection", true,
"profile.default_content_setting_values.notifications", 2
);
opciones.setExperimentalOption("prefs", preferenciasSeguridad);
}
La configuración correcta del navegador es fundamental para pruebas de descarga robustas, eliminando la intervención manual y garantizando que los archivos se almacenen en ubicaciones predecibles para su posterior verificación.
Verificación de archivos descargados
La verificación de archivos descargados constituye una fase crítica en las pruebas automatizadas de descarga, ya que debemos confirmar no solo que el archivo existe, sino también que su contenido, tamaño y propiedades corresponden a lo esperado. Java moderno proporciona APIs robustas a través de Files
y Paths
que facilitan estas validaciones de forma elegante y eficiente.
La verificación debe abordar múltiples aspectos: existencia del archivo, integridad del contenido, propiedades de metadatos y limpieza posterior para mantener un entorno de pruebas limpio.
Verificación básica de existencia y espera
El primer paso consiste en confirmar que el archivo se ha descargado correctamente en la ubicación esperada, implementando esperas que consideren el tiempo de descarga:
@Test
void deberiaVerificarDescargaArchivoBasico() {
String nombreArchivo = "reporte-ventas.pdf";
Path rutaDescarga = Paths.get("target/downloads-test", nombreArchivo);
// Iniciar descarga
driver.findElement(By.linkText("Descargar Reporte")).click();
// Esperar hasta que el archivo exista
await().atMost(Duration.ofSeconds(30))
.pollInterval(Duration.ofMillis(500))
.until(() -> Files.exists(rutaDescarga));
// Verificaciones básicas
assertTrue(Files.exists(rutaDescarga), "El archivo no fue descargado");
assertTrue(Files.isRegularFile(rutaDescarga), "La ruta no corresponde a un archivo regular");
assertFalse(Files.isDirectory(rutaDescarga), "La ruta no debe ser un directorio");
}
Como puedes observar, se hace uso del método
await()
, que no es nativo de Selenium. El métodoawait()
proviene de la librería Awaitility, una biblioteca muy popular en Java, es un DSL (Domain Specific Language) que permite escribir esperas condicionales de forma más expresiva que los típicosThread.sleep()
o bucles while con timeouts manuales. Por lo que si quieres hacer uso de este tipo de esperas deberías agregarla al proyecto usando Maven o Gradle, ya que no viene incorporada en JUnit ni Selenium.
Validación de tamaño y completitud
La validación del tamaño ayuda a detectar descargas incompletas o archivos corruptos, especialmente importante para archivos grandes:
@Test
void deberiaValidarTamañoArchivoDescargado() throws IOException {
String nombreArchivo = "documento-grande.zip";
Path archivoDescargado = iniciarYEsperarDescarga(nombreArchivo);
// Obtener tamaño del archivo
long tamañoArchivo = Files.size(archivoDescargado);
// Validar tamaño mínimo esperado (ejemplo: 1MB)
long tamañoMinimo = 1024 * 1024;
assertTrue(tamañoArchivo >= tamañoMinimo,
String.format("Archivo muy pequeño: %d bytes (mínimo: %d)",
tamañoArchivo, tamañoMinimo));
// Validar tamaño máximo razonable (ejemplo: 50MB)
long tamañoMaximo = 50 * 1024 * 1024;
assertTrue(tamañoArchivo <= tamañoMaximo,
String.format("Archivo demasiado grande: %d bytes (máximo: %d)",
tamañoArchivo, tamañoMaximo));
}
private Path iniciarYEsperarDescarga(String nombreArchivo) {
Path rutaDescarga = Paths.get("target/downloads-test", nombreArchivo);
driver.findElement(By.id("btn-descarga-grande")).click();
await().atMost(Duration.ofMinutes(2))
.pollInterval(Duration.ofSeconds(2))
.until(() -> Files.exists(rutaDescarga) && esDescargaCompleta(rutaDescarga));
return rutaDescarga;
}
Verificación de contenido y tipos MIME
La validación del contenido permite confirmar que el archivo descargado contiene la información esperada y corresponde al tipo correcto:
@Test
void deberiaVerificarContenidoArchivoTexto() throws IOException {
Path archivoCSV = iniciarYEsperarDescarga("datos-exportados.csv");
// Verificar tipo MIME
String tipoMime = Files.probeContentType(archivoCSV);
assertEquals("text/csv", tipoMime, "Tipo MIME incorrecto");
// Leer y validar contenido
List<String> lineas = Files.readAllLines(archivoCSV, StandardCharsets.UTF_8);
assertFalse(lineas.isEmpty(), "El archivo CSV está vacío");
assertTrue(lineas.get(0).contains("Nombre,Apellido,Email"),
"Cabeceras CSV incorrectas");
// Validar que tiene al menos 10 registros de datos (excluyendo cabecera)
assertTrue(lineas.size() >= 11, "Insuficientes registros en el CSV");
// Verificar formato de líneas de datos
lineas.stream()
.skip(1) // Saltar cabecera
.limit(5) // Verificar solo las primeras 5 líneas
.forEach(linea -> {
String[] campos = linea.split(",");
assertEquals(3, campos.length, "Formato de línea CSV incorrecto: " + linea);
});
}
Validación de archivos binarios
Para archivos binarios como imágenes o PDFs, necesitamos estrategias de validación específicas:
@Test
void deberiaVerificarArchivoPDF() throws IOException {
Path archivoPDF = iniciarYEsperarDescarga("factura-123.pdf");
// Verificar firma de archivo PDF
byte[] primerosBytes = Files.readAllBytes(archivoPDF);
assertTrue(primerosBytes.length > 4, "Archivo demasiado pequeño para ser PDF");
// Los PDFs comienzan con %PDF
String inicioPDF = new String(Arrays.copyOf(primerosBytes, 4), StandardCharsets.US_ASCII);
assertEquals("%PDF", inicioPDF, "Firma de archivo PDF inválida");
// Verificar que termina correctamente
String finalArchivo = new String(Arrays.copyOfRange(primerosBytes,
Math.max(0, primerosBytes.length - 6),
primerosBytes.length), StandardCharsets.US_ASCII);
assertTrue(finalArchivo.contains("EOF"), "PDF no termina correctamente");
}
@Test
void deberiaVerificarArchivoImagen() throws IOException {
Path archivoImagen = iniciarYEsperarDescarga("grafico-ventas.png");
// Verificar firma PNG
byte[] firma = Files.readAllBytes(archivoImagen);
byte[] firmaPNG = {(byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
assertTrue(Arrays.equals(Arrays.copyOf(firma, 8), firmaPNG),
"Firma de archivo PNG inválida");
// Verificar tamaño mínimo para imagen válida
assertTrue(firma.length > 1000, "Imagen demasiado pequeña, posiblemente corrupta");
}
Manejo de timeouts y archivos grandes
Los archivos grandes requieren estrategias especiales de espera y validación progresiva:
@Test
void deberiaEsperarDescargaArchivoGrande() {
String nombreArchivo = "backup-completo.zip";
Path rutaDescarga = Paths.get("target/downloads-test", nombreArchivo);
driver.findElement(By.id("descargar-backup")).click();
// Espera con validación progresiva
await().atMost(Duration.ofMinutes(5))
.pollInterval(Duration.ofSeconds(5))
.until(() -> {
if (!Files.exists(rutaDescarga)) return false;
try {
long tamaño = Files.size(rutaDescarga);
// Verificar que el archivo sigue creciendo o ha alcanzado un tamaño mínimo
return tamaño > 10 * 1024 * 1024 && esDescargaCompleta(rutaDescarga);
} catch (IOException e) {
return false;
}
});
}
private boolean esDescargaCompleta(Path archivo) {
try {
long tamañoInicial = Files.size(archivo);
Thread.sleep(1000);
long tamañoFinal = Files.size(archivo);
// Si el tamaño no cambió en 1 segundo, probablemente la descarga terminó
return tamañoInicial == tamañoFinal;
} catch (IOException | InterruptedException e) {
return false;
}
}
Verificación de múltiples archivos
Cuando se descargan múltiples archivos simultáneamente, necesitamos validar cada uno individualmente:
@Test
void deberiaVerificarDescargaMultiplesArchivos() {
var archivosEsperados = List.of(
"informe-enero.pdf",
"informe-febrero.pdf",
"informe-marzo.pdf"
);
// Iniciar descarga múltiple
driver.findElement(By.id("descargar-trimestre")).click();
// Esperar a que todos los archivos se descarguen
archivosEsperados.parallelStream().forEach(nombreArchivo -> {
Path rutaArchivo = Paths.get("target/downloads-test", nombreArchivo);
await().atMost(Duration.ofMinutes(1))
.until(() -> Files.exists(rutaArchivo));
// Validaciones específicas por archivo
assertAll(
() -> assertTrue(Files.exists(rutaArchivo)),
() -> assertThat(obtenerTamañoArchivo(rutaArchivo)).isGreaterThan(1000L),
() -> assertEquals("application/pdf", Files.probeContentType(rutaArchivo))
);
});
}
Limpieza y gestión de archivos de test
La limpieza adecuada de archivos descargados es esencial para mantener un entorno de pruebas limpio:
@AfterEach
void limpiarArchivosDescargados() {
Path carpetaDescargas = Paths.get("target/downloads-test");
if (Files.exists(carpetaDescargas)) {
try (Stream<Path> archivos = Files.walk(carpetaDescargas)) {
archivos.sorted(Comparator.reverseOrder())
.forEach(path -> {
try {
Files.deleteIfExists(path);
} catch (IOException e) {
System.err.println("No se pudo eliminar: " + path);
}
});
} catch (IOException e) {
System.err.println("Error al limpiar carpeta de descargas: " + e.getMessage());
}
}
}
@Test
void deberiaLimpiarArchivosAntiguosDurantePrueba() throws IOException {
Path carpetaDescargas = Paths.get("target/downloads-test");
// Eliminar archivos anteriores a 1 hora
if (Files.exists(carpetaDescargas)) {
Instant hace1Hora = Instant.now().minus(1, ChronoUnit.HOURS);
try (Stream<Path> archivos = Files.list(carpetaDescargas)) {
archivos.filter(Files::isRegularFile)
.filter(archivo -> {
try {
return Files.getLastModifiedTime(archivo).toInstant().isBefore(hace1Hora);
} catch (IOException e) {
return false;
}
})
.forEach(archivo -> {
try {
Files.delete(archivo);
} catch (IOException e) {
System.err.println("No se pudo eliminar archivo antiguo: " + archivo);
}
});
}
}
}
Utilidades para validación de archivos
Crear métodos de utilidad reutilizables mejora la mantenibilidad de las pruebas de descarga:
public class ValidadorArchivos {
public static void validarArchivoDescargado(Path archivo, long tamañoMinimo, String tipoMimeEsperado) {
assertAll("Validaciones básicas de archivo",
() -> assertTrue(Files.exists(archivo), "El archivo no existe"),
() -> assertTrue(Files.isRegularFile(archivo), "No es un archivo regular"),
() -> assertThat(obtenerTamañoArchivo(archivo)).isGreaterThan(tamañoMinimo),
() -> assertEquals(tipoMimeEsperado, Files.probeContentType(archivo))
);
}
public static boolean esArchivoTextoValido(Path archivo, String contenidoEsperado) {
try {
String contenido = Files.readString(archivo, StandardCharsets.UTF_8);
return contenido.contains(contenidoEsperado) && !contenido.trim().isEmpty();
} catch (IOException e) {
return false;
}
}
private static long obtenerTamañoArchivo(Path archivo) {
try {
return Files.size(archivo);
} catch (IOException e) {
throw new RuntimeException("Error al obtener tamaño del archivo", e);
}
}
}
La verificación exhaustiva de archivos descargados garantiza que nuestras pruebas no solo confirmen la descarga, sino que validen la integridad y correctitud del contenido recibido, proporcionando confianza en el funcionamiento completo del proceso de descarga.
Aprendizajes de esta lección de Selenium
- Comprender cómo realizar uploads de archivos usando sendKeys() en elementos input de tipo file.
- Configurar navegadores para descargas automáticas y gestionar carpetas de destino.
- Validar la existencia, integridad y contenido de archivos descargados en pruebas automatizadas.
- Implementar esperas y sincronización para procesos de upload y download.
- Gestionar la limpieza y mantenimiento de archivos de prueba para entornos robustos.
Completa este curso de Selenium y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs