@rickcedwhat/playwright-smart-table 6.9.0 → 6.10.0
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/dist/engine/rowFinder.js +153 -168
- package/dist/engine/tableIteration.js +105 -120
- package/dist/engine/tableMapper.js +88 -103
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/presets/glide/columns.js +23 -32
- package/dist/presets/glide/headers.js +18 -27
- package/dist/presets/glide/index.d.ts +9 -9
- package/dist/presets/glide/index.js +24 -33
- package/dist/presets/mui.js +197 -124
- package/dist/presets/rdg.d.ts +1 -1
- package/dist/presets/rdg.js +32 -41
- package/dist/smartRow.js +162 -96
- package/dist/strategies/columns.js +2 -11
- package/dist/strategies/dedupe.js +3 -12
- package/dist/strategies/fill.js +20 -29
- package/dist/strategies/headers.js +22 -31
- package/dist/strategies/index.d.ts +4 -0
- package/dist/strategies/index.js +3 -0
- package/dist/strategies/loading.js +24 -33
- package/dist/strategies/pagination.js +21 -30
- package/dist/strategies/sorting.js +18 -31
- package/dist/strategies/stabilization.js +28 -37
- package/dist/strategies/viewport.d.ts +52 -0
- package/dist/strategies/viewport.js +123 -0
- package/dist/typeContext.d.ts +1 -1
- package/dist/typeContext.js +97 -0
- package/dist/types.d.ts +97 -0
- package/dist/useTable.js +98 -76
- package/dist/utils/debugUtils.js +5 -16
- package/dist/utils/elementTracker.js +27 -40
- package/dist/utils/mutex.js +5 -16
- package/dist/utils/navigationBarrier.js +25 -36
- package/dist/utils/paginationPath.js +102 -115
- package/dist/utils/smartRowArray.js +2 -11
- package/dist/utils.js +4 -13
- package/package.json +9 -5
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.TableMapper = void 0;
|
|
13
4
|
const headers_1 = require("../strategies/headers");
|
|
@@ -22,69 +13,65 @@ class TableMapper {
|
|
|
22
13
|
log(msg) {
|
|
23
14
|
(0, debugUtils_1.logDebug)(this.config, 'verbose', msg);
|
|
24
15
|
}
|
|
25
|
-
getMap(timeout) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
yield this.rootLocator.scrollIntoViewIfNeeded({ timeout: 1000 });
|
|
36
|
-
}
|
|
37
|
-
catch (e) { }
|
|
16
|
+
async getMap(timeout) {
|
|
17
|
+
var _a;
|
|
18
|
+
if (this._headerMap)
|
|
19
|
+
return this._headerMap;
|
|
20
|
+
this.log('Mapping headers...');
|
|
21
|
+
const headerTimeout = timeout !== null && timeout !== void 0 ? timeout : 3000;
|
|
22
|
+
const startTime = Date.now();
|
|
23
|
+
if (this.config.autoScroll) {
|
|
24
|
+
try {
|
|
25
|
+
await this.rootLocator.scrollIntoViewIfNeeded({ timeout: 1000 });
|
|
38
26
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// 3. Attempt Scan
|
|
66
|
-
try {
|
|
67
|
-
const rawHeaders = yield strategy(context);
|
|
68
|
-
const entries = yield this.processHeaders(rawHeaders);
|
|
69
|
-
// Success
|
|
70
|
-
this._headerMap = new Map(entries);
|
|
71
|
-
this.log(`Mapped ${entries.length} columns: ${JSON.stringify(entries.map(e => e[0]))}`);
|
|
72
|
-
return this._headerMap;
|
|
73
|
-
}
|
|
74
|
-
catch (e) {
|
|
75
|
-
lastError = e;
|
|
76
|
-
this.log(`Header mapping failed. Attempt ${Math.floor((Date.now() - startTime) / 100)}: ${e.message}`);
|
|
77
|
-
yield new Promise(r => setTimeout(r, 100));
|
|
27
|
+
catch (e) { }
|
|
28
|
+
}
|
|
29
|
+
const headerLoc = this.resolve(this.config.headerSelector, this.rootLocator);
|
|
30
|
+
const strategy = this.config.strategies.header || headers_1.HeaderStrategies.visible;
|
|
31
|
+
const context = {
|
|
32
|
+
root: this.rootLocator,
|
|
33
|
+
config: this.config,
|
|
34
|
+
page: this.rootLocator.page(),
|
|
35
|
+
resolve: this.resolve
|
|
36
|
+
};
|
|
37
|
+
let lastError = null;
|
|
38
|
+
while (Date.now() - startTime < headerTimeout) {
|
|
39
|
+
// 1. Wait for visibility
|
|
40
|
+
try {
|
|
41
|
+
await headerLoc.first().waitFor({ state: 'visible', timeout: 200 });
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
// Continue to check existing/loading state even if not strictly "visible" yet
|
|
45
|
+
}
|
|
46
|
+
// 2. Check Smart Loading State
|
|
47
|
+
if ((_a = this.config.strategies.loading) === null || _a === void 0 ? void 0 : _a.isHeaderLoading) {
|
|
48
|
+
const isStable = !(await this.config.strategies.loading.isHeaderLoading(context));
|
|
49
|
+
if (!isStable) {
|
|
50
|
+
this.log('Headers are loading/unstable... waiting');
|
|
51
|
+
await new Promise(r => setTimeout(r, 100));
|
|
52
|
+
continue;
|
|
78
53
|
}
|
|
79
54
|
}
|
|
80
|
-
|
|
81
|
-
|
|
55
|
+
// 3. Attempt Scan
|
|
56
|
+
try {
|
|
57
|
+
const rawHeaders = await strategy(context);
|
|
58
|
+
const entries = await this.processHeaders(rawHeaders);
|
|
59
|
+
// Success
|
|
60
|
+
this._headerMap = new Map(entries);
|
|
61
|
+
this.log(`Mapped ${entries.length} columns: ${JSON.stringify(entries.map(e => e[0]))}`);
|
|
62
|
+
return this._headerMap;
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
lastError = e;
|
|
66
|
+
this.log(`Header mapping failed. Attempt ${Math.floor((Date.now() - startTime) / 100)}: ${e.message}`);
|
|
67
|
+
await new Promise(r => setTimeout(r, 100));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
throw lastError || new Error(`Timed out waiting for headers after ${headerTimeout}ms`);
|
|
82
71
|
}
|
|
83
|
-
remapHeaders() {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
yield this.getMap();
|
|
87
|
-
});
|
|
72
|
+
async remapHeaders() {
|
|
73
|
+
this._headerMap = null;
|
|
74
|
+
await this.getMap();
|
|
88
75
|
}
|
|
89
76
|
getMapSync() {
|
|
90
77
|
return this._headerMap;
|
|
@@ -95,43 +82,41 @@ class TableMapper {
|
|
|
95
82
|
clear() {
|
|
96
83
|
this._headerMap = null;
|
|
97
84
|
}
|
|
98
|
-
processHeaders(rawHeaders) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
text
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
this.log(`Header mapping index ${i}: "${text}"`);
|
|
113
|
-
entries.push([text, i]);
|
|
114
|
-
seenHeaders.add(text);
|
|
115
|
-
}
|
|
116
|
-
// Validation: Check for empty table
|
|
117
|
-
if (entries.length === 0) {
|
|
118
|
-
throw new Error(`Initialization Error: No columns found using selector "${this.config.headerSelector}". Check your selector or ensure the table is visible.`);
|
|
119
|
-
}
|
|
120
|
-
// Validation: Check for duplicates
|
|
121
|
-
const seen = new Set();
|
|
122
|
-
const duplicates = new Set();
|
|
123
|
-
for (const [name] of entries) {
|
|
124
|
-
if (seen.has(name)) {
|
|
125
|
-
duplicates.add(name);
|
|
126
|
-
}
|
|
127
|
-
seen.add(name);
|
|
85
|
+
async processHeaders(rawHeaders) {
|
|
86
|
+
const seenHeaders = new Set();
|
|
87
|
+
const entries = [];
|
|
88
|
+
for (let i = 0; i < rawHeaders.length; i++) {
|
|
89
|
+
let text = rawHeaders[i].trim() || `__col_${i}`;
|
|
90
|
+
if (this.config.headerTransformer) {
|
|
91
|
+
text = await this.config.headerTransformer({
|
|
92
|
+
text,
|
|
93
|
+
index: i,
|
|
94
|
+
locator: this.resolve(this.config.headerSelector, this.rootLocator).nth(i),
|
|
95
|
+
seenHeaders
|
|
96
|
+
});
|
|
128
97
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
98
|
+
this.log(`Header mapping index ${i}: "${text}"`);
|
|
99
|
+
entries.push([text, i]);
|
|
100
|
+
seenHeaders.add(text);
|
|
101
|
+
}
|
|
102
|
+
// Validation: Check for empty table
|
|
103
|
+
if (entries.length === 0) {
|
|
104
|
+
throw new Error(`Initialization Error: No columns found using selector "${this.config.headerSelector}". Check your selector or ensure the table is visible.`);
|
|
105
|
+
}
|
|
106
|
+
// Validation: Check for duplicates
|
|
107
|
+
const seen = new Set();
|
|
108
|
+
const duplicates = new Set();
|
|
109
|
+
for (const [name] of entries) {
|
|
110
|
+
if (seen.has(name)) {
|
|
111
|
+
duplicates.add(name);
|
|
132
112
|
}
|
|
133
|
-
|
|
134
|
-
}
|
|
113
|
+
seen.add(name);
|
|
114
|
+
}
|
|
115
|
+
if (duplicates.size > 0) {
|
|
116
|
+
const dupList = Array.from(duplicates).map(d => `"${d}"`).join(', ');
|
|
117
|
+
throw new Error(`Initialization Error: Duplicate column names found: ${dupList}. Use 'headerTransformer' to rename duplicate columns.`);
|
|
118
|
+
}
|
|
119
|
+
return entries;
|
|
135
120
|
}
|
|
136
121
|
}
|
|
137
122
|
exports.TableMapper = TableMapper;
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* Generated by scripts/embed-version.mjs from package.json
|
|
4
4
|
*/
|
|
5
5
|
/** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
|
|
6
|
-
export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.
|
|
6
|
+
export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.10.0";
|
package/dist/packageVersion.js
CHANGED
|
@@ -6,4 +6,4 @@ exports.PLAYWRIGHT_SMART_TABLE_VERSION = void 0;
|
|
|
6
6
|
* Generated by scripts/embed-version.mjs from package.json
|
|
7
7
|
*/
|
|
8
8
|
/** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
|
|
9
|
-
exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.
|
|
9
|
+
exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.10.0";
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.glideSnapFirstColumnIntoView = exports.glideSeekColumnIndex = exports.glideGoRight = exports.glideGoLeft = exports.glideGoDown = exports.glideGoUp = void 0;
|
|
13
4
|
/**
|
|
@@ -15,48 +6,48 @@ exports.glideSnapFirstColumnIntoView = exports.glideSeekColumnIndex = exports.gl
|
|
|
15
6
|
* These define HOW to move, not WHEN to move.
|
|
16
7
|
* The orchestration logic lives in _navigateToCell.
|
|
17
8
|
*/
|
|
18
|
-
const glideGoUp = (context) =>
|
|
19
|
-
|
|
20
|
-
}
|
|
9
|
+
const glideGoUp = async (context) => {
|
|
10
|
+
await context.page.keyboard.press('ArrowUp');
|
|
11
|
+
};
|
|
21
12
|
exports.glideGoUp = glideGoUp;
|
|
22
|
-
const glideGoDown = (context) =>
|
|
23
|
-
|
|
24
|
-
}
|
|
13
|
+
const glideGoDown = async (context) => {
|
|
14
|
+
await context.page.keyboard.press('ArrowDown');
|
|
15
|
+
};
|
|
25
16
|
exports.glideGoDown = glideGoDown;
|
|
26
17
|
// Horizontal: use page `.dvn-scroller` (canvas root is not its ancestor). Virtualized rows expose
|
|
27
18
|
// a small window of `td[aria-colindex]` that shifts with scrollLeft.
|
|
28
|
-
const nudgePageScroller = (page, delta) =>
|
|
19
|
+
const nudgePageScroller = async (page, delta) => {
|
|
29
20
|
const scroller = page.locator('.dvn-scroller').first();
|
|
30
|
-
|
|
21
|
+
await scroller.evaluate((el, d) => {
|
|
31
22
|
el.scrollLeft += d;
|
|
32
23
|
}, delta);
|
|
33
|
-
}
|
|
34
|
-
const glideGoLeft = (context) =>
|
|
35
|
-
|
|
36
|
-
}
|
|
24
|
+
};
|
|
25
|
+
const glideGoLeft = async (context) => {
|
|
26
|
+
await nudgePageScroller(context.page, -400);
|
|
27
|
+
};
|
|
37
28
|
exports.glideGoLeft = glideGoLeft;
|
|
38
|
-
const glideGoRight = (context) =>
|
|
39
|
-
|
|
40
|
-
}
|
|
29
|
+
const glideGoRight = async (context) => {
|
|
30
|
+
await nudgePageScroller(context.page, 400);
|
|
31
|
+
};
|
|
41
32
|
exports.glideGoRight = glideGoRight;
|
|
42
33
|
/** Coarse `scrollLeft` toward `columnIndex`; `goLeft`/`goRight` correct the remainder. */
|
|
43
|
-
const glideSeekColumnIndex = (context, columnIndex) =>
|
|
34
|
+
const glideSeekColumnIndex = async (context, columnIndex) => {
|
|
44
35
|
const { page } = context;
|
|
45
36
|
const scroller = page.locator('.dvn-scroller').first();
|
|
46
|
-
|
|
37
|
+
await scroller.evaluate((el, colIdx) => {
|
|
47
38
|
const max = Math.max(0, el.scrollWidth - el.clientWidth);
|
|
48
39
|
const ratio = Math.min(1, Math.max(0, (colIdx + 0.5) / 64));
|
|
49
40
|
el.scrollLeft = Math.floor(ratio * max);
|
|
50
41
|
}, columnIndex);
|
|
51
|
-
|
|
52
|
-
}
|
|
42
|
+
await page.waitForTimeout(100);
|
|
43
|
+
};
|
|
53
44
|
exports.glideSeekColumnIndex = glideSeekColumnIndex;
|
|
54
45
|
/** `scrollLeft = 0` so low `aria-colindex` cells exist again (see smartRow for optional `Home`). */
|
|
55
|
-
const glideSnapFirstColumnIntoView = (context) =>
|
|
46
|
+
const glideSnapFirstColumnIntoView = async (context) => {
|
|
56
47
|
const { page } = context;
|
|
57
|
-
|
|
48
|
+
await page.locator('.dvn-scroller').first().evaluate((el) => {
|
|
58
49
|
el.scrollLeft = 0;
|
|
59
50
|
});
|
|
60
|
-
|
|
61
|
-
}
|
|
51
|
+
await page.waitForTimeout(150);
|
|
52
|
+
};
|
|
62
53
|
exports.glideSnapFirstColumnIntoView = glideSnapFirstColumnIntoView;
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.scrollRightHeader = void 0;
|
|
13
4
|
/**
|
|
14
5
|
* Scans for headers by finding a scrollable container and setting scrollLeft.
|
|
15
6
|
*/
|
|
16
|
-
const scrollRightHeader = (context, options) =>
|
|
7
|
+
const scrollRightHeader = async (context, options) => {
|
|
17
8
|
var _a, _b;
|
|
18
9
|
const { resolve, config, root, page } = context;
|
|
19
10
|
const limit = (_a = options === null || options === void 0 ? void 0 : options.limit) !== null && _a !== void 0 ? _a : 20;
|
|
20
11
|
const scrollAmount = (_b = options === null || options === void 0 ? void 0 : options.scrollAmount) !== null && _b !== void 0 ? _b : 300;
|
|
21
12
|
const collectedHeaders = new Set();
|
|
22
|
-
const getVisible = () =>
|
|
13
|
+
const getVisible = async () => {
|
|
23
14
|
const headerLoc = resolve(config.headerSelector, root);
|
|
24
|
-
const texts =
|
|
15
|
+
const texts = await headerLoc.allInnerTexts();
|
|
25
16
|
return texts.map(t => t.trim());
|
|
26
|
-
}
|
|
27
|
-
let currentHeaders =
|
|
17
|
+
};
|
|
18
|
+
let currentHeaders = await getVisible();
|
|
28
19
|
currentHeaders.forEach(h => collectedHeaders.add(h));
|
|
29
|
-
const scrollerHandle =
|
|
20
|
+
const scrollerHandle = await root.evaluateHandle((el, selector) => {
|
|
30
21
|
if (selector && el.matches(selector))
|
|
31
22
|
return el;
|
|
32
23
|
const effectiveSelector = selector || '.dvn-scroller';
|
|
@@ -35,20 +26,20 @@ const scrollRightHeader = (context, options) => __awaiter(void 0, void 0, void 0
|
|
|
35
26
|
return ancestor;
|
|
36
27
|
return document.querySelector(effectiveSelector);
|
|
37
28
|
}, options === null || options === void 0 ? void 0 : options.selector);
|
|
38
|
-
const isScrollerFound =
|
|
29
|
+
const isScrollerFound = await scrollerHandle.evaluate(el => !!el);
|
|
39
30
|
if (isScrollerFound) {
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
await scrollerHandle.evaluate(el => el.scrollLeft = 0);
|
|
32
|
+
await page.waitForTimeout(200);
|
|
42
33
|
for (let i = 0; i < limit; i++) {
|
|
43
34
|
const sizeBefore = collectedHeaders.size;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const newHeaders =
|
|
35
|
+
await scrollerHandle.evaluate((el, amount) => el.scrollLeft += amount, scrollAmount);
|
|
36
|
+
await page.waitForTimeout(300);
|
|
37
|
+
const newHeaders = await getVisible();
|
|
47
38
|
newHeaders.forEach(h => collectedHeaders.add(h));
|
|
48
39
|
if (collectedHeaders.size === sizeBefore) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const retryHeaders =
|
|
40
|
+
await scrollerHandle.evaluate((el, amount) => el.scrollLeft += amount, scrollAmount);
|
|
41
|
+
await page.waitForTimeout(300);
|
|
42
|
+
const retryHeaders = await getVisible();
|
|
52
43
|
retryHeaders.forEach(h => collectedHeaders.add(h));
|
|
53
44
|
if (collectedHeaders.size === sizeBefore)
|
|
54
45
|
break;
|
|
@@ -58,8 +49,8 @@ const scrollRightHeader = (context, options) => __awaiter(void 0, void 0, void 0
|
|
|
58
49
|
else {
|
|
59
50
|
console.warn("HeaderStrategies.scrollRight: Could not find scroller. Returning visible headers.");
|
|
60
51
|
}
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
await scrollerHandle.evaluate(el => el.scrollLeft = 0);
|
|
53
|
+
await page.waitForTimeout(200);
|
|
63
54
|
return Array.from(collectedHeaders);
|
|
64
|
-
}
|
|
55
|
+
};
|
|
65
56
|
exports.scrollRightHeader = scrollRightHeader;
|
|
@@ -3,20 +3,20 @@ import { FillStrategy, TableConfig } from '../../types';
|
|
|
3
3
|
export declare const GlideStrategies: {
|
|
4
4
|
fillSimple: FillStrategy;
|
|
5
5
|
fill: FillStrategy;
|
|
6
|
-
pagination: import("
|
|
7
|
-
header: (context: import("
|
|
6
|
+
pagination: import("../..").PaginationPrimitives;
|
|
7
|
+
header: (context: import("../..").StrategyContext, options?: {
|
|
8
8
|
limit?: number;
|
|
9
9
|
selector?: string;
|
|
10
10
|
scrollAmount?: number;
|
|
11
11
|
}) => Promise<string[]>;
|
|
12
12
|
navigation: {
|
|
13
|
-
goUp: (context: import("
|
|
14
|
-
goDown: (context: import("
|
|
15
|
-
goLeft: (context: import("
|
|
16
|
-
goRight: (context: import("
|
|
17
|
-
goHome: (context: import("
|
|
18
|
-
snapFirstColumnIntoView: (context: import("
|
|
19
|
-
seekColumnIndex: (context: import("
|
|
13
|
+
goUp: (context: import("../..").StrategyContext) => Promise<void>;
|
|
14
|
+
goDown: (context: import("../..").StrategyContext) => Promise<void>;
|
|
15
|
+
goLeft: (context: import("../..").StrategyContext) => Promise<void>;
|
|
16
|
+
goRight: (context: import("../..").StrategyContext) => Promise<void>;
|
|
17
|
+
goHome: (context: import("../..").StrategyContext) => Promise<void>;
|
|
18
|
+
snapFirstColumnIntoView: (context: import("../..").StrategyContext) => Promise<void>;
|
|
19
|
+
seekColumnIndex: (context: import("../..").StrategyContext, columnIndex: number) => Promise<void>;
|
|
20
20
|
};
|
|
21
21
|
loading: {
|
|
22
22
|
isHeaderLoading: () => Promise<boolean>;
|
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.Glide = exports.GlideStrategies = void 0;
|
|
13
4
|
const columns_1 = require("./columns");
|
|
14
5
|
const headers_1 = require("./headers");
|
|
15
6
|
const pagination_1 = require("../../strategies/pagination");
|
|
16
7
|
const stabilization_1 = require("../../strategies/stabilization");
|
|
17
|
-
const glideFillStrategy =
|
|
8
|
+
const glideFillStrategy = async ({ row, columnName, value, page }) => {
|
|
18
9
|
// Canvas-aware click: Glide is a canvas grid. The accessibility 'td' elements
|
|
19
10
|
// may not trigger internal focus on a simple click. We click the canvas at the cell's location.
|
|
20
11
|
const cell = row.getCell(columnName);
|
|
21
|
-
const box =
|
|
12
|
+
const box = await cell.boundingBox();
|
|
22
13
|
const canvas = page.locator('canvas').first();
|
|
23
|
-
const cBox =
|
|
14
|
+
const cBox = await canvas.boundingBox();
|
|
24
15
|
if (box && cBox) {
|
|
25
|
-
|
|
16
|
+
await canvas.click({
|
|
26
17
|
position: {
|
|
27
18
|
x: box.x - cBox.x + box.width / 2,
|
|
28
19
|
y: box.y - cBox.y + box.height / 2
|
|
@@ -31,13 +22,13 @@ const glideFillStrategy = (_a) => __awaiter(void 0, [_a], void 0, function* ({ r
|
|
|
31
22
|
}
|
|
32
23
|
else {
|
|
33
24
|
// Fallback
|
|
34
|
-
|
|
25
|
+
await cell.focus();
|
|
35
26
|
}
|
|
36
|
-
|
|
27
|
+
await page.keyboard.press('Enter');
|
|
37
28
|
const textarea = page.locator('textarea.gdg-input');
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
await textarea.waitFor({ state: 'visible', timeout: 2000 });
|
|
30
|
+
await page.keyboard.type(String(value));
|
|
31
|
+
await textarea.evaluate((el, expectedValue) => {
|
|
41
32
|
return new Promise((resolve) => {
|
|
42
33
|
const checkValue = () => {
|
|
43
34
|
if (el.value === expectedValue) {
|
|
@@ -50,16 +41,16 @@ const glideFillStrategy = (_a) => __awaiter(void 0, [_a], void 0, function* ({ r
|
|
|
50
41
|
checkValue();
|
|
51
42
|
});
|
|
52
43
|
}, String(value));
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
const glideFillSimple =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
44
|
+
await page.waitForTimeout(50);
|
|
45
|
+
await page.keyboard.press('Enter');
|
|
46
|
+
await textarea.waitFor({ state: 'detached', timeout: 2000 });
|
|
47
|
+
await page.waitForTimeout(300);
|
|
48
|
+
};
|
|
49
|
+
const glideFillSimple = async ({ value, page }) => {
|
|
50
|
+
await page.keyboard.press('Enter');
|
|
51
|
+
await page.keyboard.type(String(value));
|
|
52
|
+
await page.keyboard.press('Enter');
|
|
53
|
+
};
|
|
63
54
|
const glidePaginationStrategy = pagination_1.PaginationStrategies.infiniteScroll({
|
|
64
55
|
scrollTarget: 'xpath=//ancestor::body//div[contains(@class, "dvn-scroller")]',
|
|
65
56
|
scrollAmount: 500,
|
|
@@ -72,11 +63,11 @@ const glideGetCellLocator = ({ row, columnIndex }) => {
|
|
|
72
63
|
// Rows are virtualized: only a window of `td`s exists; navigation must scroll `.dvn-scroller`.
|
|
73
64
|
return row.locator(`td[aria-colindex="${columnIndex + 1}"]`);
|
|
74
65
|
};
|
|
75
|
-
const glideGetActiveCell =
|
|
66
|
+
const glideGetActiveCell = async ({ page }) => {
|
|
76
67
|
const focused = page.locator('*:focus').first();
|
|
77
|
-
if (
|
|
68
|
+
if (await focused.count() === 0)
|
|
78
69
|
return null;
|
|
79
|
-
const id =
|
|
70
|
+
const id = await focused.getAttribute('id') || '';
|
|
80
71
|
const parts = id.split('-');
|
|
81
72
|
let rowIndex = -1;
|
|
82
73
|
let columnIndex = -1;
|
|
@@ -89,7 +80,7 @@ const glideGetActiveCell = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
89
80
|
columnIndex,
|
|
90
81
|
locator: focused
|
|
91
82
|
};
|
|
92
|
-
}
|
|
83
|
+
};
|
|
93
84
|
/** Default strategies for the Glide preset (fill only; no fillSimple). */
|
|
94
85
|
const GlideDefaultStrategies = {
|
|
95
86
|
fill: glideFillStrategy,
|
|
@@ -105,7 +96,7 @@ const GlideDefaultStrategies = {
|
|
|
105
96
|
seekColumnIndex: columns_1.glideSeekColumnIndex
|
|
106
97
|
},
|
|
107
98
|
loading: {
|
|
108
|
-
isHeaderLoading: () =>
|
|
99
|
+
isHeaderLoading: async () => false
|
|
109
100
|
},
|
|
110
101
|
getCellLocator: glideGetCellLocator,
|
|
111
102
|
getActiveCell: glideGetActiveCell
|