1

I'm trying to get hold of two users in a hideous structure with tables within tables and I'm just not getting it to work... The structure is something like this (inner most table):

<table>
  <tbody>
    <tr>
    <tr>
    <tr>
    <tr>
      <td>
      <td>
      <td>
        <input lotsofuselesstext value="Steve">
        <img>
      </td>
      <td>
    </tr>
    <tr>
    <tr>
    <tr>
      <td>
      <td>
      <td>
        <input lotsofuselesstext value="Mark">
        <img>
      </td>
      <td>
    </tr>
  </tbody>
</table>

I'm trying to get hold of Steve and Mark. I can get an xpath that will give me the two input tags, but no matter what I can't get the value fields. I'm using Playwright with C#...

I've tried so many variants that I can't keep track of them, but some that I still have in my code are:

var Planners = await Page.QuerySelectorAllAsync("//*[@summary=\"Planners\"]/tbody/tr/td[3]/input");
var values = await Task.WhenAll(Planners.Select(async element => await element.GetAttributeAsync("value")));

var Planners= await Page.Locator("//*[@summary=\"Planners\"]/tbody/tr/td[3]/input").ElementHandlesAsync();

var Planners = await Page.Locator("//*[@summary=\"Planners\"]/tbody/tr/td[3]/input").AllTextContentsAsync();

And, I'm new to this, as if you couldn't already tell...

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • 2
    Are you sure this is really your table? It's invalid HTML (paste it into [this checker to see the many errors](https://validator.w3.org/nu/#textarea)). – ggorlen Apr 27 '23 at 14:43
  • It's obviously not the complete code since it's a fairly large page, and all the and tags are full of stuff of no interest for my problem. I tried to narrow it down to the essential. – Fredrik Thörnblad Apr 27 '23 at 19:01
  • 1
    That's great in theory, it's good to strip out unneeded info, but what you have shown makes no sense as HTML, so there's no way to discuss how to scrape it. I suggest stripping out what you don't need, but keeping the fundamental structure of the subset of the table you're working with valid. – ggorlen Apr 27 '23 at 19:30

2 Answers2

1

The below code solutions are in JavaScript

How to verify a certain text from a specific column from a Table?

await expect(page.locator('.my-table-row').nth(2)).toContainText('Steve');

To get all values from an specific column in an array:(JS)

    const textsFromNthColumn = [];    
    const rowCount = await page.locator('.table-tbody').locator('tr').count();
    
    for (let i = 0; i < rowCount; i++) {
       textsFromNthColumn.push(await page.locator('.table-tbody').locator('tr').nth(i).locator('td').nth(n).innerText())
    }  //change n with your column number
    
    console.log(textsFromNthColumn)

Reference: How to get text from a specific column from a table in Playwright

https://github.com/microsoft/playwright/issues/9747

Vishal Aggarwal
  • 1,929
  • 1
  • 13
  • 23
0

I rewrote the xpath and managed to eventually get the names. This is what I ended up with (but I still don't understand why the use of the input tag didn't work):

        List<string> textsFromNthColumn = new List<string>();
        var rowCount = await Page.Locator("//*[@summary=\"Planners\"]/tbody/tr//td/*[contains(@id,'tdrow_[C:1]_txt-tb')]").CountAsync();

        for (int i = 0; i < rowCount; i++)
        {
            textsFromNthColumn.Add(await Page.Locator("//*[@summary=\"Planners\"]/tbody/tr//td/*[contains(@id,'tdrow_[C:1]_txt-tb')]").Nth(i).GetAttributeAsync("value"));
        }