1

I am having trouble dealing with a dynamic table.

This is our table:

<table class="table" style="min-width: 870px; max-width: 870px">
  <colgroup>
    <col style="width: 30px">
    <col style="width: 200px">
    <col style="width: 80px">
    <col style="width: 70px">
    <col style="width: 200px">
    <col style="width: 50px">
    <col style="width: 50px">
  </colgroup>
  <tbody>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
  </tbody>
  <tfoot>
    <tr>
      <td class="text-right" colspan="3">Media del grupo</td>
      <td class="text-center media" colspan="1">1</td>
      <td class="text-center noeditable" colspan="1"></td>
      <td class="text-center media" colspan="1"></td>
      <td class="text-center media" colspan="1"></td>
    </tr>
  </tfoot>
</table>

Each <tr> contains the following:

<tr>
  <td class="indice">1</td>
  <td id="accion-1-alumno-0" data-tooltip="" class="has-tip titulo" title="">Ap_Alumno_1ESOA_1, Nb_Alumno_1ESOA_1</td>
  <td data-tooltip="" class="has-tip titulo" data-selector="tooltipdtk00g" title="">1ESOA</td>
  <td class="nota relative " style="text-align:center; color: #ed1c24!important">
    <div id="accion-1-celda-0-0-0" class="elemento comentarios">1</div>
  </td>
  <td class="nota relative " style="text-align:center; color: #000000!important">
    <div class="elemento comentarios"><span id="accion-1-editar-1-0" class="block left ellipsis span  comentario" title=""></span><span id="accion-1-prismaticos-1-0" class="glyphicons glyph_observaciones observacion right"></span></div>
  </td>
  <td class="nota relative " style="text-align:center; color: #000000!important">
    <div id="accion-1-celda-2-0-0" class="elemento comentarios"></div>
  </td>
  <td class="nota relative " style="text-align:center; color: #000000!important">
    <div id="accion-1-celda-3-0-0" class="elemento comentarios"></div>
  </td>
</tr>

We are interested in the elements

<div id="accion-1-celda-0-0-0" class="elemento comentarios">1</div>

which are being added to a IList<IWebElement>

However, when trying to SendKeys to the element, the first time it will work correctly, however the second time will always fail with StaleElementReferenceException, this is because the previous element (the first one) has changed and with it the page DOM has also changed.

I am trying to find a way to find the element again if StaleElementReferenceException is thrown.

So far, both this methods have failed:

Method one

public virtual void Introducir_NotasAlumnos(string nota)
{
    IList<IWebElement> divNota = tablaNotas
    .Select((element, index) => element.FindElement(By.Id("accion-1-celda-0-" + index + "-0")))
    .ToList();

    divNota.ToList().ForEach(element => Introducir_Nota(element, nota));
}

Method two

public virtual void Introducir_NotasAlumnos(string nota)
{
    int index = 0;

        foreach (IWebElement element in tablaNotas)
        {
            By locator = By.Id("accion-1-celda-0-" + index + "-0");

            Introducir_Nota(element.FindElement(locator), nota);

            index++;
        }
}

Thanks for your time.

elgato
  • 506
  • 1
  • 5
  • 20
  • 1
    What is `tablaNotas`? – Sers Oct 29 '18 at 10:52
  • tablaNotas is defined as follows: [FindsBySequence] [FindsBy(How = How.Id, Using = "tabla-virtual")] [FindsBy(How = How.CssSelector, Using = "div.row.row-overflow.bodyPlaceHolder")] [FindsBy(How = How.CssSelector, Using = "table.table")] [FindsBy(How = How.TagName, Using = "tbody")] [FindsBy(How = How.TagName, Using = "tr")] private IList tablaNotas { get; set; } – elgato Oct 29 '18 at 10:57
  • 1
    Are you sure `By.Id("accion-1-celda-0-" + index + "-0");` selector correct. In html provided there are elements `accion-1-celda-0-0-0`,`accion-1-celda-2-0-0` and `accion-1-celda-3-0-0`, but `accion-1-celda-0-1-0` not exist. – Sers Oct 29 '18 at 11:02
  • Take into account that I just pasted one tr, but the structure is replicated in each tr, so for `tr0` `accion-1-celda-0-0-0` exists, for `tr1` `accion-1-celda-0-1-0` exists, and so forth – elgato Oct 29 '18 at 11:28
  • 1
    Check my answer and let me know if my code works. My code in Java but there almost no difference – Sers Oct 29 '18 at 11:35
  • @CoreyGoldberg could you shed some light on why a webelement has no refresh or getBy methods? I started a few months ago and still do not dominate Selenium – elgato Oct 29 '18 at 20:57
  • when elements are stale, you must re-load the page (not the element) – Corey Goldberg Oct 30 '18 at 01:49

1 Answers1

1

Here your locators:

  • table: .table tbody > tr
  • table row by index: .table tbody > tr:nth-child(1)

and you method (java code):

int size = driver.findElements(By.cssSelector(".table tbody > tr")).size();

for (int i = 0; i < size; i++) {
    WebElement row = driver.findElement(By.cssSelector(".table tbody > tr:nth-child(" + i + ")"));
    By locator = By.id("accion-1-celda-0-" + i + "-0");
    Introducir_Nota(row.findElement(locator), nota);
}

You have certain count of rows and you find row element independently, should not throw StaleElementReferenceException exception.

Here shorter version:

int size = driver.findElements(By.cssSelector(".table tbody > tr")).size();

for (int i = 0; i < size; i++) {
    Introducir_Nota(row.findElement(By.cssSelector("#accion-1-celda-0-" + i + "-0")), nota);
}
Sers
  • 12,047
  • 2
  • 12
  • 31
  • Thanks @Sers, I used your solution and is working correctly. I am however disappointed that there is no clear way to "refresh" or get the IWebElement by so the element can be searched again in case something like this happens. Thank you. – elgato Oct 29 '18 at 16:33