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 PlusTrabajar con inputs, textareas y checkboxes
Los formularios web constituyen uno de los elementos más frecuentes en las aplicaciones modernas, y su correcta automatización resulta fundamental para garantizar la calidad del software. Selenium WebDriver proporciona métodos específicos para interactuar con diferentes tipos de campos de entrada, desde inputs básicos hasta elementos más complejos como checkboxes y radio buttons.
La interacción con campos de texto sigue patrones consistentes que permiten simular el comportamiento real del usuario. Los métodos principales incluyen sendKeys()
para introducir texto, clear()
para limpiar el contenido existente, y getText()
o getAttribute("value")
para recuperar valores.
Interacción con campos de entrada de texto
Los campos de entrada (<input>
) representan la forma más común de captura de datos en formularios web. Selenium maneja diferentes tipos de input de manera uniforme, adaptándose automáticamente a las características específicas de cada tipo.
@Test
void testInputFields() {
// Input de texto básico
WebElement nameField = driver.findElement(By.id("name"));
nameField.clear();
nameField.sendKeys("Juan Pérez");
// Input de email con validación HTML5
WebElement emailField = driver.findElement(By.name("email"));
emailField.sendKeys("juan.perez@empresa.com");
// Input de contraseña
WebElement passwordField = driver.findElement(By.id("password"));
passwordField.sendKeys("MiContraseña123!");
}
Los campos numéricos requieren consideraciones especiales, especialmente cuando el navegador aplica validaciones automáticas. Es recomendable enviar los valores como cadenas de texto para mantener compatibilidad entre diferentes navegadores.
@Test
void testNumericInputs() {
WebElement ageField = driver.findElement(By.id("age"));
ageField.clear();
ageField.sendKeys("25");
// Para campos con decimales
WebElement salaryField = driver.findElement(By.name("salary"));
salaryField.sendKeys("45000.50");
// Verificar que el valor se ha establecido correctamente
String enteredValue = ageField.getAttribute("value");
assertEquals("25", enteredValue);
}
Los campos de fecha presentan variabilidad según el navegador y la configuración regional. La aproximación más robusta consiste en utilizar el formato ISO (YYYY-MM-DD) y verificar que el valor se ha establecido correctamente.
@Test
void testDateInputs() {
WebElement birthDateField = driver.findElement(By.id("birthdate"));
// Formato ISO para máxima compatibilidad
birthDateField.sendKeys("1990-05-15");
// Alternativamente, para campos que no soportan type="date"
WebElement customDateField = driver.findElement(By.className("date-picker"));
customDateField.clear();
customDateField.sendKeys("15/05/1990");
}
Manejo de áreas de texto
Las áreas de texto (<textarea>
) permiten la entrada de contenido multilínea y requieren técnicas específicas para manejar saltos de línea y formato. El método sendKeys()
acepta caracteres especiales como \n
para representar saltos de línea.
@Test
void testTextareaHandling() {
WebElement commentArea = driver.findElement(By.id("comments"));
String multilineText = """
Este es un comentario de prueba
que abarca múltiples líneas
para verificar el comportamiento del textarea.
""";
commentArea.clear();
commentArea.sendKeys(multilineText);
// Verificar que el contenido se ha establecido
String actualContent = commentArea.getAttribute("value");
assertTrue(actualContent.contains("múltiples líneas"));
}
Para contenido extenso, es útil simular el comportamiento real del usuario combinando diferentes métodos de entrada. Esto incluye el uso de teclas especiales como Keys.TAB
para navegación entre campos.
@Test
void testAdvancedTextareaInteraction() {
WebElement descriptionArea = driver.findElement(By.name("description"));
// Simular escritura gradual con teclas especiales
descriptionArea.sendKeys("Descripción del producto:");
descriptionArea.sendKeys(Keys.ENTER, Keys.ENTER);
descriptionArea.sendKeys("- Característica 1");
descriptionArea.sendKeys(Keys.ENTER);
descriptionArea.sendKeys("- Característica 2");
// Seleccionar todo el texto y reemplazarlo
descriptionArea.sendKeys(Keys.CONTROL + "a");
descriptionArea.sendKeys("Nueva descripción completa");
}
Interacción con checkboxes y radio buttons
Los checkboxes representan opciones binarias que pueden estar seleccionadas o no. El método click()
alterna su estado, mientras que isSelected()
permite verificar el estado actual. Es fundamental comprobar el estado antes de hacer clic para evitar comportamientos inesperados.
@Test
void testCheckboxInteraction() {
WebElement termsCheckbox = driver.findElement(By.id("terms"));
WebElement newsletterCheckbox = driver.findElement(By.name("newsletter"));
// Verificar estado inicial
assertFalse(termsCheckbox.isSelected());
// Seleccionar checkbox si no está marcado
if (!termsCheckbox.isSelected()) {
termsCheckbox.click();
}
// Verificar que se ha seleccionado
assertTrue(termsCheckbox.isSelected());
// Manejar checkbox opcional
if (!newsletterCheckbox.isSelected()) {
newsletterCheckbox.click();
}
}
Los radio buttons funcionan en grupos donde solo una opción puede estar seleccionada simultáneamente. La estrategia consiste en localizar el grupo completo y seleccionar la opción deseada verificando que las demás se deseleccionen automáticamente.
@Test
void testRadioButtonGroups() {
// Localizar grupo de radio buttons por name
List<WebElement> genderOptions = driver.findElements(By.name("gender"));
// Seleccionar opción específica por valor
genderOptions.stream()
.filter(option -> "female".equals(option.getAttribute("value")))
.findFirst()
.ifPresent(WebElement::click);
// Verificar selección
WebElement selectedOption = genderOptions.stream()
.filter(WebElement::isSelected)
.findFirst()
.orElseThrow();
assertEquals("female", selectedOption.getAttribute("value"));
}
Para formularios complejos con múltiples grupos de radio buttons, es recomendable crear métodos auxiliares que encapsulen la lógica de selección y verificación.
@Test
void testMultipleRadioGroups() {
// Grupo de experiencia
selectRadioOption("experience", "senior");
// Grupo de modalidad de trabajo
selectRadioOption("work_mode", "remote");
// Verificar selecciones
assertTrue(isRadioSelected("experience", "senior"));
assertTrue(isRadioSelected("work_mode", "remote"));
}
private void selectRadioOption(String groupName, String value) {
driver.findElements(By.name(groupName)).stream()
.filter(option -> value.equals(option.getAttribute("value")))
.findFirst()
.ifPresent(WebElement::click);
}
private boolean isRadioSelected(String groupName, String value) {
return driver.findElements(By.name(groupName)).stream()
.filter(option -> value.equals(option.getAttribute("value")))
.findFirst()
.map(WebElement::isSelected)
.orElse(false);
}
La verificación de estado resulta crucial para asegurar la consistencia de los datos. Los checkboxes y radio buttons pueden cambiar su estado mediante JavaScript, por lo que es importante validar el estado después de cada interacción.
@Test
void testStateVerification() {
WebElement agreeCheckbox = driver.findElement(By.id("agree"));
WebElement disagreeCheckbox = driver.findElement(By.id("disagree"));
// Estado inicial
assertFalse(agreeCheckbox.isSelected());
assertFalse(disagreeCheckbox.isSelected());
// Seleccionar agree
agreeCheckbox.click();
// Verificar estados mutuamente excluyentes
assertTrue(agreeCheckbox.isSelected());
assertFalse(disagreeCheckbox.isSelected());
// Cambiar selección
disagreeCheckbox.click();
// Verificar nuevo estado
assertFalse(agreeCheckbox.isSelected());
assertTrue(disagreeCheckbox.isSelected());
}
Manejo de dropdowns y Select
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
Los elementos dropdown (<select>
) representan uno de los componentes más versátiles en formularios web, permitiendo a los usuarios elegir entre múltiples opciones de manera organizada. Selenium WebDriver proporciona la clase Select
especializada que encapsula toda la funcionalidad necesaria para interactuar con estos elementos de forma robusta y eficiente.
La clase Select de Selenium
La clase Select actúa como un wrapper que simplifica significativamente la interacción con elementos <select>
. Esta clase proporciona métodos específicos para seleccionar opciones por diferentes criterios y obtener información sobre el estado actual del dropdown.
@Test
void testBasicSelectUsage() {
WebElement countryDropdown = driver.findElement(By.id("country"));
Select countrySelect = new Select(countryDropdown);
// Verificar que es un dropdown válido
assertTrue(countrySelect.isMultiple() == false);
// Seleccionar por texto visible
countrySelect.selectByVisibleText("España");
// Verificar selección actual
WebElement selectedOption = countrySelect.getFirstSelectedOption();
assertEquals("España", selectedOption.getText());
}
Métodos de selección
La clase Select ofrece tres métodos principales para seleccionar opciones, cada uno optimizado para diferentes escenarios de uso. La elección del método apropiado depende de la información disponible y la estabilidad de los datos.
1 - Selección por texto visible:
@Test
void testSelectByVisibleText() {
Select departmentSelect = new Select(driver.findElement(By.name("department")));
// Selección exacta por texto
departmentSelect.selectByVisibleText("Recursos Humanos");
// Verificar que la opción correcta está seleccionada
String selectedText = departmentSelect.getFirstSelectedOption().getText();
assertEquals("Recursos Humanos", selectedText);
}
2 - Selección por valor del atributo:
@Test
void testSelectByValue() {
Select prioritySelect = new Select(driver.findElement(By.id("priority")));
// Seleccionar por valor del atributo value
prioritySelect.selectByValue("high");
// Verificar usando el atributo value
String selectedValue = prioritySelect.getFirstSelectedOption().getAttribute("value");
assertEquals("high", selectedValue);
}
3 - Selección por índice:
@Test
void testSelectByIndex() {
Select monthSelect = new Select(driver.findElement(By.id("birth_month")));
// Seleccionar el tercer elemento (índice 2)
monthSelect.selectByIndex(2);
// Verificar que el índice correcto está seleccionado
List<WebElement> allOptions = monthSelect.getOptions();
WebElement selectedOption = monthSelect.getFirstSelectedOption();
assertEquals(allOptions.get(2).getText(), selectedOption.getText());
}
Trabajar con opciones múltiples
Los elementos select múltiples permiten seleccionar varias opciones simultáneamente. La clase Select proporciona métodos específicos para manejar estas selecciones múltiples, incluyendo la capacidad de deseleccionar opciones específicas o todas las opciones.
@Test
void testMultipleSelectHandling() {
Select skillsSelect = new Select(driver.findElement(By.id("skills")));
// Verificar que soporta selección múltiple
assertTrue(skillsSelect.isMultiple());
// Seleccionar múltiples opciones
skillsSelect.selectByVisibleText("Java");
skillsSelect.selectByVisibleText("Python");
skillsSelect.selectByValue("javascript");
// Obtener todas las opciones seleccionadas
List<WebElement> selectedOptions = skillsSelect.getAllSelectedOptions();
assertEquals(3, selectedOptions.size());
// Verificar opciones específicas
List<String> selectedTexts = selectedOptions.stream()
.map(WebElement::getText)
.toList();
assertTrue(selectedTexts.contains("Java"));
assertTrue(selectedTexts.contains("Python"));
}
Métodos de deselección
Para elementos de selección múltiple, la clase Select proporciona métodos de deselección que permiten quitar opciones específicas o limpiar toda la selección. Estos métodos son especialmente útiles en formularios dinámicos donde las selecciones pueden cambiar durante la interacción.
@Test
void testDeselectMethods() {
Select categoriesSelect = new Select(driver.findElement(By.name("categories")));
// Seleccionar varias opciones inicialmente
categoriesSelect.selectByVisibleText("Tecnología");
categoriesSelect.selectByVisibleText("Ciencia");
categoriesSelect.selectByVisibleText("Deportes");
// Deseleccionar una opción específica por texto
categoriesSelect.deselectByVisibleText("Deportes");
// Deseleccionar por valor
categoriesSelect.deselectByValue("science");
// Verificar que solo queda una selección
List<WebElement> remainingSelected = categoriesSelect.getAllSelectedOptions();
assertEquals(1, remainingSelected.size());
assertEquals("Tecnología", remainingSelected.get(0).getText());
// Deseleccionar todas las opciones
categoriesSelect.deselectAll();
assertTrue(categoriesSelect.getAllSelectedOptions().isEmpty());
}
Obtención de información del dropdown
La clase Select permite extraer información completa sobre el estado y las opciones disponibles en un dropdown. Esta capacidad resulta fundamental para validaciones y verificaciones durante las pruebas automatizadas.
@Test
void testDropdownInformation() {
Select statusSelect = new Select(driver.findElement(By.id("status")));
// Obtener todas las opciones disponibles
List<WebElement> allOptions = statusSelect.getOptions();
// Verificar número total de opciones
assertTrue(allOptions.size() > 0);
// Extraer textos de todas las opciones
List<String> optionTexts = allOptions.stream()
.map(WebElement::getText)
.filter(text -> !text.isEmpty())
.toList();
// Verificar que contiene opciones esperadas
assertTrue(optionTexts.contains("Activo"));
assertTrue(optionTexts.contains("Inactivo"));
// Obtener valores de los atributos
List<String> optionValues = allOptions.stream()
.map(option -> option.getAttribute("value"))
.filter(value -> value != null && !value.isEmpty())
.toList();
assertFalse(optionValues.isEmpty());
}
Manejo de dropdowns dinámicos
Los dropdowns dinámicos que cargan opciones mediante JavaScript requieren técnicas específicas para asegurar que las opciones estén disponibles antes de intentar seleccionarlas. La combinación de esperas explícitas con la clase Select proporciona una solución robusta.
@Test
void testDynamicDropdown() {
// Trigger que carga opciones dinámicamente
driver.findElement(By.id("load-cities")).click();
// Esperar a que el dropdown tenga opciones
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement cityDropdown = wait.until(driver -> {
WebElement dropdown = driver.findElement(By.id("city"));
Select select = new Select(dropdown);
return select.getOptions().size() > 1 ? dropdown : null;
});
Select citySelect = new Select(cityDropdown);
// Verificar que las opciones se han cargado
List<WebElement> options = citySelect.getOptions();
assertTrue(options.size() > 1); // Más que solo la opción por defecto
// Seleccionar una ciudad específica
citySelect.selectByVisibleText("Madrid");
assertEquals("Madrid", citySelect.getFirstSelectedOption().getText());
}
Validación y manejo de errores
La validación robusta de dropdowns incluye verificar que las opciones existen antes de intentar seleccionarlas, manejar casos donde las opciones pueden no estar disponibles, y proporcionar mensajes de error informativos.
@Test
void testDropdownValidation() {
Select regionSelect = new Select(driver.findElement(By.name("region")));
// Verificar que una opción específica existe antes de seleccionarla
boolean optionExists = regionSelect.getOptions().stream()
.anyMatch(option -> "Andalucía".equals(option.getText()));
if (optionExists) {
regionSelect.selectByVisibleText("Andalucía");
assertEquals("Andalucía", regionSelect.getFirstSelectedOption().getText());
} else {
fail("La opción 'Andalucía' no está disponible en el dropdown");
}
}
@Test
void testSafeDropdownSelection() {
Select languageSelect = new Select(driver.findElement(By.id("language")));
// Método seguro para seleccionar con fallback
String[] preferredLanguages = {"Español", "Spanish", "ES"};
boolean selected = Arrays.stream(preferredLanguages)
.anyMatch(lang -> {
try {
languageSelect.selectByVisibleText(lang);
return true;
} catch (NoSuchElementException e) {
return false;
}
});
assertTrue(selected, "No se pudo seleccionar ningún idioma de las opciones preferidas");
}
Dropdowns personalizados y no nativos
Muchas aplicaciones modernas utilizan dropdowns personalizados construidos con divs y JavaScript en lugar de elementos <select>
nativos. Para estos casos, es necesario utilizar métodos de interacción estándar de WebDriver sin la clase Select.
@Test
void testCustomDropdown() {
// Abrir dropdown personalizado
WebElement customDropdown = driver.findElement(By.className("custom-dropdown"));
customDropdown.click();
// Esperar a que aparezcan las opciones
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.className("dropdown-options")));
// Seleccionar opción específica
List<WebElement> options = driver.findElements(By.className("dropdown-option"));
options.stream()
.filter(option -> "Premium Plan".equals(option.getText()))
.findFirst()
.ifPresentOrElse(
WebElement::click,
() -> fail("Opción 'Premium Plan' no encontrada")
);
// Verificar selección
WebElement selectedDisplay = driver.findElement(By.className("selected-value"));
assertEquals("Premium Plan", selectedDisplay.getText());
}
Validación de formularios
La validación de formularios representa un aspecto crítico en las pruebas automatizadas, ya que garantiza que los datos introducidos por los usuarios cumplan con los criterios establecidos antes de ser procesados. Las aplicaciones web modernas implementan validaciones tanto en el lado del cliente como del servidor, y Selenium WebDriver permite verificar ambos niveles de validación de manera sistemática.
Validación de campos obligatorios
Los campos obligatorios constituyen la primera línea de validación en cualquier formulario. Selenium permite verificar que estos campos implementen las restricciones correctas y muestren los mensajes de error apropiados cuando permanecen vacíos.
@Test
void testRequiredFieldValidation() {
// Intentar enviar formulario con campos obligatorios vacíos
WebElement nameField = driver.findElement(By.id("name"));
WebElement emailField = driver.findElement(By.id("email"));
WebElement submitButton = driver.findElement(By.id("submit"));
// Dejar campos vacíos y enviar
submitButton.click();
// Verificar que el navegador previene el envío
String nameValidationMessage = nameField.getAttribute("validationMessage");
assertFalse(nameValidationMessage.isEmpty(),
"El campo nombre debería mostrar mensaje de validación");
// Verificar atributo required en HTML5
assertTrue(nameField.getAttribute("required") != null,
"El campo nombre debería tener atributo required");
}
La validación HTML5 proporciona mecanismos nativos que los navegadores interpretan automáticamente. Es fundamental verificar que estos atributos estén correctamente configurados y que los mensajes de validación se muestren según las expectativas.
@Test
void testHTML5ValidationAttributes() {
WebElement emailField = driver.findElement(By.id("email"));
WebElement phoneField = driver.findElement(By.id("phone"));
// Verificar tipos de input específicos
assertEquals("email", emailField.getAttribute("type"));
assertEquals("tel", phoneField.getAttribute("type"));
// Introducir datos inválidos
emailField.sendKeys("correo-invalido");
phoneField.sendKeys("123abc");
driver.findElement(By.id("submit")).click();
// Verificar mensajes de validación del navegador
String emailValidation = emailField.getAttribute("validationMessage");
assertTrue(emailValidation.contains("@") || emailValidation.contains("email"),
"Debería mostrar mensaje de formato de email inválido");
}
Validación de mensajes de error personalizados
Las validaciones personalizadas implementadas mediante JavaScript requieren técnicas específicas para verificar que los mensajes de error aparezcan correctamente y contengan la información apropiada para guiar al usuario.
@Test
void testCustomErrorMessages() {
WebElement passwordField = driver.findElement(By.id("password"));
WebElement confirmPasswordField = driver.findElement(By.id("confirm-password"));
// Introducir contraseñas que no coinciden
passwordField.sendKeys("MiContraseña123");
confirmPasswordField.sendKeys("OtraContraseña456");
driver.findElement(By.id("submit")).click();
// Buscar mensaje de error específico
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
WebElement errorMessage = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.className("password-error")));
String errorText = errorMessage.getText();
assertTrue(errorText.toLowerCase().contains("contraseñas no coinciden") ||
errorText.toLowerCase().contains("passwords do not match"),
"Mensaje de error debe indicar que las contraseñas no coinciden");
}
La verificación de múltiples errores requiere estrategias para manejar formularios complejos donde varios campos pueden fallar simultáneamente. Es importante verificar que todos los errores se muestren de manera coherente.
@Test
void testMultipleValidationErrors() {
// Completar formulario con múltiples errores
driver.findElement(By.id("name")).sendKeys("AB"); // Muy corto
driver.findElement(By.id("email")).sendKeys("email-invalido"); // Sin @
driver.findElement(By.id("age")).sendKeys("15"); // Menor de edad
driver.findElement(By.id("submit")).click();
// Recopilar todos los mensajes de error
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
List<WebElement> errorElements = wait.until(driver -> {
List<WebElement> errors = driver.findElements(By.className("error-message"));
return errors.size() >= 3 ? errors : null;
});
// Verificar que se muestran errores para cada campo problemático
List<String> errorMessages = errorElements.stream()
.map(WebElement::getText)
.filter(text -> !text.isEmpty())
.toList();
assertTrue(errorMessages.size() >= 3,
"Deberían mostrarse al menos 3 mensajes de error");
// Verificar contenido específico de errores
String allErrors = String.join(" ", errorMessages).toLowerCase();
assertTrue(allErrors.contains("nombre") || allErrors.contains("name"));
assertTrue(allErrors.contains("email") || allErrors.contains("correo"));
assertTrue(allErrors.contains("edad") || allErrors.contains("age"));
}
Validación client-side vs server-side
Las validaciones del lado del cliente proporcionan retroalimentación inmediata al usuario, mientras que las validaciones del servidor garantizan la integridad de los datos. Es crucial probar ambos niveles para asegurar una experiencia de usuario completa y datos seguros.
@Test
void testClientSideValidation() {
WebElement usernameField = driver.findElement(By.id("username"));
// Introducir un nombre de usuario que debería ser validado en tiempo real
usernameField.sendKeys("us");
// Cambiar foco para activar validación
driver.findElement(By.id("email")).click();
// Verificar mensaje de validación inmediata
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
WebElement clientError = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.className("username-hint")));
String hintText = clientError.getText();
assertTrue(hintText.contains("mínimo") || hintText.contains("minimum"),
"Debería mostrar mensaje sobre longitud mínima");
// Corregir y verificar que el mensaje desaparece
usernameField.clear();
usernameField.sendKeys("usuario_valido");
wait.until(ExpectedConditions.invisibilityOf(clientError));
}
Las validaciones del servidor requieren que el formulario se envíe para ser procesadas. Estas validaciones son fundamentales para verificar reglas de negocio complejas y restricciones de integridad de datos.
@Test
void testServerSideValidation() {
// Completar formulario con datos que pasen validación client-side
// pero fallen en server-side (ej: email ya registrado)
driver.findElement(By.id("name")).sendKeys("Juan Pérez");
driver.findElement(By.id("email")).sendKeys("juan.existente@empresa.com");
driver.findElement(By.id("password")).sendKeys("ContraseñaSegura123!");
driver.findElement(By.id("submit")).click();
// Esperar respuesta del servidor
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Verificar que se muestra error del servidor
WebElement serverError = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.className("server-error")));
String errorText = serverError.getText();
assertTrue(errorText.toLowerCase().contains("ya existe") ||
errorText.toLowerCase().contains("already exists"),
"Debería mostrar mensaje de email ya registrado");
// Verificar que el formulario no se ha enviado exitosamente
assertFalse(driver.getCurrentUrl().contains("success"),
"No debería redirigir a página de éxito");
}
Validación de formatos específicos
Los formatos de datos requieren validaciones específicas que verifiquen patrones como números de teléfono, códigos postales, o identificadores únicos. Estas validaciones pueden implementarse tanto en cliente como en servidor.
@Test
void testFormatValidations() {
WebElement phoneField = driver.findElement(By.id("phone"));
WebElement postalCodeField = driver.findElement(By.id("postal-code"));
// Probar formato de teléfono inválido
phoneField.sendKeys("123");
driver.findElement(By.id("submit")).click();
// Verificar mensaje de formato
WebElement phoneError = driver.findElement(By.className("phone-error"));
assertTrue(phoneError.isDisplayed());
// Corregir formato
phoneField.clear();
phoneField.sendKeys("612-345-678");
// Probar código postal inválido
postalCodeField.sendKeys("1234"); // Formato español requiere 5 dígitos
driver.findElement(By.id("submit")).click();
WebElement postalError = driver.findElement(By.className("postal-error"));
assertTrue(postalError.isDisplayed());
// Corregir y verificar
postalCodeField.clear();
postalCodeField.sendKeys("28001");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.invisibilityOf(postalError));
}
Envío exitoso de formularios completos
La validación de envío exitoso requiere verificar que todos los campos pasen las validaciones y que el formulario se procese correctamente, incluyendo redirecciones, mensajes de confirmación, o cambios en el estado de la aplicación.
@Test
void testSuccessfulFormSubmission() {
// Completar formulario con todos los datos válidos
driver.findElement(By.id("name")).sendKeys("María García");
driver.findElement(By.id("email")).sendKeys("maria.garcia@nuevo.com");
Select countrySelect = new Select(driver.findElement(By.id("country")));
countrySelect.selectByVisibleText("España");
driver.findElement(By.id("phone")).sendKeys("654-321-987");
driver.findElement(By.id("terms")).click(); // Aceptar términos
WebElement submitButton = driver.findElement(By.id("submit"));
submitButton.click();
// Verificar envío exitoso mediante múltiples indicadores
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Opción 1: Redirección a página de éxito
wait.until(driver -> driver.getCurrentUrl().contains("success") ||
driver.getCurrentUrl().contains("confirmation"));
// Opción 2: Mensaje de confirmación en la misma página
try {
WebElement successMessage = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.className("success-message")));
assertTrue(successMessage.getText().toLowerCase().contains("éxito") ||
successMessage.getText().toLowerCase().contains("success"));
} catch (TimeoutException e) {
// Si no hay mensaje, verificar por URL
assertTrue(driver.getCurrentUrl().contains("success"),
"Debería haber redirigido a página de éxito o mostrado mensaje de confirmación");
}
}
Validación de formularios dinámicos
Los formularios dinámicos que cambian su estructura según las selecciones del usuario requieren estrategias de validación adaptativas que consideren los diferentes estados posibles del formulario.
@Test
void testDynamicFormValidation() {
// Seleccionar tipo de usuario que muestra campos adicionales
Select userTypeSelect = new Select(driver.findElement(By.id("user-type")));
userTypeSelect.selectByVisibleText("Empresa");
// Esperar a que aparezcan campos adicionales
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
WebElement companyField = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.id("company-name")));
WebElement taxIdField = driver.findElement(By.id("tax-id"));
// Completar campos básicos pero dejar campos de empresa vacíos
driver.findElement(By.id("name")).sendKeys("Representante Legal");
driver.findElement(By.id("email")).sendKeys("representante@empresa.com");
driver.findElement(By.id("submit")).click();
// Verificar que se validan los campos dinámicos
WebElement companyError = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.className("company-error")));
assertTrue(companyError.isDisplayed(),
"Debería mostrar error para campo de empresa obligatorio");
// Completar campos dinámicos
companyField.sendKeys("Empresa Ejemplo S.L.");
taxIdField.sendKeys("B12345678");
driver.findElement(By.id("submit")).click();
// Verificar envío exitoso con campos dinámicos
wait.until(driver -> driver.getCurrentUrl().contains("success"));
}
Verificación de estado de formulario
La verificación del estado del formulario incluye comprobar que los campos mantengan su estado durante la validación, que los datos no se pierdan al mostrar errores, y que la experiencia del usuario sea consistente.
@Test
void testFormStatePreservation() {
String originalName = "Juan Pérez";
String originalEmail = "juan@empresa.com";
String invalidEmail = "email-invalido";
// Completar formulario parcialmente con un error
driver.findElement(By.id("name")).sendKeys(originalName);
driver.findElement(By.id("email")).sendKeys(invalidEmail);
driver.findElement(By.id("phone")).sendKeys(""); // Campo obligatorio vacío
driver.findElement(By.id("submit")).click();
// Verificar que los datos válidos se mantienen
WebElement nameField = driver.findElement(By.id("name"));
WebElement emailField = driver.findElement(By.id("email"));
assertEquals(originalName, nameField.getAttribute("value"),
"El nombre válido debería mantenerse después del error");
assertEquals(invalidEmail, emailField.getAttribute("value"),
"El email inválido debería mantenerse para que el usuario lo corrija");
// Corregir errores
emailField.clear();
emailField.sendKeys(originalEmail);
driver.findElement(By.id("phone")).sendKeys("612-345-678");
driver.findElement(By.id("submit")).click();
// Verificar envío exitoso
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(driver -> driver.getCurrentUrl().contains("success"));
}
Aprendizajes de esta lección de Selenium
- Comprender cómo interactuar con diferentes tipos de campos de formulario como inputs, textareas, checkboxes y radio buttons.
- Aprender a utilizar la clase Select para manejar dropdowns nativos y personalizados.
- Conocer técnicas para validar formularios, incluyendo campos obligatorios, mensajes de error personalizados y validaciones HTML5.
- Diferenciar y probar validaciones del lado del cliente y del servidor.
- Implementar estrategias para manejar formularios dinámicos y verificar el estado del formulario tras validaciones.
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