@rickcedwhat/playwright-smart-table 6.3.2 ā 6.4.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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/minimalConfigContext.d.ts +6 -0
- package/dist/minimalConfigContext.js +78 -0
- package/dist/plugins.d.ts +7 -0
- package/dist/smartRow.js +13 -25
- package/dist/strategies/rdg.d.ts +14 -0
- package/dist/strategies/rdg.js +43 -1
- package/dist/typeContext.d.ts +1 -1
- package/dist/typeContext.js +7 -30
- package/dist/types.d.ts +5 -34
- package/dist/useTable.d.ts +1 -43
- package/dist/useTable.js +6 -33
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* š¤ AUTO-GENERATED FILE. DO NOT EDIT.
|
|
3
|
+
* This file is generated by scripts/embed-config-types.mjs
|
|
4
|
+
* It contains minimal type definitions for config generation prompts.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MINIMAL_CONFIG_CONTEXT = "\n/**\n * Flexible selector type - can be a CSS string or function returning a Locator.\n * @example\n * // String selector\n * rowSelector: 'tbody tr'\n * \n * // Function selector\n * rowSelector: (root) => root.locator('[role=\"row\"]')\n */\nexport type Selector = string | ((root: Locator | Page) => Locator);\n\n/**\n * Debug configuration for development and troubleshooting\n */\nexport type DebugConfig = {\n slow?: number | {\n pagination?: number;\n getCell?: number;\n findRow?: number;\n default?: number;\n };\n logLevel?: 'verbose' | 'info' | 'error' | 'none';\n};\n\n/**\n * Configuration options for useTable - focus on selectors and basic setup\n */\nexport interface TableConfig<T = any> {\n /** CSS selector or function for table headers */\n headerSelector?: string | ((root: Locator) => Locator);\n \n /** CSS selector or function for table rows */\n rowSelector?: string | ((root: Locator) => Locator);\n \n /** CSS selector or function for cells within a row */\n cellSelector?: string | ((row: Locator) => Locator);\n \n /** Transform header text (e.g., normalize, deduplicate) */\n headerTransformer?: (args: { \n text: string; \n index: number; \n locator: Locator;\n seenHeaders: Set<string>;\n }) => string | Promise<string>;\n \n /** Automatically scroll to table on init (default: true) */\n autoScroll?: boolean;\n \n /** Debug options for development and troubleshooting */\n debug?: DebugConfig;\n \n /** Advanced: Custom strategies for pagination, sorting, navigation, etc. */\n strategies?: TableStrategies;\n \n /** Custom data mappers for extracting complex types (boolean, number) */\n dataMapper?: Partial<Record<keyof T, (cell: Locator) => Promise<T[keyof T]> | T[keyof T]>>;\n}\n\n/**\n * Example usage:\n */\n// const table = useTable(page.locator('table'), {\n// headerSelector: 'thead th',\n// rowSelector: 'tbody tr',\n// cellSelector: 'td',\n// headerTransformer: ({ text }) => text.trim()\n// });\n\n";
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MINIMAL_CONFIG_CONTEXT = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* š¤ AUTO-GENERATED FILE. DO NOT EDIT.
|
|
6
|
+
* This file is generated by scripts/embed-config-types.mjs
|
|
7
|
+
* It contains minimal type definitions for config generation prompts.
|
|
8
|
+
*/
|
|
9
|
+
exports.MINIMAL_CONFIG_CONTEXT = `
|
|
10
|
+
/**
|
|
11
|
+
* Flexible selector type - can be a CSS string or function returning a Locator.
|
|
12
|
+
* @example
|
|
13
|
+
* // String selector
|
|
14
|
+
* rowSelector: 'tbody tr'
|
|
15
|
+
*
|
|
16
|
+
* // Function selector
|
|
17
|
+
* rowSelector: (root) => root.locator('[role="row"]')
|
|
18
|
+
*/
|
|
19
|
+
export type Selector = string | ((root: Locator | Page) => Locator);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Debug configuration for development and troubleshooting
|
|
23
|
+
*/
|
|
24
|
+
export type DebugConfig = {
|
|
25
|
+
slow?: number | {
|
|
26
|
+
pagination?: number;
|
|
27
|
+
getCell?: number;
|
|
28
|
+
findRow?: number;
|
|
29
|
+
default?: number;
|
|
30
|
+
};
|
|
31
|
+
logLevel?: 'verbose' | 'info' | 'error' | 'none';
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Configuration options for useTable - focus on selectors and basic setup
|
|
36
|
+
*/
|
|
37
|
+
export interface TableConfig<T = any> {
|
|
38
|
+
/** CSS selector or function for table headers */
|
|
39
|
+
headerSelector?: string | ((root: Locator) => Locator);
|
|
40
|
+
|
|
41
|
+
/** CSS selector or function for table rows */
|
|
42
|
+
rowSelector?: string | ((root: Locator) => Locator);
|
|
43
|
+
|
|
44
|
+
/** CSS selector or function for cells within a row */
|
|
45
|
+
cellSelector?: string | ((row: Locator) => Locator);
|
|
46
|
+
|
|
47
|
+
/** Transform header text (e.g., normalize, deduplicate) */
|
|
48
|
+
headerTransformer?: (args: {
|
|
49
|
+
text: string;
|
|
50
|
+
index: number;
|
|
51
|
+
locator: Locator;
|
|
52
|
+
seenHeaders: Set<string>;
|
|
53
|
+
}) => string | Promise<string>;
|
|
54
|
+
|
|
55
|
+
/** Automatically scroll to table on init (default: true) */
|
|
56
|
+
autoScroll?: boolean;
|
|
57
|
+
|
|
58
|
+
/** Debug options for development and troubleshooting */
|
|
59
|
+
debug?: DebugConfig;
|
|
60
|
+
|
|
61
|
+
/** Advanced: Custom strategies for pagination, sorting, navigation, etc. */
|
|
62
|
+
strategies?: TableStrategies;
|
|
63
|
+
|
|
64
|
+
/** Custom data mappers for extracting complex types (boolean, number) */
|
|
65
|
+
dataMapper?: Partial<Record<keyof T, (cell: Locator) => Promise<T[keyof T]> | T[keyof T]>>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Example usage:
|
|
70
|
+
*/
|
|
71
|
+
// const table = useTable(page.locator('table'), {
|
|
72
|
+
// headerSelector: 'thead th',
|
|
73
|
+
// rowSelector: 'tbody tr',
|
|
74
|
+
// cellSelector: 'td',
|
|
75
|
+
// headerTransformer: ({ text }) => text.trim()
|
|
76
|
+
// });
|
|
77
|
+
|
|
78
|
+
`;
|
package/dist/plugins.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ export declare const Plugins: {
|
|
|
4
4
|
header: (context: import("./types").TableContext) => Promise<string[]>;
|
|
5
5
|
getCellLocator: ({ row, columnIndex }: any) => any;
|
|
6
6
|
cellNavigation: ({ root, page, index }: any) => Promise<void>;
|
|
7
|
+
navigation: {
|
|
8
|
+
goRight: ({ root, page }: any) => Promise<void>;
|
|
9
|
+
goLeft: ({ root, page }: any) => Promise<void>;
|
|
10
|
+
goDown: ({ root, page }: any) => Promise<void>;
|
|
11
|
+
goUp: ({ root, page }: any) => Promise<void>;
|
|
12
|
+
goHome: ({ root, page }: any) => Promise<void>;
|
|
13
|
+
};
|
|
7
14
|
pagination: import("./types").PaginationStrategy;
|
|
8
15
|
};
|
|
9
16
|
};
|
package/dist/smartRow.js
CHANGED
|
@@ -77,33 +77,21 @@ const _navigateToCell = (params) => __awaiter(void 0, void 0, void 0, function*
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
yield page.waitForTimeout(50);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
rowIndex,
|
|
92
|
-
activeCell
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
// Get the active cell locator after navigation (for virtualized tables)
|
|
96
|
-
if (config.strategies.getActiveCell) {
|
|
97
|
-
const updatedActiveCell = yield config.strategies.getActiveCell({
|
|
98
|
-
config,
|
|
99
|
-
root: rootLocator,
|
|
100
|
-
page,
|
|
101
|
-
resolve
|
|
102
|
-
});
|
|
103
|
-
if (updatedActiveCell) {
|
|
104
|
-
return updatedActiveCell.locator;
|
|
80
|
+
// Get the active cell locator after navigation (for virtualized tables)
|
|
81
|
+
if (config.strategies.getActiveCell) {
|
|
82
|
+
const updatedActiveCell = yield config.strategies.getActiveCell({
|
|
83
|
+
config,
|
|
84
|
+
root: rootLocator,
|
|
85
|
+
page,
|
|
86
|
+
resolve
|
|
87
|
+
});
|
|
88
|
+
if (updatedActiveCell) {
|
|
89
|
+
return updatedActiveCell.locator;
|
|
90
|
+
}
|
|
105
91
|
}
|
|
92
|
+
return null;
|
|
106
93
|
}
|
|
94
|
+
;
|
|
107
95
|
return null;
|
|
108
96
|
});
|
|
109
97
|
/**
|
package/dist/strategies/rdg.d.ts
CHANGED
|
@@ -17,9 +17,23 @@ export declare const rdgCellNavigation: ({ root, page, index }: any) => Promise<
|
|
|
17
17
|
* Scrolls the grid vertically to load more virtualized rows.
|
|
18
18
|
*/
|
|
19
19
|
export declare const rdgPaginationStrategy: import("../types").PaginationStrategy;
|
|
20
|
+
export declare const rdgNavigation: {
|
|
21
|
+
goRight: ({ root, page }: any) => Promise<void>;
|
|
22
|
+
goLeft: ({ root, page }: any) => Promise<void>;
|
|
23
|
+
goDown: ({ root, page }: any) => Promise<void>;
|
|
24
|
+
goUp: ({ root, page }: any) => Promise<void>;
|
|
25
|
+
goHome: ({ root, page }: any) => Promise<void>;
|
|
26
|
+
};
|
|
20
27
|
export declare const RDGStrategies: {
|
|
21
28
|
header: (context: TableContext) => Promise<string[]>;
|
|
22
29
|
getCellLocator: ({ row, columnIndex }: any) => any;
|
|
23
30
|
cellNavigation: ({ root, page, index }: any) => Promise<void>;
|
|
31
|
+
navigation: {
|
|
32
|
+
goRight: ({ root, page }: any) => Promise<void>;
|
|
33
|
+
goLeft: ({ root, page }: any) => Promise<void>;
|
|
34
|
+
goDown: ({ root, page }: any) => Promise<void>;
|
|
35
|
+
goUp: ({ root, page }: any) => Promise<void>;
|
|
36
|
+
goHome: ({ root, page }: any) => Promise<void>;
|
|
37
|
+
};
|
|
24
38
|
pagination: import("../types").PaginationStrategy;
|
|
25
39
|
};
|
package/dist/strategies/rdg.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.RDGStrategies = exports.rdgPaginationStrategy = exports.rdgCellNavigation = exports.rdgGetCellLocator = exports.scrollRightHeaderRDG = void 0;
|
|
12
|
+
exports.RDGStrategies = exports.rdgNavigation = exports.rdgPaginationStrategy = exports.rdgCellNavigation = exports.rdgGetCellLocator = exports.scrollRightHeaderRDG = void 0;
|
|
13
13
|
/**
|
|
14
14
|
* Scrolls the grid horizontally to collect all column headers.
|
|
15
15
|
* Handles empty headers by labeling them (e.g. "Checkbox").
|
|
@@ -20,6 +20,7 @@ const scrollRightHeaderRDG = (context) => __awaiter(void 0, void 0, void 0, func
|
|
|
20
20
|
const gridHandle = yield root.evaluateHandle((el) => {
|
|
21
21
|
return el.querySelector('[role="grid"]') || el.closest('[role="grid"]');
|
|
22
22
|
});
|
|
23
|
+
const scrollContainer = gridHandle; // RDG usually scrolls the grid container itself
|
|
23
24
|
const expectedColumns = yield gridHandle.evaluate(el => el ? parseInt(el.getAttribute('aria-colcount') || '0', 10) : 0);
|
|
24
25
|
const getVisible = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
26
|
const headerLoc = resolve(config.headerSelector, root);
|
|
@@ -92,9 +93,50 @@ exports.rdgPaginationStrategy = pagination_1.PaginationStrategies.infiniteScroll
|
|
|
92
93
|
scrollAmount: 500,
|
|
93
94
|
stabilization: stabilization_1.StabilizationStrategies.contentChanged({ timeout: 5000 })
|
|
94
95
|
});
|
|
96
|
+
exports.rdgNavigation = {
|
|
97
|
+
goRight: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
98
|
+
yield root.evaluate((el) => {
|
|
99
|
+
// Find grid container
|
|
100
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
101
|
+
if (grid)
|
|
102
|
+
grid.scrollLeft += 150;
|
|
103
|
+
});
|
|
104
|
+
}),
|
|
105
|
+
goLeft: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
106
|
+
yield root.evaluate((el) => {
|
|
107
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
108
|
+
if (grid)
|
|
109
|
+
grid.scrollLeft -= 150;
|
|
110
|
+
});
|
|
111
|
+
}),
|
|
112
|
+
goDown: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
113
|
+
yield root.evaluate((el) => {
|
|
114
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
115
|
+
if (grid)
|
|
116
|
+
grid.scrollTop += 35;
|
|
117
|
+
});
|
|
118
|
+
}),
|
|
119
|
+
goUp: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
120
|
+
yield root.evaluate((el) => {
|
|
121
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
122
|
+
if (grid)
|
|
123
|
+
grid.scrollTop -= 35;
|
|
124
|
+
});
|
|
125
|
+
}),
|
|
126
|
+
goHome: (_a) => __awaiter(void 0, [_a], void 0, function* ({ root, page }) {
|
|
127
|
+
yield root.evaluate((el) => {
|
|
128
|
+
const grid = el.querySelector('[role="grid"]') || el.closest('[role="grid"]') || el;
|
|
129
|
+
if (grid) {
|
|
130
|
+
grid.scrollLeft = 0;
|
|
131
|
+
grid.scrollTop = 0;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
})
|
|
135
|
+
};
|
|
95
136
|
exports.RDGStrategies = {
|
|
96
137
|
header: exports.scrollRightHeaderRDG,
|
|
97
138
|
getCellLocator: exports.rdgGetCellLocator,
|
|
98
139
|
cellNavigation: exports.rdgCellNavigation,
|
|
140
|
+
navigation: exports.rdgNavigation,
|
|
99
141
|
pagination: exports.rdgPaginationStrategy
|
|
100
142
|
};
|
package/dist/typeContext.d.ts
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* This file is generated by scripts/embed-types.js
|
|
4
4
|
* It contains the raw text of types.ts to provide context for LLM prompts.
|
|
5
5
|
*/
|
|
6
|
-
export declare const TYPE_CONTEXT = "\n/**\n * Flexible selector type - can be a CSS string, function returning a Locator, or Locator itself.\n * @example\n * // String selector\n * rowSelector: 'tbody tr'\n * \n * // Function selector\n * rowSelector: (root) => root.locator('[role=\"row\"]')\n */\nexport type Selector = string | ((root: Locator | Page) => Locator);\n\n/**\n * Value used to filter rows.\n * - string/number/RegExp: filter by text content of the cell.\n * - function: filter by custom locator logic within the cell.\n * @example\n * // Text filter\n * { Name: 'John' }\n * \n * // Custom locator filter (e.g. checkbox is checked)\n * { Status: (cell) => cell.locator('input:checked') }\n */\nexport type FilterValue = string | RegExp | number | ((cell: Locator) => Locator);\n\n/**\n * Function to get a cell locator given row, column info.\n * Replaces the old cellResolver.\n */\nexport type GetCellLocatorFn = (args: {\n row: Locator;\n columnName: string;\n columnIndex: number;\n rowIndex?: number;\n page: Page;\n}) => Locator;\n\n/**\n * Function to get the currently active/focused cell.\n * Returns null if no cell is active.\n */\nexport type GetActiveCellFn = (args: TableContext) => Promise<{\n rowIndex: number;\n columnIndex: number;\n columnName?: string;\n locator: Locator;\n} | null>;\n\n\n/**\n * SmartRow - A Playwright Locator with table-aware methods.\n * \n * Extends all standard Locator methods (click, isVisible, etc.) with table-specific functionality.\n * \n * @example\n * const row = table.getRow({ Name: 'John Doe' });\n * await row.click(); // Standard Locator method\n * const email = row.getCell('Email'); // Table-aware method\n * const data = await row.toJSON(); // Extract all row data\n * await row.smartFill({ Name: 'Jane', Status: 'Active' }); // Fill form fields\n */\nexport type SmartRow<T = any> = Locator & {\n /** Optional row index (0-based) if known */\n rowIndex?: number;\n\n /**\n * Get a cell locator by column name.\n * @param column - Column name (case-sensitive)\n * @returns Locator for the cell\n * @example\n * const emailCell = row.getCell('Email');\n * await expect(emailCell).toHaveText('john@example.com');\n */\n getCell(column: string): Locator;\n\n /**\n * Extract all cell data as a key-value object.\n * @param options - Optional configuration\n * @param options.columns - Specific columns to extract (extracts all if not specified)\n * @returns Promise resolving to row data\n * @example\n * const data = await row.toJSON();\n * // { Name: 'John', Email: 'john@example.com', ... }\n * \n * const partial = await row.toJSON({ columns: ['Name', 'Email'] });\n * // { Name: 'John', Email: 'john@example.com' }\n */\n toJSON(options?: { columns?: string[] }): Promise<T>;\n\n /**\n * Scrolls/paginates to bring this row into view.\n * Only works if rowIndex is known (e.g., from getRowByIndex).\n * @throws Error if rowIndex is unknown\n */\n bringIntoView(): Promise<void>;\n\n /**\n * Intelligently fills form fields in the row.\n * Automatically detects input types (text, select, checkbox, contenteditable).\n * \n * @param data - Column-value pairs to fill\n * @param options - Optional configuration\n * @param options.inputMappers - Custom input selectors per column\n * @example\n * // Auto-detection\n * await row.smartFill({ Name: 'John', Status: 'Active', Subscribe: true });\n * \n * // Custom input mappers\n * await row.smartFill(\n * { Name: 'John' },\n * { inputMappers: { Name: (cell) => cell.locator('.custom-input') } }\n * );\n */\n smartFill: (data: Partial<T> | Record<string, any>, options?: FillOptions) => Promise<void>;\n};\n\nexport type StrategyContext = TableContext & { rowLocator?: Locator; rowIndex?: number };\n\n/**\n * Defines the contract for a sorting strategy.\n */\nexport interface SortingStrategy {\n /**\n * Performs the sort action on a column.\n */\n doSort(options: {\n columnName: string;\n direction: 'asc' | 'desc';\n context: StrategyContext;\n }): Promise<void>;\n\n /**\n * Retrieves the current sort state of a column.\n */\n getSortState(options: {\n columnName: string;\n context: StrategyContext;\n }): Promise<'asc' | 'desc' | 'none'>;\n}\n\n/**\n * Debug configuration for development and troubleshooting\n */\nexport type DebugConfig = {\n /**\n * Slow down operations for debugging\n * - number: Apply same delay to all operations (ms)\n * - object: Granular delays per operation type\n */\n slow?: number | {\n pagination?: number;\n getCell?: number;\n findRow?: number;\n default?: number;\n };\n /**\n * Log level for debug output\n * - 'verbose': All logs (verbose, info, error)\n * - 'info': Info and error logs only\n * - 'error': Error logs only\n * - 'none': No logs\n */\n logLevel?: 'verbose' | 'info' | 'error' | 'none';\n};\n\nexport interface TableContext<T = any> {\n root: Locator;\n config: FinalTableConfig<T>;\n page: Page;\n resolve: (selector: Selector, parent: Locator | Page) => Locator;\n}\n\nexport type PaginationStrategy = (context: TableContext) => Promise<boolean>;\n\nexport type DedupeStrategy = (row: SmartRow) => string | number | Promise<string | number>;\n\nexport interface PromptOptions {\n /**\n * Output Strategy:\n * - 'error': Throws an error with the prompt (useful for platforms that capture error output cleanly).\n * - 'console': Standard console logs (Default).\n */\n output?: 'console' | 'error';\n includeTypes?: boolean;\n}\n\nexport type FillStrategy = (options: {\n row: SmartRow;\n columnName: string;\n value: any;\n index: number;\n page: Page;\n rootLocator: Locator;\n table: TableResult; // The parent table instance\n fillOptions?: FillOptions;\n}) => Promise<void>;\n\nexport type { HeaderStrategy } from './strategies/headers';\nexport type { CellNavigationStrategy, NavigationPrimitives } from './strategies/columns';\n\n/**\n * Strategy to resolve column names (string or regex) to their index.\n */\nexport type { ColumnResolutionStrategy } from './strategies/resolution';\n\n/**\n * Strategy to filter rows based on criteria.\n */\nexport interface FilterStrategy {\n apply(options: {\n rows: Locator;\n filter: { column: string, value: FilterValue };\n colIndex: number;\n tableContext: TableContext;\n }): Locator;\n}\n\n/**\n * Strategy to check if the table or rows are loading.\n */\nexport interface LoadingStrategy {\n isTableLoading?: (context: TableContext) => Promise<boolean>;\n isRowLoading?: (row: SmartRow) => Promise<boolean>;\n isHeaderLoading?: (context: TableContext) => Promise<boolean>;\n}\n\n/**\n * Organized container for all table interaction strategies.\n */\nexport interface TableStrategies {\n /** Strategy for discovering/scanning headers */\n header?: HeaderStrategy;\n /** Primitive navigation functions (goUp, goDown, goLeft, goRight, goHome) */\n navigation?: NavigationPrimitives;\n /** @deprecated Use navigation primitives instead. Strategy for navigating to specific cells (row + column) */\n cellNavigation?: CellNavigationStrategy;\n /** Strategy for filling form inputs */\n fill?: FillStrategy;\n /** Strategy for paginating through data */\n pagination?: PaginationStrategy;\n /** Strategy for sorting columns */\n sorting?: SortingStrategy;\n /** Strategy for deduplicating rows during iteration/scrolling */\n dedupe?: DedupeStrategy;\n /** Function to get a cell locator */\n getCellLocator?: GetCellLocatorFn;\n /** Function to get the currently active/focused cell */\n getActiveCell?: GetActiveCellFn;\n /** Custom helper to check if a table is fully loaded/ready */\n isTableLoaded?: (args: TableContext) => Promise<boolean>;\n /** Custom helper to check if a row is fully loaded/ready */\n isRowLoaded?: (args: { row: Locator, index: number }) => Promise<boolean>;\n /** Custom helper to check if a cell is fully loaded/ready (e.g. for editing) */\n isCellLoaded?: (args: { cell: Locator, column: string, row: Locator }) => Promise<boolean>;\n /** Strategy for detecting loading states */\n loading?: LoadingStrategy;\n}\n\n/**\n * Configuration options for useTable.\n */\n/**\n * Configuration options for useTable.\n */\nexport interface TableConfig<T = any> {\n /** Selector for the table headers */\n headerSelector?: string;\n /** Selector for the table rows */\n rowSelector?: string;\n /** Selector for the cells within a row */\n cellSelector?: string;\n /** Number of pages to scan for verification */\n maxPages?: number;\n /** Hook to rename columns dynamically */\n headerTransformer?: (args: { text: string, index: number, locator: Locator, seenHeaders: Set<string> }) => string | Promise<string>;\n /** Automatically scroll to table on init */\n autoScroll?: boolean;\n /** Debug options for development and troubleshooting */\n debug?: DebugConfig;\n /** Reset hook */\n onReset?: (context: TableContext) => Promise<void>;\n /** All interaction strategies */\n strategies?: TableStrategies;\n /**\n * Custom data mappers for specific columns.\n * Allows extracting complex data types (boolean, number) instead of just string.\n */\n dataMapper?: Partial<Record<keyof T, (cell: Locator) => Promise<T[keyof T]> | T[keyof T]>>;\n}\n\nexport interface FinalTableConfigLike<T = any> extends TableConfig<T> {\n headerSelector: string;\n rowSelector: string;\n cellSelector: string;\n maxPages: number;\n autoScroll: boolean;\n debug?: TableConfig['debug'];\n headerTransformer: (args: { text: string, index: number, locator: Locator, seenHeaders: Set<string> }) => string | Promise<string>;\n onReset: (context: TableContext) => Promise<void>;\n strategies: TableStrategies;\n}\n// Alias for backward compatibility if needed, or update usages\nexport type FinalTableConfig<T = any> = FinalTableConfigLike<T>;\n\n\nexport interface FillOptions {\n /**\n * Custom input mappers for specific columns.\n * Maps column names to functions that return the input locator for that cell.\n */\n inputMappers?: Record<string, (cell: Locator) => Locator>;\n}\n\n/**\n * Options for generateConfigPrompt\n */\nexport interface PromptOptions {\n /**\n * Output Strategy:\n * - 'error': Throws an error with the prompt (useful for platforms that capture error output cleanly).\n * - 'console': Standard console logs (Default).\n */\n output?: 'console' | 'error';\n /**\n * Include TypeScript type definitions in the prompt\n * @default true\n */\n includeTypes?: boolean;\n}\n\nexport interface TableResult<T = any> {\n /**\n * Initializes the table by resolving headers. Must be called before using sync methods.\n * @param options Optional timeout for header resolution (default: 3000ms)\n */\n init(options?: { timeout?: number }): Promise<TableResult>;\n\n /**\n * SYNC: Checks if the table has been initialized.\n * @returns true if init() has been called and completed, false otherwise\n */\n isInitialized(): boolean;\n\n getHeaders: () => Promise<string[]>;\n getHeaderCell: (columnName: string) => Promise<Locator>;\n\n /**\n * Finds a row by filters on the current page only. Returns immediately (sync).\n * Throws error if table is not initialized.\n */\n getRow: (\n filters: Record<string, FilterValue>,\n options?: { exact?: boolean }\n ) => SmartRow;\n\n /**\n * Gets a row by 1-based index on the current page.\n * Throws error if table is not initialized.\n * @param index 1-based row index\n * @param options Optional settings including bringIntoView\n */\n getRowByIndex: (\n index: number,\n options?: { bringIntoView?: boolean }\n ) => SmartRow;\n\n /**\n * ASYNC: Searches for a single row across pages using pagination.\n * Auto-initializes the table if not already initialized.\n * @param filters - The filter criteria to match\n * @param options - Search options including exact match and max pages\n */\n findRow: (\n filters: Record<string, FilterValue>,\n options?: { exact?: boolean, maxPages?: number }\n ) => Promise<SmartRow>;\n\n /**\n * ASYNC: Searches for all matching rows across pages using pagination.\n * Auto-initializes the table if not already initialized.\n * @param filters - The filter criteria to match\n * @param options - Search options including exact match and max pages\n */\n findRows: (\n filters: Record<string, FilterValue>,\n options?: { exact?: boolean, maxPages?: number }\n ) => Promise<SmartRowArray<T>>;\n\n /**\n * Navigates to a specific column using the configured CellNavigationStrategy.\n */\n scrollToColumn: (columnName: string) => Promise<void>;\n\n /**\n * Gets all rows on the current page only (does not paginate).\n * Auto-initializes the table if not already initialized.\n * Returns a SmartRowArray which extends Array with a toJSON() helper method.\n * @param options - Filter options\n */\n getRows: (options?: { filter?: Record<string, any>, exact?: boolean }) => Promise<SmartRowArray>;\n\n /**\n * Resets the table state (clears cache, flags) and invokes the onReset strategy.\n */\n reset: () => Promise<void>;\n\n /**\n * Revalidates the table's structure (headers, columns) without resetting pagination or state.\n * Useful when columns change visibility or order dynamically.\n */\n revalidate: () => Promise<void>;\n\n /**\n * Scans a specific column across all pages and returns the values.\n */\n getColumnValues: <V = string>(column: string, options?: { mapper?: (cell: Locator) => Promise<V> | V, maxPages?: number }) => Promise<V[]>;\n\n /**\n * Provides access to sorting actions and assertions.\n */\n sorting: {\n /**\n * Applies the configured sorting strategy to the specified column.\n * @param columnName The name of the column to sort.\n * @param direction The direction to sort ('asc' or 'desc').\n */\n apply(columnName: string, direction: 'asc' | 'desc'): Promise<void>;\n /**\n * Gets the current sort state of a column using the configured sorting strategy.\n * @param columnName The name of the column to check.\n * @returns A promise that resolves to 'asc', 'desc', or 'none'.\n */\n getState(columnName: string): Promise<'asc' | 'desc' | 'none'>;\n };\n\n /**\n * Iterates through paginated table data, calling the callback for each iteration.\n * Callback return values are automatically appended to allData, which is returned.\n */\n iterateThroughTable: <T = any>(\n callback: (context: {\n index: number;\n isFirst: boolean;\n isLast: boolean;\n rows: SmartRowArray;\n allData: T[];\n table: RestrictedTableResult;\n batchInfo?: {\n startIndex: number;\n endIndex: number;\n size: number;\n };\n\n }) => T | T[] | Promise<T | T[]>,\n options?: {\n pagination?: PaginationStrategy;\n dedupeStrategy?: DedupeStrategy;\n maxIterations?: number;\n batchSize?: number;\n getIsFirst?: (context: { index: number }) => boolean;\n getIsLast?: (context: { index: number, paginationResult: boolean }) => boolean;\n beforeFirst?: (context: { index: number, rows: SmartRowArray, allData: any[] }) => void | Promise<void>;\n afterLast?: (context: { index: number, rows: SmartRowArray, allData: any[] }) => void | Promise<void>;\n /**\n * If true, flattens array results from callback into the main data array.\n * If false (default), pushes the return value as-is (preserves batching/arrays).\n */\n autoFlatten?: boolean;\n }\n ) => Promise<T[]>;\n\n /**\n * Generate an AI-friendly configuration prompt for debugging.\n * Outputs table HTML and TypeScript definitions to help AI assistants generate config.\n */\n generateConfigPrompt: (options?: PromptOptions) => Promise<void>;\n}\n\n/**\n * Restricted table result that excludes methods that shouldn't be called during iteration.\n */\nexport type RestrictedTableResult<T = any> = Omit<TableResult<T>, 'searchForRow' | 'iterateThroughTable' | 'reset'>;\n";
|
|
6
|
+
export declare const TYPE_CONTEXT = "\n/**\n * Flexible selector type - can be a CSS string, function returning a Locator, or Locator itself.\n * @example\n * // String selector\n * rowSelector: 'tbody tr'\n * \n * // Function selector\n * rowSelector: (root) => root.locator('[role=\"row\"]')\n */\nexport type Selector = string | ((root: Locator | Page) => Locator);\n\n/**\n * Value used to filter rows.\n * - string/number/RegExp: filter by text content of the cell.\n * - function: filter by custom locator logic within the cell.\n * @example\n * // Text filter\n * { Name: 'John' }\n * \n * // Custom locator filter (e.g. checkbox is checked)\n * { Status: (cell) => cell.locator('input:checked') }\n */\nexport type FilterValue = string | RegExp | number | ((cell: Locator) => Locator);\n\n/**\n * Function to get a cell locator given row, column info.\n * Replaces the old cellResolver.\n */\nexport type GetCellLocatorFn = (args: {\n row: Locator;\n columnName: string;\n columnIndex: number;\n rowIndex?: number;\n page: Page;\n}) => Locator;\n\n/**\n * Function to get the currently active/focused cell.\n * Returns null if no cell is active.\n */\nexport type GetActiveCellFn = (args: TableContext) => Promise<{\n rowIndex: number;\n columnIndex: number;\n columnName?: string;\n locator: Locator;\n} | null>;\n\n\n/**\n * SmartRow - A Playwright Locator with table-aware methods.\n * \n * Extends all standard Locator methods (click, isVisible, etc.) with table-specific functionality.\n * \n * @example\n * const row = table.getRow({ Name: 'John Doe' });\n * await row.click(); // Standard Locator method\n * const email = row.getCell('Email'); // Table-aware method\n * const data = await row.toJSON(); // Extract all row data\n * await row.smartFill({ Name: 'Jane', Status: 'Active' }); // Fill form fields\n */\nexport type SmartRow<T = any> = Locator & {\n /** Optional row index (0-based) if known */\n rowIndex?: number;\n\n /**\n * Get a cell locator by column name.\n * @param column - Column name (case-sensitive)\n * @returns Locator for the cell\n * @example\n * const emailCell = row.getCell('Email');\n * await expect(emailCell).toHaveText('john@example.com');\n */\n getCell(column: string): Locator;\n\n /**\n * Extract all cell data as a key-value object.\n * @param options - Optional configuration\n * @param options.columns - Specific columns to extract (extracts all if not specified)\n * @returns Promise resolving to row data\n * @example\n * const data = await row.toJSON();\n * // { Name: 'John', Email: 'john@example.com', ... }\n * \n * const partial = await row.toJSON({ columns: ['Name', 'Email'] });\n * // { Name: 'John', Email: 'john@example.com' }\n */\n toJSON(options?: { columns?: string[] }): Promise<T>;\n\n /**\n * Scrolls/paginates to bring this row into view.\n * Only works if rowIndex is known (e.g., from getRowByIndex).\n * @throws Error if rowIndex is unknown\n */\n bringIntoView(): Promise<void>;\n\n /**\n * Intelligently fills form fields in the row.\n * Automatically detects input types (text, select, checkbox, contenteditable).\n * \n * @param data - Column-value pairs to fill\n * @param options - Optional configuration\n * @param options.inputMappers - Custom input selectors per column\n * @example\n * // Auto-detection\n * await row.smartFill({ Name: 'John', Status: 'Active', Subscribe: true });\n * \n * // Custom input mappers\n * await row.smartFill(\n * { Name: 'John' },\n * { inputMappers: { Name: (cell) => cell.locator('.custom-input') } }\n * );\n */\n smartFill: (data: Partial<T> | Record<string, any>, options?: FillOptions) => Promise<void>;\n};\n\nexport type StrategyContext = TableContext & { rowLocator?: Locator; rowIndex?: number };\n\n/**\n * Defines the contract for a sorting strategy.\n */\nexport interface SortingStrategy {\n /**\n * Performs the sort action on a column.\n */\n doSort(options: {\n columnName: string;\n direction: 'asc' | 'desc';\n context: StrategyContext;\n }): Promise<void>;\n\n /**\n * Retrieves the current sort state of a column.\n */\n getSortState(options: {\n columnName: string;\n context: StrategyContext;\n }): Promise<'asc' | 'desc' | 'none'>;\n}\n\n/**\n * Debug configuration for development and troubleshooting\n */\nexport type DebugConfig = {\n /**\n * Slow down operations for debugging\n * - number: Apply same delay to all operations (ms)\n * - object: Granular delays per operation type\n */\n slow?: number | {\n pagination?: number;\n getCell?: number;\n findRow?: number;\n default?: number;\n };\n /**\n * Log level for debug output\n * - 'verbose': All logs (verbose, info, error)\n * - 'info': Info and error logs only\n * - 'error': Error logs only\n * - 'none': No logs\n */\n logLevel?: 'verbose' | 'info' | 'error' | 'none';\n};\n\nexport interface TableContext<T = any> {\n root: Locator;\n config: FinalTableConfig<T>;\n page: Page;\n resolve: (selector: Selector, parent: Locator | Page) => Locator;\n}\n\nexport type PaginationStrategy = (context: TableContext) => Promise<boolean>;\n\nexport type DedupeStrategy = (row: SmartRow) => string | number | Promise<string | number>;\n\n\n\nexport type FillStrategy = (options: {\n row: SmartRow;\n columnName: string;\n value: any;\n index: number;\n page: Page;\n rootLocator: Locator;\n table: TableResult; // The parent table instance\n fillOptions?: FillOptions;\n}) => Promise<void>;\n\nexport type { HeaderStrategy } from './strategies/headers';\n\n/**\n * Strategy to resolve column names (string or regex) to their index.\n */\nexport type { ColumnResolutionStrategy } from './strategies/resolution';\n\n/**\n * Strategy to filter rows based on criteria.\n */\nexport interface FilterStrategy {\n apply(options: {\n rows: Locator;\n filter: { column: string, value: FilterValue };\n colIndex: number;\n tableContext: TableContext;\n }): Locator;\n}\n\n/**\n * Strategy to check if the table or rows are loading.\n */\nexport interface LoadingStrategy {\n isTableLoading?: (context: TableContext) => Promise<boolean>;\n isRowLoading?: (row: SmartRow) => Promise<boolean>;\n isHeaderLoading?: (context: TableContext) => Promise<boolean>;\n}\n\n/**\n * Organized container for all table interaction strategies.\n */\nexport interface TableStrategies {\n /** Strategy for discovering/scanning headers */\n header?: HeaderStrategy;\n /** Primitive navigation functions (goUp, goDown, goLeft, goRight, goHome) */\n navigation?: NavigationPrimitives;\n\n /** Strategy for filling form inputs */\n fill?: FillStrategy;\n /** Strategy for paginating through data */\n pagination?: PaginationStrategy;\n /** Strategy for sorting columns */\n sorting?: SortingStrategy;\n /** Strategy for deduplicating rows during iteration/scrolling */\n dedupe?: DedupeStrategy;\n /** Function to get a cell locator */\n getCellLocator?: GetCellLocatorFn;\n /** Function to get the currently active/focused cell */\n getActiveCell?: GetActiveCellFn;\n /** Custom helper to check if a table is fully loaded/ready */\n isTableLoaded?: (args: TableContext) => Promise<boolean>;\n /** Custom helper to check if a row is fully loaded/ready */\n isRowLoaded?: (args: { row: Locator, index: number }) => Promise<boolean>;\n /** Custom helper to check if a cell is fully loaded/ready (e.g. for editing) */\n isCellLoaded?: (args: { cell: Locator, column: string, row: Locator }) => Promise<boolean>;\n /** Strategy for detecting loading states */\n loading?: LoadingStrategy;\n}\n\n\nexport interface TableConfig<T = any> {\n /** Selector for the table headers */\n headerSelector?: string | ((root: Locator) => Locator);\n /** Selector for the table rows */\n rowSelector?: string;\n /** Selector for the cells within a row */\n cellSelector?: string;\n /** Number of pages to scan for verification */\n maxPages?: number;\n /** Hook to rename columns dynamically */\n headerTransformer?: (args: { text: string, index: number, locator: Locator, seenHeaders: Set<string> }) => string | Promise<string>;\n /** Automatically scroll to table on init */\n autoScroll?: boolean;\n /** Debug options for development and troubleshooting */\n debug?: DebugConfig;\n /** Reset hook */\n onReset?: (context: TableContext) => Promise<void>;\n /** All interaction strategies */\n strategies?: TableStrategies;\n /**\n * Custom data mappers for specific columns.\n * Allows extracting complex data types (boolean, number) instead of just string.\n */\n dataMapper?: Partial<Record<keyof T, (cell: Locator) => Promise<T[keyof T]> | T[keyof T]>>;\n}\n\nexport interface FinalTableConfig<T = any> extends TableConfig<T> {\n headerSelector: string | ((root: Locator) => Locator);\n rowSelector: string;\n cellSelector: string;\n maxPages: number;\n autoScroll: boolean;\n debug?: TableConfig['debug'];\n headerTransformer: (args: { text: string, index: number, locator: Locator, seenHeaders: Set<string> }) => string | Promise<string>;\n onReset: (context: TableContext) => Promise<void>;\n strategies: TableStrategies;\n}\n\n\nexport interface FillOptions {\n /**\n * Custom input mappers for specific columns.\n * Maps column names to functions that return the input locator for that cell.\n */\n inputMappers?: Record<string, (cell: Locator) => Locator>;\n}\n\n/**\n * Options for generateConfigPrompt\n */\nexport interface PromptOptions {\n /**\n * Output Strategy:\n * - 'error': Throws an error with the prompt (useful for platforms that capture error output cleanly).\n * - 'console': Standard console logs (Default).\n */\n output?: 'console' | 'error';\n /**\n * Include TypeScript type definitions in the prompt\n * @default true\n */\n includeTypes?: boolean;\n}\n\nexport interface TableResult<T = any> {\n /**\n * Initializes the table by resolving headers. Must be called before using sync methods.\n * @param options Optional timeout for header resolution (default: 3000ms)\n */\n init(options?: { timeout?: number }): Promise<TableResult>;\n\n /**\n * SYNC: Checks if the table has been initialized.\n * @returns true if init() has been called and completed, false otherwise\n */\n isInitialized(): boolean;\n\n getHeaders: () => Promise<string[]>;\n getHeaderCell: (columnName: string) => Promise<Locator>;\n\n /**\n * Finds a row by filters on the current page only. Returns immediately (sync).\n * Throws error if table is not initialized.\n */\n getRow: (\n filters: Record<string, FilterValue>,\n options?: { exact?: boolean }\n ) => SmartRow;\n\n /**\n * Gets a row by 1-based index on the current page.\n * Throws error if table is not initialized.\n * @param index 1-based row index\n * @param options Optional settings including bringIntoView\n */\n getRowByIndex: (\n index: number,\n options?: { bringIntoView?: boolean }\n ) => SmartRow;\n\n /**\n * ASYNC: Searches for a single row across pages using pagination.\n * Auto-initializes the table if not already initialized.\n * @param filters - The filter criteria to match\n * @param options - Search options including exact match and max pages\n */\n findRow: (\n filters: Record<string, FilterValue>,\n options?: { exact?: boolean, maxPages?: number }\n ) => Promise<SmartRow>;\n\n /**\n * ASYNC: Searches for all matching rows across pages using pagination.\n * Auto-initializes the table if not already initialized.\n * @param filters - The filter criteria to match\n * @param options - Search options including exact match and max pages\n */\n findRows: (\n filters: Record<string, FilterValue>,\n options?: { exact?: boolean, maxPages?: number }\n ) => Promise<SmartRowArray<T>>;\n\n /**\n * Navigates to a specific column using the configured CellNavigationStrategy.\n */\n scrollToColumn: (columnName: string) => Promise<void>;\n\n\n\n /**\n * Resets the table state (clears cache, flags) and invokes the onReset strategy.\n */\n reset: () => Promise<void>;\n\n /**\n * Revalidates the table's structure (headers, columns) without resetting pagination or state.\n * Useful when columns change visibility or order dynamically.\n */\n revalidate: () => Promise<void>;\n\n /**\n * Scans a specific column across all pages and returns the values.\n */\n getColumnValues: <V = string>(column: string, options?: { mapper?: (cell: Locator) => Promise<V> | V, maxPages?: number }) => Promise<V[]>;\n\n /**\n * Provides access to sorting actions and assertions.\n */\n sorting: {\n /**\n * Applies the configured sorting strategy to the specified column.\n * @param columnName The name of the column to sort.\n * @param direction The direction to sort ('asc' or 'desc').\n */\n apply(columnName: string, direction: 'asc' | 'desc'): Promise<void>;\n /**\n * Gets the current sort state of a column using the configured sorting strategy.\n * @param columnName The name of the column to check.\n * @returns A promise that resolves to 'asc', 'desc', or 'none'.\n */\n getState(columnName: string): Promise<'asc' | 'desc' | 'none'>;\n };\n\n /**\n * Iterates through paginated table data, calling the callback for each iteration.\n * Callback return values are automatically appended to allData, which is returned.\n */\n iterateThroughTable: <T = any>(\n callback: (context: {\n index: number;\n isFirst: boolean;\n isLast: boolean;\n rows: SmartRowArray;\n allData: T[];\n table: RestrictedTableResult;\n batchInfo?: {\n startIndex: number;\n endIndex: number;\n size: number;\n };\n\n }) => T | T[] | Promise<T | T[]>,\n options?: {\n pagination?: PaginationStrategy;\n dedupeStrategy?: DedupeStrategy;\n maxIterations?: number;\n batchSize?: number;\n getIsFirst?: (context: { index: number }) => boolean;\n getIsLast?: (context: { index: number, paginationResult: boolean }) => boolean;\n beforeFirst?: (context: { index: number, rows: SmartRowArray, allData: any[] }) => void | Promise<void>;\n afterLast?: (context: { index: number, rows: SmartRowArray, allData: any[] }) => void | Promise<void>;\n /**\n * If true, flattens array results from callback into the main data array.\n * If false (default), pushes the return value as-is (preserves batching/arrays).\n */\n autoFlatten?: boolean;\n }\n ) => Promise<T[]>;\n\n /**\n * Generate an AI-friendly configuration prompt for debugging.\n * Outputs table HTML and TypeScript definitions to help AI assistants generate config.\n */\n generateConfigPrompt: (options?: PromptOptions) => Promise<void>;\n}\n\n/**\n * Restricted table result that excludes methods that shouldn't be called during iteration.\n */\nexport type RestrictedTableResult<T = any> = Omit<TableResult<T>, 'searchForRow' | 'iterateThroughTable' | 'reset'>;\n";
|
package/dist/typeContext.js
CHANGED
|
@@ -182,15 +182,7 @@ export type PaginationStrategy = (context: TableContext) => Promise<boolean>;
|
|
|
182
182
|
|
|
183
183
|
export type DedupeStrategy = (row: SmartRow) => string | number | Promise<string | number>;
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Output Strategy:
|
|
188
|
-
* - 'error': Throws an error with the prompt (useful for platforms that capture error output cleanly).
|
|
189
|
-
* - 'console': Standard console logs (Default).
|
|
190
|
-
*/
|
|
191
|
-
output?: 'console' | 'error';
|
|
192
|
-
includeTypes?: boolean;
|
|
193
|
-
}
|
|
185
|
+
|
|
194
186
|
|
|
195
187
|
export type FillStrategy = (options: {
|
|
196
188
|
row: SmartRow;
|
|
@@ -204,7 +196,6 @@ export type FillStrategy = (options: {
|
|
|
204
196
|
}) => Promise<void>;
|
|
205
197
|
|
|
206
198
|
export type { HeaderStrategy } from './strategies/headers';
|
|
207
|
-
export type { CellNavigationStrategy, NavigationPrimitives } from './strategies/columns';
|
|
208
199
|
|
|
209
200
|
/**
|
|
210
201
|
* Strategy to resolve column names (string or regex) to their index.
|
|
@@ -240,8 +231,7 @@ export interface TableStrategies {
|
|
|
240
231
|
header?: HeaderStrategy;
|
|
241
232
|
/** Primitive navigation functions (goUp, goDown, goLeft, goRight, goHome) */
|
|
242
233
|
navigation?: NavigationPrimitives;
|
|
243
|
-
|
|
244
|
-
cellNavigation?: CellNavigationStrategy;
|
|
234
|
+
|
|
245
235
|
/** Strategy for filling form inputs */
|
|
246
236
|
fill?: FillStrategy;
|
|
247
237
|
/** Strategy for paginating through data */
|
|
@@ -264,15 +254,10 @@ export interface TableStrategies {
|
|
|
264
254
|
loading?: LoadingStrategy;
|
|
265
255
|
}
|
|
266
256
|
|
|
267
|
-
|
|
268
|
-
* Configuration options for useTable.
|
|
269
|
-
*/
|
|
270
|
-
/**
|
|
271
|
-
* Configuration options for useTable.
|
|
272
|
-
*/
|
|
257
|
+
|
|
273
258
|
export interface TableConfig<T = any> {
|
|
274
259
|
/** Selector for the table headers */
|
|
275
|
-
headerSelector?: string;
|
|
260
|
+
headerSelector?: string | ((root: Locator) => Locator);
|
|
276
261
|
/** Selector for the table rows */
|
|
277
262
|
rowSelector?: string;
|
|
278
263
|
/** Selector for the cells within a row */
|
|
@@ -296,8 +281,8 @@ export interface TableConfig<T = any> {
|
|
|
296
281
|
dataMapper?: Partial<Record<keyof T, (cell: Locator) => Promise<T[keyof T]> | T[keyof T]>>;
|
|
297
282
|
}
|
|
298
283
|
|
|
299
|
-
export interface
|
|
300
|
-
headerSelector: string;
|
|
284
|
+
export interface FinalTableConfig<T = any> extends TableConfig<T> {
|
|
285
|
+
headerSelector: string | ((root: Locator) => Locator);
|
|
301
286
|
rowSelector: string;
|
|
302
287
|
cellSelector: string;
|
|
303
288
|
maxPages: number;
|
|
@@ -307,8 +292,6 @@ export interface FinalTableConfigLike<T = any> extends TableConfig<T> {
|
|
|
307
292
|
onReset: (context: TableContext) => Promise<void>;
|
|
308
293
|
strategies: TableStrategies;
|
|
309
294
|
}
|
|
310
|
-
// Alias for backward compatibility if needed, or update usages
|
|
311
|
-
export type FinalTableConfig<T = any> = FinalTableConfigLike<T>;
|
|
312
295
|
|
|
313
296
|
|
|
314
297
|
export interface FillOptions {
|
|
@@ -399,13 +382,7 @@ export interface TableResult<T = any> {
|
|
|
399
382
|
*/
|
|
400
383
|
scrollToColumn: (columnName: string) => Promise<void>;
|
|
401
384
|
|
|
402
|
-
|
|
403
|
-
* Gets all rows on the current page only (does not paginate).
|
|
404
|
-
* Auto-initializes the table if not already initialized.
|
|
405
|
-
* Returns a SmartRowArray which extends Array with a toJSON() helper method.
|
|
406
|
-
* @param options - Filter options
|
|
407
|
-
*/
|
|
408
|
-
getRows: (options?: { filter?: Record<string, any>, exact?: boolean }) => Promise<SmartRowArray>;
|
|
385
|
+
|
|
409
386
|
|
|
410
387
|
/**
|
|
411
388
|
* Resets the table state (clears cache, flags) and invokes the onReset strategy.
|
package/dist/types.d.ts
CHANGED
|
@@ -163,15 +163,6 @@ export interface TableContext<T = any> {
|
|
|
163
163
|
}
|
|
164
164
|
export type PaginationStrategy = (context: TableContext) => Promise<boolean>;
|
|
165
165
|
export type DedupeStrategy = (row: SmartRow) => string | number | Promise<string | number>;
|
|
166
|
-
export interface PromptOptions {
|
|
167
|
-
/**
|
|
168
|
-
* Output Strategy:
|
|
169
|
-
* - 'error': Throws an error with the prompt (useful for platforms that capture error output cleanly).
|
|
170
|
-
* - 'console': Standard console logs (Default).
|
|
171
|
-
*/
|
|
172
|
-
output?: 'console' | 'error';
|
|
173
|
-
includeTypes?: boolean;
|
|
174
|
-
}
|
|
175
166
|
export type FillStrategy = (options: {
|
|
176
167
|
row: SmartRow;
|
|
177
168
|
columnName: string;
|
|
@@ -182,10 +173,9 @@ export type FillStrategy = (options: {
|
|
|
182
173
|
table: TableResult;
|
|
183
174
|
fillOptions?: FillOptions;
|
|
184
175
|
}) => Promise<void>;
|
|
185
|
-
export type { HeaderStrategy } from './strategies/headers';
|
|
186
|
-
export type { CellNavigationStrategy, NavigationPrimitives } from './strategies/columns';
|
|
187
176
|
import { HeaderStrategy } from './strategies/headers';
|
|
188
|
-
|
|
177
|
+
export type { HeaderStrategy } from './strategies/headers';
|
|
178
|
+
import { NavigationPrimitives } from './strategies/columns';
|
|
189
179
|
/**
|
|
190
180
|
* Strategy to resolve column names (string or regex) to their index.
|
|
191
181
|
*/
|
|
@@ -220,8 +210,6 @@ export interface TableStrategies {
|
|
|
220
210
|
header?: HeaderStrategy;
|
|
221
211
|
/** Primitive navigation functions (goUp, goDown, goLeft, goRight, goHome) */
|
|
222
212
|
navigation?: NavigationPrimitives;
|
|
223
|
-
/** @deprecated Use navigation primitives instead. Strategy for navigating to specific cells (row + column) */
|
|
224
|
-
cellNavigation?: CellNavigationStrategy;
|
|
225
213
|
/** Strategy for filling form inputs */
|
|
226
214
|
fill?: FillStrategy;
|
|
227
215
|
/** Strategy for paginating through data */
|
|
@@ -250,15 +238,9 @@ export interface TableStrategies {
|
|
|
250
238
|
/** Strategy for detecting loading states */
|
|
251
239
|
loading?: LoadingStrategy;
|
|
252
240
|
}
|
|
253
|
-
/**
|
|
254
|
-
* Configuration options for useTable.
|
|
255
|
-
*/
|
|
256
|
-
/**
|
|
257
|
-
* Configuration options for useTable.
|
|
258
|
-
*/
|
|
259
241
|
export interface TableConfig<T = any> {
|
|
260
242
|
/** Selector for the table headers */
|
|
261
|
-
headerSelector?: string;
|
|
243
|
+
headerSelector?: string | ((root: Locator) => Locator);
|
|
262
244
|
/** Selector for the table rows */
|
|
263
245
|
rowSelector?: string;
|
|
264
246
|
/** Selector for the cells within a row */
|
|
@@ -286,8 +268,8 @@ export interface TableConfig<T = any> {
|
|
|
286
268
|
*/
|
|
287
269
|
dataMapper?: Partial<Record<keyof T, (cell: Locator) => Promise<T[keyof T]> | T[keyof T]>>;
|
|
288
270
|
}
|
|
289
|
-
export interface
|
|
290
|
-
headerSelector: string;
|
|
271
|
+
export interface FinalTableConfig<T = any> extends TableConfig<T> {
|
|
272
|
+
headerSelector: string | ((root: Locator) => Locator);
|
|
291
273
|
rowSelector: string;
|
|
292
274
|
cellSelector: string;
|
|
293
275
|
maxPages: number;
|
|
@@ -302,7 +284,6 @@ export interface FinalTableConfigLike<T = any> extends TableConfig<T> {
|
|
|
302
284
|
onReset: (context: TableContext) => Promise<void>;
|
|
303
285
|
strategies: TableStrategies;
|
|
304
286
|
}
|
|
305
|
-
export type FinalTableConfig<T = any> = FinalTableConfigLike<T>;
|
|
306
287
|
export interface FillOptions {
|
|
307
288
|
/**
|
|
308
289
|
* Custom input mappers for specific columns.
|
|
@@ -381,16 +362,6 @@ export interface TableResult<T = any> {
|
|
|
381
362
|
* Navigates to a specific column using the configured CellNavigationStrategy.
|
|
382
363
|
*/
|
|
383
364
|
scrollToColumn: (columnName: string) => Promise<void>;
|
|
384
|
-
/**
|
|
385
|
-
* Gets all rows on the current page only (does not paginate).
|
|
386
|
-
* Auto-initializes the table if not already initialized.
|
|
387
|
-
* Returns a SmartRowArray which extends Array with a toJSON() helper method.
|
|
388
|
-
* @param options - Filter options
|
|
389
|
-
*/
|
|
390
|
-
getRows: (options?: {
|
|
391
|
-
filter?: Record<string, any>;
|
|
392
|
-
exact?: boolean;
|
|
393
|
-
}) => Promise<SmartRowArray>;
|
|
394
365
|
/**
|
|
395
366
|
* Resets the table state (clears cache, flags) and invokes the onReset strategy.
|
|
396
367
|
*/
|
package/dist/useTable.d.ts
CHANGED
|
@@ -1,48 +1,6 @@
|
|
|
1
1
|
import type { Locator } from '@playwright/test';
|
|
2
|
-
import { TableConfig,
|
|
3
|
-
import { FillStrategies } from './strategies/fill';
|
|
4
|
-
import { HeaderStrategies } from './strategies/headers';
|
|
5
|
-
import { CellNavigationStrategies } from './strategies/columns';
|
|
6
|
-
import { ResolutionStrategies } from './strategies/resolution';
|
|
7
|
-
import { Strategies } from './strategies';
|
|
2
|
+
import { TableConfig, TableResult } from './types';
|
|
8
3
|
/**
|
|
9
4
|
* Main hook to interact with a table.
|
|
10
5
|
*/
|
|
11
6
|
export declare const useTable: <T = any>(rootLocator: Locator, configOptions?: TableConfig<T>) => TableResult<T>;
|
|
12
|
-
export declare const PaginationStrategies: {
|
|
13
|
-
clickNext: (nextButtonSelector: Selector, options?: {
|
|
14
|
-
stabilization?: import("./strategies/stabilization").StabilizationStrategy;
|
|
15
|
-
timeout?: number;
|
|
16
|
-
}) => PaginationStrategy;
|
|
17
|
-
infiniteScroll: (options?: {
|
|
18
|
-
action?: "scroll" | "js-scroll";
|
|
19
|
-
scrollTarget?: Selector;
|
|
20
|
-
scrollAmount?: number;
|
|
21
|
-
stabilization?: import("./strategies/stabilization").StabilizationStrategy;
|
|
22
|
-
timeout?: number;
|
|
23
|
-
}) => PaginationStrategy;
|
|
24
|
-
};
|
|
25
|
-
export declare const LoadingStrategies: {
|
|
26
|
-
Table: {
|
|
27
|
-
hasSpinner: (selector?: string) => ({ root }: TableContext) => Promise<boolean>;
|
|
28
|
-
custom: (fn: (context: TableContext) => Promise<boolean>) => (context: TableContext) => Promise<boolean>;
|
|
29
|
-
never: () => Promise<boolean>;
|
|
30
|
-
};
|
|
31
|
-
Row: {
|
|
32
|
-
hasClass: (className?: string) => (row: SmartRowType) => Promise<boolean>;
|
|
33
|
-
hasText: (text?: string | RegExp) => (row: SmartRowType) => Promise<boolean>;
|
|
34
|
-
hasEmptyCells: () => (row: SmartRowType) => Promise<boolean>;
|
|
35
|
-
never: () => Promise<boolean>;
|
|
36
|
-
};
|
|
37
|
-
Headers: {
|
|
38
|
-
stable: (duration?: number) => (context: TableContext) => Promise<boolean>;
|
|
39
|
-
never: () => Promise<boolean>;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
export declare const SortingStrategies: {
|
|
43
|
-
AriaSort: () => import("./types").SortingStrategy;
|
|
44
|
-
};
|
|
45
|
-
export declare const DedupeStrategies: {
|
|
46
|
-
byTopPosition: (tolerance?: number) => DedupeStrategy;
|
|
47
|
-
};
|
|
48
|
-
export { FillStrategies, HeaderStrategies, CellNavigationStrategies, ResolutionStrategies, Strategies };
|
package/dist/useTable.js
CHANGED
|
@@ -9,26 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
const
|
|
14
|
-
const sorting_1 = require("./strategies/sorting");
|
|
15
|
-
const pagination_1 = require("./strategies/pagination");
|
|
16
|
-
const dedupe_1 = require("./strategies/dedupe");
|
|
12
|
+
exports.useTable = void 0;
|
|
13
|
+
const minimalConfigContext_1 = require("./minimalConfigContext");
|
|
17
14
|
const loading_1 = require("./strategies/loading");
|
|
18
15
|
const fill_1 = require("./strategies/fill");
|
|
19
|
-
Object.defineProperty(exports, "FillStrategies", { enumerable: true, get: function () { return fill_1.FillStrategies; } });
|
|
20
16
|
const headers_1 = require("./strategies/headers");
|
|
21
|
-
Object.defineProperty(exports, "HeaderStrategies", { enumerable: true, get: function () { return headers_1.HeaderStrategies; } });
|
|
22
|
-
const columns_1 = require("./strategies/columns");
|
|
23
|
-
Object.defineProperty(exports, "CellNavigationStrategies", { enumerable: true, get: function () { return columns_1.CellNavigationStrategies; } });
|
|
24
17
|
const smartRow_1 = require("./smartRow");
|
|
25
18
|
const filterEngine_1 = require("./filterEngine");
|
|
26
19
|
const tableMapper_1 = require("./engine/tableMapper");
|
|
27
20
|
const rowFinder_1 = require("./engine/rowFinder");
|
|
28
|
-
const resolution_1 = require("./strategies/resolution");
|
|
29
|
-
Object.defineProperty(exports, "ResolutionStrategies", { enumerable: true, get: function () { return resolution_1.ResolutionStrategies; } });
|
|
30
|
-
const strategies_1 = require("./strategies");
|
|
31
|
-
Object.defineProperty(exports, "Strategies", { enumerable: true, get: function () { return strategies_1.Strategies; } });
|
|
32
21
|
const debugUtils_1 = require("./utils/debugUtils");
|
|
33
22
|
const smartRowArray_1 = require("./utils/smartRowArray");
|
|
34
23
|
/**
|
|
@@ -42,7 +31,6 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
42
31
|
const defaultStrategies = {
|
|
43
32
|
fill: fill_1.FillStrategies.default,
|
|
44
33
|
header: headers_1.HeaderStrategies.visible,
|
|
45
|
-
cellNavigation: columns_1.CellNavigationStrategies.default,
|
|
46
34
|
pagination: () => __awaiter(void 0, void 0, void 0, function* () { return false; }),
|
|
47
35
|
loading: {
|
|
48
36
|
isHeaderLoading: loading_1.LoadingStrategies.Headers.stable(200)
|
|
@@ -117,7 +105,7 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
117
105
|
const { output = 'console', includeTypes = true } = options;
|
|
118
106
|
let finalPrompt = content;
|
|
119
107
|
if (includeTypes) {
|
|
120
|
-
finalPrompt += `\n\nš Useful TypeScript Definitions š\n\`\`\`typescript\n${
|
|
108
|
+
finalPrompt += `\n\nš Useful TypeScript Definitions š\n\`\`\`typescript\n${minimalConfigContext_1.MINIMAL_CONFIG_CONTEXT}\n\`\`\`\n`;
|
|
121
109
|
}
|
|
122
110
|
if (output === 'error') {
|
|
123
111
|
console.log(`ā ļø Throwing error to display [${promptName}] cleanly...`);
|
|
@@ -144,14 +132,9 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
144
132
|
const idx = map.get(columnName);
|
|
145
133
|
if (idx === undefined)
|
|
146
134
|
throw _createColumnError(columnName, map);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
page: rootLocator.page(),
|
|
151
|
-
resolve,
|
|
152
|
-
column: columnName,
|
|
153
|
-
index: idx
|
|
154
|
-
});
|
|
135
|
+
// Use header cell for scrolling
|
|
136
|
+
const headerCell = resolve(config.headerSelector, rootLocator).nth(idx);
|
|
137
|
+
yield headerCell.scrollIntoViewIfNeeded();
|
|
155
138
|
}),
|
|
156
139
|
getHeaders: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
140
|
const map = yield tableMapper.getMap();
|
|
@@ -228,11 +211,6 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
228
211
|
// @ts-ignore
|
|
229
212
|
return rowFinder.findRow(filters, options);
|
|
230
213
|
}),
|
|
231
|
-
getRows: (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
232
|
-
console.warn('DEPRECATED: table.getRows() is deprecated and will be removed in a future version. Use table.findRows() instead.');
|
|
233
|
-
// @ts-ignore
|
|
234
|
-
return rowFinder.findRows((options === null || options === void 0 ? void 0 : options.filter) || {}, Object.assign(Object.assign({}, options), { maxPages: 1 }));
|
|
235
|
-
}),
|
|
236
214
|
findRows: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
237
215
|
return rowFinder.findRows(filters, options);
|
|
238
216
|
}),
|
|
@@ -273,7 +251,6 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
273
251
|
getRow: result.getRow,
|
|
274
252
|
getRowByIndex: result.getRowByIndex,
|
|
275
253
|
findRow: result.findRow,
|
|
276
|
-
getRows: result.getRows,
|
|
277
254
|
findRows: result.findRows,
|
|
278
255
|
getColumnValues: result.getColumnValues,
|
|
279
256
|
isInitialized: result.isInitialized,
|
|
@@ -438,7 +415,3 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
438
415
|
return result;
|
|
439
416
|
};
|
|
440
417
|
exports.useTable = useTable;
|
|
441
|
-
exports.PaginationStrategies = Object.assign({}, pagination_1.PaginationStrategies);
|
|
442
|
-
exports.LoadingStrategies = loading_1.LoadingStrategies;
|
|
443
|
-
exports.SortingStrategies = sorting_1.SortingStrategies;
|
|
444
|
-
exports.DedupeStrategies = dedupe_1.DedupeStrategies;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rickcedwhat/playwright-smart-table",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"description": "Smart, column-aware table interactions for Playwright",
|
|
5
5
|
"author": "Cedrick Catalan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"generate-types": "node scripts/embed-types.mjs",
|
|
18
|
+
"generate-config-types": "node scripts/embed-config-types.mjs",
|
|
18
19
|
"generate-docs": "node scripts/generate-readme.mjs",
|
|
19
20
|
"generate-all-api-docs": "node scripts/generate-all-api-docs.mjs",
|
|
20
21
|
"update-all-api-signatures": "node scripts/update-all-api-signatures.mjs",
|
|
21
22
|
"docs:dev": "vitepress dev docs",
|
|
22
23
|
"docs:build": "vitepress build docs",
|
|
23
|
-
"build": "npm run generate-types && npm run generate-docs && npm run generate-all-api-docs && npm run update-all-api-signatures && tsc",
|
|
24
|
+
"build": "npm run generate-types && npm run generate-config-types && npm run generate-docs && npm run generate-all-api-docs && npm run update-all-api-signatures && tsc",
|
|
24
25
|
"prepublishOnly": "npm run build",
|
|
25
26
|
"test": "npm run test:unit && npx playwright test",
|
|
26
27
|
"test:unit": "vitest run --reporter=verbose --reporter=html",
|