@smartbit4all/playwright-qa 0.1.11 → 0.2.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.
Files changed (58) hide show
  1. package/README.md +47 -0
  2. package/dist/basedata/hash.d.ts +2 -0
  3. package/dist/basedata/hash.d.ts.map +1 -0
  4. package/dist/basedata/hash.js +23 -0
  5. package/dist/basedata/hash.js.map +1 -0
  6. package/dist/basedata/history.d.ts +10 -0
  7. package/dist/basedata/history.d.ts.map +1 -0
  8. package/dist/basedata/history.js +144 -0
  9. package/dist/basedata/history.js.map +1 -0
  10. package/dist/basedata/index.d.ts +6 -0
  11. package/dist/basedata/index.d.ts.map +1 -0
  12. package/dist/basedata/index.js +16 -0
  13. package/dist/basedata/index.js.map +1 -0
  14. package/dist/basedata/loader.d.ts +12 -0
  15. package/dist/basedata/loader.d.ts.map +1 -0
  16. package/dist/basedata/loader.js +230 -0
  17. package/dist/basedata/loader.js.map +1 -0
  18. package/dist/basedata/processors/basic-screen.d.ts +31 -0
  19. package/dist/basedata/processors/basic-screen.d.ts.map +1 -0
  20. package/dist/basedata/processors/basic-screen.js +128 -0
  21. package/dist/basedata/processors/basic-screen.js.map +1 -0
  22. package/dist/basedata/registry.d.ts +11 -0
  23. package/dist/basedata/registry.d.ts.map +1 -0
  24. package/dist/basedata/registry.js +50 -0
  25. package/dist/basedata/registry.js.map +1 -0
  26. package/dist/basedata/runner.d.ts +3 -0
  27. package/dist/basedata/runner.d.ts.map +1 -0
  28. package/dist/basedata/runner.js +324 -0
  29. package/dist/basedata/runner.js.map +1 -0
  30. package/dist/basedata/types.d.ts +161 -0
  31. package/dist/basedata/types.d.ts.map +1 -0
  32. package/dist/basedata/types.js +3 -0
  33. package/dist/basedata/types.js.map +1 -0
  34. package/dist/steps/actions.d.ts +23 -0
  35. package/dist/steps/actions.d.ts.map +1 -0
  36. package/dist/steps/actions.js +106 -0
  37. package/dist/steps/actions.js.map +1 -0
  38. package/dist/steps/forms.d.ts +6 -0
  39. package/dist/steps/forms.d.ts.map +1 -1
  40. package/dist/steps/forms.js +13 -0
  41. package/dist/steps/forms.js.map +1 -1
  42. package/dist/steps/grid.steps.d.ts +2 -2
  43. package/dist/steps/grid.steps.d.ts.map +1 -1
  44. package/dist/steps/grid.steps.js +14 -4
  45. package/dist/steps/grid.steps.js.map +1 -1
  46. package/dist/steps/index.d.ts +2 -1
  47. package/dist/steps/index.d.ts.map +1 -1
  48. package/dist/steps/index.js +6 -1
  49. package/dist/steps/index.js.map +1 -1
  50. package/dist/steps/locators.d.ts +19 -4
  51. package/dist/steps/locators.d.ts.map +1 -1
  52. package/dist/steps/locators.js +24 -6
  53. package/dist/steps/locators.js.map +1 -1
  54. package/dist/steps/navigation.steps.d.ts +1 -1
  55. package/dist/steps/navigation.steps.d.ts.map +1 -1
  56. package/dist/steps/navigation.steps.js +13 -8
  57. package/dist/steps/navigation.steps.js.map +1 -1
  58. package/package.json +1 -1
package/README.md CHANGED
@@ -253,6 +253,10 @@ await selectGridRow(page, { rowId: 'doc-12345' });
253
253
  // Open the row's context menu and click an action
254
254
  await selectGridRow(page, { 'Azonosító': 'DOC-001' }, 'Szerkesztés');
255
255
 
256
+ // Reach an action nested under submenus — pass an action path (see "Actions" below).
257
+ // Intermediate items are submenu triggers (opened by hover), the last is the leaf (clicked).
258
+ await selectGridRow(page, { 'Azonosító': 'DOC-001' }, ['MORE', 'EXPORT', 'PDF']);
259
+
256
260
  // Open context menu only (for screenshots) — pass true, then close with Escape
257
261
  await selectGridRow(page, { 'Azonosító': 'DOC-001' }, true);
258
262
  await screenshot(page, 'grid-context-menu');
@@ -302,12 +306,55 @@ await navigateInTree(page, ['Dokumentumok', 'Tender']);
302
306
  // Open the last node's context menu (hamburger button) and click an action
303
307
  await navigateInTree(page, ['Dokumentumok', 'Bejövő e-mail'], 'Új mappa');
304
308
 
309
+ // Nested action: the tree path and the action path are separate arguments.
310
+ // ['Dokumentumok','Bejövő e-mail'] is the tree path; ['MORE','NEW_FOLDER'] is the action path.
311
+ await navigateInTree(page, ['Dokumentumok', 'Bejövő e-mail'], ['MORE', 'NEW_FOLDER']);
312
+
305
313
  // Open context menu only (for screenshots) — pass true, then close with Escape
306
314
  await navigateInTree(page, ['Dokumentumok', 'Bejövő e-mail'], true);
307
315
  await screenshot(page, 'context-menu-open');
308
316
  await page.keyboard.press('Escape');
309
317
  ```
310
318
 
319
+ ### Actions
320
+
321
+ Toolbar, navbar and menu actions — including submenus. Since ng-client #29411 an action that has
322
+ child actions renders a **submenu**: reaching a nested action means opening the intermediate submenu
323
+ triggers first. `clickAction` and `openActionPath` handle that with an **action path**.
324
+
325
+ ```typescript
326
+ import { clickAction, openActionPath } from '@smartbit4all/playwright-qa/steps';
327
+
328
+ // Single action — clicks a plain toolbar button (by data-testid, then text).
329
+ await clickAction(page, 'SAVE');
330
+
331
+ // Action path: the last element is the leaf action (clicked); the earlier elements are submenu
332
+ // triggers opened along the way. Works whether the menu opens on hover or on click — you don't
333
+ // need to know which.
334
+ await clickAction(page, ['Administrator', 'Admin beállítások']);
335
+ await clickAction(page, ['MORE', 'EXPORT', 'PDF']);
336
+
337
+ // Scope to a container (dialog, section, toolbar) by passing a Locator.
338
+ await clickAction(topDialog(page), ['MORE', 'DUPLICATE']);
339
+ ```
340
+
341
+ `openActionPath` opens the same path but **returns the leaf's Locator without clicking it** — so you
342
+ can screenshot the highlighted item and click when ready:
343
+
344
+ ```typescript
345
+ const leaf = await openActionPath(page, ['MORE', 'EXPORT', 'PDF']);
346
+ await screenshotRegionHighlight(page, 'export-pdf-highlight', findPopupMenu(page), leaf);
347
+ await leaf.click();
348
+ ```
349
+
350
+ `openActionPath` is dual-mode by whether a menu is already open: with none open, `path[0]` is the
351
+ top-level trigger to open; with one open (e.g. after a grid/tree menu button, or after
352
+ `navigateInTree(..., true)`), `path[0]` is the first submenu trigger inside it. `clickAction` is
353
+ exactly `openActionPath` followed by clicking the returned leaf.
354
+
355
+ The same action-path form is accepted by the grid and navigation helpers (`selectGridRow`,
356
+ `filterAndSelectGridRow`, `navigateInTree`) for their menu action argument.
357
+
311
358
  ### Dialog
312
359
 
313
360
  ```typescript
@@ -0,0 +1,2 @@
1
+ export declare function computeChangeSetHash(datapoolContent: string, processorName: string, manifestParams: Record<string, unknown>, sessionControllerName?: string): string;
2
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/basedata/hash.ts"],"names":[],"mappings":"AAeA,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,qBAAqB,GAAE,MAAW,GACjC,MAAM,CAGR"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeChangeSetHash = computeChangeSetHash;
4
+ const crypto_1 = require("crypto");
5
+ function canonicalize(value) {
6
+ if (value === null || value === undefined)
7
+ return JSON.stringify(value);
8
+ if (typeof value !== 'object')
9
+ return JSON.stringify(value);
10
+ if (Array.isArray(value)) {
11
+ return '[' + value.map(canonicalize).join(',') + ']';
12
+ }
13
+ const sorted = Object.keys(value)
14
+ .sort()
15
+ .map(k => JSON.stringify(k) + ':' + canonicalize(value[k]))
16
+ .join(',');
17
+ return '{' + sorted + '}';
18
+ }
19
+ function computeChangeSetHash(datapoolContent, processorName, manifestParams, sessionControllerName = '') {
20
+ const raw = datapoolContent + processorName + canonicalize(manifestParams) + sessionControllerName;
21
+ return 'sha256:' + (0, crypto_1.createHash)('sha256').update(raw, 'utf8').digest('hex');
22
+ }
23
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/basedata/hash.ts"],"names":[],"mappings":";;AAeA,oDAQC;AAvBD,mCAAoC;AAEpC,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACvD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC;SACzD,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,YAAY,CAAE,KAAiC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvF,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;AAC5B,CAAC;AAED,SAAgB,oBAAoB,CAClC,eAAuB,EACvB,aAAqB,EACrB,cAAuC,EACvC,wBAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,eAAe,GAAG,aAAa,GAAG,YAAY,CAAC,cAAc,CAAC,GAAG,qBAAqB,CAAC;IACnG,OAAO,SAAS,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ChangelogHistory, ChangelogRecord, HistoryEntry } from './types';
2
+ export declare function lockfilePath(historyFile: string): string;
3
+ export declare function acquireLock(historyFile: string): Promise<void>;
4
+ export declare function releaseLock(historyFile: string): void;
5
+ export declare function readHistory(historyFile: string): ChangelogHistory;
6
+ export declare function writeHistory(historyFile: string, history: ChangelogHistory): void;
7
+ export declare function findHistoryEntry(history: ChangelogHistory, id: string, author: string, filename: string): HistoryEntry | undefined;
8
+ export declare function upsertHistoryEntry(history: ChangelogHistory, entry: HistoryEntry): void;
9
+ export declare function upsertChangelogRecord(history: ChangelogHistory, record: ChangelogRecord): void;
10
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/basedata/history.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK/E,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBpE;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAkCjE;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CASjF;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,YAAY,GAAG,SAAS,CAE1B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CASvF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAO9F"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.lockfilePath = lockfilePath;
37
+ exports.acquireLock = acquireLock;
38
+ exports.releaseLock = releaseLock;
39
+ exports.readHistory = readHistory;
40
+ exports.writeHistory = writeHistory;
41
+ exports.findHistoryEntry = findHistoryEntry;
42
+ exports.upsertHistoryEntry = upsertHistoryEntry;
43
+ exports.upsertChangelogRecord = upsertChangelogRecord;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const LOCK_RETRY_MS = 50;
47
+ const LOCK_TIMEOUT_MS = 5000;
48
+ function lockfilePath(historyFile) {
49
+ return historyFile + '.lock';
50
+ }
51
+ async function acquireLock(historyFile) {
52
+ const lockFile = lockfilePath(historyFile);
53
+ const dir = path.dirname(lockFile);
54
+ if (!fs.existsSync(dir)) {
55
+ fs.mkdirSync(dir, { recursive: true });
56
+ }
57
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
58
+ while (Date.now() < deadline) {
59
+ try {
60
+ fs.writeFileSync(lockFile, String(process.pid), { flag: 'wx' });
61
+ return;
62
+ }
63
+ catch (err) {
64
+ const code = err.code;
65
+ if (code !== 'EEXIST') {
66
+ throw err;
67
+ }
68
+ await new Promise(r => setTimeout(r, LOCK_RETRY_MS));
69
+ }
70
+ }
71
+ throw new Error(`Could not acquire lock on history file: ${historyFile} (timeout after ${LOCK_TIMEOUT_MS}ms)`);
72
+ }
73
+ function releaseLock(historyFile) {
74
+ const lockFile = lockfilePath(historyFile);
75
+ try {
76
+ fs.unlinkSync(lockFile);
77
+ }
78
+ catch {
79
+ // ignore — lock may already be gone
80
+ }
81
+ }
82
+ function readHistory(historyFile) {
83
+ if (!fs.existsSync(historyFile)) {
84
+ return { historyVersion: 2, lastRun: '', changelogs: [], entries: [] };
85
+ }
86
+ const raw = fs.readFileSync(historyFile, 'utf-8');
87
+ let parsed;
88
+ try {
89
+ parsed = JSON.parse(raw);
90
+ }
91
+ catch {
92
+ throw new Error(`Corrupted history file (invalid JSON): ${historyFile}`);
93
+ }
94
+ if (parsed.historyVersion === 2) {
95
+ if (!Array.isArray(parsed.entries) || !Array.isArray(parsed.changelogs)) {
96
+ throw new Error(`Corrupted history file (missing entries or changelogs array): ${historyFile}`);
97
+ }
98
+ return parsed;
99
+ }
100
+ // v1 → v2 migration
101
+ if (parsed.stateVersion === 1) {
102
+ if (!Array.isArray(parsed.entries)) {
103
+ throw new Error(`Corrupted v1 history file (missing entries array): ${historyFile}`);
104
+ }
105
+ return {
106
+ historyVersion: 2,
107
+ lastRun: parsed.lastRun ?? '',
108
+ changelogs: [],
109
+ entries: parsed.entries,
110
+ };
111
+ }
112
+ throw new Error(`Unrecognised history file version: ${historyFile}`);
113
+ }
114
+ function writeHistory(historyFile, history) {
115
+ const dir = path.dirname(historyFile);
116
+ if (!fs.existsSync(dir)) {
117
+ fs.mkdirSync(dir, { recursive: true });
118
+ }
119
+ const tmpFile = historyFile + '.tmp';
120
+ fs.writeFileSync(tmpFile, JSON.stringify(history, null, 2), 'utf-8');
121
+ fs.renameSync(tmpFile, historyFile);
122
+ }
123
+ function findHistoryEntry(history, id, author, filename) {
124
+ return history.entries.find(e => e.id === id && e.author === author && e.filename === filename);
125
+ }
126
+ function upsertHistoryEntry(history, entry) {
127
+ const idx = history.entries.findIndex(e => e.id === entry.id && e.author === entry.author && e.filename === entry.filename);
128
+ if (idx >= 0) {
129
+ history.entries[idx] = entry;
130
+ }
131
+ else {
132
+ history.entries.push(entry);
133
+ }
134
+ }
135
+ function upsertChangelogRecord(history, record) {
136
+ const idx = history.changelogs.findIndex(c => c.path === record.path);
137
+ if (idx >= 0) {
138
+ history.changelogs[idx] = record;
139
+ }
140
+ else {
141
+ history.changelogs.push(record);
142
+ }
143
+ }
144
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/basedata/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { runChangelog } from './runner';
2
+ export { registerProcessor, resetProcessors, registerSessionController, resetSessionControllers, registerType, getType, resetTypes, } from './registry';
3
+ export { BasicScreenProcessor } from './processors/basic-screen';
4
+ export type { BasicScreenParams } from './processors/basic-screen';
5
+ export type { BaseDataProcessor, BaseDataContext, ApplyResult, ChangelogRunResult, ChangeSetExecution, DatapoolJson, ChangeSetManifest, ManifestBlock, Changelog, ChangelogEntry, ChangeSetEntry, IncludeEntry, InlineManifestEntry, TypeBundle, ChangelogHistory, HistoryEntry, RunChangelogOptions, SessionController, } from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/basedata/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,yBAAyB,EACzB,uBAAuB,EACvB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BasicScreenProcessor = exports.resetTypes = exports.getType = exports.registerType = exports.resetSessionControllers = exports.registerSessionController = exports.resetProcessors = exports.registerProcessor = exports.runChangelog = void 0;
4
+ var runner_1 = require("./runner");
5
+ Object.defineProperty(exports, "runChangelog", { enumerable: true, get: function () { return runner_1.runChangelog; } });
6
+ var registry_1 = require("./registry");
7
+ Object.defineProperty(exports, "registerProcessor", { enumerable: true, get: function () { return registry_1.registerProcessor; } });
8
+ Object.defineProperty(exports, "resetProcessors", { enumerable: true, get: function () { return registry_1.resetProcessors; } });
9
+ Object.defineProperty(exports, "registerSessionController", { enumerable: true, get: function () { return registry_1.registerSessionController; } });
10
+ Object.defineProperty(exports, "resetSessionControllers", { enumerable: true, get: function () { return registry_1.resetSessionControllers; } });
11
+ Object.defineProperty(exports, "registerType", { enumerable: true, get: function () { return registry_1.registerType; } });
12
+ Object.defineProperty(exports, "getType", { enumerable: true, get: function () { return registry_1.getType; } });
13
+ Object.defineProperty(exports, "resetTypes", { enumerable: true, get: function () { return registry_1.resetTypes; } });
14
+ var basic_screen_1 = require("./processors/basic-screen");
15
+ Object.defineProperty(exports, "BasicScreenProcessor", { enumerable: true, get: function () { return basic_screen_1.BasicScreenProcessor; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/basedata/index.ts"],"names":[],"mappings":";;;AAAA,mCAAwC;AAA/B,sGAAA,YAAY,OAAA;AACrB,uCAQoB;AAPlB,6GAAA,iBAAiB,OAAA;AACjB,2GAAA,eAAe,OAAA;AACf,qHAAA,yBAAyB,OAAA;AACzB,mHAAA,uBAAuB,OAAA;AACvB,wGAAA,YAAY,OAAA;AACZ,mGAAA,OAAO,OAAA;AACP,sGAAA,UAAU,OAAA;AAEZ,0DAAiE;AAAxD,oHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,12 @@
1
+ import type { DatapoolJson, ResolveResult } from './types';
2
+ export declare function loadJson(filePath: string): unknown;
3
+ export declare function loadDatapoolFile(filePath: string): DatapoolJson;
4
+ /**
5
+ * Resolves an entry-point file (changelog or manifest) into a flat ordered list of
6
+ * ResolvedChangeSet tuples along with the set of changelog files visited.
7
+ * masterPath: path to the entry-point file.
8
+ * masterBase: directory used for portable filenames stored in history.
9
+ */
10
+ export declare function resolveChangelog(masterPath: string, masterBase: string): ResolveResult;
11
+ export declare function computeIncludeFingerprint(includeList: string[]): string;
12
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/basedata/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EASV,YAAY,EAEZ,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAUlD;AAmED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAc/D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,aAAa,CAKf;AA0GD,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAGvE"}
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadJson = loadJson;
37
+ exports.loadDatapoolFile = loadDatapoolFile;
38
+ exports.resolveChangelog = resolveChangelog;
39
+ exports.computeIncludeFingerprint = computeIncludeFingerprint;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const crypto_1 = require("crypto");
43
+ function loadJson(filePath) {
44
+ if (!fs.existsSync(filePath)) {
45
+ throw new Error(`File not found: ${filePath}`);
46
+ }
47
+ const raw = fs.readFileSync(filePath, 'utf-8');
48
+ try {
49
+ return JSON.parse(raw);
50
+ }
51
+ catch {
52
+ throw new Error(`Invalid JSON in file: ${filePath}`);
53
+ }
54
+ }
55
+ function isManifestFile(obj) {
56
+ return typeof obj === 'object' && obj !== null && 'manifest' in obj;
57
+ }
58
+ function isChangelogFile(obj) {
59
+ return typeof obj === 'object' && obj !== null && 'changelog' in obj;
60
+ }
61
+ function isIncludeEntry(entry) {
62
+ return 'include' in entry;
63
+ }
64
+ function isInlineManifestEntry(entry) {
65
+ return 'manifest' in entry;
66
+ }
67
+ function validateManifestBlock(block, ownerFile, where) {
68
+ if (!block?.name)
69
+ throw new Error(`Manifest missing 'manifest.name' (${where}): ${ownerFile}`);
70
+ }
71
+ function validateManifestFile(obj, filePath) {
72
+ validateManifestBlock(obj.manifest, filePath, 'top-level manifest');
73
+ if (!Array.isArray(obj.changeSets)) {
74
+ throw new Error(`Manifest missing 'changeSets' array: ${filePath}`);
75
+ }
76
+ for (const cs of obj.changeSets)
77
+ validateChangeSet(cs, filePath);
78
+ }
79
+ function validateChangeSet(cs, ownerFile) {
80
+ if (!cs.id)
81
+ throw new Error(`ChangeSet missing 'id' in manifest: ${ownerFile}`);
82
+ if (!cs.author)
83
+ throw new Error(`ChangeSet missing 'author' in manifest: ${ownerFile}`);
84
+ if (!cs.datapool)
85
+ throw new Error(`ChangeSet missing 'datapool' in manifest: ${ownerFile}`);
86
+ }
87
+ function validateChangelogFile(obj, filePath) {
88
+ if (!obj.changelog?.name)
89
+ throw new Error(`Changelog missing 'changelog.name': ${filePath}`);
90
+ if (!Array.isArray(obj.entries))
91
+ throw new Error(`Changelog missing 'entries' array: ${filePath}`);
92
+ for (let i = 0; i < obj.entries.length; i++) {
93
+ const entry = obj.entries[i];
94
+ if (typeof entry !== 'object' || entry === null) {
95
+ throw new Error(`Changelog entry [${i}] is not an object: ${filePath}`);
96
+ }
97
+ const hasInclude = isIncludeEntry(entry);
98
+ const hasManifest = isInlineManifestEntry(entry);
99
+ if (hasInclude && hasManifest) {
100
+ throw new Error(`Changelog entry [${i}] mixes 'include' with inline 'manifest': ${filePath}`);
101
+ }
102
+ if (!hasInclude && !hasManifest) {
103
+ throw new Error(`Changelog entry [${i}] must be either { include } or { manifest, changeSets }: ${filePath}`);
104
+ }
105
+ if (hasInclude) {
106
+ if (typeof entry.include !== 'string' || !entry.include) {
107
+ throw new Error(`Changelog entry [${i}] has invalid 'include' value: ${filePath}`);
108
+ }
109
+ }
110
+ else {
111
+ validateManifestBlock(entry.manifest, filePath, `entry [${i}]`);
112
+ if (!Array.isArray(entry.changeSets)) {
113
+ throw new Error(`Inline manifest entry [${i}] missing 'changeSets' array: ${filePath}`);
114
+ }
115
+ for (const cs of entry.changeSets)
116
+ validateChangeSet(cs, filePath);
117
+ }
118
+ }
119
+ }
120
+ function loadDatapoolFile(filePath) {
121
+ const obj = loadJson(filePath);
122
+ if (!obj.meta || typeof obj.meta !== 'object') {
123
+ throw new Error(`Datapool missing 'meta': ${filePath}`);
124
+ }
125
+ const meta = obj.meta;
126
+ if (!meta.entity)
127
+ throw new Error(`Datapool meta missing 'entity': ${filePath}`);
128
+ if (!Array.isArray(meta.locales) || meta.locales.length === 0) {
129
+ throw new Error(`Datapool meta missing 'locales': ${filePath}`);
130
+ }
131
+ if (!Array.isArray(obj.items)) {
132
+ throw new Error(`Datapool missing 'items' array: ${filePath}`);
133
+ }
134
+ return obj;
135
+ }
136
+ /**
137
+ * Resolves an entry-point file (changelog or manifest) into a flat ordered list of
138
+ * ResolvedChangeSet tuples along with the set of changelog files visited.
139
+ * masterPath: path to the entry-point file.
140
+ * masterBase: directory used for portable filenames stored in history.
141
+ */
142
+ function resolveChangelog(masterPath, masterBase) {
143
+ const tuples = [];
144
+ const visitedChangelogs = [];
145
+ resolveFileInto(masterPath, masterBase, new Set(), tuples, visitedChangelogs, true);
146
+ return { tuples, visitedChangelogs };
147
+ }
148
+ function resolveFileInto(filePath, masterBase, visited, tuples, visitedChangelogs, isMaster) {
149
+ const absPath = path.resolve(filePath);
150
+ if (visited.has(absPath)) {
151
+ throw new Error(`Circular include detected: ${absPath}`);
152
+ }
153
+ visited.add(absPath);
154
+ const obj = loadJson(absPath);
155
+ const dir = path.dirname(absPath);
156
+ const ownerFile = toPortablePath(path.relative(masterBase, absPath));
157
+ const looksManifest = isManifestFile(obj);
158
+ const looksChangelog = isChangelogFile(obj);
159
+ if (looksManifest && looksChangelog) {
160
+ throw new Error(`File has both 'manifest' and 'changelog' top-level keys (pick one): ${absPath}`);
161
+ }
162
+ if (looksManifest) {
163
+ validateManifestFile(obj, absPath);
164
+ resolveManifestInto(obj.manifest, obj.changeSets, ownerFile, dir, masterBase, tuples);
165
+ visited.delete(absPath);
166
+ return;
167
+ }
168
+ if (looksChangelog) {
169
+ validateChangelogFile(obj, absPath);
170
+ // Build the freeze identity list while walking entries. Include entries contribute
171
+ // "include:<path>"; inline-manifest entries contribute "manifest:<name>".
172
+ const identityList = [];
173
+ const record = {
174
+ path: ownerFile,
175
+ includeList: identityList,
176
+ includeFingerprint: '',
177
+ isMaster,
178
+ };
179
+ visitedChangelogs.push(record);
180
+ for (const entry of obj.entries) {
181
+ if (isIncludeEntry(entry)) {
182
+ identityList.push(`include:${toPortablePath(entry.include)}`);
183
+ const includePath = path.resolve(dir, entry.include);
184
+ resolveFileInto(includePath, masterBase, new Set(visited), tuples, visitedChangelogs, false);
185
+ }
186
+ else {
187
+ identityList.push(`manifest:${entry.manifest.name}`);
188
+ resolveManifestInto(entry.manifest, entry.changeSets, ownerFile, dir, masterBase, tuples);
189
+ }
190
+ }
191
+ record.includeFingerprint = computeIncludeFingerprint(identityList);
192
+ visited.delete(absPath);
193
+ return;
194
+ }
195
+ throw new Error(`Unrecognised file format (expected { manifest, changeSets } or { changelog, entries }): ${absPath}`);
196
+ }
197
+ /**
198
+ * Helper: turns a manifest block (file-level or inline) + its changeSets into
199
+ * ResolvedChangeSet tuples and pushes them onto the accumulator.
200
+ */
201
+ function resolveManifestInto(manifest, changeSets, ownerFile, manifestDir, masterBase, tuples) {
202
+ const manifestDefaults = {
203
+ processor: manifest.defaults?.processor,
204
+ params: manifest.defaults?.params ?? {},
205
+ };
206
+ const sessionControllerName = manifest.session?.controller;
207
+ const manifestType = manifest.type;
208
+ const manifestName = manifest.name;
209
+ for (const cs of changeSets) {
210
+ const datapoolAbsPath = path.resolve(manifestDir, cs.datapool);
211
+ const datapoolPath = toPortablePath(path.relative(masterBase, datapoolAbsPath));
212
+ tuples.push({
213
+ manifestFile: ownerFile,
214
+ manifestName,
215
+ manifestDefaults,
216
+ manifestType,
217
+ sessionControllerName,
218
+ changeSet: cs,
219
+ datapoolPath,
220
+ });
221
+ }
222
+ }
223
+ function toPortablePath(p) {
224
+ return p.replace(/\\/g, '/');
225
+ }
226
+ function computeIncludeFingerprint(includeList) {
227
+ const raw = JSON.stringify(includeList);
228
+ return 'sha256:' + (0, crypto_1.createHash)('sha256').update(raw, 'utf8').digest('hex');
229
+ }
230
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/basedata/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Page, Locator } from '@playwright/test';
2
+ import type { BaseDataProcessor, BaseDataContext, ApplyResult, DatapoolMeta, Operation } from '../types';
3
+ export interface BasicScreenParams {
4
+ navigationPath?: string[];
5
+ newButtonLabel?: string;
6
+ saveButtonLabel?: string;
7
+ deleteMenuLabel?: string;
8
+ confirmButtonLabel?: string;
9
+ }
10
+ export declare class BasicScreenProcessor implements BaseDataProcessor<BasicScreenParams> {
11
+ apply(items: Array<Record<string, unknown>>, operation: Operation, meta: DatapoolMeta, params: BasicScreenParams, ctx: BaseDataContext): Promise<ApplyResult>;
12
+ protected processItem(ctx: BaseDataContext, page: Page, item: Record<string, unknown>, operation: Operation, keyField: string, params: BasicScreenParams): Promise<void>;
13
+ protected insertItem(ctx: BaseDataContext, page: Page, item: Record<string, unknown>, params: BasicScreenParams): Promise<void>;
14
+ protected updateItem(ctx: BaseDataContext, page: Page, item: Record<string, unknown>, keyField: string, params: BasicScreenParams): Promise<void>;
15
+ protected deleteItem(ctx: BaseDataContext, page: Page, item: Record<string, unknown>, keyField: string, params: BasicScreenParams): Promise<void>;
16
+ protected upsertItem(ctx: BaseDataContext, page: Page, item: Record<string, unknown>, keyField: string, params: BasicScreenParams): Promise<void>;
17
+ /**
18
+ * Fills every field of `item` for which a widget can be found. Fields with no matching
19
+ * widget are skipped with a `console.warn` so the author notices without the run failing.
20
+ */
21
+ protected fillFields(form: Locator, item: Record<string, unknown>): Promise<void>;
22
+ /**
23
+ * Override this in a subclass to handle special per-field mapping
24
+ * (split one item field into multiple form fields, merge several into one,
25
+ * open a detail dialog for a field, etc.). Call `super.fillField(...)` for
26
+ * fields you do NOT need to customise.
27
+ */
28
+ protected fillField(form: Locator, key: string, value: unknown): Promise<void>;
29
+ protected save(ctx: BaseDataContext, page: Page, item: Record<string, unknown>): Promise<void>;
30
+ }
31
+ //# sourceMappingURL=basic-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic-screen.d.ts","sourceRoot":"","sources":["../../../src/basedata/processors/basic-screen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAOzG,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAsBD,qBAAa,oBAAqB,YAAW,iBAAiB,CAAC,iBAAiB,CAAC;IACzE,KAAK,CACT,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACrC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,WAAW,CAAC;cA8BP,WAAW,CACzB,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,IAAI,CAAC;cASA,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;cAUrH,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;cAUvI,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;cAMvI,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBvJ;;;OAGG;cACa,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvF;;;;;OAKG;cACa,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;cAOpE,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAIrG"}