@rickcedwhat/playwright-smart-table 6.7.4 → 6.7.5
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.d.ts +1 -1
- package/dist/engine/rowFinder.js +5 -4
- package/dist/engine/tableIteration.d.ts +25 -0
- package/dist/engine/tableIteration.js +210 -0
- package/dist/plugins/glide/columns.d.ts +11 -0
- package/dist/plugins/glide/columns.js +51 -0
- package/dist/plugins/glide/headers.d.ts +9 -0
- package/dist/plugins/glide/headers.js +65 -0
- package/dist/plugins/glide/index.d.ts +31 -0
- package/dist/plugins/glide/index.js +104 -0
- package/dist/plugins/glide.d.ts +31 -0
- package/dist/plugins/glide.js +104 -0
- package/dist/plugins/index.d.ts +16 -0
- package/dist/plugins/index.js +16 -0
- package/dist/plugins/mui/index.d.ts +8 -0
- package/dist/plugins/mui/index.js +25 -0
- package/dist/plugins/mui.d.ts +8 -0
- package/dist/plugins/mui.js +25 -0
- package/dist/plugins/rdg/index.d.ts +17 -0
- package/dist/plugins/rdg/index.js +124 -0
- package/dist/plugins/rdg.d.ts +17 -0
- package/dist/plugins/rdg.js +124 -0
- package/dist/plugins.d.ts +12 -40
- package/dist/plugins.js +9 -6
- package/dist/smartRow.js +22 -7
- package/dist/strategies/glide.d.ts +6 -20
- package/dist/strategies/glide.js +22 -12
- package/dist/strategies/mui.d.ts +8 -0
- package/dist/strategies/mui.js +25 -0
- package/dist/strategies/rdg.d.ts +5 -22
- package/dist/strategies/rdg.js +23 -10
- package/dist/typeContext.d.ts +1 -1
- package/dist/typeContext.js +12 -11
- package/dist/types.d.ts +12 -18
- package/dist/useTable.js +46 -183
- package/dist/utils/sentinel.d.ts +5 -0
- package/dist/utils/sentinel.js +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Glide = exports.GlideStrategies = void 0;
|
|
13
|
+
const columns_1 = require("./glide/columns");
|
|
14
|
+
const headers_1 = require("./glide/headers");
|
|
15
|
+
const pagination_1 = require("../strategies/pagination");
|
|
16
|
+
const stabilization_1 = require("../strategies/stabilization");
|
|
17
|
+
const glideFillStrategy = (_a) => __awaiter(void 0, [_a], void 0, function* ({ value, page }) {
|
|
18
|
+
yield page.keyboard.press('Enter');
|
|
19
|
+
const textarea = page.locator('textarea.gdg-input');
|
|
20
|
+
yield textarea.waitFor({ state: 'visible', timeout: 2000 });
|
|
21
|
+
yield page.keyboard.type(String(value));
|
|
22
|
+
yield textarea.evaluate((el, expectedValue) => {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
const checkValue = () => {
|
|
25
|
+
if (el.value === expectedValue) {
|
|
26
|
+
resolve();
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
setTimeout(checkValue, 10);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
checkValue();
|
|
33
|
+
});
|
|
34
|
+
}, String(value));
|
|
35
|
+
yield page.waitForTimeout(50);
|
|
36
|
+
yield page.keyboard.press('Enter');
|
|
37
|
+
yield textarea.waitFor({ state: 'detached', timeout: 2000 });
|
|
38
|
+
yield page.waitForTimeout(300);
|
|
39
|
+
});
|
|
40
|
+
const glideFillSimple = (_a) => __awaiter(void 0, [_a], void 0, function* ({ value, page }) {
|
|
41
|
+
yield page.keyboard.press('Enter');
|
|
42
|
+
yield page.keyboard.type(String(value));
|
|
43
|
+
yield page.keyboard.press('Enter');
|
|
44
|
+
});
|
|
45
|
+
const glidePaginationStrategy = pagination_1.PaginationStrategies.infiniteScroll({
|
|
46
|
+
scrollTarget: 'xpath=//ancestor::body//div[contains(@class, "dvn-scroller")]',
|
|
47
|
+
scrollAmount: 500,
|
|
48
|
+
action: 'js-scroll',
|
|
49
|
+
stabilization: stabilization_1.StabilizationStrategies.contentChanged({ timeout: 5000 }),
|
|
50
|
+
timeout: 5000
|
|
51
|
+
});
|
|
52
|
+
const glideGetCellLocator = ({ row, columnIndex }) => {
|
|
53
|
+
return row.locator('td').nth(columnIndex);
|
|
54
|
+
};
|
|
55
|
+
const glideGetActiveCell = (_a) => __awaiter(void 0, [_a], void 0, function* ({ page }) {
|
|
56
|
+
const focused = page.locator('*:focus').first();
|
|
57
|
+
if ((yield focused.count()) === 0)
|
|
58
|
+
return null;
|
|
59
|
+
const id = (yield focused.getAttribute('id')) || '';
|
|
60
|
+
const parts = id.split('-');
|
|
61
|
+
let rowIndex = -1;
|
|
62
|
+
let columnIndex = -1;
|
|
63
|
+
if (parts.length >= 4 && parts[0] === 'glide' && parts[1] === 'cell') {
|
|
64
|
+
columnIndex = parseInt(parts[2]) - 1;
|
|
65
|
+
rowIndex = parseInt(parts[3]);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
rowIndex,
|
|
69
|
+
columnIndex,
|
|
70
|
+
locator: focused
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
/** Default strategies for the Glide preset (fill only; no fillSimple). */
|
|
74
|
+
const GlideDefaultStrategies = {
|
|
75
|
+
fill: glideFillStrategy,
|
|
76
|
+
pagination: glidePaginationStrategy,
|
|
77
|
+
header: headers_1.scrollRightHeader,
|
|
78
|
+
navigation: {
|
|
79
|
+
goUp: columns_1.glideGoUp,
|
|
80
|
+
goDown: columns_1.glideGoDown,
|
|
81
|
+
goLeft: columns_1.glideGoLeft,
|
|
82
|
+
goRight: columns_1.glideGoRight,
|
|
83
|
+
goHome: columns_1.glideGoHome
|
|
84
|
+
},
|
|
85
|
+
loading: {
|
|
86
|
+
isHeaderLoading: () => __awaiter(void 0, void 0, void 0, function* () { return false; })
|
|
87
|
+
},
|
|
88
|
+
getCellLocator: glideGetCellLocator,
|
|
89
|
+
getActiveCell: glideGetActiveCell
|
|
90
|
+
};
|
|
91
|
+
/** Strategies only for Glide Data Grid. Includes fillSimple; use when you want to supply your own selectors or override fill. */
|
|
92
|
+
exports.GlideStrategies = Object.assign(Object.assign({}, GlideDefaultStrategies), { fillSimple: glideFillSimple });
|
|
93
|
+
/**
|
|
94
|
+
* Full preset for Glide Data Grid (selectors + default strategies only).
|
|
95
|
+
* Spread: useTable(loc, { ...Plugins.Glide, maxPages: 5 }).
|
|
96
|
+
* Strategies only (including fillSimple): useTable(loc, { rowSelector: '...', strategies: Plugins.Glide.Strategies }).
|
|
97
|
+
*/
|
|
98
|
+
const GlidePreset = {
|
|
99
|
+
headerSelector: 'table[role="grid"] thead tr th',
|
|
100
|
+
rowSelector: 'table[role="grid"] tbody tr',
|
|
101
|
+
cellSelector: 'td',
|
|
102
|
+
strategies: GlideDefaultStrategies
|
|
103
|
+
};
|
|
104
|
+
exports.Glide = Object.defineProperty(GlidePreset, 'Strategies', { get: () => exports.GlideStrategies, enumerable: false });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presets for specific table/grid libraries. Each plugin exposes:
|
|
3
|
+
* - Plugins.X — full preset (selectors + headerTransformer if any + strategies). Spread: useTable(loc, { ...Plugins.MUI, maxPages: 5 }).
|
|
4
|
+
* - Plugins.X.Strategies — strategies only. Use with your own selectors: useTable(loc, { rowSelector: '...', strategies: Plugins.MUI.Strategies }).
|
|
5
|
+
*/
|
|
6
|
+
export declare const Plugins: {
|
|
7
|
+
RDG: Partial<import("..").TableConfig<any>> & {
|
|
8
|
+
Strategies: typeof import("./rdg").RDGStrategies;
|
|
9
|
+
};
|
|
10
|
+
Glide: Partial<import("..").TableConfig<any>> & {
|
|
11
|
+
Strategies: typeof import("./glide").GlideStrategies;
|
|
12
|
+
};
|
|
13
|
+
MUI: Partial<import("..").TableConfig<any>> & {
|
|
14
|
+
Strategies: typeof import("./mui").MUIStrategies;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Plugins = void 0;
|
|
4
|
+
const rdg_1 = require("./rdg");
|
|
5
|
+
const glide_1 = require("./glide");
|
|
6
|
+
const mui_1 = require("./mui");
|
|
7
|
+
/**
|
|
8
|
+
* Presets for specific table/grid libraries. Each plugin exposes:
|
|
9
|
+
* - Plugins.X — full preset (selectors + headerTransformer if any + strategies). Spread: useTable(loc, { ...Plugins.MUI, maxPages: 5 }).
|
|
10
|
+
* - Plugins.X.Strategies — strategies only. Use with your own selectors: useTable(loc, { rowSelector: '...', strategies: Plugins.MUI.Strategies }).
|
|
11
|
+
*/
|
|
12
|
+
exports.Plugins = {
|
|
13
|
+
RDG: rdg_1.RDG,
|
|
14
|
+
Glide: glide_1.Glide,
|
|
15
|
+
MUI: mui_1.MUI,
|
|
16
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TableConfig } from '../../types';
|
|
2
|
+
/** Full strategies for MUI Data Grid. Use when you want to supply your own selectors: strategies: Plugins.MUI.Strategies */
|
|
3
|
+
export declare const MUIStrategies: {
|
|
4
|
+
pagination: import("../../types").PaginationPrimitives;
|
|
5
|
+
};
|
|
6
|
+
export declare const MUI: Partial<TableConfig> & {
|
|
7
|
+
Strategies: typeof MUIStrategies;
|
|
8
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MUI = exports.MUIStrategies = void 0;
|
|
4
|
+
const pagination_1 = require("../../strategies/pagination");
|
|
5
|
+
/** Default strategies for the MUI preset (used when you spread Plugins.MUI). */
|
|
6
|
+
const MUIDefaultStrategies = {
|
|
7
|
+
pagination: pagination_1.PaginationStrategies.click({
|
|
8
|
+
next: (root) => root.getByRole('button', { name: 'Go to next page' }),
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
/** Full strategies for MUI Data Grid. Use when you want to supply your own selectors: strategies: Plugins.MUI.Strategies */
|
|
12
|
+
exports.MUIStrategies = MUIDefaultStrategies;
|
|
13
|
+
/**
|
|
14
|
+
* Full preset for MUI Data Grid (selectors + headerTransformer + default strategies).
|
|
15
|
+
* Spread: useTable(loc, { ...Plugins.MUI, maxPages: 5 }).
|
|
16
|
+
* Strategies only: useTable(loc, { rowSelector: '...', strategies: Plugins.MUI.Strategies }).
|
|
17
|
+
*/
|
|
18
|
+
const MUIPreset = {
|
|
19
|
+
rowSelector: '.MuiDataGrid-row',
|
|
20
|
+
headerSelector: '.MuiDataGrid-columnHeader',
|
|
21
|
+
cellSelector: '.MuiDataGrid-cell',
|
|
22
|
+
headerTransformer: ({ text }) => (text.includes('__col_') ? 'Actions' : text),
|
|
23
|
+
strategies: MUIDefaultStrategies,
|
|
24
|
+
};
|
|
25
|
+
exports.MUI = Object.defineProperty(MUIPreset, 'Strategies', { get: () => exports.MUIStrategies, enumerable: false });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TableConfig } from '../types';
|
|
2
|
+
/** Full strategies for MUI Data Grid. Use when you want to supply your own selectors: strategies: Plugins.MUI.Strategies */
|
|
3
|
+
export declare const MUIStrategies: {
|
|
4
|
+
pagination: import("../types").PaginationPrimitives;
|
|
5
|
+
};
|
|
6
|
+
export declare const MUI: Partial<TableConfig> & {
|
|
7
|
+
Strategies: typeof MUIStrategies;
|
|
8
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MUI = exports.MUIStrategies = void 0;
|
|
4
|
+
const pagination_1 = require("../strategies/pagination");
|
|
5
|
+
/** Default strategies for the MUI preset (used when you spread Plugins.MUI). */
|
|
6
|
+
const MUIDefaultStrategies = {
|
|
7
|
+
pagination: pagination_1.PaginationStrategies.click({
|
|
8
|
+
next: (root) => root.getByRole('button', { name: 'Go to next page' }),
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
/** Full strategies for MUI Data Grid. Use when you want to supply your own selectors: strategies: Plugins.MUI.Strategies */
|
|
12
|
+
exports.MUIStrategies = MUIDefaultStrategies;
|
|
13
|
+
/**
|
|
14
|
+
* Full preset for MUI Data Grid (selectors + headerTransformer + default strategies).
|
|
15
|
+
* Spread: useTable(loc, { ...Plugins.MUI, maxPages: 5 }).
|
|
16
|
+
* Strategies only: useTable(loc, { rowSelector: '...', strategies: Plugins.MUI.Strategies }).
|
|
17
|
+
*/
|
|
18
|
+
const MUIPreset = {
|
|
19
|
+
rowSelector: '.MuiDataGrid-row',
|
|
20
|
+
headerSelector: '.MuiDataGrid-columnHeader',
|
|
21
|
+
cellSelector: '.MuiDataGrid-cell',
|
|
22
|
+
headerTransformer: ({ text }) => (text.includes('__col_') ? 'Actions' : text),
|
|
23
|
+
strategies: MUIDefaultStrategies,
|
|
24
|
+
};
|
|
25
|
+
exports.MUI = Object.defineProperty(MUIPreset, 'Strategies', { get: () => exports.MUIStrategies, enumerable: false });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TableContext, TableConfig } from '../../types';
|
|
2
|
+
/** Full strategies for React Data Grid. Use when you want to supply your own selectors: strategies: Plugins.RDG.Strategies */
|
|
3
|
+
export declare const RDGStrategies: {
|
|
4
|
+
header: (context: TableContext) => Promise<string[]>;
|
|
5
|
+
getCellLocator: ({ row, columnIndex }: any) => any;
|
|
6
|
+
navigation: {
|
|
7
|
+
goRight: ({ root, page }: any) => Promise<void>;
|
|
8
|
+
goLeft: ({ root, page }: any) => Promise<void>;
|
|
9
|
+
goDown: ({ root, page }: any) => Promise<void>;
|
|
10
|
+
goUp: ({ root, page }: any) => Promise<void>;
|
|
11
|
+
goHome: ({ root, page }: any) => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
pagination: import("../../types").PaginationPrimitives;
|
|
14
|
+
};
|
|
15
|
+
export declare const RDG: Partial<TableConfig> & {
|
|
16
|
+
Strategies: typeof RDGStrategies;
|
|
17
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RDG = exports.RDGStrategies = void 0;
|
|
13
|
+
const pagination_1 = require("../../strategies/pagination");
|
|
14
|
+
const stabilization_1 = require("../../strategies/stabilization");
|
|
15
|
+
/**
|
|
16
|
+
* Scrolls the grid horizontally to collect all column headers.
|
|
17
|
+
* Handles empty headers by labeling them (e.g. "Checkbox").
|
|
18
|
+
*/
|
|
19
|
+
const scrollRightHeaderRDG = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const { resolve, config, root, page } = context;
|
|
21
|
+
const collectedHeaders = new Set();
|
|
22
|
+
const gridHandle = yield root.evaluateHandle((el) => {
|
|
23
|
+
return el.querySelector('[role="grid"]') || el.closest('[role="grid"]');
|
|
24
|
+
});
|
|
25
|
+
const expectedColumns = yield gridHandle.evaluate(el => el ? parseInt(el.getAttribute('aria-colcount') || '0', 10) : 0);
|
|
26
|
+
const getVisible = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const headerLoc = resolve(config.headerSelector, root);
|
|
28
|
+
const texts = yield headerLoc.allInnerTexts();
|
|
29
|
+
return texts.map(t => {
|
|
30
|
+
const trimmed = t.trim();
|
|
31
|
+
return trimmed.length > 0 ? trimmed : 'Checkbox';
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
let currentHeaders = yield getVisible();
|
|
35
|
+
currentHeaders.forEach(h => collectedHeaders.add(h));
|
|
36
|
+
const hasScroll = yield gridHandle.evaluate(el => el ? el.scrollWidth > el.clientWidth : false);
|
|
37
|
+
if (hasScroll) {
|
|
38
|
+
yield gridHandle.evaluate(el => el.scrollLeft = 0);
|
|
39
|
+
yield page.waitForTimeout(200);
|
|
40
|
+
let iteration = 0;
|
|
41
|
+
while (collectedHeaders.size < expectedColumns && iteration < 30) {
|
|
42
|
+
yield gridHandle.evaluate(el => el.scrollLeft += 500);
|
|
43
|
+
yield page.waitForTimeout(300);
|
|
44
|
+
const newHeaders = yield getVisible();
|
|
45
|
+
newHeaders.forEach(h => collectedHeaders.add(h));
|
|
46
|
+
const atEnd = yield gridHandle.evaluate(el => el.scrollLeft >= el.scrollWidth - el.clientWidth - 10);
|
|
47
|
+
iteration++;
|
|
48
|
+
if (atEnd)
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
yield gridHandle.evaluate(el => el.scrollLeft = 0);
|
|
52
|
+
yield page.waitForTimeout(200);
|
|
53
|
+
}
|
|
54
|
+
return Array.from(collectedHeaders);
|
|
55
|
+
});
|
|
56
|
+
const rdgGetCellLocator = ({ row, columnIndex }) => {
|
|
57
|
+
const ariaColIndex = columnIndex + 1;
|
|
58
|
+
return row.locator(`[role="gridcell"][aria-colindex="${ariaColIndex}"]`);
|
|
59
|
+
};
|
|
60
|
+
const rdgPaginationStrategy = pagination_1.PaginationStrategies.infiniteScroll({
|
|
61
|
+
action: 'js-scroll',
|
|
62
|
+
scrollAmount: 500,
|
|
63
|
+
stabilization: stabilization_1.StabilizationStrategies.contentChanged({ timeout: 5000 })
|
|
64
|
+
});
|
|
65
|
+
const rdgNavigation = {
|
|
66
|
+
goRight: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
67
|
+
yield root.evaluate((el) => {
|
|
68
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
69
|
+
if (grid)
|
|
70
|
+
grid.scrollLeft += 150;
|
|
71
|
+
});
|
|
72
|
+
}),
|
|
73
|
+
goLeft: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
74
|
+
yield root.evaluate((el) => {
|
|
75
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
76
|
+
if (grid)
|
|
77
|
+
grid.scrollLeft -= 150;
|
|
78
|
+
});
|
|
79
|
+
}),
|
|
80
|
+
goDown: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
81
|
+
yield root.evaluate((el) => {
|
|
82
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
83
|
+
if (grid)
|
|
84
|
+
grid.scrollTop += 35;
|
|
85
|
+
});
|
|
86
|
+
}),
|
|
87
|
+
goUp: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
88
|
+
yield root.evaluate((el) => {
|
|
89
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
90
|
+
if (grid)
|
|
91
|
+
grid.scrollTop -= 35;
|
|
92
|
+
});
|
|
93
|
+
}),
|
|
94
|
+
goHome: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
95
|
+
yield root.evaluate((el) => {
|
|
96
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
97
|
+
if (grid) {
|
|
98
|
+
grid.scrollLeft = 0;
|
|
99
|
+
grid.scrollTop = 0;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
})
|
|
103
|
+
};
|
|
104
|
+
/** Default strategies for the RDG preset (used when you spread Plugins.RDG). */
|
|
105
|
+
const RDGDefaultStrategies = {
|
|
106
|
+
header: scrollRightHeaderRDG,
|
|
107
|
+
getCellLocator: rdgGetCellLocator,
|
|
108
|
+
navigation: rdgNavigation,
|
|
109
|
+
pagination: rdgPaginationStrategy
|
|
110
|
+
};
|
|
111
|
+
/** Full strategies for React Data Grid. Use when you want to supply your own selectors: strategies: Plugins.RDG.Strategies */
|
|
112
|
+
exports.RDGStrategies = RDGDefaultStrategies;
|
|
113
|
+
/**
|
|
114
|
+
* Full preset for React Data Grid (selectors + default strategies).
|
|
115
|
+
* Spread: useTable(loc, { ...Plugins.RDG, maxPages: 5 }).
|
|
116
|
+
* Strategies only: useTable(loc, { rowSelector: '...', strategies: Plugins.RDG.Strategies }).
|
|
117
|
+
*/
|
|
118
|
+
const RDGPreset = {
|
|
119
|
+
rowSelector: '[role="row"].rdg-row',
|
|
120
|
+
headerSelector: '[role="columnheader"]',
|
|
121
|
+
cellSelector: '[role="gridcell"]',
|
|
122
|
+
strategies: RDGDefaultStrategies
|
|
123
|
+
};
|
|
124
|
+
exports.RDG = Object.defineProperty(RDGPreset, 'Strategies', { get: () => exports.RDGStrategies, enumerable: false });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TableContext, TableConfig } from '../types';
|
|
2
|
+
/** Full strategies for React Data Grid. Use when you want to supply your own selectors: strategies: Plugins.RDG.Strategies */
|
|
3
|
+
export declare const RDGStrategies: {
|
|
4
|
+
header: (context: TableContext) => Promise<string[]>;
|
|
5
|
+
getCellLocator: ({ row, columnIndex }: any) => any;
|
|
6
|
+
navigation: {
|
|
7
|
+
goRight: ({ root, page }: any) => Promise<void>;
|
|
8
|
+
goLeft: ({ root, page }: any) => Promise<void>;
|
|
9
|
+
goDown: ({ root, page }: any) => Promise<void>;
|
|
10
|
+
goUp: ({ root, page }: any) => Promise<void>;
|
|
11
|
+
goHome: ({ root, page }: any) => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
pagination: import("../types").PaginationPrimitives;
|
|
14
|
+
};
|
|
15
|
+
export declare const RDG: Partial<TableConfig> & {
|
|
16
|
+
Strategies: typeof RDGStrategies;
|
|
17
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RDG = exports.RDGStrategies = void 0;
|
|
13
|
+
const pagination_1 = require("../strategies/pagination");
|
|
14
|
+
const stabilization_1 = require("../strategies/stabilization");
|
|
15
|
+
/**
|
|
16
|
+
* Scrolls the grid horizontally to collect all column headers.
|
|
17
|
+
* Handles empty headers by labeling them (e.g. "Checkbox").
|
|
18
|
+
*/
|
|
19
|
+
const scrollRightHeaderRDG = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const { resolve, config, root, page } = context;
|
|
21
|
+
const collectedHeaders = new Set();
|
|
22
|
+
const gridHandle = yield root.evaluateHandle((el) => {
|
|
23
|
+
return el.querySelector('[role="grid"]') || el.closest('[role="grid"]');
|
|
24
|
+
});
|
|
25
|
+
const expectedColumns = yield gridHandle.evaluate(el => el ? parseInt(el.getAttribute('aria-colcount') || '0', 10) : 0);
|
|
26
|
+
const getVisible = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const headerLoc = resolve(config.headerSelector, root);
|
|
28
|
+
const texts = yield headerLoc.allInnerTexts();
|
|
29
|
+
return texts.map(t => {
|
|
30
|
+
const trimmed = t.trim();
|
|
31
|
+
return trimmed.length > 0 ? trimmed : 'Checkbox';
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
let currentHeaders = yield getVisible();
|
|
35
|
+
currentHeaders.forEach(h => collectedHeaders.add(h));
|
|
36
|
+
const hasScroll = yield gridHandle.evaluate(el => el ? el.scrollWidth > el.clientWidth : false);
|
|
37
|
+
if (hasScroll) {
|
|
38
|
+
yield gridHandle.evaluate(el => el.scrollLeft = 0);
|
|
39
|
+
yield page.waitForTimeout(200);
|
|
40
|
+
let iteration = 0;
|
|
41
|
+
while (collectedHeaders.size < expectedColumns && iteration < 30) {
|
|
42
|
+
yield gridHandle.evaluate(el => el.scrollLeft += 500);
|
|
43
|
+
yield page.waitForTimeout(300);
|
|
44
|
+
const newHeaders = yield getVisible();
|
|
45
|
+
newHeaders.forEach(h => collectedHeaders.add(h));
|
|
46
|
+
const atEnd = yield gridHandle.evaluate(el => el.scrollLeft >= el.scrollWidth - el.clientWidth - 10);
|
|
47
|
+
iteration++;
|
|
48
|
+
if (atEnd)
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
yield gridHandle.evaluate(el => el.scrollLeft = 0);
|
|
52
|
+
yield page.waitForTimeout(200);
|
|
53
|
+
}
|
|
54
|
+
return Array.from(collectedHeaders);
|
|
55
|
+
});
|
|
56
|
+
const rdgGetCellLocator = ({ row, columnIndex }) => {
|
|
57
|
+
const ariaColIndex = columnIndex + 1;
|
|
58
|
+
return row.locator(`[role="gridcell"][aria-colindex="${ariaColIndex}"]`);
|
|
59
|
+
};
|
|
60
|
+
const rdgPaginationStrategy = pagination_1.PaginationStrategies.infiniteScroll({
|
|
61
|
+
action: 'js-scroll',
|
|
62
|
+
scrollAmount: 500,
|
|
63
|
+
stabilization: stabilization_1.StabilizationStrategies.contentChanged({ timeout: 5000 })
|
|
64
|
+
});
|
|
65
|
+
const rdgNavigation = {
|
|
66
|
+
goRight: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
67
|
+
yield root.evaluate((el) => {
|
|
68
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
69
|
+
if (grid)
|
|
70
|
+
grid.scrollLeft += 150;
|
|
71
|
+
});
|
|
72
|
+
}),
|
|
73
|
+
goLeft: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
74
|
+
yield root.evaluate((el) => {
|
|
75
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
76
|
+
if (grid)
|
|
77
|
+
grid.scrollLeft -= 150;
|
|
78
|
+
});
|
|
79
|
+
}),
|
|
80
|
+
goDown: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
81
|
+
yield root.evaluate((el) => {
|
|
82
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
83
|
+
if (grid)
|
|
84
|
+
grid.scrollTop += 35;
|
|
85
|
+
});
|
|
86
|
+
}),
|
|
87
|
+
goUp: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
88
|
+
yield root.evaluate((el) => {
|
|
89
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
90
|
+
if (grid)
|
|
91
|
+
grid.scrollTop -= 35;
|
|
92
|
+
});
|
|
93
|
+
}),
|
|
94
|
+
goHome: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
95
|
+
yield root.evaluate((el) => {
|
|
96
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
97
|
+
if (grid) {
|
|
98
|
+
grid.scrollLeft = 0;
|
|
99
|
+
grid.scrollTop = 0;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
})
|
|
103
|
+
};
|
|
104
|
+
/** Default strategies for the RDG preset (used when you spread Plugins.RDG). */
|
|
105
|
+
const RDGDefaultStrategies = {
|
|
106
|
+
header: scrollRightHeaderRDG,
|
|
107
|
+
getCellLocator: rdgGetCellLocator,
|
|
108
|
+
navigation: rdgNavigation,
|
|
109
|
+
pagination: rdgPaginationStrategy
|
|
110
|
+
};
|
|
111
|
+
/** Full strategies for React Data Grid. Use when you want to supply your own selectors: strategies: Plugins.RDG.Strategies */
|
|
112
|
+
exports.RDGStrategies = RDGDefaultStrategies;
|
|
113
|
+
/**
|
|
114
|
+
* Full preset for React Data Grid (selectors + default strategies).
|
|
115
|
+
* Spread: useTable(loc, { ...Plugins.RDG, maxPages: 5 }).
|
|
116
|
+
* Strategies only: useTable(loc, { rowSelector: '...', strategies: Plugins.RDG.Strategies }).
|
|
117
|
+
*/
|
|
118
|
+
const RDGPreset = {
|
|
119
|
+
rowSelector: '[role="row"].rdg-row',
|
|
120
|
+
headerSelector: '[role="columnheader"]',
|
|
121
|
+
cellSelector: '[role="gridcell"]',
|
|
122
|
+
strategies: RDGDefaultStrategies
|
|
123
|
+
};
|
|
124
|
+
exports.RDG = Object.defineProperty(RDGPreset, 'Strategies', { get: () => exports.RDGStrategies, enumerable: false });
|
package/dist/plugins.d.ts
CHANGED
|
@@ -1,44 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presets for specific table/grid libraries. Each plugin exposes:
|
|
3
|
+
* - Plugins.X — full preset (selectors + headerTransformer if any + strategies). Spread: useTable(loc, { ...Plugins.MUI, maxPages: 5 }).
|
|
4
|
+
* - Plugins.X.Strategies — strategies only. Use with your own selectors: useTable(loc, { rowSelector: '...', strategies: Plugins.MUI.Strategies }).
|
|
5
|
+
*/
|
|
1
6
|
export declare const Plugins: {
|
|
2
|
-
RDG: {
|
|
3
|
-
Strategies:
|
|
4
|
-
header: (context: import("./types").TableContext) => Promise<string[]>;
|
|
5
|
-
getCellLocator: ({ row, columnIndex }: any) => any;
|
|
6
|
-
navigation: {
|
|
7
|
-
goRight: ({ root, page }: any) => Promise<void>;
|
|
8
|
-
goLeft: ({ root, page }: any) => Promise<void>;
|
|
9
|
-
goDown: ({ root, page }: any) => Promise<void>;
|
|
10
|
-
goUp: ({ root, page }: any) => Promise<void>;
|
|
11
|
-
goHome: ({ root, page }: any) => Promise<void>;
|
|
12
|
-
};
|
|
13
|
-
pagination: import("./types").PaginationPrimitives;
|
|
14
|
-
};
|
|
7
|
+
RDG: Partial<import("./types").TableConfig<any>> & {
|
|
8
|
+
Strategies: typeof import("./strategies/rdg").RDGStrategies;
|
|
15
9
|
};
|
|
16
|
-
Glide: {
|
|
17
|
-
Strategies:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
header: (context: import("./types").StrategyContext, options?: {
|
|
22
|
-
limit?: number;
|
|
23
|
-
selector?: string;
|
|
24
|
-
scrollAmount?: number;
|
|
25
|
-
}) => Promise<string[]>;
|
|
26
|
-
navigation: {
|
|
27
|
-
goUp: (context: import("./types").StrategyContext) => Promise<void>;
|
|
28
|
-
goDown: (context: import("./types").StrategyContext) => Promise<void>;
|
|
29
|
-
goLeft: (context: import("./types").StrategyContext) => Promise<void>;
|
|
30
|
-
goRight: (context: import("./types").StrategyContext) => Promise<void>;
|
|
31
|
-
goHome: (context: import("./types").StrategyContext) => Promise<void>;
|
|
32
|
-
};
|
|
33
|
-
loading: {
|
|
34
|
-
isHeaderLoading: () => Promise<boolean>;
|
|
35
|
-
};
|
|
36
|
-
getCellLocator: ({ row, columnIndex }: any) => any;
|
|
37
|
-
getActiveCell: ({ page }: any) => Promise<{
|
|
38
|
-
rowIndex: number;
|
|
39
|
-
columnIndex: number;
|
|
40
|
-
locator: any;
|
|
41
|
-
} | null>;
|
|
42
|
-
};
|
|
10
|
+
Glide: Partial<import("./types").TableConfig<any>> & {
|
|
11
|
+
Strategies: typeof import("./strategies/glide").GlideStrategies;
|
|
12
|
+
};
|
|
13
|
+
MUI: Partial<import("./types").TableConfig<any>> & {
|
|
14
|
+
Strategies: typeof import("./strategies/mui").MUIStrategies;
|
|
43
15
|
};
|
|
44
16
|
};
|
package/dist/plugins.js
CHANGED
|
@@ -3,11 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Plugins = void 0;
|
|
4
4
|
const rdg_1 = require("./strategies/rdg");
|
|
5
5
|
const glide_1 = require("./strategies/glide");
|
|
6
|
+
const mui_1 = require("./strategies/mui");
|
|
7
|
+
/**
|
|
8
|
+
* Presets for specific table/grid libraries. Each plugin exposes:
|
|
9
|
+
* - Plugins.X — full preset (selectors + headerTransformer if any + strategies). Spread: useTable(loc, { ...Plugins.MUI, maxPages: 5 }).
|
|
10
|
+
* - Plugins.X.Strategies — strategies only. Use with your own selectors: useTable(loc, { rowSelector: '...', strategies: Plugins.MUI.Strategies }).
|
|
11
|
+
*/
|
|
6
12
|
exports.Plugins = {
|
|
7
|
-
RDG:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Glide: {
|
|
11
|
-
Strategies: glide_1.GlideStrategies
|
|
12
|
-
}
|
|
13
|
+
RDG: rdg_1.RDG,
|
|
14
|
+
Glide: glide_1.Glide,
|
|
15
|
+
MUI: mui_1.MUI,
|
|
13
16
|
};
|
package/dist/smartRow.js
CHANGED
|
@@ -14,6 +14,7 @@ const fill_1 = require("./strategies/fill");
|
|
|
14
14
|
const stringUtils_1 = require("./utils/stringUtils");
|
|
15
15
|
const debugUtils_1 = require("./utils/debugUtils");
|
|
16
16
|
const paginationPath_1 = require("./utils/paginationPath");
|
|
17
|
+
const sentinel_1 = require("./utils/sentinel");
|
|
17
18
|
/**
|
|
18
19
|
* Internal helper to navigate to a cell with active cell optimization.
|
|
19
20
|
* Uses navigation primitives (goUp, goDown, goLeft, goRight, goHome) for orchestration.
|
|
@@ -76,18 +77,32 @@ const _navigateToCell = (params) => __awaiter(void 0, void 0, void 0, function*
|
|
|
76
77
|
yield nav.goLeft(context);
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
-
// Get the active cell locator after navigation (for virtualized tables)
|
|
80
|
+
// Wait for active cell to match target: poll getActiveCell or fallback to fixed delay
|
|
81
81
|
if (config.strategies.getActiveCell) {
|
|
82
|
-
const
|
|
82
|
+
const pollIntervalMs = 10;
|
|
83
|
+
const maxWaitMs = 50;
|
|
84
|
+
const start = Date.now();
|
|
85
|
+
while (Date.now() - start < maxWaitMs) {
|
|
86
|
+
const updatedActiveCell = yield config.strategies.getActiveCell({
|
|
87
|
+
config,
|
|
88
|
+
root: rootLocator,
|
|
89
|
+
page,
|
|
90
|
+
resolve
|
|
91
|
+
});
|
|
92
|
+
if (updatedActiveCell && updatedActiveCell.rowIndex === rowIndex && updatedActiveCell.columnIndex === index) {
|
|
93
|
+
return updatedActiveCell.locator;
|
|
94
|
+
}
|
|
95
|
+
yield page.waitForTimeout(pollIntervalMs);
|
|
96
|
+
}
|
|
97
|
+
const final = yield config.strategies.getActiveCell({
|
|
83
98
|
config,
|
|
84
99
|
root: rootLocator,
|
|
85
100
|
page,
|
|
86
101
|
resolve
|
|
87
102
|
});
|
|
88
|
-
if (
|
|
89
|
-
return
|
|
90
|
-
|
|
103
|
+
if (final)
|
|
104
|
+
return final.locator;
|
|
105
|
+
return null;
|
|
91
106
|
}
|
|
92
107
|
return null;
|
|
93
108
|
}
|
|
@@ -121,7 +136,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
121
136
|
return resolve(config.cellSelector, rowLocator).nth(idx);
|
|
122
137
|
};
|
|
123
138
|
smart.wasFound = () => {
|
|
124
|
-
return !smart.
|
|
139
|
+
return !smart[sentinel_1.SENTINEL_ROW];
|
|
125
140
|
};
|
|
126
141
|
smart.toJSON = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
142
|
var _a;
|