@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.
- package/README.md +70 -0
- package/dist/basedata/hash.d.ts +2 -0
- package/dist/basedata/hash.d.ts.map +1 -0
- package/dist/basedata/hash.js +23 -0
- package/dist/basedata/hash.js.map +1 -0
- package/dist/basedata/history.d.ts +10 -0
- package/dist/basedata/history.d.ts.map +1 -0
- package/dist/basedata/history.js +144 -0
- package/dist/basedata/history.js.map +1 -0
- package/dist/basedata/index.d.ts +6 -0
- package/dist/basedata/index.d.ts.map +1 -0
- package/dist/basedata/index.js +16 -0
- package/dist/basedata/index.js.map +1 -0
- package/dist/basedata/loader.d.ts +12 -0
- package/dist/basedata/loader.d.ts.map +1 -0
- package/dist/basedata/loader.js +230 -0
- package/dist/basedata/loader.js.map +1 -0
- package/dist/basedata/processors/basic-screen.d.ts +31 -0
- package/dist/basedata/processors/basic-screen.d.ts.map +1 -0
- package/dist/basedata/processors/basic-screen.js +128 -0
- package/dist/basedata/processors/basic-screen.js.map +1 -0
- package/dist/basedata/registry.d.ts +11 -0
- package/dist/basedata/registry.d.ts.map +1 -0
- package/dist/basedata/registry.js +50 -0
- package/dist/basedata/registry.js.map +1 -0
- package/dist/basedata/runner.d.ts +3 -0
- package/dist/basedata/runner.d.ts.map +1 -0
- package/dist/basedata/runner.js +324 -0
- package/dist/basedata/runner.js.map +1 -0
- package/dist/basedata/types.d.ts +161 -0
- package/dist/basedata/types.d.ts.map +1 -0
- package/dist/basedata/types.js +3 -0
- package/dist/basedata/types.js.map +1 -0
- package/dist/steps/debug.d.ts +15 -0
- package/dist/steps/debug.d.ts.map +1 -0
- package/dist/steps/debug.js +41 -0
- package/dist/steps/debug.js.map +1 -0
- package/dist/steps/forms.d.ts +29 -0
- package/dist/steps/forms.d.ts.map +1 -1
- package/dist/steps/forms.js +93 -0
- package/dist/steps/forms.js.map +1 -1
- package/dist/steps/grid.steps.d.ts +3 -1
- package/dist/steps/grid.steps.d.ts.map +1 -1
- package/dist/steps/grid.steps.js +52 -8
- package/dist/steps/grid.steps.js.map +1 -1
- package/dist/steps/index.d.ts +2 -1
- package/dist/steps/index.d.ts.map +1 -1
- package/dist/steps/index.js +5 -1
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/locators.d.ts +17 -3
- package/dist/steps/locators.d.ts.map +1 -1
- package/dist/steps/locators.js +22 -5
- package/dist/steps/locators.js.map +1 -1
- 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 @@
|
|
|
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"}
|