A4Q Selenium Tester Examen de práctica #1 — Preguntas y respuestas

Todas las preguntas de este examen de práctica, con la respuesta correcta marcada y una justificación escrita para cada opción a continuación — para leer y repasar, no una prueba cronometrada.

Pregunta 1

¿Cómo se comunica Selenium WebDriver con un navegador real como Chrome o Firefox?

A través de un driver específico del navegador usando el protocolo W3C WebDriver

Respuesta correcta

Correcto — la librería cliente habla con un driver (chromedriver/geckodriver) por HTTP y el driver controla el navegador.

Inyectando JavaScript, que es su única forma de control

Incorrecto — WebDriver puede ejecutar JavaScript, pero los comandos nativos pasan por el driver, no solo por JS inyectado.

Modificando directamente el código fuente del navegador en tiempo de ejecución

Incorrecto — WebDriver nunca edita el código fuente del navegador; lo automatiza a través de su driver.

Mediante captura de píxeles y simulación de clics a nivel de SO

Incorrecto — eso describe herramientas basadas en imagen; WebDriver usa la API de automatización del navegador vía el driver.

Por qué

WebDriver envía comandos mediante el protocolo W3C WebDriver (HTTP/JSON) a un ejecutable de driver específico del navegador (p. ej. chromedriver, geckodriver) que controla el navegador.

Pregunta 2

¿Qué ocurre cuando se llama a driver.findElement(By.id("login")) y no existe ningún elemento con ese id en la página?

Lanza una NoSuchElementException

Respuesta correcta

Correcto — findElement lanza NoSuchElementException cuando nada coincide.

Devuelve null

Incorrecto — findElement nunca devuelve null; lanza una excepción. findElements devuelve una lista vacía.

Devuelve un WebElement vacío

Incorrecto — no existe un 'WebElement vacío'; la llamada falla con una excepción.

Espera indefinidamente hasta que el elemento aparezca

Incorrecto — findElement no se bloquea indefinidamente; sin espera falla de inmediato.

Por qué

findElement lanza inmediatamente una NoSuchElementException cuando no encuentra un elemento coincidente.

Pregunta 3

¿Cómo se comporta driver.findElements(By.className("row")) cuando no hay elementos coincidentes?

Devuelve una lista vacía

Respuesta correcta

Correcto — findElements devuelve una lista de tamaño 0 cuando nada coincide.

Lanza una NoSuchElementException

Incorrecto — ese es el comportamiento de findElement; findElements no lanza con cero coincidencias.

Devuelve null

Incorrecto — devuelve una colección vacía, nunca null.

Por qué

findElements devuelve una lista vacía (tamaño 0) en lugar de lanzar excepción; es útil para comprobar la presencia.

Pregunta 4

¿Cuál es la diferencia entre driver.close() y driver.quit()?

close() cierra la ventana actual; quit() cierra todas las ventanas y finaliza la sesión

Respuesta correcta

Correcto — quit() también termina el proceso del driver y libera recursos.

Son alias idénticos de la misma operación

Incorrecto — difieren: close() afecta a una ventana, quit() a toda la sesión.

quit() cierra solo la pestaña activa; close() finaliza la sesión

Incorrecto — esto invierte ambos métodos.

close() borra cookies; quit() mantiene el navegador abierto

Incorrecto — ninguno trata de cookies y quit() no mantiene el navegador abierto.

Por qué

close() cierra la ventana/pestaña actual; quit() cierra todas las ventanas abiertas por esa sesión del driver y finaliza la sesión de WebDriver.

Pregunta 5

¿Cuáles de las siguientes son estrategias de localización integradas válidas de la clase By en Selenium WebDriver? (Elige dos.)

By.cssSelector

Respuesta correcta

Correcto — cssSelector es una estrategia By principal.

By.xpath

Respuesta correcta

Correcto — xpath es una estrategia By principal.

By.value

Incorrecto — no existe By.value; usa CSS o XPath para un valor de atributo.

By.placeholder

Incorrecto — placeholder no es una estrategia By; usa un selector de atributo CSS.

Por qué

Las estrategias By válidas incluyen id, name, className, tagName, linkText, partialLinkText, cssSelector y xpath. 'value' y 'placeholder' no son estrategias propias.

Pregunta 6

Necesita leer la etiqueta visible de un botón en una cadena. ¿Qué método de WebElement debe usar?

getText()

Respuesta correcta

Correcto — getText() devuelve el texto visible renderizado del elemento.

getAttribute("text")

Incorrecto — no existe un atributo estándar 'text'; usa getText() para el contenido visible.

getTagName()

Incorrecto — getTagName() devuelve la etiqueta HTML, no el texto del botón.

getCssValue("label")

Incorrecto — getCssValue lee propiedades CSS, no el texto del elemento.

Por qué

getText() devuelve el texto visible y renderizado de un elemento; getAttribute() lee el valor de un atributo HTML concreto.

Pregunta 7

Un campo <input> ya contiene el texto "abc". Llama a element.sendKeys("123"). ¿Cuál es el valor del campo después (sin otra acción)?

abc123

Respuesta correcta

Correcto — sendKeys añade, así que se conserva "abc" y se agrega "123".

123

Incorrecto — eso requeriría llamar antes a clear(); sendKeys por sí solo no borra.

123abc

Incorrecto — las teclas se añaden en el cursor (al final), no al principio.

Una cadena vacía

Incorrecto — sendKeys agrega texto, nunca vacía el campo.

Por qué

sendKeys añade al contenido existente; no limpia el campo. Para reemplazar, llama antes a clear().

Pregunta 8

¿Qué afirmación describe mejor la relación entre la interfaz WebDriver y una clase como ChromeDriver?

WebDriver es una interfaz que ChromeDriver implementa

Respuesta correcta

Correcto — programar contra la interfaz WebDriver mantiene las pruebas independientes del navegador.

ChromeDriver es una interfaz que WebDriver implementa

Incorrecto — invierte la relación; WebDriver es la interfaz.

Son clases no relacionadas, sin vínculo de herencia

Incorrecto — ChromeDriver implementa WebDriver, así que están relacionadas.

WebDriver es una subclase de ChromeDriver

Incorrecto — es al revés; ChromeDriver implementa la interfaz WebDriver.

Por qué

WebDriver es una interfaz; las clases específicas del navegador como ChromeDriver, FirefoxDriver y EdgeDriver la implementan, lo que permite escribir pruebas contra la interfaz.

Pregunta 9

Una página contiene el siguiente elemento:

<input type="text" id="user-email" name="email" class="form-control required">

¿Qué selector CSS apunta de forma única y más robusta a este input por su id?

#user-email

Respuesta correcta

Correcto — # selecciona por id, que es único, dando un localizador corto y estable.

.form-control.required

Incorrecto — los selectores de clase pueden coincidir con varios elementos y las clases cambian a menudo; menos robusto que el id.

input

Incorrecto — el selector de etiqueta coincide con todos los input de la página, no es único.

#email

Incorrecto — el id es user-email, no email; #email no coincide con nada aquí.

Por qué

Un id es único en una página válida, por lo que el selector de id #user-email es el localizador CSS más robusto aquí.

Pregunta 10

En XPath, ¿cuál es la diferencia entre una ruta que empieza con // y otra que empieza con /?

// busca descendientes en cualquier parte; / selecciona desde la raíz

Respuesta correcta

Correcto — // es una búsqueda relativa/de descendientes; un solo / inicial es una ruta absoluta desde la raíz.

// es para CSS y / para XPath

Incorrecto — ambos son sintaxis XPath; ninguno es CSS.

// selecciona solo la primera coincidencia; / todas

Incorrecto — ninguno limita a la primera coincidencia; eso lo hace un índice como [1].

No hay diferencia; son intercambiables

Incorrecto — se comportan de forma muy distinta (búsqueda de descendientes vs. ruta absoluta).

Por qué

Un / inicial selecciona desde la raíz del documento (absoluto), mientras que // selecciona nodos coincidentes en cualquier parte del documento (búsqueda de descendientes).

Pregunta 11

La página tiene dos botones:

<button class="btn">Cancel</button> <button class="btn">Submit</button>

¿Qué XPath selecciona solo el botón Submit por su texto visible?

//button[text()='Submit']

Respuesta correcta

Correcto — coincide con el botón cuyo nodo de texto es 'Submit'.

//button[@class='btn']

Incorrecto — ambos botones tienen la clase btn, coincide con dos elementos.

//button

Incorrecto — coincide con todos los botones, no solo Submit.

//button[@text='Submit']

Incorrecto — no existe un atributo text; el texto visible requiere la función text(), no @text.

Por qué

Ambos botones comparten la clase btn, por lo que un localizador de clase es ambiguo. Coincidir el texto exacto con text()='Submit' selecciona solo el botón Submit.

Pregunta 12

En un selector CSS, ¿qué prefijo selecciona un elemento por su atributo class?

Un punto, p. ej. .btn

Respuesta correcta

Correcto — el prefijo de punto selecciona por nombre de clase en CSS.

Una almohadilla, p. ej. #btn

Incorrecto — la almohadilla selecciona por id, no por clase.

Una arroba, p. ej. @btn

Incorrecto — @ es sintaxis de atributo XPath, no CSS.

Dos puntos, p. ej. :btn

Incorrecto — los dos puntos introducen una pseudoclase (como :hover), no una coincidencia de clase.

Por qué

En CSS, . (punto) selecciona por clase y # (almohadilla) por id.

Pregunta 13

¿Cuáles de las siguientes prácticas de localización suelen producir pruebas MÁS estables y mantenibles? (Elige dos.)

Usar un id único o un atributo data-testid dedicado

Respuesta correcta

Correcto — son estables y rara vez cambian con el estilo o el diseño.

Selectores CSS cortos y acotados basados en atributos significativos

Respuesta correcta

Correcto — un CSS conciso basado en atributos es legible y resistente a cambios de diseño.

XPath absolutos largos como /html/body/div[3]/div[2]/form/input[1]

Incorrecto — las rutas absolutas se rompen con casi cualquier cambio del DOM; son frágiles.

Seleccionar elementos por su índice de posición numérico

Incorrecto — los índices de posición cambian al cambiar el orden de los hermanos, volviendo las pruebas inestables.

Por qué

Los localizadores estables prefieren ids únicos y atributos de prueba dedicados; los XPath absolutos largos y los índices de posición se rompen con facilidad al cambiar el DOM.

Pregunta 14

Debe seleccionar este campo por su atributo name:

<input name="email" type="email">

¿Qué selector de atributo CSS es correcto?

input[name='email']

Respuesta correcta

Correcto — la sintaxis de atributo entre corchetes coincide exactamente con el atributo name.

input(name='email')

Incorrecto — CSS no usa paréntesis para seleccionar atributos.

input@name='email'

Incorrecto — @ es sintaxis de atributo XPath, no CSS.

input.name.email

Incorrecto — los puntos seleccionan clases llamadas 'name' y 'email', no el atributo name.

Por qué

Un selector de atributo CSS usa corchetes: input[name='email'] coincide con un input cuyo atributo name es email.

Pregunta 15

Dado este marcado, necesita el <input> que sigue inmediatamente a la etiqueta:

<label for="q">Search</label><input id="q" type="text">

¿Qué XPath usa un eje para seleccionar el input que es following-sibling de la etiqueta?

//label/following-sibling::input

Respuesta correcta

Correcto — el eje following-sibling selecciona el input que sigue a la etiqueta en el mismo nivel.

//label/child::input

Incorrecto — el input es hermano de la etiqueta, no su hijo; child:: no coincide.

//label/parent::input

Incorrecto — el eje parent va hacia arriba; un input no es el padre de una etiqueta.

//label/preceding-sibling::input

Incorrecto — preceding-sibling mira hacia atrás, pero el input viene después de la etiqueta.

Por qué

El eje following-sibling selecciona hermanos posteriores al nodo de contexto. //label/following-sibling::input elige el input tras la etiqueta.

Pregunta 16

Un elemento tiene una clase dinámica que siempre contiene la palabra 'alert' pero con sufijos extra, p. ej. class="alert alert-danger fade-in". ¿Qué XPath coincide de forma fiable con cualquier elemento cuya class contenga 'alert'?

//*[contains(@class,'alert')]

Respuesta correcta

Correcto — contains() hace coincidencia de subcadena en class y tolera tokens extra.

//*[@class='alert']

Incorrecto — la coincidencia exacta falla porque la clase completa es 'alert alert-danger fade-in'.

//*[class='alert']

Incorrecto — los atributos requieren el prefijo @ en XPath; class sin @ se refiere a un nodo hijo llamado class.

//*[starts-with(@id,'alert')]

Incorrecto — comprueba el id, no la clase, y usa coincidencia de prefijo, no de subcadena.

Por qué

La función contains() hace una coincidencia de subcadena, por lo que contains(@class,'alert') coincide sin importar los demás tokens de clase.

Pregunta 17

¿Cuál es el propósito principal del patrón de diseño Page Object Model (POM) en la automatización con Selenium?

Encapsular los localizadores y acciones de una página en una clase, mejorando legibilidad y mantenibilidad

Respuesta correcta

Correcto — este objetivo central reduce la duplicación y aísla los cambios de UI en una sola clase.

Hacer que las pruebas corran más rápido en paralelo

Incorrecto — POM ayuda al mantenimiento; la velocidad en paralelo viene del runner/grid, no del patrón.

Eliminar la necesidad de cualquier localizador

Incorrecto — POM sigue usando localizadores; solo los centraliza en clases de página.

Generar datos de prueba automáticamente

Incorrecto — la generación de datos no tiene relación con POM, que modela páginas.

Por qué

POM encapsula los localizadores y las interacciones de una página en una clase dedicada, de modo que los scripts llaman a métodos legibles y los cambios de localizador se hacen en un solo lugar.

Pregunta 18

Según la guía habitual del Page Object Model, ¿dónde deben colocarse normalmente las aserciones de prueba?

En los métodos de prueba, no dentro de los page objects

Respuesta correcta

Correcto — mantener las aserciones en las pruebas hace reutilizables los page objects.

Dentro de cada método de page object

Incorrecto — incrustar aserciones en todos lados acopla las páginas a verificaciones concretas y daña la reutilización.

En la configuración de WebDriver

Incorrecto — la configuración del driver es del arranque, no de verificar resultados esperados.

En el HTML de la página bajo prueba

Incorrecto — las aserciones son código de prueba; nunca se ponen en el HTML de la aplicación.

Por qué

Los page objects deben exponer estado/comportamiento y devolver datos u otros page objects; las aserciones van en los métodos de prueba, manteniendo reutilizables los page objects.

Pregunta 19

Un método de LoginPage envía el formulario y lleva al usuario al dashboard:

public DashboardPage login(String u, String p) { ... }

¿Por qué devolver un objeto DashboardPage (en vez de void) se considera buena práctica de Page Object?

Modela la transición de página y permite encadenar a la siguiente página con seguridad de tipos

Respuesta correcta

Correcto — devolver el page object resultante expresa la navegación y habilita cadenas fluidas y legibles.

Hace que el login se ejecute sin navegador

Incorrecto — el tipo de retorno no cambia si se usa un navegador; WebDriver sigue controlando uno.

Verifica automáticamente que el login tuvo éxito

Incorrecto — devolver un page object no verifica nada; las aserciones quedan en la prueba.

Evita instanciar WebDriver

Incorrecto — el driver sigue siendo necesario; el tipo de retorno no se relaciona con su creación.

Por qué

Devolver el siguiente page object modela la navegación y permite encadenar llamadas con fluidez, manteniendo la transición de página explícita y con seguridad de tipos.

Pregunta 20

Un localizador del botón de login cambia en la UI de la aplicación. En un proyecto Page Object Model bien estructurado, ¿cuántos lugares suelen necesitar actualización?

Uno — el localizador definido en el page object correspondiente

Respuesta correcta

Correcto — centralizar los localizadores hace que una sola edición arregle todas las pruebas dependientes.

Cada prueba que pulsa el botón

Incorrecto — eso es lo que POM resuelve; sin POM editarías muchas pruebas.

Ninguno — los localizadores se actualizan solos

Incorrecto — los localizadores son definiciones estáticas; no se actualizan solos.

Hay que reinstalar el binario de WebDriver

Incorrecto — un cambio de localizador no tiene relación con el binario del driver.

Por qué

Como cada localizador se define una vez dentro de su page object, un cambio de UI se corrige en un único lugar, sin importar cuántas pruebas lo usen.

Pregunta 21

¿Cuáles de los siguientes suelen pertenecer DENTRO de una clase page object? (Elige dos.)

Los localizadores de los elementos de esa página

Respuesta correcta

Correcto — los localizadores se encapsulan en el page object.

Métodos que realizan interacciones del usuario en esa página

Respuesta correcta

Correcto — los métodos de acción (p. ej. login, search) van en el page object.

Los datos de prueba esperados y las aserciones

Incorrecto — van en la prueba, no en el page object, para mantenerlo reutilizable.

La configuración del runner (p. ej. XML de suite TestNG)

Incorrecto — la configuración del runner es del proyecto, separada de los page objects.

Por qué

Un page object contiene los localizadores de la página y métodos que realizan interacciones del usuario o devuelven información; los datos de prueba y las aserciones van en las pruebas.

Pregunta 22

En el enfoque PageFactory de Selenium (Java), un campo se declara así:

@FindBy(id = "submit") private WebElement submitButton;

¿Qué logra la anotación @FindBy junto con PageFactory.initElements?

Inicializa el campo WebElement para localizar el elemento de forma perezosa al primer uso

Respuesta correcta

Correcto — PageFactory conecta los campos anotados y resuelve el localizador al acceder al elemento.

Cachea el elemento de forma permanente para que nunca quede obsoleto

Incorrecto — los elementos cacheados de PageFactory pueden seguir lanzando StaleElementReferenceException tras cambios del DOM.

Agrega una aserción implícita de que el botón existe

Incorrecto — @FindBy localiza; no verifica la presencia.

Descarga automáticamente el driver del navegador adecuado

Incorrecto — la gestión de drivers no se relaciona con @FindBy.

Por qué

PageFactory usa @FindBy para localizar el elemento de forma perezosa en el primer uso, inicializando los campos WebElement anotados para no llamar a findElement explícitamente.

Pregunta 23

¿Cómo afecta a las búsquedas de elementos una espera implícita configurada con driver.manage().timeouts().implicitlyWait(...)?

Se aplica globalmente, haciendo que cada findElement sondee hasta el timeout antes de fallar

Respuesta correcta

Correcto — la espera implícita se fija una vez y afecta a todas las búsquedas posteriores.

Espera solo por un elemento específico que nombras cada vez

Incorrecto — eso describe una espera explícita; la implícita es global.

Pausa toda la prueba por la duración completa cada vez

Incorrecto — solo espera lo necesario; si el elemento aparece antes, la llamada retorna de inmediato.

Solo afecta la navegación driver.get(), no findElement

Incorrecto — la espera implícita afecta la localización de elementos, no los timeouts de navegación.

Por qué

Una espera implícita establece un tiempo de sondeo global: cada findElement sondeará el DOM hasta esa duración antes de lanzar NoSuchElementException.

Pregunta 24

Una prueba falla de forma intermitente porque un botón está en el DOM pero queda brevemente deshabilitado tras cargar la página. ¿Qué condición de espera explícita lo arregla mejor?

new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.________)

elementToBeClickable(locator)

Respuesta correcta

Correcto — espera a que el elemento esté visible Y habilitado.

presenceOfElementLocated(locator)

Incorrecto — presence solo comprueba que el elemento está en el DOM, no que esté habilitado/clicable.

titleContains("...")

Incorrecto — comprueba el título de la página, no el estado del botón.

Thread.sleep(10000)

Incorrecto — no es una ExpectedCondition y un sleep fijo es justo el enfoque frágil a evitar.

Por qué

elementToBeClickable espera hasta que el elemento esté visible y habilitado, justo la condición para un botón presente pero temporalmente deshabilitado.

Pregunta 25

¿Por qué se desaconseja generalmente usar Thread.sleep() para sincronización en pruebas Selenium?

Siempre espera el tiempo fijo completo, haciendo las pruebas lentas y aún inestables

Respuesta correcta

Correcto — un sleep estático no se adapta a los tiempos reales de carga, así que pierde tiempo o falla.

No está soportado por Java

Incorrecto — Thread.sleep es Java válido; el problema es la idoneidad, no el soporte.

Cierra la sesión del navegador

Incorrecto — dormir pausa el hilo; no cierra el navegador.

Solo funciona en modo headless

Incorrecto — Thread.sleep se comporta igual en modo con y sin interfaz.

Por qué

Thread.sleep siempre pausa el tiempo fijo sin importar si el elemento está listo, lo que hace las pruebas más lentas y aún inestables si la espera es corta.

Pregunta 26

¿Cuál es la diferencia de comportamiento clave entre una espera explícita (WebDriverWait + ExpectedConditions) y una implícita?

Las explícitas apuntan a una condición concreta; las implícitas son un timeout global para todas las búsquedas

Respuesta correcta

Correcto — las explícitas son por condición y locales; las implícitas son generales y globales.

Las explícitas son globales; las implícitas apuntan a una condición

Incorrecto — esto invierte los dos tipos de espera.

No hay diferencia; los términos son sinónimos

Incorrecto — son mecanismos distintos con diferente alcance y comportamiento.

Las explícitas solo funcionan en Python; las implícitas solo en Java

Incorrecto — ambos tipos existen en todos los bindings de lenguaje de Selenium.

Por qué

Una espera explícita apunta a una condición concreta para un elemento concreto, mientras que la implícita aplica un único timeout global a todas las búsquedas.

Pregunta 27

¿Cuáles de las siguientes son prácticas de sincronización recomendadas para pruebas Selenium estables? (Elige dos.)

Usar esperas explícitas con condiciones que reflejen lo que la prueba necesita (visible, clicable)

Respuesta correcta

Correcto — las esperas por condición retornan en cuanto la app está lista, mejorando velocidad y estabilidad.

Usar un FluentWait para sondear con timeout e ignorar excepciones transitorias esperadas

Respuesta correcta

Correcto — FluentWait permite fijar el intervalo de sondeo e ignorar excepciones como NoSuchElement mientras espera.

Mezclar libremente esperas implícitas y explícitas en toda la suite

Incorrecto — mezclarlas puede producir tiempos de espera impredecibles y aditivos; se desaconseja.

Añadir largas llamadas Thread.sleep antes de cada interacción

Incorrecto — los sleeps fijos vuelven lentas las suites y no garantizan disponibilidad.

Por qué

La buena práctica prefiere esperas explícitas/fluent sobre condiciones significativas y evita mezclar esperas implícitas y explícitas o esparcir sleeps fijos.

Pregunta 28

¿Por qué se considera arriesgado mezclar una espera implícita y un WebDriverWait explícito en la misma sesión de prueba?

Sus timeouts pueden combinarse de forma impredecible, dando esperas más largas o inconsistentes

Respuesta correcta

Correcto — la guía oficial advierte que ambas pueden interactuar e inflar los tiempos de espera.

Provoca un error de compilación

Incorrecto — el código compila; el problema es el comportamiento de tiempo en ejecución.

Las esperas explícitas se desactivan cuando existe una implícita

Incorrecto — ambas siguen activas; por eso pueden interferir.

Corrompe permanentemente el perfil del navegador

Incorrecto — no hay corrupción de perfil; el único efecto es en el tiempo de espera.

Por qué

Si ambas están activas, sus timeouts pueden combinarse de forma impredecible (lo documentado es que los tiempos pueden sumarse), produciendo esperas más largas o inconsistentes.

Pregunta 29

¿Qué método navega el navegador de vuelta a la página anterior en su historial?

driver.navigate().back()

Respuesta correcta

Correcto — navigate().back() retrocede una página en el historial.

driver.get("back")

Incorrecto — get() carga una URL; 'back' no es una URL.

driver.previous()

Incorrecto — no existe el método previous() en WebDriver.

driver.close()

Incorrecto — close() cierra la ventana; no navega atrás.

Por qué

driver.navigate().back() retrocede una entrada en el historial del navegador, como el botón Atrás.

Pregunta 30

Al pulsar un enlace se abre una segunda pestaña. ¿Qué debe hacer antes de que WebDriver pueda interactuar con los elementos de esa nueva pestaña?

Cambiar al nuevo handle de ventana con switchTo().window(handle)

Respuesta correcta

Correcto — hay que indicar a WebDriver en qué ventana actuar; el cambio de foco es necesario.

Nada — WebDriver enfoca automáticamente la pestaña más nueva

Incorrecto — WebDriver no cambia automáticamente; el foco queda en la ventana original.

Llamar a driver.refresh() en la nueva pestaña

Incorrecto — refrescar no mueve el foco a otra ventana.

Reiniciar la sesión de WebDriver

Incorrecto — reiniciar es innecesario; basta cambiar de handle de ventana.

Por qué

WebDriver permanece enfocado en la ventana original hasta que cambie. Use getWindowHandles() para hallar el nuevo handle y switchTo().window(handle) para enfocarlo.

Pregunta 31

Un formulario se renderiza dentro de un iframe:

<iframe id="payment"><input id="card"></iframe>

driver.findElement(By.id("card")) lanza NoSuchElementException aunque el campo es visible. ¿Cuál es la solución correcta?

Llamar a driver.switchTo().frame("payment") antes de localizar el campo

Respuesta correcta

Correcto — hay que cambiar al contexto del iframe antes de poder encontrar sus elementos.

Aumentar la espera implícita a 60 segundos

Incorrecto — esperar más no ayuda; el elemento está en otro contexto de frame, no es lentitud.

Usar driver.navigate().refresh()

Incorrecto — refrescar recarga la página pero no entra al contexto del iframe.

Cambiar By.id por By.name

Incorrecto — el tipo de localizador no es el problema; el elemento está en otro frame.

Por qué

Los elementos dentro de un iframe no están en el contexto del documento principal. Hay que switchTo().frame(...) primero, interactuar y luego switchTo().defaultContent() para volver.

Pregunta 32

Aparece una alerta nativa de JavaScript. ¿Cómo la aceptas (pulsar Aceptar) con WebDriver?

driver.switchTo().alert().accept()

Respuesta correcta

Correcto — cambiar a la alerta y llamar a accept() la confirma.

driver.findElement(By.id("ok")).click()

Incorrecto — las alertas nativas no son elementos del DOM; findElement no puede localizar Aceptar.

driver.navigate().refresh()

Incorrecto — refrescar no interactúa con el diálogo de alerta.

driver.quit()

Incorrecto — quit finaliza la sesión en vez de aceptar la alerta.

Por qué

Las alertas JavaScript se manejan con la interfaz Alert: driver.switchTo().alert().accept() pulsa Aceptar; dismiss() pulsa Cancelar.

Pregunta 33

¿Para cuáles de los siguientes WebDriver requiere una llamada switchTo() antes de poder interactuar? (Elige dos.)

Interactuar con un elemento dentro de un iframe

Respuesta correcta

Correcto — hay que switchTo().frame(...) para entrar al contexto del iframe.

Aceptar o descartar una alerta JavaScript

Respuesta correcta

Correcto — las alertas se manejan vía switchTo().alert().

Pulsar un botón en la página actual

Incorrecto — los elementos del documento actual se manejan directamente, sin cambio.

Leer el texto de un encabezado en la página actual

Incorrecto — getText() sobre un elemento del documento actual no necesita switchTo().

Por qué

switchTo() es necesario para entrar en iframes y manejar alertas JavaScript (y para cambiar el foco de ventana). Un clic normal o leer texto en el documento actual no lo requiere.

Pregunta 34

¿Qué API de Selenium está diseñada para gestos complejos del usuario como pasar el cursor sobre un menú o arrastrar y soltar?

La clase Actions

Respuesta correcta

Correcto — Actions ofrece gestos avanzados de ratón/teclado ejecutados con perform().

La clase Select

Incorrecto — Select es solo para desplegables <select>, no para gestos generales.

La interfaz Alert

Incorrecto — Alert maneja diálogos JavaScript, no gestos de ratón.

La interfaz TakesScreenshot

Incorrecto — TakesScreenshot captura imágenes; no realiza gestos.

Por qué

La clase Actions construye secuencias de interacciones de bajo nivel (moveToElement, dragAndDrop, clickAndHold) que se ejecutan con perform().

Pregunta 35

Una prueba guarda una referencia WebElement y luego la página actualiza parte del DOM vía AJAX. Usar la referencia antigua lanza StaleElementReferenceException. ¿Cuál es la forma correcta de manejarlo?

Volver a localizar el elemento tras el cambio del DOM en vez de reutilizar la referencia antigua

Respuesta correcta

Correcto — un findElement nuevo (a menudo dentro de una espera) da una referencia válida al nuevo nodo.

Capturar la excepción e ignorarla para que la prueba continúe

Incorrecto — ignorarla deja la acción sin ejecutar y oculta un problema real de sincronización.

Aumentar el tamaño de la ventana del navegador

Incorrecto — el tamaño de ventana no tiene relación con una referencia obsoleta del DOM.

Cambiar de Chrome a Firefox

Incorrecto — la excepción es independiente del navegador; cambiarlo no arregla una referencia obsoleta.

Por qué

La referencia apunta a un nodo del DOM que fue eliminado/reemplazado. La solución es volver a localizar el elemento tras el cambio del DOM, idealmente dentro de una espera explícita.

Pregunta 36

En automatización de pruebas, ¿qué describe mejor una prueba 'flaky' (inestable)?

Una prueba que pasa y falla de forma intermitente sin cambios en el código bajo prueba

Respuesta correcta

Correcto — resultados inconsistentes en ejecuciones idénticas es el rasgo definitorio de la inestabilidad.

Una prueba que siempre falla

Incorrecto — una prueba que falla siempre está rota de forma fiable, no es flaky.

Una prueba que se ejecuta lentamente

Incorrecto — la lentitud es un tema de rendimiento, no lo mismo que resultados inconsistentes.

Una prueba sin aserciones

Incorrecto — una prueba sin aserciones es débil, pero eso no es lo que significa 'flaky'.

Por qué

Una prueba flaky produce resultados distintos (pasa/falla) entre ejecuciones sin cambiar el código ni el sistema, normalmente por problemas de tiempo, orden o entorno.

Pregunta 37

¿Por qué las pruebas de UI automatizadas deben ser generalmente independientes entre sí (sin orden ni estado compartido)?

Para que se ejecuten en cualquier orden o en paralelo, y un fallo no se propague a otras

Respuesta correcta

Correcto — la independencia habilita el paralelismo y aísla los fallos a su causa real.

Para que las pruebas compartan el estado de login y corran más rápido

Incorrecto — compartir estado crea justo las dependencias que hacen frágiles y sensibles al orden las suites.

Porque Selenium no puede ejecutar más de una prueba

Incorrecto — Selenium ejecuta muchas pruebas; la independencia es una decisión de diseño, no un límite.

Para no tener que escribir aserciones

Incorrecto — la independencia no elimina la necesidad de aserciones; las pruebas siguen verificando resultados.

Por qué

Las pruebas independientes pueden ejecutarse en cualquier orden o en paralelo, y un fallo en una no se propaga a otras, lo que hace los resultados fiables y facilita la depuración.

Pregunta 38

¿Dónde debe limpiar sus datos una prueba que crea datos (p. ej. un usuario nuevo) para mantener la suite repetible?

En un paso de teardown que corre tras la prueba, pase o falle

Respuesta correcta

Correcto — el teardown garantiza la limpieza para que ejecuciones posteriores partan de un estado conocido.

En ningún sitio — los datos sobrantes nunca afectan a otras pruebas

Incorrecto — los datos sobrantes suelen causar fallos como errores de usuario duplicado en ejecuciones posteriores.

Solo manualmente, por una persona, tras terminar toda la suite

Incorrecto — la limpieza manual es poco fiable y anula la automatización; debe ir en el teardown.

Dentro de las definiciones de localizadores del page object

Incorrecto — los localizadores describen elementos; no es donde va la limpieza de datos.

Por qué

La limpieza va en un paso de teardown (p. ej. @AfterMethod / teardown de fixture) para que cada prueba deje el sistema en un estado conocido pase o falle.

Pregunta 39

¿Cuáles de las siguientes prácticas ayudan a reducir la inestabilidad en una suite Selenium? (Elige dos.)

Sincronizar con esperas explícitas sobre condiciones significativas

Respuesta correcta

Correcto — esperar la condición correcta elimina la mayor parte de la inestabilidad por tiempos.

Usar localizadores estables y únicos (ids / atributos de prueba)

Respuesta correcta

Correcto — los localizadores robustos evitan roturas por cambios de diseño o clase.

Hacer que las pruebas dependan de los datos que dejan las anteriores

Incorrecto — los datos sobrantes compartidos crean dependencia de orden y fallos intermitentes.

Añadir retardos fijos Thread.sleep 'por si acaso'

Incorrecto — los sleeps fijos ralentizan la suite y aún fallan cuando la app es más lenta de lo previsto.

Por qué

Las esperas explícitas sobre condiciones reales y los localizadores estables y únicos reducen la inestabilidad; un orden compartido aleatorio o los sleeps fijos hacen lo contrario.

Pregunta 40

Un clic falla con ElementClickInterceptedException porque un banner de cookies fijo solapa el botón objetivo. ¿Cuál es la solución más robusta?

Cerrar o desplazarse más allá del banner que solapa, luego esperar a que el botón sea clicable

Respuesta correcta

Correcto — manejar el elemento que intercepta aborda la causa real y mantiene el clic realista.

Envolver el clic en un bucle que reintenta miles de veces

Incorrecto — los reintentos a ciegas pierden tiempo y no quitan el overlay que sigue interceptando.

Eliminar la aserción que comprueba el resultado

Incorrecto — quitar la aserción oculta el fallo en vez de lograr que el clic funcione.

Reducir la espera implícita a cero

Incorrecto — el problema es un elemento que solapa, no el tiempo de espera; reducirlo no ayuda.

Por qué

El elemento está cubierto por otro. La solución robusta es eliminar/manejar el overlay (p. ej. cerrar el banner) o desplazar/esperar hasta que el objetivo sea realmente clicable, en vez de forzar el clic a ciegas.