Skip to main content
Stack Overflow
  1. About
  2. For Teams
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

Selenium + Serenity BDD cannot find <tbody id="bodyArchivos"> inside iframe even though it exists in DevTools (Java + Cucumber)

I’m working on an automated test with Java + Maven + Selenium WebDriver + Serenity BDD + Cucumber.

The test needs to click the "Download" button of the most recent projection file in a table that is rendered inside an iframe.


Problem

At runtime, my step fails with this assertion:

No se encontró la tabla bodyArchivos ni en el DOM principal ni en ninguno de los iframes de la página. Revisa que la URL sea la de 'Archivos de resultados de proyecciones' y que el id sea exactamente 'bodyArchivos'.

Serenity output (Cucumber scenario):


Descargar y validar archivo de proyección ya existente
\-----------------------------------------------------------------------
23:33:03.045 ERROR \[ main\] : Test failed at step: Y descargo el archivo de proyección más reciente
23:33:03.045 ERROR \[ main\] : No se encontró la tabla bodyArchivos ni en el DOM principal ni en ninguno de los iframes de la página. Revisa que la URL sea la de 'Archivos de resultados de proyecciones' y que el id sea exactamente 'bodyArchivos'.
Failed scenarios:
.../archivos_proyeccion.feature:24 # Descargar y validar archivo de proyección ya existente
java.lang.AssertionError: No se encontró la tabla bodyArchivos ni en el DOM principal ni en ninguno de los iframes de la página. Revisa que la URL sea la de 'Archivos de resultados de proyecciones' y que el id sea exactamente 'bodyArchivos'.
 at org.af.gestion.mi.pension.stepdefinitions.ArchivosProyeccionStepDefinitions.cambiarAFrameConTablaArchivos(ArchivosProyeccionStepDefinitions.java:407)
 at org.af.gestion.mi.pension.stepdefinitions.ArchivosProyeccionStepDefinitions.descargoArchivoMasReciente(ArchivosProyeccionStepDefinitions.java:202)
 at ?.descargo el archivo de proyección más reciente(.../archivos_proyeccion.feature:27)

So my helper method cannot find tbody#bodyArchivos either in the main DOM or in any iframe, but in the browser DevTools the element does exist.

Step definition that fails

@Cuando("descargo el archivo de proyección más reciente")
public void descargoArchivoMasReciente() {
 WebDriver driver = getDriver();
 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(40));
 // 1) Switch to the frame (or main DOM) that contains the table
 cambiarAFrameConTablaArchivos(driver);
 // 2) Wait for the table in the CURRENT context
 WebElement tabla = wait.until(
 ExpectedConditions.presenceOfElementLocated(By.id("bodyArchivos"))
 );
 // 3) Get the first row (most recent file) and its download button
 WebElement fila = tabla.findElement(By.cssSelector("tr:first-child"));
 WebElement botonDescarga = fila.findElement(By.cssSelector("td:nth-child(3) > button"));
 // Click using JS in case of overlays
 ((JavascriptExecutor) driver).executeScript("arguments[0].click();", botonDescarga);
 // 4) Go back to main content for the next steps
 driver.switchTo().defaultContent();
 // (code that waits for the downloaded .csv is omitted)
}

Helper method to switch into the iframe

/**
 * Looks for tbody#bodyArchivos either in the main DOM or inside any iframe.
 * If found, it leaves the driver already switched to the correct context.
 * Otherwise it throws an AssertionError.
 */
private void cambiarAFrameConTablaArchivos(WebDriver driver) {
 // Always start from the main document
 driver.switchTo().defaultContent();
 System.out.println("[DescargaCSV] URL actual: " + driver.getCurrentUrl());
 // 1) First try in the main DOM (no iframe)
 List<WebElement> tablasEnPrincipal = driver.findElements(By.id("bodyArchivos"));
 if (!tablasEnPrincipal.isEmpty()) {
 System.out.println("[DescargaCSV] ✔ Tabla bodyArchivos encontrada en el DOM principal (sin iframe).");
 return;
 }
 // 2) If not in main DOM, look into iframes
 List<WebElement> iframes = driver.findElements(By.tagName("iframe"));
 System.out.println("[DescargaCSV] iframes encontrados en la página: " + iframes.size());
 if (iframes.isEmpty()) {
 throw new AssertionError(
 "No se encontró la tabla bodyArchivos ni en el DOM principal ni en iframes (no hay iframes en la página)."
 );
 }
 // 3) Try each iframe by index
 for (int i = 0; i < iframes.size(); i++) {
 try {
 driver.switchTo().defaultContent();
 driver.switchTo().frame(i);
 List<WebElement> tablas = driver.findElements(By.id("bodyArchivos"));
 if (!tablas.isEmpty()) {
 System.out.println("[DescargaCSV] ✔ Tabla bodyArchivos encontrada en iframe index=" + i);
 return; // stay in this iframe
 } else {
 System.out.println("[DescargaCSV] iframe index=" + i + " no contiene bodyArchivos");
 }
 } catch (NoSuchFrameException e) {
 System.out.println("[DescargaCSV] NoSuchFrameException en iframe index=" + i);
 } catch (StaleElementReferenceException e) {
 System.out.println("[DescargaCSV] StaleElementReference en iframe index=" + i +
 " → ignoring and continuing with the next one");
 }
 }
 // 4) If we get here, the table was not found anywhere
 throw new AssertionError(
 "No se encontró la tabla bodyArchivos ni en el DOM principal ni en ninguno de los iframes de la página. " +
 "Revisa que la URL sea la de 'Archivos de resultados de proyecciones' y que el id sea exactamente 'bodyArchivos'."
 );
}

HTML structure (iframe + table)

From the Elements tab in DevTools, the page has this iframe:

<iframe
 name="ifrcontent"
 id="ifrcontent"
 src="/PortalAccesoWeb/jsp/templates/blank.jsp"
 class="min-width: 500px;"
 width="100%"
 height="450px"
 frameborder="0"
 allowtransparency="yes">
</iframe>

When I expand that iframe in DevTools, I see that its document loads another URL and contains the form and the table I need:

<div class="col-md-12">
 <div class="card-table">
 <h5 class="text-center text-white">Archivos de resultados de proyecciones</h5>
 </div>
 <div>
 <table class="table mb-0">
 <caption class="text-end pb-0">Últimos archivos de resultados</caption>
 <thead>
 <tr class="tdtituloAz mx-2">
 <th class="align-middle">Archivo</th>
 <th class="align-middle text-center">Fecha fin procesamiento</th>
 <th class="align-middle text-center">Descargar</th>
 </tr>
 </thead>
 <tbody id="bodyArchivos">
 <tr class="trTablaImpar">
 <td class="align-middle">ProyeccionPensionISSSTE_260925_resultado_58.csv</td>
 <td class="align-middle text-center">26/09/2025</td>
 <td class="align-middle text-center">
 <button class="btn btn-secondary btn-sm" type="button"
 onclick="descargarProyeccion('ProyeccionPensionISSSTE_260925_resultado_58.csv');">
 <i class="fa fa-file-excel-o"></i>
 </button>
 </td>
 </tr>
 <!-- several more <tr> rows ... -->
 </tbody>
 </table>
 </div>
</div>

Browser console output

In the browser console I tried:

document.querySelectorAll("iframe")
document.querySelectorAll("iframe").length

and I get:

  • NodeList []
  • 0

I also tried:

let frame = window.frames[0];
frame.document.getElementById("bodyArchivos");

and I get:

Uncaught TypeError: Cannot read properties of undefined (reading 'document')

At the same time, in the Console I see a JavaScript error coming from the application:

Uncaught ReferenceError: setUpArchivos is not defined at onload (archivos.do:48)

What I have already tried

  • Iterating all iframes by index (driver.switchTo().frame(i)) and searching for By.id("bodyArchivos") in each one.
  • Looking for the table in the main DOM before switching to frames.
  • Confirming in DevTools that the id really is bodyArchivos and that the table is inside ifrcontent.
  • Running the test in Edge and Chrome with the same result.

Question

What am I doing wrong when trying to locate tbody#bodyArchivos inside this iframe?

  • Is there something special about this iframe because its src is /PortalAccesoWeb/jsp/templates/blank.jsp but internally it loads /ProyeccionPensionWeb/archivos.do?
  • Could the JavaScript error (setUpArchivos is not defined) prevent the iframe document from being attached to window.frames / document.querySelectorAll("iframe") from Selenium’s point of view?
  • Do I need a different strategy to switch into this iframe (for example by name or WebElement, or waiting for the inner document to be fully loaded) so that WebDriver can see tbody#bodyArchivos?enter image description hereenter image description here

Answer*

Draft saved
Draft discarded
Cancel

lang-java

AltStyle によって変換されたページ (->オリジナル) /