diff --git a/docs-site/docs/recipes/read-table-rows.md b/docs-site/docs/recipes/read-table-rows.md new file mode 100644 index 0000000..5362a20 --- /dev/null +++ b/docs-site/docs/recipes/read-table-rows.md @@ -0,0 +1,120 @@ +--- +description: "Read HTML table rows with Selenium Boot Locator.rows(), find rows by column value, assert cells, and handle short rows and group headings." +id: read-table-rows +title: Read table rows +sidebar_label: Read table rows +--- + +# Read table rows + +Read an HTML table as data instead of walking its cells by hand. Call `rows()` on a +locator that points at the ``, and you get back one map per row, keyed by +column header. + +## Read, find, and assert on rows + +Given a table like this: + +```html +
+ + + + + + + +
Last NameFirst NameDue
SmithJohn$50.00
DoeJason$100.00
+``` + +read it, find a row by a column's value, and assert on a cell: + +```java title="AccountsTableTest.java" +import com.seleniumboot.test.BaseTest; +import java.util.List; +import java.util.Map; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class AccountsTableTest extends BaseTest { + + @Test + public void doeOwesOneHundred() { + open("/accounts"); + + // One map per row, keyed by column header: + // [{Last Name=Smith, First Name=John, Due=$50.00}, + // {Last Name=Doe, First Name=Jason, Due=$100.00}] + List> rows = $("#table1").rows(); + + // Find a row by a column's value + Map doe = rows.stream() + .filter(row -> row.get("Last Name").equals("Doe")) + .findFirst() + .orElseThrow(); + + // Assert on a cell by its column header + Assert.assertEquals(doe.get("Due"), "$100.00"); + // fails with: expected [$100.00] but found [$90.00] if the cell says $90.00 + } +} +``` + +`rows()` returns a plain `List`, so finding a row is ordinary Java: a stream as above, +or a `for` loop if you prefer. + +For each example below, reuse `#table1` and its ``, replacing only the ``. + +## Short rows + +When a row has fewer `` cells than there are headers, `rows()` retains every +header key and fills missing trailing values with `""`. Here, Smith's final +cell is missing, while Doe's row is complete: + +```html + + SmithJohn + DoeJason$100.00 + +``` + +```java +List> rows = $("#table1").rows(); +Map smith = rows.get(0); +Assert.assertTrue(smith.containsKey("Due")); +Assert.assertEquals(smith.get("Due"), ""); +// Smith retains the Due key with an empty-string value. +Assert.assertEquals(rows.get(1).get("Due"), "$100.00"); +// Doe's complete row keeps its original value. +``` + +Note that cells are matched by position. Omitting a middle `` shifts later +values to earlier columns; use an empty `` to preserve the position. +Cells beyond the header count are ignored. + +## Group rows containing only `` + +Once the column headers are selected, rows containing no `` cells are +skipped. The group heading below spans three columns but is not a data row: + +```html + + Outstanding accounts + SmithJohn + DoeJason$100.00 + +``` + +```java +List> rows = $("#table1").rows(); +Assert.assertEquals(rows.size(), 2); +Assert.assertEquals(rows.get(0).get("Last Name"), "Smith"); +Assert.assertEquals(rows.get(1).get("Last Name"), "Doe"); +// The group heading is skipped; Smith and Doe remain in order. +``` + +Note that header selection matters: without a `` header, the first row +containing `` supplies the keys. Keep the column headers in `` so a +preceding group heading is not selected as the header. + +**Deeper reference:** [Accessibility-First Locators](/docs/guides/semantic-locators) — the `$()` / `Locator` API that `rows()` belongs to. diff --git a/docs-site/sidebars.js b/docs-site/sidebars.js index bc790c3..a8450a7 100644 --- a/docs-site/sidebars.js +++ b/docs-site/sidebars.js @@ -65,6 +65,7 @@ const sidebars = { 'recipes/handle-new-windows', 'recipes/drag-and-drop', 'recipes/handle-shadow-dom', + 'recipes/read-table-rows', ], }, {