@smartbit4all/playwright-qa 0.1.10 → 0.1.12

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 (54) hide show
  1. package/README.md +70 -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/debug.d.ts +15 -0
  35. package/dist/steps/debug.d.ts.map +1 -0
  36. package/dist/steps/debug.js +41 -0
  37. package/dist/steps/debug.js.map +1 -0
  38. package/dist/steps/forms.d.ts +29 -0
  39. package/dist/steps/forms.d.ts.map +1 -1
  40. package/dist/steps/forms.js +93 -0
  41. package/dist/steps/forms.js.map +1 -1
  42. package/dist/steps/grid.steps.d.ts +3 -1
  43. package/dist/steps/grid.steps.d.ts.map +1 -1
  44. package/dist/steps/grid.steps.js +52 -8
  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 +5 -1
  49. package/dist/steps/index.js.map +1 -1
  50. package/dist/steps/locators.d.ts +17 -3
  51. package/dist/steps/locators.d.ts.map +1 -1
  52. package/dist/steps/locators.js +22 -5
  53. package/dist/steps/locators.js.map +1 -1
  54. package/package.json +1 -1
package/README.md CHANGED
@@ -187,6 +187,47 @@ await uploadFile(dialog, 'data.attachment', '/path/to/file.pdf');
187
187
 
188
188
  All form utilities accept a `data-testid` value or a visible label text as identifier. When a `data-testid` match is found on the element, it takes priority; otherwise the function falls back to label text matching (`.smart-form-widget-label`, `h3`, `h4`, or `label`). They work with both Angular Material and PrimeNG components, and accept any `Locator` or `Page` as container — use `topDialog(page)` to scope to a dialog.
189
189
 
190
+ #### Generic field setter
191
+
192
+ For data-driven scenarios, `setField` and `setFields` route to the right utility based on the value type and the widget's DOM signature — no need to know which form widget you are targeting.
193
+
194
+ ```typescript
195
+ import { setField, setFields } from '@smartbit4all/playwright-qa/steps';
196
+
197
+ // One field at a time
198
+ await setField(dialog, 'data.name', 'Teszt mappa'); // → fillField
199
+ await setField(dialog, 'data.canIncludeFiles', 'Igen'); // → selectRadio (widget has mat-radio-group)
200
+ await setField(dialog, 'data.category', 'Ügyintézés'); // → selectOption (widget has mat-select / p-dropdown)
201
+ await setField(dialog, 'data.isActive', true); // → setToggle / setCheckbox
202
+ await setField(dialog, 'data.skills', ['Angular', 'React']); // → selectMultiple or setChips
203
+ await setField(dialog, 'data.deadline', '2026-04-15 14:30'); // → fillDateTime (matches YYYY-MM-DD HH:mm)
204
+ await setField(dialog, 'data.attachment', '/path/file.pdf'); // → uploadFile (widget has smart-file-editor)
205
+ await setField(dialog, 'permissions', { 'Olvasás': true, 'Írás': false }); // → setCheckboxGroup
206
+
207
+ // Many fields at once
208
+ await setFields(dialog, {
209
+ 'data.name': 'Teszt mappa',
210
+ 'data.canIncludeFiles': 'Nem',
211
+ 'data.isActive': true,
212
+ 'data.tags': ['urgent', 'review'],
213
+ 'permissions': { 'Olvasás': true, 'Írás': true },
214
+ });
215
+ ```
216
+
217
+ Routing is decided by `value`'s TypeScript type plus the DOM tags inside the widget:
218
+ - `Record<string, boolean>` → `setCheckboxGroup`
219
+ - `boolean` + `mat-slide-toggle` / `p-inputSwitch` → `setToggle`
220
+ - `boolean` + `mat-checkbox` / `p-checkbox` → `setCheckbox`
221
+ - `string[]` + `mat-chip-grid` / `p-chips` → `setChips`
222
+ - `string[]` + `p-multiSelect` / `mat-select[multiple]` → `selectMultiple`
223
+ - `string` + `smart-file-editor` → `uploadFile`
224
+ - `string` + `mat-select` / `p-dropdown` → `selectOption`
225
+ - `string` + `mat-radio-group` / `p-radiobutton` → `selectRadio`
226
+ - `string` matching `YYYY-MM-DD HH:mm` → `fillDateTime`
227
+ - `string` + any `input` / `textarea` → `fillField`
228
+
229
+ If no branch matches, `setField` throws with the identifier in the message. Datetime detection is value-format based (a single `YYYY-MM-DD HH:mm` string), since the Material datetime widget has no distinctive tag — pass an ISO date+time string and let `setField` split it.
230
+
190
231
  ### Grid
191
232
 
192
233
  ```typescript
@@ -206,6 +247,9 @@ await selectGridRow(page, { 'Azonosító': 'DOC-001' });
206
247
  // Find by simple text match
207
248
  await selectGridRow(page, 'DOC-001');
208
249
 
250
+ // Find by row data-testid (rendered from row.id on the <tr>)
251
+ await selectGridRow(page, { rowId: 'doc-12345' });
252
+
209
253
  // Open the row's context menu and click an action
210
254
  await selectGridRow(page, { 'Azonosító': 'DOC-001' }, 'Szerkesztés');
211
255
 
@@ -232,6 +276,10 @@ await applyGridFilters(page, { 'Név': 'Teszt' });
232
276
  await clearGridFilters(page);
233
277
  ```
234
278
 
279
+ Column keys in a row filter accept either the header label or the header `data-testid` (rendered from `col.propertyName` on the `<th>`). Both resolve to the same column, so `{ 'Adószám': '12345' }` and `{ 'taxNumber': '12345' }` are equivalent — prefer `data-testid` for stability against label/locale changes.
280
+
281
+ For row-level addressing, `{ rowId: 'doc-12345' }` matches the `<tr>` `data-testid` attribute (rendered from `row.id`). `rowId` must be the only key in the filter object and is supported by `selectGridRow`, `checkGridRow`, and `checkGridRowsOnPage`. `filterAndSelectGridRow` throws if given a `rowId` filter — use `selectGridRow` instead, since row identifiers do not need a filter form pass.
282
+
235
283
  All grid functions accept `Page` or `Locator` as container — use a Locator to scope to a dialog or section:
236
284
 
237
285
  ```typescript
@@ -319,6 +367,28 @@ await screenshotRegionHighlight(page, 'menu-region',
319
367
 
320
368
  All built-in steps (`clickInDialog`, `selectGridRow`, `navigateInTree`) use these locators internally, so they automatically support `data-testid` values alongside text matching.
321
369
 
370
+ ### Debug
371
+
372
+ ```typescript
373
+ import { dumpDom } from '@smartbit4all/playwright-qa/steps';
374
+
375
+ // Dump visible elements on the page — useful when writing a new locator
376
+ console.log(await dumpDom(page));
377
+
378
+ // Scope to a container (dialog, section, grid row)
379
+ console.log(await dumpDom(topDialog(page)));
380
+
381
+ // Narrow with a selector
382
+ console.log(await dumpDom(page, { selector: 'button, [data-testid]' }));
383
+
384
+ // Include hidden elements and longer text
385
+ console.log(await dumpDom(page, { visibleOnly: false, maxText: 200 }));
386
+ ```
387
+
388
+ Each entry contains `tag`, `id`, `classes`, `testId` and own `text` (text nodes only, not the recursive `textContent`). Non-rendering tags (`script`, `style`, `meta`, `link`, `head`, `html`, `noscript`) are filtered out, and by default only visible elements are returned. Use this during test authoring to discover available `data-testid` values without manually inspecting the DOM in DevTools.
389
+
390
+ The `testId` field falls back through `data-testid` → `data-automationid`. PrimeNG `MenuItem` (e.g. grid row popup menus) does not expose `data-testid`; only the `automationId` MenuItem property is supported, and it renders as the `data-automationid` DOM attribute. `findMenuItem` honors both attributes.
391
+
322
392
  ## Developer Guide — Writing TestSteps
323
393
 
324
394
  TestSteps are simple async functions that implement one atomic UI operation.
@@ -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"}