@rickcedwhat/playwright-smart-table 4.0.0 → 5.1.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/useTable.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.Strategies = exports.ResolutionStrategies = exports.ColumnStrategies = exports.CellNavigationStrategies = exports.HeaderStrategies = exports.FillStrategies = exports.SortingStrategies = exports.DeprecatedTableStrategies = exports.PaginationStrategies = exports.useTable = void 0;
12
+ exports.Strategies = exports.ResolutionStrategies = exports.CellNavigationStrategies = exports.HeaderStrategies = exports.FillStrategies = exports.SortingStrategies = exports.PaginationStrategies = exports.useTable = void 0;
13
13
  const typeContext_1 = require("./typeContext");
14
14
  const sorting_1 = require("./strategies/sorting");
15
15
  const pagination_1 = require("./strategies/pagination");
@@ -19,13 +19,14 @@ const headers_1 = require("./strategies/headers");
19
19
  Object.defineProperty(exports, "HeaderStrategies", { enumerable: true, get: function () { return headers_1.HeaderStrategies; } });
20
20
  const columns_1 = require("./strategies/columns");
21
21
  Object.defineProperty(exports, "CellNavigationStrategies", { enumerable: true, get: function () { return columns_1.CellNavigationStrategies; } });
22
- Object.defineProperty(exports, "ColumnStrategies", { enumerable: true, get: function () { return columns_1.ColumnStrategies; } });
23
22
  const smartRow_1 = require("./smartRow");
24
23
  const filterEngine_1 = require("./filterEngine");
25
24
  const resolution_1 = require("./strategies/resolution");
26
25
  Object.defineProperty(exports, "ResolutionStrategies", { enumerable: true, get: function () { return resolution_1.ResolutionStrategies; } });
27
26
  const strategies_1 = require("./strategies");
28
27
  Object.defineProperty(exports, "Strategies", { enumerable: true, get: function () { return strategies_1.Strategies; } });
28
+ const validation_1 = require("./strategies/validation");
29
+ const traceUtils_1 = require("./utils/traceUtils");
29
30
  /**
30
31
  * Main hook to interact with a table.
31
32
  */
@@ -40,7 +41,7 @@ const useTable = (rootLocator, configOptions = {}) => {
40
41
  cellNavigation: columns_1.CellNavigationStrategies.default,
41
42
  pagination: () => __awaiter(void 0, void 0, void 0, function* () { return false; }),
42
43
  };
43
- const config = Object.assign(Object.assign({ rowSelector: "tbody tr", headerSelector: "th", cellSelector: "td", maxPages: 1, headerTransformer: ({ text, index, locator }) => text, autoScroll: true, debug: false, onReset: () => __awaiter(void 0, void 0, void 0, function* () { }) }, configOptions), { strategies: Object.assign(Object.assign({}, defaultStrategies), configOptions.strategies) });
44
+ const config = Object.assign(Object.assign({ rowSelector: "tbody tr", headerSelector: "thead th", cellSelector: "td", maxPages: 1, headerTransformer: ({ text, index, locator }) => text, autoScroll: true, debug: false, onReset: () => __awaiter(void 0, void 0, void 0, function* () { }) }, configOptions), { strategies: Object.assign(Object.assign({}, defaultStrategies), configOptions.strategies) });
44
45
  const resolve = (item, parent) => {
45
46
  if (typeof item === 'string')
46
47
  return parent.locator(item);
@@ -162,7 +163,8 @@ const useTable = (rootLocator, configOptions = {}) => {
162
163
  page: rootLocator.page(),
163
164
  resolve: resolve
164
165
  };
165
- const didLoadMore = yield config.strategies.pagination(context);
166
+ const paginationResult = yield config.strategies.pagination(context);
167
+ const didLoadMore = (0, validation_1.validatePaginationResult)(paginationResult, 'Pagination Strategy');
166
168
  if (didLoadMore) {
167
169
  _hasPaginated = true;
168
170
  currentPage++;
@@ -224,6 +226,9 @@ const useTable = (rootLocator, configOptions = {}) => {
224
226
  return result;
225
227
  yield _getMap(options === null || options === void 0 ? void 0 : options.timeout);
226
228
  _isInitialized = true;
229
+ if (_headerMap) {
230
+ yield (0, traceUtils_1.addTraceEvent)(rootLocator.page(), 'init', { headers: Array.from(_headerMap.keys()), columnCount: _headerMap.size });
231
+ }
227
232
  return result;
228
233
  }),
229
234
  scrollToColumn: (columnName) => __awaiter(void 0, void 0, void 0, function* () {
@@ -242,7 +247,7 @@ const useTable = (rootLocator, configOptions = {}) => {
242
247
  }),
243
248
  getHeaders: () => __awaiter(void 0, void 0, void 0, function* () {
244
249
  if (!_isInitialized || !_headerMap)
245
- throw new Error('Table not initialized. Call await table.init() first.');
250
+ throw new Error('Table not initialized. Call await table.init() first, or use async methods like table.findRow() or table.getRows() which auto-initialize.');
246
251
  return Array.from(_headerMap.keys());
247
252
  }),
248
253
  getHeaderCell: (columnName) => __awaiter(void 0, void 0, void 0, function* () {
@@ -299,22 +304,22 @@ const useTable = (rootLocator, configOptions = {}) => {
299
304
  }
300
305
  return results;
301
306
  }),
302
- getByRow: (filters, options = { exact: false }) => {
307
+ getRow: (filters, options = { exact: false }) => {
303
308
  if (!_isInitialized || !_headerMap)
304
- throw new Error('Table not initialized. Call await table.init() first.');
309
+ throw new Error('Table not initialized. Call await table.init() first, or use async methods like table.findRow() or table.getRows() which auto-initialize.');
305
310
  const allRows = resolve(config.rowSelector, rootLocator);
306
311
  const matchedRows = filterEngine.applyFilters(allRows, filters, _headerMap, options.exact || false, rootLocator.page());
307
312
  const rowLocator = matchedRows.first();
308
313
  return _makeSmart(rowLocator, _headerMap, 0); // fallback index 0
309
314
  },
310
- getByRowIndex: (index, options = {}) => {
315
+ getRowByIndex: (index, options = {}) => {
311
316
  if (!_isInitialized || !_headerMap)
312
- throw new Error('Table not initialized. Call await table.init() first.');
317
+ throw new Error('Table not initialized. Call await table.init() first, or use async methods like table.findRow() or table.getRows() which auto-initialize.');
313
318
  const rowIndex = index - 1; // Convert 1-based to 0-based
314
319
  const rowLocator = resolve(config.rowSelector, rootLocator).nth(rowIndex);
315
320
  return _makeSmart(rowLocator, _headerMap, rowIndex);
316
321
  },
317
- searchForRow: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
322
+ findRow: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
318
323
  yield _ensureInitialized();
319
324
  let row = yield _findRowLocator(filters, options);
320
325
  if (!row) {
@@ -322,7 +327,7 @@ const useTable = (rootLocator, configOptions = {}) => {
322
327
  }
323
328
  return _makeSmart(row, _headerMap, 0);
324
329
  }),
325
- getAllCurrentRows: (options) => __awaiter(void 0, void 0, void 0, function* () {
330
+ getRows: (options) => __awaiter(void 0, void 0, void 0, function* () {
326
331
  yield _ensureInitialized();
327
332
  let rowLocators = resolve(config.rowSelector, rootLocator);
328
333
  if (options === null || options === void 0 ? void 0 : options.filter) {
@@ -335,22 +340,44 @@ const useTable = (rootLocator, configOptions = {}) => {
335
340
  }
336
341
  return smartRows;
337
342
  }),
338
- getAllRows: (options) => __awaiter(void 0, void 0, void 0, function* () {
339
- console.warn("⚠️ [SmartTable] getAllRows is deprecated. Use getAllCurrentRows instead.");
340
- return result.getAllCurrentRows(options);
341
- }),
342
- generateConfigPrompt: (options) => __awaiter(void 0, void 0, void 0, function* () {
343
- const html = yield _getCleanHtml(rootLocator);
344
- const separator = "=".repeat(50);
345
- const content = `\n${separator}\n🤖 COPY INTO GEMINI/ChatGPT 🤖\n${separator}\nI am using 'playwright-smart-table'.\nTarget Table Locator: ${rootLocator.toString()}\nGenerate config for:\n\`\`\`html\n${html.substring(0, 10000)} ...\n\`\`\`\n${separator}\n`;
346
- yield _handlePrompt('Smart Table Config', content, options);
347
- }),
348
- generateStrategyPrompt: (options) => __awaiter(void 0, void 0, void 0, function* () {
349
- const container = rootLocator.locator('xpath=..');
350
- const html = yield _getCleanHtml(container);
351
- const content = `\n==================================================\n🤖 COPY INTO GEMINI/ChatGPT TO WRITE A STRATEGY 🤖\n==================================================\nI need a custom Pagination Strategy for 'playwright-smart-table'.\nContainer HTML:\n\`\`\`html\n${html.substring(0, 10000)} ...\n\`\`\`\n`;
352
- yield _handlePrompt('Smart Table Strategy', content, options);
343
+ findRows: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
344
+ var _a, _b, _c, _d;
345
+ yield _ensureInitialized();
346
+ const allRows = [];
347
+ const effectiveMaxPages = (_b = (_a = options === null || options === void 0 ? void 0 : options.maxPages) !== null && _a !== void 0 ? _a : config.maxPages) !== null && _b !== void 0 ? _b : Infinity;
348
+ let pageCount = 0;
349
+ // Collect rows from current page
350
+ let rowLocators = resolve(config.rowSelector, rootLocator);
351
+ rowLocators = filterEngine.applyFilters(rowLocators, filters, _headerMap, (_c = options === null || options === void 0 ? void 0 : options.exact) !== null && _c !== void 0 ? _c : false, rootLocator.page());
352
+ let rows = yield rowLocators.all();
353
+ allRows.push(...rows.map((loc, i) => _makeSmart(loc, _headerMap, i)));
354
+ // Paginate and collect more rows
355
+ while (pageCount < effectiveMaxPages && config.strategies.pagination) {
356
+ const paginationResult = yield config.strategies.pagination({
357
+ root: rootLocator,
358
+ config,
359
+ resolve,
360
+ page: rootLocator.page()
361
+ });
362
+ const didPaginate = (0, validation_1.validatePaginationResult)(paginationResult, 'Pagination Strategy');
363
+ if (!didPaginate)
364
+ break;
365
+ pageCount++;
366
+ _hasPaginated = true;
367
+ // Collect rows from new page
368
+ rowLocators = resolve(config.rowSelector, rootLocator);
369
+ rowLocators = filterEngine.applyFilters(rowLocators, filters, _headerMap, (_d = options === null || options === void 0 ? void 0 : options.exact) !== null && _d !== void 0 ? _d : false, rootLocator.page());
370
+ rows = yield rowLocators.all();
371
+ allRows.push(...rows.map((loc, i) => _makeSmart(loc, _headerMap, i)));
372
+ }
373
+ if (options === null || options === void 0 ? void 0 : options.asJSON) {
374
+ return Promise.all(allRows.map(r => r.toJSON()));
375
+ }
376
+ return allRows;
353
377
  }),
378
+ isInitialized: () => {
379
+ return _isInitialized;
380
+ },
354
381
  sorting: {
355
382
  apply: (columnName, direction) => __awaiter(void 0, void 0, void 0, function* () {
356
383
  yield _ensureInitialized();
@@ -381,12 +408,13 @@ const useTable = (rootLocator, configOptions = {}) => {
381
408
  init: result.init,
382
409
  getHeaders: result.getHeaders,
383
410
  getHeaderCell: result.getHeaderCell,
384
- getByRow: result.getByRow,
385
- getByRowIndex: result.getByRowIndex,
386
- getAllCurrentRows: result.getAllCurrentRows,
411
+ getRow: result.getRow,
412
+ getRowByIndex: result.getRowByIndex,
413
+ findRow: result.findRow,
414
+ getRows: result.getRows,
415
+ findRows: result.findRows,
387
416
  getColumnValues: result.getColumnValues,
388
- generateConfigPrompt: result.generateConfigPrompt,
389
- generateStrategyPrompt: result.generateStrategyPrompt,
417
+ isInitialized: result.isInitialized,
390
418
  sorting: result.sorting,
391
419
  scrollToColumn: result.scrollToColumn,
392
420
  revalidate: result.revalidate,
@@ -395,10 +423,14 @@ const useTable = (rootLocator, configOptions = {}) => {
395
423
  const getIsLast = (_c = options === null || options === void 0 ? void 0 : options.getIsLast) !== null && _c !== void 0 ? _c : (() => false);
396
424
  const allData = [];
397
425
  const effectiveMaxIterations = (_d = options === null || options === void 0 ? void 0 : options.maxIterations) !== null && _d !== void 0 ? _d : config.maxPages;
426
+ const batchSize = options === null || options === void 0 ? void 0 : options.batchSize;
427
+ const isBatching = batchSize !== undefined && batchSize > 1;
398
428
  let index = 0;
399
429
  let paginationResult = true;
400
430
  let seenKeys = null;
401
- logDebug(`Starting iterateThroughTable (maxIterations: ${effectiveMaxIterations})`);
431
+ let batchRows = [];
432
+ let batchStartIndex = 0;
433
+ logDebug(`Starting iterateThroughTable (maxIterations: ${effectiveMaxIterations}, batchSize: ${batchSize !== null && batchSize !== void 0 ? batchSize : 'none'})`);
402
434
  while (index < effectiveMaxIterations) {
403
435
  const rowLocators = yield resolve(config.rowSelector, rootLocator).all();
404
436
  let rows = rowLocators.map((loc, i) => _makeSmart(loc, _headerMap, i));
@@ -416,21 +448,91 @@ const useTable = (rootLocator, configOptions = {}) => {
416
448
  rows = deduplicated;
417
449
  logDebug(`Deduplicated ${rowLocators.length} rows to ${rows.length} unique rows (total seen: ${seenKeys.size})`);
418
450
  }
419
- const isFirst = getIsFirst({ index });
420
- let isLast = getIsLast({ index, paginationResult });
421
- const isLastDueToMax = index === effectiveMaxIterations - 1;
422
- if (isFirst && (options === null || options === void 0 ? void 0 : options.onFirst))
423
- yield options.onFirst({ index, rows, allData });
424
- const returnValue = yield callback({ index, isFirst, isLast, rows, allData, table: restrictedTable });
425
- allData.push(returnValue);
426
- const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
427
- paginationResult = yield paginationStrategy(context);
428
- isLast = getIsLast({ index, paginationResult }) || isLastDueToMax;
429
- if (isLast && (options === null || options === void 0 ? void 0 : options.onLast))
430
- yield options.onLast({ index, rows, allData });
431
- if (isLast || !paginationResult) {
432
- logDebug(`Reached last iteration (index: ${index}, paginationResult: ${paginationResult})`);
433
- break;
451
+ // Add rows to batch if batching is enabled
452
+ if (isBatching) {
453
+ batchRows.push(...rows);
454
+ }
455
+ const isLastIteration = index === effectiveMaxIterations - 1;
456
+ // Determine if we should invoke the callback
457
+ const batchComplete = isBatching && (index - batchStartIndex + 1) >= batchSize;
458
+ const shouldInvokeCallback = !isBatching || batchComplete || isLastIteration;
459
+ if (shouldInvokeCallback) {
460
+ const callbackRows = isBatching ? batchRows : rows;
461
+ const callbackIndex = isBatching ? batchStartIndex : index;
462
+ const isFirst = getIsFirst({ index: callbackIndex });
463
+ let isLast = getIsLast({ index: callbackIndex, paginationResult });
464
+ const isLastDueToMax = index === effectiveMaxIterations - 1;
465
+ if (isFirst && (options === null || options === void 0 ? void 0 : options.beforeFirst)) {
466
+ yield options.beforeFirst({ index: callbackIndex, rows: callbackRows, allData });
467
+ }
468
+ const batchInfo = isBatching ? {
469
+ startIndex: batchStartIndex,
470
+ endIndex: index,
471
+ size: index - batchStartIndex + 1
472
+ } : undefined;
473
+ const returnValue = yield callback({
474
+ index: callbackIndex,
475
+ isFirst,
476
+ isLast,
477
+ rows: callbackRows,
478
+ allData,
479
+ table: restrictedTable,
480
+ batchInfo
481
+ });
482
+ allData.push(returnValue);
483
+ // Determine if this is truly the last iteration
484
+ let finalIsLast = isLastDueToMax;
485
+ if (!isLastIteration) {
486
+ const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
487
+ paginationResult = yield paginationStrategy(context);
488
+ finalIsLast = getIsLast({ index: callbackIndex, paginationResult }) || !paginationResult;
489
+ }
490
+ if (finalIsLast && (options === null || options === void 0 ? void 0 : options.afterLast)) {
491
+ yield options.afterLast({ index: callbackIndex, rows: callbackRows, allData });
492
+ }
493
+ if (finalIsLast || !paginationResult) {
494
+ logDebug(`Reached last iteration (index: ${index}, paginationResult: ${paginationResult})`);
495
+ break;
496
+ }
497
+ // Reset batch
498
+ if (isBatching) {
499
+ batchRows = [];
500
+ batchStartIndex = index + 1;
501
+ }
502
+ }
503
+ else {
504
+ // Continue paginating even when batching
505
+ const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
506
+ paginationResult = yield paginationStrategy(context);
507
+ if (!paginationResult) {
508
+ // Pagination failed, invoke callback with current batch
509
+ const callbackIndex = batchStartIndex;
510
+ const isFirst = getIsFirst({ index: callbackIndex });
511
+ const isLast = true;
512
+ if (isFirst && (options === null || options === void 0 ? void 0 : options.beforeFirst)) {
513
+ yield options.beforeFirst({ index: callbackIndex, rows: batchRows, allData });
514
+ }
515
+ const batchInfo = {
516
+ startIndex: batchStartIndex,
517
+ endIndex: index,
518
+ size: index - batchStartIndex + 1
519
+ };
520
+ const returnValue = yield callback({
521
+ index: callbackIndex,
522
+ isFirst,
523
+ isLast,
524
+ rows: batchRows,
525
+ allData,
526
+ table: restrictedTable,
527
+ batchInfo
528
+ });
529
+ allData.push(returnValue);
530
+ if (options === null || options === void 0 ? void 0 : options.afterLast) {
531
+ yield options.afterLast({ index: callbackIndex, rows: batchRows, allData });
532
+ }
533
+ logDebug(`Pagination failed mid-batch (index: ${index})`);
534
+ break;
535
+ }
434
536
  }
435
537
  index++;
436
538
  logDebug(`Iteration ${index} completed, continuing...`);
@@ -444,6 +546,4 @@ const useTable = (rootLocator, configOptions = {}) => {
444
546
  };
445
547
  exports.useTable = useTable;
446
548
  exports.PaginationStrategies = pagination_1.PaginationStrategies;
447
- /** @deprecated Use Strategies.Pagination instead */
448
- exports.DeprecatedTableStrategies = pagination_1.DeprecatedPaginationStrategies;
449
549
  exports.SortingStrategies = sorting_1.SortingStrategies;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Calculate Levenshtein distance between two strings
3
+ * Used for "did you mean?" suggestions
4
+ */
5
+ export declare function levenshteinDistance(a: string, b: string): number;
6
+ /**
7
+ * Calculate similarity score between two strings (0-1)
8
+ * 1 = identical, 0 = completely different
9
+ */
10
+ export declare function stringSimilarity(a: string, b: string): number;
11
+ /**
12
+ * Find similar strings from a list
13
+ * Returns matches above threshold, sorted by similarity
14
+ */
15
+ export declare function findSimilar(input: string, available: string[], threshold?: number): Array<{
16
+ value: string;
17
+ score: number;
18
+ }>;
19
+ /**
20
+ * Build a helpful error message for column not found
21
+ */
22
+ export declare function buildColumnNotFoundError(columnName: string, availableColumns: string[]): string;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.levenshteinDistance = levenshteinDistance;
4
+ exports.stringSimilarity = stringSimilarity;
5
+ exports.findSimilar = findSimilar;
6
+ exports.buildColumnNotFoundError = buildColumnNotFoundError;
7
+ /**
8
+ * Calculate Levenshtein distance between two strings
9
+ * Used for "did you mean?" suggestions
10
+ */
11
+ function levenshteinDistance(a, b) {
12
+ const matrix = [];
13
+ for (let i = 0; i <= b.length; i++) {
14
+ matrix[i] = [i];
15
+ }
16
+ for (let j = 0; j <= a.length; j++) {
17
+ matrix[0][j] = j;
18
+ }
19
+ for (let i = 1; i <= b.length; i++) {
20
+ for (let j = 1; j <= a.length; j++) {
21
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
22
+ matrix[i][j] = matrix[i - 1][j - 1];
23
+ }
24
+ else {
25
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
26
+ matrix[i][j - 1] + 1, // insertion
27
+ matrix[i - 1][j] + 1 // deletion
28
+ );
29
+ }
30
+ }
31
+ }
32
+ return matrix[b.length][a.length];
33
+ }
34
+ /**
35
+ * Calculate similarity score between two strings (0-1)
36
+ * 1 = identical, 0 = completely different
37
+ */
38
+ function stringSimilarity(a, b) {
39
+ const distance = levenshteinDistance(a.toLowerCase(), b.toLowerCase());
40
+ const maxLen = Math.max(a.length, b.length);
41
+ return maxLen === 0 ? 1 : 1 - (distance / maxLen);
42
+ }
43
+ /**
44
+ * Find similar strings from a list
45
+ * Returns matches above threshold, sorted by similarity
46
+ */
47
+ function findSimilar(input, available, threshold = 0.5) {
48
+ return available
49
+ .map(value => ({
50
+ value,
51
+ score: stringSimilarity(input, value)
52
+ }))
53
+ .filter(x => x.score >= threshold)
54
+ .sort((a, b) => b.score - a.score)
55
+ .slice(0, 3); // Top 3 suggestions
56
+ }
57
+ /**
58
+ * Build a helpful error message for column not found
59
+ */
60
+ function buildColumnNotFoundError(columnName, availableColumns) {
61
+ const suggestions = findSimilar(columnName, availableColumns);
62
+ let message = `Column '${columnName}' not found`;
63
+ if (suggestions.length > 0) {
64
+ message += `\n\nDid you mean:`;
65
+ suggestions.forEach(({ value, score }) => {
66
+ const percentage = Math.round(score * 100);
67
+ message += `\n • ${value} (${percentage}% match)`;
68
+ });
69
+ }
70
+ message += `\n\nAvailable columns: ${availableColumns.join(', ')}`;
71
+ message += `\n\nTip: Column names are case-sensitive`;
72
+ return message;
73
+ }
@@ -0,0 +1,11 @@
1
+ import type { Page } from '@playwright/test';
2
+ /**
3
+ * Add a custom trace event to Playwright's trace viewer
4
+ * Uses page.evaluate to log events that appear in the trace
5
+ */
6
+ export declare function addTraceEvent(page: Page, type: string, data?: Record<string, any>): Promise<void>;
7
+ /**
8
+ * Check if tracing is currently enabled
9
+ * Used for conditional trace logic
10
+ */
11
+ export declare function isTracingEnabled(page: Page): Promise<boolean>;
@@ -0,0 +1,47 @@
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.addTraceEvent = addTraceEvent;
13
+ exports.isTracingEnabled = isTracingEnabled;
14
+ /**
15
+ * Add a custom trace event to Playwright's trace viewer
16
+ * Uses page.evaluate to log events that appear in the trace
17
+ */
18
+ function addTraceEvent(page_1, type_1) {
19
+ return __awaiter(this, arguments, void 0, function* (page, type, data = {}) {
20
+ try {
21
+ // Add a console log that will appear in the trace viewer
22
+ // Prefix with [SmartTable] for easy filtering
23
+ const message = `[SmartTable:${type}] ${JSON.stringify(data)}`;
24
+ yield page.evaluate((msg) => console.log(msg), message);
25
+ }
26
+ catch (_a) {
27
+ // Silently ignore if page is not available
28
+ // This ensures zero overhead when tracing is off
29
+ }
30
+ });
31
+ }
32
+ /**
33
+ * Check if tracing is currently enabled
34
+ * Used for conditional trace logic
35
+ */
36
+ function isTracingEnabled(page) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ try {
39
+ // We can't directly check if tracing is enabled
40
+ // But we can safely call addTraceEvent - it will just be a no-op if not tracing
41
+ return true;
42
+ }
43
+ catch (_a) {
44
+ return false;
45
+ }
46
+ });
47
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rickcedwhat/playwright-smart-table",
3
- "version": "4.0.0",
4
- "description": "A smart table utility for Playwright with built-in pagination strategies that are fully extensible.",
3
+ "version": "5.1.0",
4
+ "description": "Production-ready table testing for Playwright with smart column-aware locators. Core library with plugin support for custom table implementations.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/rickcedwhat/playwright-smart-table.git"