@vuu-ui/vuu-playwright-helpers 3.5.5 → 3.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  Playwright helpers for Vuu components.
4
4
 
5
+ All helpers extend `PlaywrightPageObject` and are instantiated from the Playwright `page`.
6
+ `PwTable` locates its target element using a default CSS selector, which can be
7
+ overridden at runtime. `PwTableHeaderCell` requires an explicit CSS selector.
8
+
5
9
  ```ts
6
- const cell = await table.locateCell(2, "currency");
10
+ // uses the default selector (.vuuTable)
11
+ const table = new PwTable(page);
12
+ // override the default selector
13
+ const table1 = new PwTable(page, '[data-testid="table-1"]');
14
+
15
+ const cell = await table.cell("currency", 2);
16
+ const header = table.headerCell("currency");
17
+ const isSelected = await header.isSelected;
18
+ await header.assertSelected();
19
+ await table.editCell("currency", 2, "USD"); // commits by default
20
+ await table.editCell("currency", 2, "EUR", "cancel");
7
21
  ```
22
+
23
+ Prefer `cell(colName, ariaRowIndex)` for new usage. `ariaRowIndex` is the 1-based
24
+ ARIA row index, including header rows (with one header, the first data row is 2).
25
+ The existing `locateCell` overloads remain available for gradual migration.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.5.5",
2
+ "version": "3.5.7",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./src/index.js",
@@ -9,7 +9,7 @@
9
9
  "type-defs": "node ../../scripts/build-type-defs.mjs"
10
10
  },
11
11
  "dependencies": {
12
- "@vuu-ui/vuu-protocol-types": "3.5.5"
12
+ "@vuu-ui/vuu-protocol-types": "3.5.7"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "@playwright/test": "^1.62.1"
@@ -0,0 +1,7 @@
1
+ class PlaywrightPageObject {
2
+ page;
3
+ constructor(page){
4
+ this.page = page;
5
+ }
6
+ }
7
+ export { PlaywrightPageObject };
@@ -1,14 +1,20 @@
1
1
  import { expect } from "@playwright/test";
2
+ import { PlaywrightPageObject } from "./PlaywrightPageObject.js";
3
+ import { PwTableHeaderCell } from "./PwTableHeaderCell.js";
2
4
  const byAriaRowIndex = (ariaRowIndex)=>`[aria-rowindex="${ariaRowIndex}"]:scope`;
3
5
  const xpathStringLiteral = (value)=>{
4
6
  if (!value.includes("'")) return `'${value}'`;
5
7
  if (!value.includes('"')) return `"${value}"`;
6
8
  return `concat('${value.split("'").join("', \"'\", '")}')`;
7
9
  };
8
- class TableOM {
9
- #locator;
10
- constructor(locator){
11
- this.#locator = locator;
10
+ class PwTable extends PlaywrightPageObject {
11
+ cssSelector;
12
+ defaultCssSelector = ".vuuTable";
13
+ constructor(page, cssSelector){
14
+ super(page), this.cssSelector = cssSelector;
15
+ }
16
+ get #locator() {
17
+ return this.page.locator(this.cssSelector ?? this.defaultCssSelector);
12
18
  }
13
19
  get contentContainer() {
14
20
  return this.#locator.locator(".vuuTable-contentContainer");
@@ -19,12 +25,30 @@ class TableOM {
19
25
  row(row) {
20
26
  return this.#locator.locator(`[aria-rowindex="${row}"]`);
21
27
  }
28
+ cell(colName, ariaRowIndex) {
29
+ return this.locateCell(ariaRowIndex, colName);
30
+ }
31
+ async editCell(columnName, ariaRowIndex, value, action = "commit") {
32
+ const cell = await this.cell(columnName, ariaRowIndex);
33
+ await cell.dblclick();
34
+ const textbox = cell.getByRole("textbox");
35
+ await textbox.fill(value);
36
+ await expect(textbox).toHaveValue(value);
37
+ await textbox.press("commit" === action ? "Enter" : "Escape");
38
+ }
39
+ headerCell(columnName) {
40
+ const escapedColumnName = Array.from(columnName, (character)=>{
41
+ const code = character.charCodeAt(0);
42
+ return '"' === character || "\\" === character || code < 32 || 127 === code ? `\\${code.toString(16)} ` : character;
43
+ }).join("");
44
+ return new PwTableHeaderCell(this.page, `${this.cssSelector ?? this.defaultCssSelector} >> .vuuTableHeaderCell[data-column-name="${escapedColumnName}"]`);
45
+ }
22
46
  locateCell(rowOrText, column) {
23
47
  if ("number" == typeof rowOrText && "number" == typeof column) return this.#locator.locator(`[aria-rowindex="${rowOrText}"] > [aria-colindex="${column}"]`);
24
48
  if ("number" == typeof rowOrText && "string" == typeof column) {
25
49
  const columnHeader = this.#locator.locator(`xpath=.//*[@data-column-name=${xpathStringLiteral(column)}]`).first();
26
50
  return columnHeader.getAttribute("aria-colindex").then((ariaColIndex)=>{
27
- if (null === ariaColIndex) throw Error(`TableOM, locateCell, column "${column}" does not have an aria-colindex`);
51
+ if (null === ariaColIndex) throw Error(`PwTable, locateCell, column "${column}" does not have an aria-colindex`);
28
52
  return this.#locator.locator(`[aria-rowindex="${rowOrText}"] > [aria-colindex="${ariaColIndex}"]`);
29
53
  });
30
54
  }
@@ -65,13 +89,13 @@ class TableOM {
65
89
  const [cell, text, role] = this.getCellText(arg1, arg2, arg3, arg4);
66
90
  const target = role ? cell.getByRole(role) : cell;
67
91
  if (target) await expect(target).toHaveValue(text);
68
- else throw Error("TableOM, assertCellValue, invalid parameters");
92
+ else throw Error("PwTable, assertCellValue, invalid parameters");
69
93
  }
70
94
  async assertCellContent(arg1, arg2, arg3, arg4) {
71
95
  const [cell, text, role] = this.getCellText(arg1, arg2, arg3, arg4);
72
96
  const target = role ? cell.getByRole(role) : cell;
73
97
  if (target) await expect(target).toHaveText(text);
74
- else throw Error("TableOM, assertCellContent, invalid parameters");
98
+ else throw Error("PwTable, assertCellContent, invalid parameters");
75
99
  }
76
100
  async assertCellIsFocused(rowOrCell, columnOrRole, role) {
77
101
  let target;
@@ -80,7 +104,7 @@ class TableOM {
80
104
  target = role ? cell.getByRole(role) : cell;
81
105
  } else if ("number" != typeof rowOrCell) target = columnOrRole && "number" != typeof columnOrRole ? rowOrCell.getByRole(columnOrRole) : rowOrCell;
82
106
  if (target) await expect(target).toBeFocused();
83
- else throw Error("TableOM, assertCellIsFocused, invalid parameters");
107
+ else throw Error("PwTable, assertCellIsFocused, invalid parameters");
84
108
  }
85
109
  async assertCellIsEditing(rowOrCell, columnOrEditing, isEditing) {
86
110
  let target;
@@ -97,7 +121,7 @@ class TableOM {
97
121
  if (editing) return expect(target.locator(editControl)).toContainClass("vuuEditing");
98
122
  return expect(target.locator(editControl)).not.toContainClass("vuuEditing");
99
123
  }
100
- throw Error("TableOM, assertCellIsEditing, invalid parameters");
124
+ throw Error("PwTable, assertCellIsEditing, invalid parameters");
101
125
  }
102
126
  async assertRenderedRows({ from, to }, renderBufferSize, totalRowCount, headerCount = 1) {
103
127
  const leadingBufferedRows = from < renderBufferSize ? from : renderBufferSize;
@@ -126,4 +150,4 @@ class TableOM {
126
150
  if (lastRendered > lastVisible) await expect(this.locateCell(2, lastVisible + 1)).not.toBeInViewport();
127
151
  }
128
152
  }
129
- export { TableOM };
153
+ export { PwTable };
@@ -0,0 +1,15 @@
1
+ import { expect } from "@playwright/test";
2
+ import { PlaywrightPageObject } from "./PlaywrightPageObject.js";
3
+ class PwTableHeaderCell extends PlaywrightPageObject {
4
+ cssSelector;
5
+ constructor(page, cssSelector){
6
+ super(page), this.cssSelector = cssSelector;
7
+ }
8
+ get isSelected() {
9
+ return this.page.locator(this.cssSelector).evaluate((element)=>element.classList.contains("vuuTableHeaderCell-selected"));
10
+ }
11
+ async assertSelected() {
12
+ await expect(this.page.locator(this.cssSelector)).toContainClass("vuuTableHeaderCell-selected");
13
+ }
14
+ }
15
+ export { PwTableHeaderCell };
package/src/index.js CHANGED
@@ -1 +1,3 @@
1
- export { TableOM } from "./Table.js";
1
+ export { PlaywrightPageObject } from "./PlaywrightPageObject.js";
2
+ export { PwTable } from "./PwTable.js";
3
+ export { PwTableHeaderCell } from "./PwTableHeaderCell.js";
@@ -0,0 +1,5 @@
1
+ import type { Page } from "@playwright/test";
2
+ export declare class PlaywrightPageObject {
3
+ protected readonly page: Page;
4
+ constructor(page: Page);
5
+ }
@@ -1,15 +1,29 @@
1
- import { type Locator } from "@playwright/test";
1
+ import { type Locator, type Page } from "@playwright/test";
2
2
  import type { VuuRange } from "@vuu-ui/vuu-protocol-types";
3
+ import { PlaywrightPageObject } from "./PlaywrightPageObject";
4
+ import { PwTableHeaderCell } from "./PwTableHeaderCell";
3
5
  type AriaRole = "cell" | "textbox" | "combobox";
4
- export declare class TableOM {
6
+ export declare class PwTable extends PlaywrightPageObject {
5
7
  #private;
6
- constructor(locator: Locator);
8
+ private readonly cssSelector?;
9
+ protected readonly defaultCssSelector = ".vuuTable";
10
+ /**
11
+ * @param page the Playwright page
12
+ * @param cssSelector optional selector for the Table, overrides defaultCssSelector
13
+ */
14
+ constructor(page: Page, cssSelector?: string | undefined);
7
15
  get contentContainer(): Locator;
8
16
  get scrollbarContainer(): Locator;
9
17
  /**
10
18
  * row Locator by aria-index
11
19
  */
12
20
  row(row: number): Locator;
21
+ /**
22
+ * Locate cell by column name and 1-based aria row index, including headers.
23
+ */
24
+ cell(colName: string, ariaRowIndex: number): Promise<Locator>;
25
+ editCell(columnName: string, ariaRowIndex: number, value: string, action?: "commit" | "cancel"): Promise<void>;
26
+ headerCell(columnName: string): PwTableHeaderCell;
13
27
  /**
14
28
  * Locate cell by cell contents
15
29
  * @param text
@@ -0,0 +1,8 @@
1
+ import { type Page } from "@playwright/test";
2
+ import { PlaywrightPageObject } from "./PlaywrightPageObject";
3
+ export declare class PwTableHeaderCell extends PlaywrightPageObject {
4
+ private readonly cssSelector;
5
+ constructor(page: Page, cssSelector: string);
6
+ get isSelected(): Promise<boolean>;
7
+ assertSelected(): Promise<void>;
8
+ }
package/types/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export { TableOM } from "./Table";
1
+ export { PlaywrightPageObject } from "./PlaywrightPageObject";
2
+ export { PwTable } from "./PwTable";
3
+ export { PwTableHeaderCell } from "./PwTableHeaderCell";