@vuu-ui/vuu-playwright-helpers 3.5.22 → 3.5.23
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/package.json +2 -2
- package/src/PwTable.js +51 -0
- package/types/PwTable.d.ts +88 -0
- package/types/index.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.5.
|
|
2
|
+
"version": "3.5.23",
|
|
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.
|
|
12
|
+
"@vuu-ui/vuu-protocol-types": "3.5.23"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"@playwright/test": "^1.62.1"
|
package/src/PwTable.js
CHANGED
|
@@ -3,6 +3,7 @@ import { PwComponent } from "./PwComponent.js";
|
|
|
3
3
|
import { PwContextMenu } from "./PwContextMenu.js";
|
|
4
4
|
import { PwTableHeaderCell } from "./PwTableHeaderCell.js";
|
|
5
5
|
import { byDataIcon, cssAttributeValue } from "./selector-utils.js";
|
|
6
|
+
const SCROLL_TOLERANCE = 1;
|
|
6
7
|
const byAriaRowIndex = (ariaRowIndex)=>`[aria-rowindex="${ariaRowIndex}"]:scope`;
|
|
7
8
|
const xpathStringLiteral = (value)=>{
|
|
8
9
|
if (!value.includes("'")) return `'${value}'`;
|
|
@@ -17,6 +18,56 @@ class PwTable extends PwComponent {
|
|
|
17
18
|
get scrollbarContainer() {
|
|
18
19
|
return this.locator.locator(".vuuTable-scrollbarContainer");
|
|
19
20
|
}
|
|
21
|
+
scrollPosition() {
|
|
22
|
+
return this.scrollbarContainer.evaluate(({ scrollLeft, scrollTop })=>({
|
|
23
|
+
scrollLeft,
|
|
24
|
+
scrollTop
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
scrollUp(distance) {
|
|
28
|
+
return this.scroll("vertical", -1, distance);
|
|
29
|
+
}
|
|
30
|
+
scrollDown(distance) {
|
|
31
|
+
return this.scroll("vertical", 1, distance);
|
|
32
|
+
}
|
|
33
|
+
scrollLeft(distance) {
|
|
34
|
+
return this.scroll("horizontal", -1, distance);
|
|
35
|
+
}
|
|
36
|
+
scrollRight(distance) {
|
|
37
|
+
return this.scroll("horizontal", 1, distance);
|
|
38
|
+
}
|
|
39
|
+
async scroll(axis, direction, distance) {
|
|
40
|
+
if ("number" == typeof distance && distance < 0) throw Error("PwTable, scroll, distance must not be negative, use the opposite direction");
|
|
41
|
+
await this.scrollbarContainer.evaluate((el, { axis, direction, distance })=>{
|
|
42
|
+
const vertical = "vertical" === axis;
|
|
43
|
+
const current = vertical ? el.scrollTop : el.scrollLeft;
|
|
44
|
+
const max = vertical ? el.scrollHeight - el.clientHeight : el.scrollWidth - el.clientWidth;
|
|
45
|
+
const pos = "start" === distance ? 0 : "end" === distance ? max : current + direction * ("page" === distance ? el.clientHeight : distance);
|
|
46
|
+
el.scrollTo({
|
|
47
|
+
[vertical ? "top" : "left"]: Math.min(max, Math.max(0, pos)),
|
|
48
|
+
behavior: "instant"
|
|
49
|
+
});
|
|
50
|
+
}, {
|
|
51
|
+
axis,
|
|
52
|
+
direction,
|
|
53
|
+
distance
|
|
54
|
+
});
|
|
55
|
+
await expect.poll(()=>this.isContentScrollSynced(), {
|
|
56
|
+
message: "PwTable, content container scroll position not synced"
|
|
57
|
+
}).toBe(true);
|
|
58
|
+
}
|
|
59
|
+
isContentScrollSynced() {
|
|
60
|
+
return this.locator.evaluate((table, tolerance)=>{
|
|
61
|
+
const scrollbar = table.querySelector(".vuuTable-scrollbarContainer");
|
|
62
|
+
const content = table.querySelector(".vuuTable-contentContainer");
|
|
63
|
+
if (!scrollbar || !content) return false;
|
|
64
|
+
const isSynced = (sourcePos, sourceMax, targetPos, targetMax)=>{
|
|
65
|
+
const expected = sourceMax > 0 ? sourcePos / sourceMax * targetMax : 0;
|
|
66
|
+
return Math.abs(targetPos - expected) <= tolerance;
|
|
67
|
+
};
|
|
68
|
+
return isSynced(scrollbar.scrollTop, scrollbar.scrollHeight - scrollbar.clientHeight, content.scrollTop, content.scrollHeight - content.clientHeight) && isSynced(scrollbar.scrollLeft, scrollbar.scrollWidth - scrollbar.clientWidth, content.scrollLeft, content.scrollWidth - content.clientWidth);
|
|
69
|
+
}, SCROLL_TOLERANCE);
|
|
70
|
+
}
|
|
20
71
|
row(row) {
|
|
21
72
|
return this.locator.locator(`[aria-rowindex="${row}"]`);
|
|
22
73
|
}
|
package/types/PwTable.d.ts
CHANGED
|
@@ -4,6 +4,20 @@ import { PwComponent } from "./PwComponent";
|
|
|
4
4
|
import { PwContextMenu } from "./PwContextMenu";
|
|
5
5
|
import { PwTableHeaderCell } from "./PwTableHeaderCell";
|
|
6
6
|
type AriaRole = "cell" | "textbox" | "combobox";
|
|
7
|
+
/**
|
|
8
|
+
* How far to scroll: 'start' or 'end' scroll to that end of the axis, a number
|
|
9
|
+
* scrolls by that many pixels in the direction of the method.
|
|
10
|
+
*/
|
|
11
|
+
export type ScrollDistance = "start" | "end" | number;
|
|
12
|
+
/**
|
|
13
|
+
* As ScrollDistance, plus 'page' to scroll vertically by the height of the
|
|
14
|
+
* viewport (as the PageUp and PageDown keys do).
|
|
15
|
+
*/
|
|
16
|
+
export type VerticalScrollDistance = ScrollDistance | "page";
|
|
17
|
+
export interface ScrollPosition {
|
|
18
|
+
scrollLeft: number;
|
|
19
|
+
scrollTop: number;
|
|
20
|
+
}
|
|
7
21
|
/**
|
|
8
22
|
* A Vuu Table. Rows are located by 1-based aria row index, which includes
|
|
9
23
|
* header rows (with one header, the first data row is 2).
|
|
@@ -39,6 +53,80 @@ export declare class PwTable extends PwComponent {
|
|
|
39
53
|
* });
|
|
40
54
|
*/
|
|
41
55
|
get scrollbarContainer(): Locator;
|
|
56
|
+
/**
|
|
57
|
+
* The scroll position of the scrollbar container.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* test("scrolled to top", async ({ page }) => {
|
|
61
|
+
* const table = new PwTable(page);
|
|
62
|
+
* expect((await table.scrollPosition()).scrollTop).toBe(0);
|
|
63
|
+
* });
|
|
64
|
+
*/
|
|
65
|
+
scrollPosition(): Promise<ScrollPosition>;
|
|
66
|
+
/**
|
|
67
|
+
* Scroll up, by a number of pixels, a page (the height of the viewport), or
|
|
68
|
+
* to the 'start' (top) or 'end' (bottom). Scrolls the scrollbar container,
|
|
69
|
+
* as a user dragging the scrollbar would, and resolves once the content
|
|
70
|
+
* container has been scrolled to match.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* test("scroll back to top", async ({ page }) => {
|
|
74
|
+
* const table = new PwTable(page);
|
|
75
|
+
* await table.scrollDown("page");
|
|
76
|
+
* await table.scrollUp("start");
|
|
77
|
+
* await expect(table.row(2)).toBeInViewport();
|
|
78
|
+
* });
|
|
79
|
+
*/
|
|
80
|
+
scrollUp(distance: VerticalScrollDistance): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Scroll down, by a number of pixels, a page (the height of the viewport),
|
|
83
|
+
* or to the 'start' (top) or 'end' (bottom). Scrolls the scrollbar
|
|
84
|
+
* container, as a user dragging the scrollbar would, and resolves once the
|
|
85
|
+
* content container has been scrolled to match.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* test("scroll to last row", async ({ page }) => {
|
|
89
|
+
* const table = new PwTable(page);
|
|
90
|
+
* await table.scrollDown("end");
|
|
91
|
+
* await expect(table.row(1001)).toBeInViewport();
|
|
92
|
+
* });
|
|
93
|
+
*/
|
|
94
|
+
scrollDown(distance: VerticalScrollDistance): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Scroll left, by a number of pixels, or to the 'start' (leftmost) or 'end'
|
|
97
|
+
* (rightmost). Scrolls the scrollbar container, as a user dragging the
|
|
98
|
+
* scrollbar would, and resolves once the content container has been
|
|
99
|
+
* scrolled to match.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* test("scroll back to first column", async ({ page }) => {
|
|
103
|
+
* const table = new PwTable(page);
|
|
104
|
+
* await table.scrollRight("end");
|
|
105
|
+
* await table.scrollLeft("start");
|
|
106
|
+
* await expect(table.locateCell(2, 1)).toBeInViewport();
|
|
107
|
+
* });
|
|
108
|
+
*/
|
|
109
|
+
scrollLeft(distance: ScrollDistance): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Scroll right, by a number of pixels, or to the 'start' (leftmost) or
|
|
112
|
+
* 'end' (rightmost). Scrolls the scrollbar container, as a user dragging the
|
|
113
|
+
* scrollbar would, and resolves once the content container has been
|
|
114
|
+
* scrolled to match.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* test("scroll right by 200px", async ({ page }) => {
|
|
118
|
+
* const table = new PwTable(page);
|
|
119
|
+
* await table.scrollRight(200);
|
|
120
|
+
* expect((await table.scrollPosition()).scrollLeft).toBe(200);
|
|
121
|
+
* });
|
|
122
|
+
*/
|
|
123
|
+
scrollRight(distance: ScrollDistance): Promise<void>;
|
|
124
|
+
private scroll;
|
|
125
|
+
/**
|
|
126
|
+
* The table keeps the content container at the same proportional scroll
|
|
127
|
+
* position as the scrollbar container.
|
|
128
|
+
*/
|
|
129
|
+
private isContentScrollSynced;
|
|
42
130
|
/**
|
|
43
131
|
* Row Locator by 1-based aria row index, including headers.
|
|
44
132
|
*
|
package/types/index.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export { PwColumnPicker } from "./PwColumnPicker";
|
|
|
5
5
|
export { PwComponent, type PwComponentTarget } from "./PwComponent";
|
|
6
6
|
export { PwContextMenu } from "./PwContextMenu";
|
|
7
7
|
export { PwMenuItem } from "./PwMenuItem";
|
|
8
|
-
export { PwTable } from "./PwTable";
|
|
8
|
+
export { PwTable, type ScrollDistance, type ScrollPosition, type VerticalScrollDistance, } from "./PwTable";
|
|
9
9
|
export { PwTableFooter } from "./PwTableFooter";
|
|
10
10
|
export { PwTableHeaderCell } from "./PwTableHeaderCell";
|