@sun-asterisk/sungen 3.2.28 → 3.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities/discover.d.ts +29 -0
- package/dist/capabilities/discover.d.ts.map +1 -1
- package/dist/capabilities/discover.js +144 -10
- package/dist/capabilities/discover.js.map +1 -1
- package/dist/capabilities/registry.d.ts +18 -0
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js +25 -0
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +9 -0
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.js +1 -1
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/dashboard/templates/index.html +1 -1
- package/dist/exporters/feature-parser.d.ts +1 -1
- package/dist/exporters/feature-parser.js +1 -1
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +14 -1
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/item-labels.d.ts +35 -0
- package/dist/exporters/matrix/item-labels.d.ts.map +1 -0
- package/dist/exporters/matrix/item-labels.js +90 -0
- package/dist/exporters/matrix/item-labels.js.map +1 -0
- package/dist/exporters/matrix/render-coverage-sheet.d.ts +14 -0
- package/dist/exporters/matrix/render-coverage-sheet.d.ts.map +1 -0
- package/dist/exporters/matrix/render-coverage-sheet.js +160 -0
- package/dist/exporters/matrix/render-coverage-sheet.js.map +1 -0
- package/dist/exporters/matrix/render-overview-sheet.d.ts +20 -0
- package/dist/exporters/matrix/render-overview-sheet.d.ts.map +1 -0
- package/dist/exporters/matrix/render-overview-sheet.js +36 -0
- package/dist/exporters/matrix/render-overview-sheet.js.map +1 -0
- package/dist/exporters/matrix/render-testcase-sheet.d.ts +30 -0
- package/dist/exporters/matrix/render-testcase-sheet.d.ts.map +1 -0
- package/dist/exporters/matrix/render-testcase-sheet.js +156 -0
- package/dist/exporters/matrix/render-testcase-sheet.js.map +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts +41 -31
- package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
- package/dist/exporters/matrix/render-xlsx.js +72 -425
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/testcase-summary-band.d.ts +30 -0
- package/dist/exporters/matrix/testcase-summary-band.d.ts.map +1 -0
- package/dist/exporters/matrix/testcase-summary-band.js +75 -0
- package/dist/exporters/matrix/testcase-summary-band.js.map +1 -0
- package/dist/exporters/matrix/wording.d.ts.map +1 -1
- package/dist/exporters/matrix/wording.js +13 -0
- package/dist/exporters/matrix/wording.js.map +1 -1
- package/dist/exporters/matrix/xlsx-cells.d.ts +38 -0
- package/dist/exporters/matrix/xlsx-cells.d.ts.map +1 -0
- package/dist/exporters/matrix/xlsx-cells.js +52 -0
- package/dist/exporters/matrix/xlsx-cells.js.map +1 -0
- package/dist/exporters/xlsx-report-builder.d.ts +12 -1
- package/dist/exporters/xlsx-report-builder.d.ts.map +1 -1
- package/dist/exporters/xlsx-report-builder.js +10 -2
- package/dist/exporters/xlsx-report-builder.js.map +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +7 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +3 -3
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/appium/os-support.d.ts +53 -0
- package/dist/generators/test-generator/adapters/appium/os-support.d.ts.map +1 -0
- package/dist/generators/test-generator/adapters/appium/os-support.js +200 -0
- package/dist/generators/test-generator/adapters/appium/os-support.js.map +1 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/alert-fill-action.hbs +9 -2
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/capture-variable.hbs +24 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/hover-action.hbs +6 -2
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/hover-element-with-text.hbs +4 -3
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/unknown-element-action.hbs +9 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/have-value-assertion.hbs +34 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +14 -6
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/go-back-action.hbs +21 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/set-geolocation-action.hbs +16 -0
- package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +8 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row-nth.hbs +4 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +4 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +7 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/state-with-filter-assertion.hbs +7 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +4 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +4 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +4 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +12 -4
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +14 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +8 -8
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/id.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/testid.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +8 -8
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +5 -1
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/diagnostics.d.ts +38 -2
- package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
- package/dist/generators/test-generator/diagnostics.js +37 -1
- package/dist/generators/test-generator/diagnostics.js.map +1 -1
- package/dist/generators/test-generator/patterns/index.d.ts +33 -6
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +71 -7
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts +8 -0
- package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +40 -1
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +100 -17
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts +23 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +78 -12
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/harness/audit.d.ts +3 -1
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +51 -28
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/capability-plan.d.ts +4 -0
- package/dist/harness/capability-plan.d.ts.map +1 -1
- package/dist/harness/capability-plan.js +32 -2
- package/dist/harness/capability-plan.js.map +1 -1
- package/dist/harness/catalog/drivers.yaml +1 -1
- package/dist/harness/catalog/universal-viewpoints.yaml +145 -0
- package/dist/harness/parse.d.ts +6 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +1 -1
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/repair.d.ts.map +1 -1
- package/dist/harness/repair.js +8 -1
- package/dist/harness/repair.js.map +1 -1
- package/dist/harness/sensors.d.ts +48 -0
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +26 -1
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/viewpoint-ledger.d.ts +10 -0
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +23 -2
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/commands/delivery.md +4 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +14 -5
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +48 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +18 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md +16 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +11 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +10 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +88 -2
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +58 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md +13 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +59 -10
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-f-mobile-native.md +419 -0
- package/dist/orchestrator/templates/readme.md +1 -1
- package/dist/orchestrator/templates/specs-pw-shape-reporter.ts +0 -0
- package/dist/orchestrator/templates/wdio.conf.ts +105 -1
- package/package.json +3 -3
- package/src/capabilities/discover.ts +146 -10
- package/src/capabilities/registry.ts +30 -0
- package/src/cli/commands/audit.ts +9 -0
- package/src/cli/commands/capability.ts +1 -1
- package/src/dashboard/templates/index.html +1 -1
- package/src/exporters/feature-parser.ts +1 -1
- package/src/exporters/matrix/build.ts +13 -1
- package/src/exporters/matrix/item-labels.ts +78 -0
- package/src/exporters/matrix/render-coverage-sheet.ts +168 -0
- package/src/exporters/matrix/render-overview-sheet.ts +56 -0
- package/src/exporters/matrix/render-testcase-sheet.ts +178 -0
- package/src/exporters/matrix/render-xlsx.ts +67 -448
- package/src/exporters/matrix/testcase-summary-band.ts +79 -0
- package/src/exporters/matrix/wording.ts +13 -0
- package/src/exporters/matrix/xlsx-cells.ts +56 -0
- package/src/exporters/xlsx-report-builder.ts +16 -2
- package/src/generators/gherkin-parser/index.ts +1 -1
- package/src/generators/test-generator/adapters/appium/os-support.ts +176 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/alert-fill-action.hbs +9 -2
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/capture-variable.hbs +24 -1
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/hover-action.hbs +6 -2
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/hover-element-with-text.hbs +4 -3
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/unknown-element-action.hbs +9 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/have-value-assertion.hbs +34 -1
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +14 -6
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/go-back-action.hbs +21 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/gestures/set-geolocation-action.hbs +16 -0
- package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +8 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row-nth.hbs +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +7 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/state-with-filter-assertion.hbs +7 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +12 -4
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +14 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +8 -8
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/id.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/testid.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +8 -8
- package/src/generators/test-generator/code-generator.ts +5 -1
- package/src/generators/test-generator/diagnostics.ts +39 -2
- package/src/generators/test-generator/patterns/index.ts +78 -8
- package/src/generators/test-generator/patterns/types.ts +8 -0
- package/src/generators/test-generator/step-mapper.ts +107 -17
- package/src/generators/test-generator/utils/selector-resolver.ts +88 -12
- package/src/harness/audit.ts +55 -30
- package/src/harness/capability-plan.ts +33 -1
- package/src/harness/catalog/drivers.yaml +1 -1
- package/src/harness/catalog/universal-viewpoints.yaml +145 -0
- package/src/harness/parse.ts +7 -1
- package/src/harness/repair.ts +8 -1
- package/src/harness/sensors.ts +75 -1
- package/src/harness/viewpoint-ledger.ts +26 -5
- package/src/orchestrator/templates/ai-src/commands/delivery.md +4 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +14 -5
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +48 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +18 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md +16 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +11 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +10 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +88 -2
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +58 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md +13 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +59 -10
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-f-mobile-native.md +419 -0
- package/src/orchestrator/templates/readme.md +1 -1
- package/src/orchestrator/templates/specs-pw-shape-reporter.ts +0 -0
- package/src/orchestrator/templates/wdio.conf.ts +105 -1
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
* (`--version`, `capability remove`) even when a driver is missing/broken.
|
|
19
19
|
*/
|
|
20
20
|
import { createRequire } from 'module';
|
|
21
|
+
import * as fs from 'fs';
|
|
21
22
|
import * as path from 'path';
|
|
23
|
+
import { coreVersion } from '../orchestrator/lockstep-version';
|
|
22
24
|
import { capabilityRegistry } from './registry';
|
|
23
25
|
import { LOCAL_DRIVERS, registerCoreCapability } from './builtins';
|
|
26
|
+
import { loadDriverCatalog, readCapabilities } from '../harness/capability';
|
|
24
27
|
|
|
25
28
|
/**
|
|
26
29
|
* Driver packages relocated out of core, loaded before the in-core `LOCAL_DRIVERS`. As `db`/`api`
|
|
@@ -44,18 +47,116 @@ const EXTERNAL_DRIVERS = ['@sungen/driver-ui', '@sungen/driver-db', '@sungen/dri
|
|
|
44
47
|
// test-data available out of the box (no `capability add` needed); inert until a field-map/recipe exists.
|
|
45
48
|
const BUNDLED_DRIVERS = new Set(['@sungen/driver-ui', '@sungen/driver-data-factory']);
|
|
46
49
|
|
|
50
|
+
/** One installed copy of a driver package: where it was found from, and which version lives there. */
|
|
51
|
+
export interface DriverCopy {
|
|
52
|
+
/** The anchor the lookup was made from — the project's package.json, or core's own file. */
|
|
53
|
+
anchor: 'project' | 'core';
|
|
54
|
+
resolved: string;
|
|
55
|
+
version: string | undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** `3.2.28-beta.2` and `3.2.28` sit on the same lockstep line; `3.2.20` does not. */
|
|
59
|
+
export function sameVersionLine(a: string | undefined, b: string | undefined): boolean {
|
|
60
|
+
if (!a || !b || a === 'latest' || b === 'latest') return false;
|
|
61
|
+
const line = (v: string) => v.split('-')[0];
|
|
62
|
+
return line(a) === line(b);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Pick which installed copy of a driver to load.
|
|
67
|
+
*
|
|
68
|
+
* Project-first is right for an OPT-IN driver: `sungen capability add db` installs into the
|
|
69
|
+
* project's node_modules, and a globally-installed core would never see it from its own anchor.
|
|
70
|
+
*
|
|
71
|
+
* It was wrong for a BUNDLED driver. Core pins `@sungen/driver-ui` to its exact version, but the
|
|
72
|
+
* project may hold an older copy — a `^` range from an earlier scaffold, a lock file nobody
|
|
73
|
+
* refreshed — and that copy loaded first, unconditionally. Core 3.2.25 started gating every state
|
|
74
|
+
* clause on `pattern.states` (SG-E021); driver-ui 3.2.20 predates the field; so
|
|
75
|
+
* `see [Filter] button is hidden` threw on the very pattern (`is-hidden`) the message told the
|
|
76
|
+
* author to use. Every `is <state>` step in every project holding a stale driver, on Gherkin that
|
|
77
|
+
* was correct — and the message blamed the Gherkin.
|
|
78
|
+
*
|
|
79
|
+
* So for a bundled driver the copy on core's own version line wins wherever it lives. Only when no
|
|
80
|
+
* copy is on that line does the first one load — and the caller then warns, because that skew is
|
|
81
|
+
* exactly the breakage the user is about to see. An unknown core version (`latest`) keeps the old
|
|
82
|
+
* project-first order: there is no line to match against.
|
|
83
|
+
*/
|
|
84
|
+
export function pickDriverCopy(copies: readonly DriverCopy[], core: string, bundled: boolean): DriverCopy | undefined {
|
|
85
|
+
if (!copies.length) return undefined;
|
|
86
|
+
if (bundled && core !== 'latest') {
|
|
87
|
+
const lockstep = copies.find((c) => sameVersionLine(c.version, core));
|
|
88
|
+
if (lockstep) return lockstep;
|
|
89
|
+
}
|
|
90
|
+
return copies[0];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function readDriverVersion(req: NodeRequire, name: string, resolved: string): string | undefined {
|
|
94
|
+
// `<pkg>/package.json` is not always exported; fall back to walking up from the entry file.
|
|
95
|
+
try { return req(`${name}/package.json`)?.version; } catch { /* try the walk */ }
|
|
96
|
+
let dir = path.dirname(resolved);
|
|
97
|
+
for (let i = 0; i < 6; i++) {
|
|
98
|
+
try {
|
|
99
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
|
|
100
|
+
if (pkg?.name === name) return pkg.version;
|
|
101
|
+
} catch { /* keep walking */ }
|
|
102
|
+
const parent = path.dirname(dir);
|
|
103
|
+
if (parent === dir) break;
|
|
104
|
+
dir = parent;
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The lockstep contract, in the user's terms, with the one command that restores it. */
|
|
110
|
+
function versionSkewWarning(name: string, loaded: string | undefined, core: string, bypassed?: DriverCopy): string {
|
|
111
|
+
const fix = ` Fix: run \`sungen update\` in the project (or \`npm i ${name}@${core}\`) so every @sungen/driver-* matches sungen ${core}.`;
|
|
112
|
+
if (bypassed) {
|
|
113
|
+
return (
|
|
114
|
+
`⚠ sungen: the project holds "${name}" ${bypassed.version ?? '(unknown version)'} but sungen is ${core} — ` +
|
|
115
|
+
`loading core's own ${loaded ?? core} copy instead. The two are published in lockstep; a driver behind core misses ` +
|
|
116
|
+
`metadata core now requires (for the UI driver: every "is hidden"/"is disabled" clause fails SG-E021 on the pattern that should assert it).\n` + fix
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return (
|
|
120
|
+
`⚠ sungen: "${name}" ${loaded ?? '(unknown version)'} is loaded against sungen ${core} — the two are published in lockstep, ` +
|
|
121
|
+
`and a driver on another version line misses metadata core requires (for the UI driver: every "is hidden"/"is disabled" ` +
|
|
122
|
+
`clause fails SG-E021 on the pattern that should assert it).\n` + fix
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
47
126
|
function loadExternalDriver(name: string): void {
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
// core (`npm i -g`) wouldn't
|
|
51
|
-
//
|
|
52
|
-
|
|
127
|
+
const bundled = BUNDLED_DRIVERS.has(name);
|
|
128
|
+
// Look from the user's PROJECT and from core's own location. Opt-in drivers (`sungen capability add
|
|
129
|
+
// db|api`) install into the PROJECT's node_modules — a globally-installed core (`npm i -g`) wouldn't
|
|
130
|
+
// see them via a core-anchored `require`. The bundled @sungen/driver-ui is a core dependency
|
|
131
|
+
// (co-located with core), so the second anchor always has a copy on core's version line.
|
|
132
|
+
const anchors: Array<[DriverCopy['anchor'], string]> = [
|
|
133
|
+
['project', path.join(process.cwd(), 'package.json')],
|
|
134
|
+
['core', __filename],
|
|
135
|
+
];
|
|
136
|
+
const copies: DriverCopy[] = [];
|
|
137
|
+
const requires = new Map<string, NodeRequire>();
|
|
138
|
+
for (const [anchor, file] of anchors) {
|
|
53
139
|
let req: NodeRequire;
|
|
54
|
-
try { req = createRequire(
|
|
140
|
+
try { req = createRequire(file); } catch { continue; }
|
|
55
141
|
let resolved: string;
|
|
56
142
|
try { resolved = req.resolve(name); } catch { continue; } // not installed at this anchor → try next
|
|
143
|
+
if (copies.some((c) => c.resolved === resolved)) continue; // one install seen from both anchors
|
|
144
|
+
requires.set(resolved, req);
|
|
145
|
+
copies.push({ anchor, resolved, version: readDriverVersion(req, name, resolved) });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const core = coreVersion();
|
|
149
|
+
const chosen = pickDriverCopy(copies, core, bundled);
|
|
150
|
+
if (chosen) {
|
|
151
|
+
if (core !== 'latest' && chosen.version && !sameVersionLine(chosen.version, core)) {
|
|
152
|
+
console.warn(versionSkewWarning(name, chosen.version, core));
|
|
153
|
+
} else if (bundled && chosen.anchor === 'core' && copies[0] !== chosen) {
|
|
154
|
+
// A stale project copy was bypassed. Loading the right one already fixed the compile; the line
|
|
155
|
+
// is there so the stale dependency gets cleaned up rather than lingering under every future run.
|
|
156
|
+
console.warn(versionSkewWarning(name, chosen.version, core, copies[0]));
|
|
157
|
+
}
|
|
57
158
|
try {
|
|
58
|
-
const mod =
|
|
159
|
+
const mod = requires.get(chosen.resolved)!(chosen.resolved);
|
|
59
160
|
const register: ((r: typeof capabilityRegistry) => void) | undefined = mod?.sungenDriver?.register ?? mod?.register;
|
|
60
161
|
if (typeof register === 'function') register(capabilityRegistry);
|
|
61
162
|
} catch (e) {
|
|
@@ -68,10 +169,10 @@ function loadExternalDriver(name: string): void {
|
|
|
68
169
|
` Fix: reinstall it (\`sungen capability add ${name.replace(/^@sungen\/driver-/, '')}\`) or remove it.`,
|
|
69
170
|
);
|
|
70
171
|
}
|
|
71
|
-
return;
|
|
172
|
+
return;
|
|
72
173
|
}
|
|
73
174
|
// Not resolvable at ANY anchor.
|
|
74
|
-
if (
|
|
175
|
+
if (bundled) {
|
|
75
176
|
// A bundled default is missing → broken install, not a declined opt-in. Warn loudly so the user
|
|
76
177
|
// sees the real cause instead of a wall of "Unrecognized step pattern".
|
|
77
178
|
console.warn(
|
|
@@ -86,9 +187,44 @@ function loadExternalDriver(name: string): void {
|
|
|
86
187
|
// Opt-in driver not installed — capabilities are opt-in, so skip silently.
|
|
87
188
|
}
|
|
88
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Should this driver package load for the project's declared platform?
|
|
192
|
+
*
|
|
193
|
+
* Only an **opt-in platform** driver is gated. Three exclusions, each load-bearing:
|
|
194
|
+
* - `kind: 'capability'` (api/db/mock/data-factory) is gated by its ANNOTATION TAG, not by
|
|
195
|
+
* platform. Gating it here would break `@query`/`@api` on a project that legitimately has both.
|
|
196
|
+
* - `bundled: true` (driver-ui) is the BASELINE vocabulary, not a platform choice. Mobile reuses
|
|
197
|
+
* the whole web pattern set — click, fill, visibility — on the appium adapter, so skipping
|
|
198
|
+
* driver-ui on a `platform: mobile` project would delete almost every step the suite uses.
|
|
199
|
+
* - No `platform:` in `qa/capabilities.yaml` → load everything, exactly as before. A project that
|
|
200
|
+
* predates the profile, and every `--framework`-override path, must keep working.
|
|
201
|
+
*
|
|
202
|
+
* A package the catalog does not know stays ungated: an unknown driver is not evidence of a
|
|
203
|
+
* platform mismatch, and silently dropping it would be the hardest failure here to diagnose.
|
|
204
|
+
*/
|
|
205
|
+
function servesPlatform(pkg: string, platform: string | undefined): boolean {
|
|
206
|
+
if (!platform) return true;
|
|
207
|
+
const meta = Object.values(loadDriverCatalog()).find((m) => m.package === pkg);
|
|
208
|
+
if (!meta || meta.kind !== 'platform' || meta.bundled) return true;
|
|
209
|
+
if (meta.id === platform) return true;
|
|
210
|
+
// Record what the gate dropped. SG-W001 needs it: without the driver's patterns in the registry a
|
|
211
|
+
// mobile-only step reads as "sungen has no step form for it", which is untrue — the form exists in
|
|
212
|
+
// a vocabulary this project declined. Recording the SKIP is the honest half; naming the step would
|
|
213
|
+
// need a static list that rots on the next pattern added.
|
|
214
|
+
capabilityRegistry.noteGatedDriver(pkg, meta.id, platform);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
|
|
89
218
|
export function discoverAndRegisterCapabilities(): void {
|
|
90
219
|
if (capabilityRegistry.isPopulated()) return;
|
|
91
|
-
|
|
220
|
+
// CG-1b — discovery never read the project's platform, so on a machine holding both drivers the
|
|
221
|
+
// mobile vocabulary was live on web projects and vice versa. `platforms:` on the patterns is what
|
|
222
|
+
// makes a cross-platform step FAIL WELL; this is what keeps it from being reachable at all.
|
|
223
|
+
const { platform } = readCapabilities(process.cwd());
|
|
224
|
+
for (const name of EXTERNAL_DRIVERS) {
|
|
225
|
+
if (!servesPlatform(name, platform)) continue;
|
|
226
|
+
loadExternalDriver(name); // ui (external) — first, default capability
|
|
227
|
+
}
|
|
92
228
|
for (const driver of LOCAL_DRIVERS) driver.register(capabilityRegistry); // db, api (in-core for now)
|
|
93
229
|
registerCoreCapability(capabilityRegistry); // generic layer, always present, registered last
|
|
94
230
|
}
|
|
@@ -76,6 +76,10 @@ export interface CapabilityDescriptor {
|
|
|
76
76
|
|
|
77
77
|
export class CapabilityRegistry {
|
|
78
78
|
private caps = new Map<string, CapabilityDescriptor>();
|
|
79
|
+
/** package → the platform it serves, for drivers the platform gate skipped. See `noteGatedDriver`. */
|
|
80
|
+
private gated = new Map<string, string>();
|
|
81
|
+
/** The project platform those skips were made FOR — the same value for every entry in `gated`. */
|
|
82
|
+
private gatedFor: string | undefined;
|
|
79
83
|
|
|
80
84
|
/** Register (or replace, by id) a capability descriptor. Idempotent by id. */
|
|
81
85
|
register(descriptor: CapabilityDescriptor): void {
|
|
@@ -116,9 +120,35 @@ export class CapabilityRegistry {
|
|
|
116
120
|
return kind ? all.filter((s) => s.kind === kind) : all;
|
|
117
121
|
}
|
|
118
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Record a driver discovery SKIPPED because it does not serve the project's platform.
|
|
125
|
+
*
|
|
126
|
+
* Gating removes the driver's patterns from the registry, which is the point — but it also means
|
|
127
|
+
* a step belonging to that driver reaches SG-W001 ("sungen has no step form for it") instead of
|
|
128
|
+
* SG-W020 ("this step is mobile-only"). SG-W001's sentence is then false. This is the only fact
|
|
129
|
+
* available to correct it: patterns were never loaded, so what was skipped is knowable and which
|
|
130
|
+
* step it owned is not.
|
|
131
|
+
*/
|
|
132
|
+
noteGatedDriver(pkg: string, serves: string, projectPlatform: string): void {
|
|
133
|
+
this.gated.set(pkg, serves);
|
|
134
|
+
this.gatedFor = projectPlatform;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Drivers skipped by the platform gate, as `[package, platform it serves]`. Empty when nothing was gated. */
|
|
138
|
+
gatedDrivers(): Array<[string, string]> {
|
|
139
|
+
return [...this.gated.entries()];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** The project platform the gate applied, or undefined when nothing was gated. */
|
|
143
|
+
gatedForPlatform(): string | undefined {
|
|
144
|
+
return this.gatedFor;
|
|
145
|
+
}
|
|
146
|
+
|
|
119
147
|
/** Test seam: drop all registrations. */
|
|
120
148
|
_reset(): void {
|
|
121
149
|
this.caps.clear();
|
|
150
|
+
this.gated.clear();
|
|
151
|
+
this.gatedFor = undefined;
|
|
122
152
|
}
|
|
123
153
|
}
|
|
124
154
|
|
|
@@ -92,6 +92,15 @@ function render(r: AuditReport): void {
|
|
|
92
92
|
for (const c of r.duplicates.clusters.slice(0, 3)) {
|
|
93
93
|
L(` ${c.sameDataLikely ? '✗ exact' : '○ EP/data family'} (${c.scenarios.length}): ${c.scenarios.slice(0, 3).join(' | ')}${c.scenarios.length > 3 ? ' …' : ''}`);
|
|
94
94
|
}
|
|
95
|
+
// #694 — printed under the duplicate axis because that is where a reader looks for it, but it
|
|
96
|
+
// is a DIFFERENT signal: ⑤ clusters identical steps, this catches one id on distinct scenarios.
|
|
97
|
+
// Marked BLOCKING inline so a red build states its cause without scrolling to the findings.
|
|
98
|
+
if (r.reusedScenarioIds.length > 0) {
|
|
99
|
+
L(` ✗ BLOCKING — ${r.reusedScenarioIds.length} reused scenario id(s): a shared id ships as several deliverable rows under ONE testcase id`);
|
|
100
|
+
for (const d of r.reusedScenarioIds.slice(0, 3)) {
|
|
101
|
+
L(` ${d.id} ×${d.count}${d.file ? ` in ${d.file}` : ''}: ${d.titles.slice(0, 2).join(' | ')}${d.titles.length > 2 ? ' …' : ''}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
95
104
|
L('');
|
|
96
105
|
L(` ⑥ Traceability — ${(r.trace.mappedRatio * 100).toFixed(0)}% scenarios linked to viewpoint-overview`);
|
|
97
106
|
L(` ${r.trace.note}`);
|
|
@@ -98,7 +98,7 @@ export function registerCapabilityCommand(program: Command): void {
|
|
|
98
98
|
// ── plan (Planner — recommend-only, no install) ──────────────────────────
|
|
99
99
|
cap
|
|
100
100
|
.command('plan')
|
|
101
|
-
.description('Capability Planner: classify execution modes + @manual reasons (M1–
|
|
101
|
+
.description('Capability Planner: classify execution modes + @manual reasons (M1–M11) + recommend drivers (no install)')
|
|
102
102
|
.requiredOption('-s, --screen <name>', 'Screen or flow name')
|
|
103
103
|
.option('--json', 'Output the raw plan JSON')
|
|
104
104
|
.action((o: { screen: string; json?: boolean }) => {
|
|
@@ -116,7 +116,7 @@ use chrome, FireFox or Internet Explorer 11`)}var a=e(`safe-buffer`),o=e(`random
|
|
|
116
116
|
`)):s=e.stylize(`[Circular]`,`special`)),v(o)){if(a&&i.match(/^\d+$/))return s;(o=JSON.stringify(``+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,`name`)):(o=o.replace(/'/g,`\\'`).replace(/\\"/g,`"`).replace(/(^"|"$)/g,`'`),o=e.stylize(o,`string`))}return o+`: `+s}function p(e){return Array.isArray(e)}function m(e){return typeof e==`boolean`}function h(e){return e===null}function g(e){return typeof e==`number`}function _(e){return typeof e==`string`}function v(e){return e===void 0}function y(e){return b(e)&&w(e)===`[object RegExp]`}function b(e){return typeof e==`object`&&!!e}function x(e){return b(e)&&w(e)===`[object Date]`}function S(e){return b(e)&&(w(e)===`[object Error]`||e instanceof Error)}function C(e){return typeof e==`function`}function w(e){return Object.prototype.toString.call(e)}function T(e){return e<10?`0`+e.toString(10):e.toString(10)}n.debuglog=function(e){if(v(a)&&(a=t.env.NODE_DEBUG||``),e=e.toUpperCase(),!o[e])if(RegExp(`\\b`+e+`\\b`,`i`).test(a)){var r=t.pid;o[e]=function(){var t=n.format.apply(n,arguments);console.error(`%s %d: %s`,e,r,t)}}else o[e]=function(){};return o[e]},n.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:`cyan`,number:`yellow`,boolean:`yellow`,undefined:`grey`,null:`bold`,string:`green`,date:`magenta`,regexp:`red`},n.isArray=p,n.isBoolean=m,n.isNull=h,n.isNullOrUndefined=function(e){return e==null},n.isNumber=g,n.isString=_,n.isSymbol=function(e){return typeof e==`symbol`},n.isUndefined=v,n.isRegExp=y,n.isObject=b,n.isDate=x,n.isError=S,n.isFunction=C,n.isPrimitive=function(e){return e===null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`||typeof e==`symbol`||e===void 0},n.isBuffer=e(`./support/isBuffer`);var E=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function D(){var e=new Date,t=[T(e.getHours()),T(e.getMinutes()),T(e.getSeconds())].join(`:`);return[e.getDate(),E[e.getMonth()],t].join(` `)}function O(e,t){return Object.prototype.hasOwnProperty.call(e,t)}n.log=function(){console.log(`%s - %s`,D(),n.format.apply(n,arguments))},n.inherits=e(`inherits`),n._extend=function(e,t){if(!t||!b(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(this)}).call(this,e(`_process`),typeof global<`u`?global:typeof self<`u`?self:typeof window<`u`?window:{})},{"./support/isBuffer":526,_process:467,inherits:525}],528:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"v1",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(n,"v3",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(n,"v4",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(n,"v5",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(n,"NIL",{enumerable:!0,get:function(){return s.default}}),Object.defineProperty(n,"version",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(n,"validate",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(n,"stringify",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(n,"parse",{enumerable:!0,get:function(){return d.default}});var r=f(e(`./v1.js`)),i=f(e(`./v3.js`)),a=f(e(`./v4.js`)),o=f(e(`./v5.js`)),s=f(e(`./nil.js`)),c=f(e(`./version.js`)),l=f(e(`./validate.js`)),u=f(e(`./stringify.js`)),d=f(e(`./parse.js`));function f(e){return e&&e.__esModule?e:{default:e}}},{"./nil.js":530,"./parse.js":531,"./stringify.js":535,"./v1.js":536,"./v3.js":537,"./v4.js":539,"./v5.js":540,"./validate.js":541,"./version.js":542}],529:[function(e,t,n){function r(e){return 14+(e+64>>>9<<4)+1}function i(e,t){let n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function a(e,t,n,r,a,o){return i((s=i(i(t,e),i(r,o)))<<(c=a)|s>>>32-c,n);var s,c}function o(e,t,n,r,i,o,s){return a(t&n|~t&r,e,t,i,o,s)}function s(e,t,n,r,i,o,s){return a(t&r|n&~r,e,t,i,o,s)}function c(e,t,n,r,i,o,s){return a(t^n^r,e,t,i,o,s)}function l(e,t,n,r,i,o,s){return a(n^(t|~r),e,t,i,o,s)}Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=function(e){if(typeof e==`string`){let t=unescape(encodeURIComponent(e));e=new Uint8Array(t.length);for(let n=0;n<t.length;++n)e[n]=t.charCodeAt(n)}return function(e){let t=[],n=32*e.length;for(let r=0;r<n;r+=8){let n=e[r>>5]>>>r%32&255,i=parseInt(`0123456789abcdef`.charAt(n>>>4&15)+`0123456789abcdef`.charAt(15&n),16);t.push(i)}return t}(function(e,t){e[t>>5]|=128<<t%32,e[r(t)-1]=t;let n=1732584193,a=-271733879,u=-1732584194,d=271733878;for(let t=0;t<e.length;t+=16){let r=n,f=a,p=u,m=d;n=o(n,a,u,d,e[t],7,-680876936),d=o(d,n,a,u,e[t+1],12,-389564586),u=o(u,d,n,a,e[t+2],17,606105819),a=o(a,u,d,n,e[t+3],22,-1044525330),n=o(n,a,u,d,e[t+4],7,-176418897),d=o(d,n,a,u,e[t+5],12,1200080426),u=o(u,d,n,a,e[t+6],17,-1473231341),a=o(a,u,d,n,e[t+7],22,-45705983),n=o(n,a,u,d,e[t+8],7,1770035416),d=o(d,n,a,u,e[t+9],12,-1958414417),u=o(u,d,n,a,e[t+10],17,-42063),a=o(a,u,d,n,e[t+11],22,-1990404162),n=o(n,a,u,d,e[t+12],7,1804603682),d=o(d,n,a,u,e[t+13],12,-40341101),u=o(u,d,n,a,e[t+14],17,-1502002290),a=o(a,u,d,n,e[t+15],22,1236535329),n=s(n,a,u,d,e[t+1],5,-165796510),d=s(d,n,a,u,e[t+6],9,-1069501632),u=s(u,d,n,a,e[t+11],14,643717713),a=s(a,u,d,n,e[t],20,-373897302),n=s(n,a,u,d,e[t+5],5,-701558691),d=s(d,n,a,u,e[t+10],9,38016083),u=s(u,d,n,a,e[t+15],14,-660478335),a=s(a,u,d,n,e[t+4],20,-405537848),n=s(n,a,u,d,e[t+9],5,568446438),d=s(d,n,a,u,e[t+14],9,-1019803690),u=s(u,d,n,a,e[t+3],14,-187363961),a=s(a,u,d,n,e[t+8],20,1163531501),n=s(n,a,u,d,e[t+13],5,-1444681467),d=s(d,n,a,u,e[t+2],9,-51403784),u=s(u,d,n,a,e[t+7],14,1735328473),a=s(a,u,d,n,e[t+12],20,-1926607734),n=c(n,a,u,d,e[t+5],4,-378558),d=c(d,n,a,u,e[t+8],11,-2022574463),u=c(u,d,n,a,e[t+11],16,1839030562),a=c(a,u,d,n,e[t+14],23,-35309556),n=c(n,a,u,d,e[t+1],4,-1530992060),d=c(d,n,a,u,e[t+4],11,1272893353),u=c(u,d,n,a,e[t+7],16,-155497632),a=c(a,u,d,n,e[t+10],23,-1094730640),n=c(n,a,u,d,e[t+13],4,681279174),d=c(d,n,a,u,e[t],11,-358537222),u=c(u,d,n,a,e[t+3],16,-722521979),a=c(a,u,d,n,e[t+6],23,76029189),n=c(n,a,u,d,e[t+9],4,-640364487),d=c(d,n,a,u,e[t+12],11,-421815835),u=c(u,d,n,a,e[t+15],16,530742520),a=c(a,u,d,n,e[t+2],23,-995338651),n=l(n,a,u,d,e[t],6,-198630844),d=l(d,n,a,u,e[t+7],10,1126891415),u=l(u,d,n,a,e[t+14],15,-1416354905),a=l(a,u,d,n,e[t+5],21,-57434055),n=l(n,a,u,d,e[t+12],6,1700485571),d=l(d,n,a,u,e[t+3],10,-1894986606),u=l(u,d,n,a,e[t+10],15,-1051523),a=l(a,u,d,n,e[t+1],21,-2054922799),n=l(n,a,u,d,e[t+8],6,1873313359),d=l(d,n,a,u,e[t+15],10,-30611744),u=l(u,d,n,a,e[t+6],15,-1560198380),a=l(a,u,d,n,e[t+13],21,1309151649),n=l(n,a,u,d,e[t+4],6,-145523070),d=l(d,n,a,u,e[t+11],10,-1120210379),u=l(u,d,n,a,e[t+2],15,718787259),a=l(a,u,d,n,e[t+9],21,-343485551),n=i(n,r),a=i(a,f),u=i(u,p),d=i(d,m)}return[n,a,u,d]}(function(e){if(e.length===0)return[];let t=8*e.length,n=new Uint32Array(r(t));for(let r=0;r<t;r+=8)n[r>>5]|=(255&e[r/8])<<r%32;return n}(e),8*e.length))}},{}],530:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=`00000000-0000-0000-0000-000000000000`},{}],531:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./validate.js`))&&r.__esModule?r:{default:r};n.default=function(e){if(!(0,i.default)(e))throw TypeError(`Invalid UUID`);let t,n=new Uint8Array(16);return n[0]=(t=parseInt(e.slice(0,8),16))>>>24,n[1]=t>>>16&255,n[2]=t>>>8&255,n[3]=255&t,n[4]=(t=parseInt(e.slice(9,13),16))>>>8,n[5]=255&t,n[6]=(t=parseInt(e.slice(14,18),16))>>>8,n[7]=255&t,n[8]=(t=parseInt(e.slice(19,23),16))>>>8,n[9]=255&t,n[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255,n[11]=t/4294967296&255,n[12]=t>>>24&255,n[13]=t>>>16&255,n[14]=t>>>8&255,n[15]=255&t,n}},{"./validate.js":541}],532:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i},{}],533:[function(e,t,n){let r;Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(){if(!r&&(r=typeof crypto<`u`&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||typeof msCrypto<`u`&&typeof msCrypto.getRandomValues==`function`&&msCrypto.getRandomValues.bind(msCrypto),!r))throw Error(`crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported`);return r(i)};let i=new Uint8Array(16)},{}],534:[function(e,t,n){function r(e,t,n,r){switch(e){case 0:return t&n^~t&r;case 1:return t^n^r;case 2:return t&n^t&r^n&r;case 3:return t^n^r}}function i(e,t){return e<<t|e>>>32-t}Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=function(e){let t=[1518500249,1859775393,2400959708,3395469782],n=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof e==`string`){let t=unescape(encodeURIComponent(e));e=[];for(let n=0;n<t.length;++n)e.push(t.charCodeAt(n))}else Array.isArray(e)||(e=Array.prototype.slice.call(e));e.push(128);let a=e.length/4+2,o=Math.ceil(a/16),s=Array(o);for(let t=0;t<o;++t){let n=new Uint32Array(16);for(let r=0;r<16;++r)n[r]=e[64*t+4*r]<<24|e[64*t+4*r+1]<<16|e[64*t+4*r+2]<<8|e[64*t+4*r+3];s[t]=n}s[o-1][14]=8*(e.length-1)/2**32,s[o-1][14]=Math.floor(s[o-1][14]),s[o-1][15]=8*(e.length-1)&4294967295;for(let e=0;e<o;++e){let a=new Uint32Array(80);for(let t=0;t<16;++t)a[t]=s[e][t];for(let e=16;e<80;++e)a[e]=i(a[e-3]^a[e-8]^a[e-14]^a[e-16],1);let o=n[0],c=n[1],l=n[2],u=n[3],d=n[4];for(let e=0;e<80;++e){let n=Math.floor(e/20),s=i(o,5)+r(n,c,l,u)+d+t[n]+a[e]>>>0;d=u,u=l,l=i(c,30)>>>0,c=o,o=s}n[0]=n[0]+o>>>0,n[1]=n[1]+c>>>0,n[2]=n[2]+l>>>0,n[3]=n[3]+u>>>0,n[4]=n[4]+d>>>0}return[n[0]>>24&255,n[0]>>16&255,n[0]>>8&255,255&n[0],n[1]>>24&255,n[1]>>16&255,n[1]>>8&255,255&n[1],n[2]>>24&255,n[2]>>16&255,n[2]>>8&255,255&n[2],n[3]>>24&255,n[3]>>16&255,n[3]>>8&255,255&n[3],n[4]>>24&255,n[4]>>16&255,n[4]>>8&255,255&n[4]]}},{}],535:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./validate.js`))&&r.__esModule?r:{default:r};let a=[];for(let e=0;e<256;++e)a.push((e+256).toString(16).substr(1));n.default=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=(a[e[t+0]]+a[e[t+1]]+a[e[t+2]]+a[e[t+3]]+`-`+a[e[t+4]]+a[e[t+5]]+`-`+a[e[t+6]]+a[e[t+7]]+`-`+a[e[t+8]]+a[e[t+9]]+`-`+a[e[t+10]]+a[e[t+11]]+a[e[t+12]]+a[e[t+13]]+a[e[t+14]]+a[e[t+15]]).toLowerCase();if(!(0,i.default)(n))throw TypeError(`Stringified UUID is invalid`);return n}},{"./validate.js":541}],536:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./rng.js`)),i=a(e(`./stringify.js`));function a(e){return e&&e.__esModule?e:{default:e}}let o,s,c=0,l=0;n.default=function(e,t,n){let a=t&&n||0,u=t||Array(16),d=(e=e||{}).node||o,f=e.clockseq===void 0?s:e.clockseq;if(d==null||f==null){let t=e.random||(e.rng||r.default)();d??(d=o=[1|t[0],t[1],t[2],t[3],t[4],t[5]]),f??(f=s=16383&(t[6]<<8|t[7]))}let p=e.msecs===void 0?Date.now():e.msecs,m=e.nsecs===void 0?l+1:e.nsecs,h=p-c+(m-l)/1e4;if(h<0&&e.clockseq===void 0&&(f=f+1&16383),(h<0||p>c)&&e.nsecs===void 0&&(m=0),m>=1e4)throw Error(`uuid.v1(): Can't create more than 10M uuids/sec`);c=p,l=m,s=f,p+=0xb1d069b5400;let g=(1e4*(268435455&p)+m)%4294967296;u[a++]=g>>>24&255,u[a++]=g>>>16&255,u[a++]=g>>>8&255,u[a++]=255&g;let _=p/4294967296*1e4&268435455;u[a++]=_>>>8&255,u[a++]=255&_,u[a++]=_>>>24&15|16,u[a++]=_>>>16&255,u[a++]=f>>>8|128,u[a++]=255&f;for(let e=0;e<6;++e)u[a+e]=d[e];return t||(0,i.default)(u)}},{"./rng.js":533,"./stringify.js":535}],537:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./v35.js`)),i=a(e(`./md5.js`));function a(e){return e&&e.__esModule?e:{default:e}}n.default=(0,r.default)(`v3`,48,i.default)},{"./md5.js":529,"./v35.js":538}],538:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(e,t,n){function a(e,a,o,s){if(typeof e==`string`&&(e=function(e){e=unescape(encodeURIComponent(e));let t=[];for(let n=0;n<e.length;++n)t.push(e.charCodeAt(n));return t}(e)),typeof a==`string`&&(a=(0,i.default)(a)),a.length!==16)throw TypeError(`Namespace must be array-like (16 iterable integer values, 0-255)`);let c=new Uint8Array(16+e.length);if(c.set(a),c.set(e,a.length),c=n(c),c[6]=15&c[6]|t,c[8]=63&c[8]|128,o){s=s||0;for(let e=0;e<16;++e)o[s+e]=c[e];return o}return(0,r.default)(c)}try{a.name=e}catch{}return a.DNS=o,a.URL=s,a},n.URL=n.DNS=void 0;var r=a(e(`./stringify.js`)),i=a(e(`./parse.js`));function a(e){return e&&e.__esModule?e:{default:e}}let o=`6ba7b810-9dad-11d1-80b4-00c04fd430c8`;n.DNS=o;let s=`6ba7b811-9dad-11d1-80b4-00c04fd430c8`;n.URL=s},{"./parse.js":531,"./stringify.js":535}],539:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./rng.js`)),i=a(e(`./stringify.js`));function a(e){return e&&e.__esModule?e:{default:e}}n.default=function(e,t,n){let a=(e=e||{}).random||(e.rng||r.default)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=a[e];return t}return(0,i.default)(a)}},{"./rng.js":533,"./stringify.js":535}],540:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./v35.js`)),i=a(e(`./sha1.js`));function a(e){return e&&e.__esModule?e:{default:e}}n.default=(0,r.default)(`v5`,80,i.default)},{"./sha1.js":534,"./v35.js":538}],541:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./regex.js`))&&r.__esModule?r:{default:r};n.default=function(e){return typeof e==`string`&&i.default.test(e)}},{"./regex.js":532}],542:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./validate.js`))&&r.__esModule?r:{default:r};n.default=function(e){if(!(0,i.default)(e))throw TypeError(`Invalid UUID`);return parseInt(e.substr(14,1),16)}},{"./validate.js":541}],543:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.CHAR=`
|
|
117
117
|
\r --�𐀀-`,n.S=` \r
|
|
118
118
|
`,n.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,n.NAME_CHAR=`-`+n.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.CHAR_RE=RegExp(`^[`+n.CHAR+`]$`,`u`),n.S_RE=RegExp(`^[`+n.S+`]+$`,`u`),n.NAME_START_CHAR_RE=RegExp(`^[`+n.NAME_START_CHAR+`]$`,`u`),n.NAME_CHAR_RE=RegExp(`^[`+n.NAME_CHAR+`]$`,`u`),n.NAME_RE=RegExp(`^[`+n.NAME_START_CHAR+`][`+n.NAME_CHAR+`]*$`,`u`),n.NMTOKEN_RE=RegExp(`^[`+n.NAME_CHAR+`]+$`,`u`);function r(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}n.S_LIST=[32,10,13,9],n.isChar=function(e){return e>=32&&e<=55295||e===10||e===13||e===9||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isS=function(e){return e===32||e===10||e===13||e===9},n.isNameStartChar=r,n.isNameChar=function(e){return r(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}],544:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.CHAR=`--�𐀀-`,n.RESTRICTED_CHAR=`-\b\v\f---`,n.S=` \r
|
|
119
|
-
`,n.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,n.NAME_CHAR=`-`+n.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.CHAR_RE=RegExp(`^[`+n.CHAR+`]$`,`u`),n.RESTRICTED_CHAR_RE=RegExp(`^[`+n.RESTRICTED_CHAR+`]$`,`u`),n.S_RE=RegExp(`^[`+n.S+`]+$`,`u`),n.NAME_START_CHAR_RE=RegExp(`^[`+n.NAME_START_CHAR+`]$`,`u`),n.NAME_CHAR_RE=RegExp(`^[`+n.NAME_CHAR+`]$`,`u`),n.NAME_RE=RegExp(`^[`+n.NAME_START_CHAR+`][`+n.NAME_CHAR+`]*$`,`u`),n.NMTOKEN_RE=RegExp(`^[`+n.NAME_CHAR+`]+$`,`u`);function r(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}n.S_LIST=[32,10,13,9],n.isChar=function(e){return e>=1&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isRestrictedChar=function(e){return e>=1&&e<=8||e===11||e===12||e>=14&&e<=31||e>=127&&e<=132||e>=134&&e<=159},n.isCharAndNotRestricted=function(e){return e===9||e===10||e===13||e>31&&e<127||e===133||e>159&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isS=function(e){return e===32||e===10||e===13||e===9},n.isNameStartChar=r,n.isNameChar=function(e){return r(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}],545:[function(e,t,n){function r(e){return e>=65&&e<=90||e===95||e>=97&&e<=122||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}Object.defineProperty(n,"__esModule",{value:!0}),n.NC_NAME_START_CHAR=`A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ--⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,n.NC_NAME_CHAR=`-`+n.NC_NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.NC_NAME_START_CHAR_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`]$`,`u`),n.NC_NAME_CHAR_RE=RegExp(`^[`+n.NC_NAME_CHAR+`]$`,`u`),n.NC_NAME_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`][`+n.NC_NAME_CHAR+`]*$`,`u`),n.isNCNameStartChar=r,n.isNCNameChar=function(e){return r(e)||e===45||e===46||e>=48&&e<=57||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}]},{},[15])(15)}))})),aN=l(rN(),1),oN=l(iN()),sN=`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`,cN=`FFD9D2E9`,lN=`FF000000`,uN=`FFD9D2E9`,dN=`FFBFBFBF`,fN=`Times New Roman`,pN=`Arial`,mN={argb:`FF000000`},hN={argb:`FFFFFFFF`},gN={argb:`FFD9D2E9`},_N={style:`thin`,color:mN},vN={top:_N,left:_N,bottom:_N,right:_N};function yN(e){e.border={top:{style:`thin`,color:{argb:dN}},left:{style:`thin`,color:{argb:dN}},bottom:{style:`thin`,color:{argb:dN}},right:{style:`thin`,color:{argb:dN}}}}function bN(e,t,n,r,i=`BM-2-901-13`){let a=(()=>{let e=new Date;return`${String(e.getDate()).padStart(2,`0`)}/${String(e.getMonth()+1).padStart(2,`0`)}/${e.getFullYear()}`})();for(let e=1;e<=4;e++)t.getRow(e);t.mergeCells(`A1:C3`),t.mergeCells(`D1:F3`),t.mergeCells(`G1:H1`),t.mergeCells(`G2:H2`),t.mergeCells(`G3:H3`),t.mergeCells(`A4:F4`),t.mergeCells(`G4:H4`);let o=t.getCell(`A1`);o.alignment={horizontal:`center`,vertical:`middle`},o.border=vN;try{let n=e.addImage({base64:sN,extension:`png`});t.addImage(n,{tl:{nativeCol:0,nativeColOff:1237500,nativeRow:0,nativeRowOff:42862},ext:{width:90,height:51},editAs:`oneCell`})}catch{}let s=t.getCell(`D1`);s.value=n,s.font={bold:!0,size:18,name:fN},s.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},s.border=vN;let c=t.getCell(`G1`);c.value=`No: ${i}`,c.font={size:12,name:fN},c.alignment={vertical:`middle`},c.border={top:_N,left:_N,right:_N};let l=t.getCell(`G2`);l.value=`Version: ${r??`unknown`}`,l.font={size:12,name:fN},l.alignment={vertical:`middle`},l.border={left:_N,right:_N};let u=t.getCell(`G3`);u.value=`Issue Date: ${a}`,u.font={size:12,name:fN},u.alignment={vertical:`middle`},u.border={left:_N,right:_N,bottom:_N};let d=t.getCell(`A4`);d.value=`SUN ASTERISK VIETNAM CO., LTD`,d.font={bold:!0,size:10,name:fN},d.alignment={vertical:`middle`},d.border=vN;let f=t.getCell(`G4`);f.value=`ISO/IEC 27001:2022 & ISO 9001:2015`,f.font={bold:!0,size:10,name:fN},f.alignment={horizontal:`right`,vertical:`middle`,wrapText:!0},f.border=vN}var xN=[`#`,`Sheet name`,`Passed`,`Failed`,`Pending`,`N/A`,`Remain`,`Total`];function SN(e,t,n){let r=e.addWorksheet(`Overview`);r.columns=[{width:4},{width:6},{width:26},{width:13},{width:13},{width:13},{width:13},{width:13},{width:13}],bN(e,r,`${(t[0]?.summary.screen??``).toUpperCase()} TESTCASE`,n);let i=r.getRow(7);i.height=20,xN.forEach((e,t)=>{let n=i.getCell(2+t);n.value=e,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},n.border=vN});let a={passed:0,failed:0,pending:0,na:0,remain:0,total:0},o=(e,t,n)=>{let i=r.getRow(e);t.forEach((e,t)=>{let r=i.getCell(2+t);r.value=e,r.font={bold:n,size:10,color:mN,name:pN},r.alignment={horizontal:t<=1?`left`:`center`,vertical:`middle`},r.border=vN,n&&(r.fill={type:`pattern`,pattern:`solid`,fgColor:gN})})},s=e=>e.replace(/'/g,`''`),c=(e,t,n)=>({formula:`'${s(e)}'!${t}`,result:n}),l=8,u=l;t.forEach((e,t)=>{let n=e.summary,r=Math.max(0,n.total-n.passed-n.na);o(l,[t+1,e.sheetName,c(e.sheetName,`D7`,n.passed),c(e.sheetName,`E7`,n.failed),c(e.sheetName,`F7`,n.pending),c(e.sheetName,`G7`,n.na),c(e.sheetName,`H7`,r),c(e.sheetName,`C7`,n.total)],!1),a.passed+=n.passed,a.failed+=n.failed,a.pending+=n.pending,a.na+=n.na,a.remain+=r,a.total+=n.total,l+=1});let d=l-1,f=(e,t)=>({formula:`SUM(${e}${u}:${e}${d})`,result:t});o(l,[``,`Total`,f(`D`,a.passed),f(`E`,a.failed),f(`F`,a.pending),f(`G`,a.na),f(`H`,a.remain),f(`I`,a.total)],!0)}function CN(e,t,n,r,i,a){let o=e.addWorksheet(t,{views:[{state:`frozen`,ySplit:0,xSplit:0}]});o.columns=[{width:20},{width:12.5},{width:15.38},{width:16.25},{width:17},{width:25.5},{width:24.88},{width:50},{width:41},{width:12},{width:13.5},{width:15.88},{width:13.5},{width:16.5},{width:23},{width:29}],bN(e,o,`${n.screen.toUpperCase()} TESTCASE`,a);for(let e=5;e<=8;e++)o.getRow(e);for(let[e,t]of Object.entries({C:`Total TCs`,D:`Passed`,E:`Failed`,F:`Pending`,G:`N/A`,H:`Remaining`})){let n=o.getCell(`${e}6`);n.value=t,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN}let s=1e4,c={C:{formula:`COUNTA(A14:A${s})`,result:n.total},D:{formula:`COUNTIF(L14:L${s},"Passed")`,result:n.passed},E:{formula:`COUNTIF(L14:L${s},"Failed")`,result:n.failed},F:{formula:`COUNTIF(L14:L${s},"Pending")`,result:n.pending},G:{formula:`COUNTIF(L14:L${s},"N/A")`,result:n.na},H:{formula:`C7-D7-G7`,result:n.failed+n.pending}};for(let[e,t]of Object.entries(c)){let n=o.getCell(`${e}7`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,e===`H`&&(n.numFmt=`#,##0`)}let l=o.getCell(`C8`);l.font={size:10,color:mN,name:pN},l.fill={type:`pattern`,pattern:`solid`,fgColor:hN},l.alignment={horizontal:`center`,vertical:`top`},l.border=vN;let u={D:{formula:`IFERROR(D7/(C7-G7),0)`,result:n.passed/Math.max(1,n.total-n.na)},E:{formula:`IFERROR(E7/(C7-G7),0)`,result:n.failed/Math.max(1,n.total-n.na)},F:{formula:`IFERROR(F7/(C7-G7),0)`,result:n.pending/Math.max(1,n.total-n.na)},G:{formula:`IFERROR(G7/(C7-G7),0)`,result:n.na/Math.max(1,n.total-n.na)},H:{formula:`IFERROR(H7/(C7-G7),0)`,result:(n.failed+n.pending)/Math.max(1,n.total-n.na)}};for(let[e,t]of Object.entries(u)){let n=o.getCell(`${e}8`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,n.numFmt=`0%`}for(;o.rowCount<9;)o.addRow([]);let d=o.addRow([`Spec/Design link:`,i]);d.getCell(1).font={bold:!0},d.getCell(2).font={color:{argb:`FF1F4E78`},underline:!0},o.addRow([]);let f=o.addRow([`*: Mandatory`]);f.getCell(1).font={italic:!0,color:{argb:`FF808080`}};let p=o.addRow([`TC ID*`,`Screen/Function`,`Big item`,`Medium item`,`Test Object`,`Pre-condition`,`Test Data`,`Steps*`,`Expected results*`,`Priority`,`Testcase type`,`Test Result*`,`Executed Date*`,`Test Executor*`,`Test Environment`,`Note
|
|
119
|
+
`,n.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,n.NAME_CHAR=`-`+n.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.CHAR_RE=RegExp(`^[`+n.CHAR+`]$`,`u`),n.RESTRICTED_CHAR_RE=RegExp(`^[`+n.RESTRICTED_CHAR+`]$`,`u`),n.S_RE=RegExp(`^[`+n.S+`]+$`,`u`),n.NAME_START_CHAR_RE=RegExp(`^[`+n.NAME_START_CHAR+`]$`,`u`),n.NAME_CHAR_RE=RegExp(`^[`+n.NAME_CHAR+`]$`,`u`),n.NAME_RE=RegExp(`^[`+n.NAME_START_CHAR+`][`+n.NAME_CHAR+`]*$`,`u`),n.NMTOKEN_RE=RegExp(`^[`+n.NAME_CHAR+`]+$`,`u`);function r(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}n.S_LIST=[32,10,13,9],n.isChar=function(e){return e>=1&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isRestrictedChar=function(e){return e>=1&&e<=8||e===11||e===12||e>=14&&e<=31||e>=127&&e<=132||e>=134&&e<=159},n.isCharAndNotRestricted=function(e){return e===9||e===10||e===13||e>31&&e<127||e===133||e>159&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isS=function(e){return e===32||e===10||e===13||e===9},n.isNameStartChar=r,n.isNameChar=function(e){return r(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}],545:[function(e,t,n){function r(e){return e>=65&&e<=90||e===95||e>=97&&e<=122||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}Object.defineProperty(n,"__esModule",{value:!0}),n.NC_NAME_START_CHAR=`A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ--⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-`,n.NC_NAME_CHAR=`-`+n.NC_NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.NC_NAME_START_CHAR_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`]$`,`u`),n.NC_NAME_CHAR_RE=RegExp(`^[`+n.NC_NAME_CHAR+`]$`,`u`),n.NC_NAME_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`][`+n.NC_NAME_CHAR+`]*$`,`u`),n.isNCNameStartChar=r,n.isNCNameChar=function(e){return r(e)||e===45||e===46||e>=48&&e<=57||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}]},{},[15])(15)}))})),aN=l(rN(),1),oN=l(iN()),sN=`iVBORw0KGgoAAAANSUhEUgAAAlgAAAFWCAIAAAA65nRmAAAdgklEQVR4Xu3deZzU9P3H8Qri/fNovY9fVVhEQJFT1msED6SASLceAyJYBa2KooBWtIKiUq0WtVSqrVoFpB4VtIoiVgWsFxYRi4Igh6uCKIfIcu7y/eVb/OHyyU4mk2Rmk/m8no/3HwqTb5Jl8n1PZmeSHxkAABT7kfwDAAA0oQgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAgBUowgBAKpRhAAA1ShCAIBqFCEAQDWKEACgGkUIAFCNIgQAqEYRAkA469eZuwab0oPM4T/6PqcfacaOMps3y0cilihCAAhh00Zz7ok/VGD1DO0nH4xYoggBIIRH7pH9Vz1vvy4fj/ihCAEghLNay/KrnhsukY9H/FCEABBUVZVpvLMsv+opK5WLIH4oQgAIqnyhbD6RY/aUiyB+KEIACGrys7L53Fn6uVwKMUMRAkBQI2+VtefOlBflUogZihCeVq8yy5bY93/mfWQ+mmn/w8nyZaZyk3wkoNCV58nac+fBO+VSiBmKEP/vswVm8gQzcpg9tsvamhN/ao7YQR7S1dPix+aUhqZHezO4rz3UX3mOt4CQVC8+bS44zZx0qP0I6P23m4o18gGZdGgijwt3BvSUS2Xy1ZdmWH/TtZXp3NwM7GVmvy8fgPygCHVb+oV58iFzdQ/T9gB59AZLm/3MRZ3MwyPsMVxVJVcHxNBt18incbsG5sP35MPcNm4wJdvLZd3p1EwuWKOX/m4/WVN9wYb1zIQx8mHIA4pQpVUrzLgHTPd2pv528qCNMMfub79ENXWSvfQGEE93XCeft1tyxA7mgTuyvJj7aKZcqsY4Q3n/KsE5AXWOFPeCThrUoQsLgCJUZsFcc9Nlpsku8njLa1rtY24fYOZ/LDcGqF3PPyGfqyLpk82ScrnUVuNHy8dnyrzZctmtZk23v2JwL7I1zknn7BlyKUSKIlRj8Xxzxdn5PQXMmh7t7SfouBIxYqKsVD5F3TlmT/P83+SCW/z2WvngTKlxhMpK88fbfL25Oqi3XBaRoggV+HaluflK+/sG9wFWK+l4lJn2stxIoPDE7+Q8MqCn+e5bufiFHeXDMuXuG+Sy5QvNOSfIh2XKmS3l4ogURVjsXn3elB4oj6s4ZOJTclOBAmu1j3xaeuSkQ817b2yz+HEHy8dkSt8zt1lw/Ghz9O7yMR5Jp7ZZHFGjCItXxRr7jor7oIpJWvzErK2Q2wwU0mVl8mnpnQZ17Lndlg9/fbtS/q1HnBLdwlmq37nyb7Nm1PBqG43oUYRF6vNF9h1I9xEVq/AGKWrX3A9Nox3l0zJrzmptP3T2zhT5595Zs9reksn/SeTWlB5Uw7uyiBRFWIzmzIrp26EiTz8itxwosEfvk09LP2m6q+ndQf6hd3718yAfVXPOQd+dKrcZUaMIi47Tgi33lodTPEMRotZt3pzDZ14Kn7tvlBuMPKAIi8vni5JxLrglFCHiYNmSmL527NqKi1EUBkVYRNZW2Is5uQ+n2IYiRExMniCfnLWexjubT+fI7UR+UIRFZHBfeSzFPBQh4uP6i+Xzs3Yz5n65hcgbirBYTJ0kD6T4hyJEfFR8Z06uL5+itZULO3IBpkKiCIvCxg0xOob9hyJErMx405TUlc/Swqfl3ubrpXLbkE8UYVF49A/yWEpEKELEze9/I5+lhc/kZ+VWIc8owuSr3GSOP0QeS4kIRYi4cY6mbm3kE7WQuf5iuUnIP4ow+V76uzyWkhKKEDG08BP7fXn307UAObm+/VUlCo4iTL6+XeXhlJRQhIinx/8kn6sFSEld+0tK1AaKMOE2rM/jXXYb1jOnHmH6dDEDe5mhV5jhg+wVh2+5yt7U6eoepvcZpksL03wvuZT/UISIp1UrzM+Olk/XfKd/dy5DX1sowoR7Y7I8nEKm/namezvz4J3m4w/s70v8WL3KzHjLjB1lBvexxekeM1NeHi+HAgpv00b7bB8/2t5o98KOQa6LHVWco69dA3NpN3PPEPsrj4WfmKoqubXIA4ow4SL8kFuDOrbJyhfKVeRq2RLz1MP2PPLIneQqqsf525XL5bJAAXz5mb1P56jh9iTsjKa+7hFfW2myi73ZxXW/NA+PMG+9alZ8LfcFUaAIE8558eg+eAKk9EB7Vhct50zROU08s6Vc15ZwizUU0tRJ9nVeWVvTbA/5VExW2uxn0iebYf3NB+/KfURQFGHCnX6kPE4CxDm0Fs2TI0do+jR7h27njHPL6pyZ6KHfy8cAebJpo+l3jnzOF0dG3CR3FoFQhAnXsJ48NgJk8gQ5bD5885V9Vf72a3xAHAV1383yCV9M4RftUaAIk2zjBnlUBMhpjeSwQNGoqorpLZaiSllbucvIHUWYZCuXy6MiQG64RA4LFI2lX8gnfJGlZHu5y8gdRZhk5QvlUREg9wyRwwK5qqw0s2eYv/3Z3HaNueQse5rSroE58ac2qcPtbTLLSk2/c82dv7aP+c+//X4zJ7xIjpGYB6HxQ0yy5cvkIREgN14qh02u+R+b116wvzXJmikvmSXlcvHIzf3QfkzfvXZ3pk6yXzvJny8W2112r9ed1yeaBXPl4pl896155jHbfEfvLp9X3mm6q+nR3jx6nz1jyytnx91rL7IgNH6ISbZmtTwkAqRrKzlsEs2ZZS9z494771zUKV/1M+Mtc3pjuTrv1N/OnjOtWiGHCslpml6ny3Vlzc+Pta8qPDh/e/3FEVzVyNlrZ/OmvSzHj8rGDabRjnKlxZS2B8hdRu4owoSL5FOjTosk2ueLgl/p7bRGpmKNHDAk5+cZuCG6tYnybcPVq+xblO61+EmrfWo+aXb+8JrzbYG5FwmTzs3tF8bzwdla9+qKJsMHyf1F7ijChAs8zVXPeSfZ3/Ek1+A+co9yyoO/kwOG5JxoutfiP08+JAcMbOQwOXhOGdxXDjh2lDnqf+TDIkz/7vZrNtFyBozkMIlhnJdNfBkpChRhwgV416vGOFPe5s1y8KRoXyJ3J6f0aC8HDMN5SRHykl1XnC3HDOwXx8nBc8pxB/8w1NqKAn0tvc1+0Z8afrvSnjmdXF+uK6FxTsdPPcLcO9SsWyv3FIFQhAn322vlQRI4fc+076Ql0Yk/lfuSUzo1kwOG4cy57lXklHRKjhlY6jA5eE5ptsf34zhPjLJS+bf5i/NK4om/bLMjUXHOnz58z9725NarTc9TTet95arjmdKD7M1enIN9/Ggz+32zfp3cL4RDESbc5GflMRMmxx9iP+WYOBRhJiF/MluKcMN6c84J8q8KkDH3y93Jh2++Mv96xV7zb1Bve13cxjvLzSh8mu5qv38yuI/9VO3br0X/+Sm4UIQJt3L5D9fwjCrplHn7dbmiOAs53VOEmbKlCEP+CjZMnBOgAqusNJ/OMROfMh2ayI3Jd5xz7pfHm88+TfAvKRKLIky+nqfKIyqS9O4Q/f0o8iTkdE8RZopThK+9IP+wkGlYz8x8R+5UAbw7NfrXl1njnIx6f2UFeUMRJt+TD8kjKsJc2NG88lzcP1MacrqnCDOl6W7R3N4kTJxdKPAHI1evCvtzC5wuLey9MlBwFGHyOdNE4G/R+UzbA8xdg+2bNvEUctqiCGOem6+U+5VXV6XlBhQyd/5abg/yjyIsCk5LuY+ofKRHe/Ps2Nh9aC3kdE8RxjwN6phZ0+Wu5cmEMXLtBY6zs9Onya1CnlGERWHlN+aYPeURlb84J6BD+8XoejQhp3uKMP7p3UHuWj6UL8z5oqn5yEmH2ou4ooAowmLx6H3ycCpAurWxNxNYs1puTIGFnO4pwkQk3x/dqqwMe/2BCDOwl9w85BNFWCwqN9kLJbuPqAKk6W7mul/au/DUlpDTPUWYiPQ7R+5dtEJeji7yTHxKbiHyhiIsIovn5/c6kFlTVmqee9xe77/AQk73FGEicsQOefxquXO6WVJXrrF20+LHZunncjuRHxRhcZn0TPS3Bcg1pQfZy1gX8iPvIad7ijApeWyk3MFIOM/VeF6G9ILT+HJ9YVCERecvd8vDqVbSbA9z9422FQog5HRPESYlTjHkw6DeckXxyV/vlVuLPKAIi5HTQO4jqlbi1OHIYXk/Oww53VOEgdN8L3tho9/8yj7l7hlihlxu/7fprvJhUaXRjtHfb+H5J+RafOa4g+WfeCfXx2+Js8sLP5HbjKhRhEVq1HB5RNViWu9rP1xaVSU3Miohp3uKMNc4VXfLVeb9t2v+N924wfzzH/YLD+4Fw2fqJLm6MMoX2tdq7rV4p9U+dgef+Iv8c480rGdfDg69Qv65n/zyZ3KzETWKsHhNGGNfTrqPq9pKlxZ26syHkNM9Reg/JXXNsP5+3/GePs2c3liOEDIjh8m1hHHleXL8rLmo0/e3Dp75jvwrj2x9jr0+0Ry7v/zbrHljcrWNRvQowqLmHKvB3pDJUxrUsfeBW1shtzOkkNM9RegzpQfmfNGTdWvNgJ5ynDC5rEyuIrBNG+0nUd2ryJTGO9s7Q2399ErFmhw+mHbN+T+sd/kye+9P92M8cuOlPyyOPKAIi92qFabfufK4qt20L7E3F41QyOmeIvSTk+ubLxbL8f1wmsN59eMeMFiczYiKszvu8TOlc/Mabg3h/7OmD9whlx33QA6/TL20m1wckaIIdfjHONNmP3l01WIa7Wge/5PcyMBCTvcUYda0+In9lmpgThf27y7HDJaSujX/YjIA54zwyJ3k+O40qGPuuK7mm0JccpZ8cKa8PlEu61gw13RtJR9ZY4YPlMsiUhShGqtX2U/3xepbw0P7RXODp5DTPUWYNa88J0fOVcV39p0A98gB8tWXcvDAsn5x4vhDvG5SPeIm+fhMWVIul93C6de7Bme592H97SJ+BwUuFKEy8z82fbvKI60Wc2m3CK5EE3K6pwi9E9X7clMnyZGD5YN35ciBrVphzmgqx9+aK8/L8rGgiU/JRWrMMXvKBYXp07z+pe67WT4eUaMIVZrxlunTRR5vtRVnugl5XugxifgJReiduR/KYQM790Q5eIC8+rwcNozly2rowqa7mmcek490+3SOXLDGnHeSXNDtu29r/gjrHdfJRyIPKELFPpppP8zWsJ489gqfIZfLbctJyOmeIvRI93ZyzDACf3u9el4eL4cNyfknG9zn+4+uNKhjP9Lp8zvszgs4P79l9P/0Hj/atGvw/VJtDzDjHpQPQH5QhOp9vdTcO7T2v2Xxtz/LDfMv5HRPEXok2st7rl9nv4TgXktO8XOuFoDTal8szvmm011ayM1zZ+wouZQ355BcUh7ZZ4LgA0WI/3JmgSkvmivOzu2bVREmzKWkQk73FKFH3N8ZCMk5xXSvJac8/YgcsxYN7CU3z5333pBLIWYoQmxr5XIz+o/mrNbyYC5Azj0x4LX2Q073FGGmOK+Kgv2LeLj5SrmWXBOrIvRzjXtuNx97FCEymDfbDB9kf1HhPrDzl2C//gk53VOEmXJaIzlgeOGvghurIpz2stw8EeefALFHEcJTZaV57QX78QHvrzpFFaeTAvxqJOR0TxFmStdWcsDwHh4h15JrYlWEX34mN0+k9xlyEcQPRQh/nAN+xE2FOEEMcH3hkNM9RZgp6ZQcMLwiK0LH0bvLLaye2wfIxyN+KELkonKTefFpU1Yqj/YIc+V5cqVZhZzuKcJMSafkgOEVXxF6X8v3zX/KxyN+KEIEMn2a/Uq+/6vv+8+RO+V889WQ0z1FmCnplBwwvOIrwgVzM54UOscIkoAiRAjzZtvrb7mP/5CZ8qJckbeQ0z1FmCnplBwwvOIrQsd//m06NNlmI0vqmusvjv6OY8gPihChvfeG6XiUnK3C5LZr5Cq8hZzuKcJMSafkgOEVZRGa/95hY84se/m3l8ebf71ir9yG5KAIEYX167JfyN9//FybsbqQ0z1FmCnplBwwvGItQiQZRYiIOK+Ib7lKzlnBcvTucnBvIad7ijBT0ik5YHgUIeKHIkR0qqpMz1PltBUsy5bIwT2EnO4pwkxJp+SA4VGEiB+KEJFaNC+ae/9++J4c2UPI6Z4izJR0Sg4YHkWI+KEIEbUrzpYzV4DkdM+5kNN9tEX49VI5fq5Jp+SYgYX8yaRTcsDwKELED0WIqI0fLWeuAHnmUTmsh5DT/SkN5YBhLJ4vx8816ZQcM7CQP5l0Sg4YHkWI+KEIEbWPP5AzV4DkNNmFnO5LD5QDhvHOFDl+rkmn5JiBhfzJpFNywPAoQsQPRYiolS+UM1eAONOlfyGn+5K6Qa70ncm4B+T4uSadkmMGFvInk07JAcOjCBE/FCGi9sl/5MwVIE89LIf1cNKhcvFc8+kcOWZg114oB8816ZQcMzCKEPCBIkw+5wzsvTfMF4vln9eWZ8fKmStAXnhSDuuhUzO5eK4ZP1qOGYxzZnns/nLwXJNOyWEDowgBHyjCJJv7oSlr+8ME4fz39GnyMYXXp4ucuQLktRfksB7ObCkXzzXXnC/HDCbrbVr9JJ2SwwZGEQI+UISJNf/jmq95f1mZ+exT+eCCmfGW3J5g+WimHNnDhR3l4rmm6W6m4js5bAC9O8iRA8R5QRMVihDwgSJMLI+7oDWsZ698v/ATuUi+LV9mUofLjQmWnO7ENLivXDxAHvq9HDZXkZwOOunQRI4cGEUI+EARJtYxe8oJQqT+dva77e9OtVcBLYAl5eaMpnIbguWE/5WDe/vDLXKEAGm+l/nmKzmyf6tW2M12DxsgzfaQgwdGEQI+UISJ5Z4gMqV9iRk13BZV/jz/hGm9r1xv4PTtKsf3NmGMHCFYep9hKivl4H5s3GDOP0WOFiZffSlXEQxFCPhAESaWe4LIms7NzT1DzKzpAad7t6oqM3mCKSuVKwqZR/8gV+Qtki9sbEn/7qZykxzf27crI27Bw6Ob6ylCwAeKMLHcE4T/NN3N3iZixE22xhbMzXnqX7XCvPKcGXK5aXuAHDmSzPtIrtGb0+tH7iQHCZzzTrLfSPHprVcj+7Vo9XQ+JpoXKxQh4ANFmFjuCSJwGtYzpzUyF5xmz4eGDzQP3GFnq7Gj7IyzJc4p2r1DzQ2X2E9Fhpxbs+bk+nJP/TjnBDlOmDTe2Qzrbz+Xm4nTUlMn2bdS3ctGlcF9c36B4hbyHyudkgOGRxEifijCxHJPEMWRe4bIPfVj5DA5TiQ5paG9Usz9t9sr3Tjz77gHzN03mku7mZZ7y0fmI6nDzO0DzON/Mi/93d7UIgCKEPCBIkws9wRRBCmpa5Z+LvfUj1nT5VBFFues/c93yb3OiiIEfKAIE8s9QRRBBvaSu+lTVZU5/hA5WvHl9Ylyx71RhIAPFGFilWwvJ4ikx9mjRfPkbvo34iY5YPHlirPlXnujCAEfKMLEaraHnCCSnmH95T7m5PNF9hoC7mGLKemU3GtvFCHgA0WYWEVWhMcfYtaslvuYK4/LzhVH0im5y94oQsAHijCxiqkIG9Qxb78udzCAebOL/KQwnZK77I0iBHygCBOrmIpw1HC5d4ENuEAOXkxJp+T+eqMIAR8owsQ67mA5QSQ0A3tFeVnwld+YNvvJVRRN0im5v94oQsAHijCxLu4sJ4gk5rKyaK4lVt2LT8u11EoG9JR/Ej7plNxZbxQh4ANFmFhvTJYTROIy4ILoW3CLIZfLdRU4l3YzFWvMsfvLPw+ZdEruqTeKEPCBIkyyB39nP2bininin/rb2YuiRfiOqFC5Kb8XAvVOy73NsiV2M8aOkn8VMunUtvuZDUUI+EARJtzs9+3d+9yTRZzTZj8z5SW5I5FbW2G6t5OrLkBKtjf/euX7baiqingb0qlqe+gDRQj4QBEWhdkzzOW/SMY3B65KmxVfy+3Pk/Xr7O8g3duQvzgn6BPGbLMNzqlhyDaqnnRqm8GzCrnqdEoOGB5FiPihCIvIwk/MrVeb5nvJiSMm6dzc3r2vwDZvNiNvtdfydm9P5Gm0o3nhSbkBjkXzTOlB8sHBkk7Jwb11ayNHyCkXdZIDhjd+tFxLrpn4lBwTCIciLDprK8yTD9n788XnBPEXx9kbCeXvN4JZzXzHdGkhtyratGtg74CRSflC0/EouUiA9OkiR/Z212A5Qk4JcL+LrL5YHOoX285rmq++lGMC4VCExcuZcZyJ7OfHyqmkYGmyi30jdMabcsNqRVWVvZtg6YFyI8PHORH87bX29Ye3iu/MoN5y2Vwz+o9yWG8rvwm+y6nD7Dbnw9B+cl3+M3ygHA0IjSJUwHkF/cyj5przTet95bSSjzTd1X5+5x/j8jWNhrFxg31rrnNzuc3B0nQ3O6c7Lzj8e/s1+3HWYCfrzmavXycHzOrTOeZnR8uhsubMluazBXKoqDj/Cs7PLdcfgnMuOKx/vr5vA90oQk02bzbzP7ZN4ExDZW1N453lXBM4Lfc2PU+134iYPs1Oc/G3YK69rpvzQzhiB7kvWXP07vYzOM6PsWKNHNan8oX2ZP38U3L4J+h7plm+TI7jk3M2/M4Uezb58Ijscc6bZ7xViPexnRcQzs/QvQE15rnHzZJyOQIQEYpQMWey+/Iz+wGWcQ/aN/cG9rInK11b2RtBNNtDXsu0yS72T9oeYE4/0s7gV/cwwweZv95r3vxn8Ak6Djast2/ePjbS3D7A1ttZrc3pje2HLVv8xH7NI3WY6dTMnH28/VCu84CnHzEfzbS9EpXKTWbOLPvpD6cX7xlibrnK/Poi+w9xwyX2v393ve2AZ8eGuk0jgGwoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoBpFCABQjSIEAKhGEQIAVKMIAQCqUYQAANUoQgCAahQhAEA1ihAAoNr/AYmONsW7vT/nAAAAAElFTkSuQmCC`,cN=`FFD9D2E9`,lN=`FF000000`,uN=`FFD9D2E9`,dN=`FFBFBFBF`,fN=`Times New Roman`,pN=`Arial`,mN={argb:`FF000000`},hN={argb:`FFFFFFFF`},gN={argb:`FFD9D2E9`},_N={style:`thin`,color:mN},vN={top:_N,left:_N,bottom:_N,right:_N};function yN(e){e.border={top:{style:`thin`,color:{argb:dN}},left:{style:`thin`,color:{argb:dN}},bottom:{style:`thin`,color:{argb:dN}},right:{style:`thin`,color:{argb:dN}}}}function bN(e,t,n,r,i=`BM-2-901-13`){let a=(()=>{let e=new Date;return`${String(e.getDate()).padStart(2,`0`)}/${String(e.getMonth()+1).padStart(2,`0`)}/${e.getFullYear()}`})();for(let e=1;e<=4;e++)t.getRow(e);t.mergeCells(`A1:C3`),t.mergeCells(`D1:F3`),t.mergeCells(`G1:H1`),t.mergeCells(`G2:H2`),t.mergeCells(`G3:H3`),t.mergeCells(`A4:F4`),t.mergeCells(`G4:H4`);let o=t.getCell(`A1`);o.alignment={horizontal:`center`,vertical:`middle`},o.border=vN;try{let n=e.addImage({base64:sN,extension:`png`});t.addImage(n,{tl:{nativeCol:0,nativeColOff:1237500,nativeRow:0,nativeRowOff:42862},ext:{width:90,height:51},editAs:`oneCell`})}catch{}let s=t.getCell(`D1`);s.value=n,s.font={bold:!0,size:18,name:fN},s.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},s.border=vN;let c=t.getCell(`G1`);c.value=`No: ${i}`,c.font={size:12,name:fN},c.alignment={vertical:`middle`},c.border={top:_N,left:_N,right:_N};let l=t.getCell(`G2`);l.value=`Version: ${r??`unknown`}`,l.font={size:12,name:fN},l.alignment={vertical:`middle`},l.border={left:_N,right:_N};let u=t.getCell(`G3`);u.value=`Issue Date: ${a}`,u.font={size:12,name:fN},u.alignment={vertical:`middle`},u.border={left:_N,right:_N,bottom:_N};let d=t.getCell(`A4`);d.value=`SUN ASTERISK VIETNAM CO., LTD`,d.font={bold:!0,size:10,name:fN},d.alignment={vertical:`middle`},d.border=vN;let f=t.getCell(`G4`);f.value=`ISO/IEC 27001:2022 & ISO 9001:2015`,f.font={bold:!0,size:10,name:fN},f.alignment={horizontal:`right`,vertical:`middle`,wrapText:!0},f.border=vN}var xN=[`#`,`Sheet name`,`Passed`,`Failed`,`Pending`,`N/A`,`Remain`,`Total`];function SN(e,t,n,r){let i=e.addWorksheet(`Overview`);i.columns=[{width:4},{width:6},{width:26},{width:13},{width:13},{width:13},{width:13},{width:13},{width:13}];let a=t[0]?.summary.screen??``;bN(e,i,r?.titleLabel??`${a.toUpperCase()} TESTCASE`,n,r?.formNo);let o=i.getRow(7);o.height=20,xN.forEach((e,t)=>{let n=o.getCell(2+t);n.value=e,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},n.border=vN});let s={passed:0,failed:0,pending:0,na:0,remain:0,total:0},c=(e,t,n)=>{let r=i.getRow(e);t.forEach((e,t)=>{let i=r.getCell(2+t);i.value=e,i.font={bold:n,size:10,color:mN,name:pN},i.alignment={horizontal:t<=1?`left`:`center`,vertical:`middle`},i.border=vN,n&&(i.fill={type:`pattern`,pattern:`solid`,fgColor:gN})})},l=e=>e.replace(/'/g,`''`),u=(e,t,n)=>({formula:`'${l(e)}'!${t}`,result:n}),d=8,f=d;t.forEach((e,t)=>{let n=e.summary,r=Math.max(0,n.total-n.passed-n.na);c(d,[t+1,e.sheetName,u(e.sheetName,`D7`,n.passed),u(e.sheetName,`E7`,n.failed),u(e.sheetName,`F7`,n.pending),u(e.sheetName,`G7`,n.na),u(e.sheetName,`H7`,r),u(e.sheetName,`C7`,n.total)],!1),s.passed+=n.passed,s.failed+=n.failed,s.pending+=n.pending,s.na+=n.na,s.remain+=r,s.total+=n.total,d+=1});let p=d-1,m=(e,t)=>({formula:`SUM(${e}${f}:${e}${p})`,result:t});c(d,[``,`Total`,m(`D`,s.passed),m(`E`,s.failed),m(`F`,s.pending),m(`G`,s.na),m(`H`,s.remain),m(`I`,s.total)],!0)}function CN(e,t,n,r,i,a){let o=e.addWorksheet(t,{views:[{state:`frozen`,ySplit:0,xSplit:0}]});o.columns=[{width:20},{width:12.5},{width:15.38},{width:16.25},{width:17},{width:25.5},{width:24.88},{width:50},{width:41},{width:12},{width:13.5},{width:15.88},{width:13.5},{width:16.5},{width:23},{width:29}],bN(e,o,`${n.screen.toUpperCase()} TESTCASE`,a);for(let e=5;e<=8;e++)o.getRow(e);for(let[e,t]of Object.entries({C:`Total TCs`,D:`Passed`,E:`Failed`,F:`Pending`,G:`N/A`,H:`Remaining`})){let n=o.getCell(`${e}6`);n.value=t,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN}let s=1e4,c={C:{formula:`COUNTA(A14:A${s})`,result:n.total},D:{formula:`COUNTIF(L14:L${s},"Passed")`,result:n.passed},E:{formula:`COUNTIF(L14:L${s},"Failed")`,result:n.failed},F:{formula:`COUNTIF(L14:L${s},"Pending")`,result:n.pending},G:{formula:`COUNTIF(L14:L${s},"N/A")`,result:n.na},H:{formula:`C7-D7-G7`,result:n.failed+n.pending}};for(let[e,t]of Object.entries(c)){let n=o.getCell(`${e}7`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,e===`H`&&(n.numFmt=`#,##0`)}let l=o.getCell(`C8`);l.font={size:10,color:mN,name:pN},l.fill={type:`pattern`,pattern:`solid`,fgColor:hN},l.alignment={horizontal:`center`,vertical:`top`},l.border=vN;let u={D:{formula:`IFERROR(D7/(C7-G7),0)`,result:n.passed/Math.max(1,n.total-n.na)},E:{formula:`IFERROR(E7/(C7-G7),0)`,result:n.failed/Math.max(1,n.total-n.na)},F:{formula:`IFERROR(F7/(C7-G7),0)`,result:n.pending/Math.max(1,n.total-n.na)},G:{formula:`IFERROR(G7/(C7-G7),0)`,result:n.na/Math.max(1,n.total-n.na)},H:{formula:`IFERROR(H7/(C7-G7),0)`,result:(n.failed+n.pending)/Math.max(1,n.total-n.na)}};for(let[e,t]of Object.entries(u)){let n=o.getCell(`${e}8`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,n.numFmt=`0%`}for(;o.rowCount<9;)o.addRow([]);let d=o.addRow([`Spec/Design link:`,i]);d.getCell(1).font={bold:!0},d.getCell(2).font={color:{argb:`FF1F4E78`},underline:!0},o.addRow([]);let f=o.addRow([`*: Mandatory`]);f.getCell(1).font={italic:!0,color:{argb:`FF808080`}};let p=o.addRow([`TC ID*`,`Screen/Function`,`Big item`,`Medium item`,`Test Object`,`Pre-condition`,`Test Data`,`Steps*`,`Expected results*`,`Priority`,`Testcase type`,`Test Result*`,`Executed Date*`,`Test Executor*`,`Test Environment`,`Note
|
|
120
120
|
(Test evidence, DefectID, Actual result)`]);p.height=38,p.eachCell(e=>{e.font={bold:!0,color:{argb:lN}},e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:cN}},e.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},yN(e)}),o.views=[{state:`normal`}];let m=[`Basic Flow`,`Alternate Flow`,`Exception Flow`,`Accessing`,`GUI`,`Function`],h=new Map;for(let e of r){let t=h.get(e.category2)||[];t.push(e),h.set(e.category2,t)}let g=new Set;function _(e,t){let n=o.addRow([]);n.getCell(2).value=e,n.getCell(2).font={bold:!0},n.eachCell({includeEmpty:!1},e=>{e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:uN}}});for(let e=1;e<=16;e++){let t=n.getCell(e);t.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:uN}},yN(t)}for(let e of t){let t=o.addRow([e.tcId,``,``,``,e.category1,e.precondition,e.testData,e.steps,e.expectedResults,e.priority,e.testcaseType,e.testResult,e.executedDate,e.testExecutor,e.testEnvironment,e.note]);t.alignment={vertical:`top`,wrapText:!0},t.eachCell({includeEmpty:!0},(e,t)=>{if(yN(e),t===1&&(e.font={bold:!0}),t===12){let t=String(e.value||``);t===`Passed`?e.font={color:{argb:`FF107C41`},bold:!0}:t===`Failed`?e.font={color:{argb:`FFC00000`},bold:!0}:t===`Pending`?e.font={color:{argb:`FF996D00`},bold:!0}:t===`N/A`&&(e.font={color:{argb:`FF808080`}})}})}}for(let e of m){let t=h.get(e);!t||t.length===0||(g.add(e),_(e,t))}for(let[e,t]of h.entries())g.has(e)||_(e,t);o.autoFilter={from:{row:p.number,column:1},to:{row:o.rowCount,column:16}},o.sheetProtection={sheet:!0,objects:!1,scenarios:!1}}var wN=`FF2E5984`,TN=`FFFFFFFF`;function EN(e,t){let n=e.addWorksheet(`API detail`),r=`Arial`;n.columns=[{header:`Endpoint`,width:35},{header:`Method`,width:10},{header:`Auth / Datasource`,width:22},{header:`Request shape`,width:40},{header:`Expected-status matrix`,width:30},{header:`Flow steps`,width:40},{header:`Concurrency invariant`,width:35}];let i=n.getRow(1);i.height=30,i.eachCell(e=>{e.font={bold:!0,color:{argb:TN},name:r},e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:wN}},e.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},yN(e)}),n.views=[{state:`frozen`,ySplit:1}];for(let e of t){let t=n.addRow([e.endpoint,e.method,e.authDatasource,e.requestShape,e.expectedStatusMatrix,e.flowSteps,e.concurrencyInvariant]);t.alignment={vertical:`top`,wrapText:!0},t.eachCell({includeEmpty:!0},e=>{yN(e),e.font={name:r}})}n.autoFilter={from:{row:1,column:1},to:{row:n.rowCount,column:7}}}function DN(e,t){if(e.length===0)throw Error(`renderXlsxMultiSheet requires at least one locale sheet`);let n=new oN.default.Workbook;n.creator=`sungen delivery`,n.created=new Date,SN(n,e,t?.sungenVersion);for(let r of e)CN(n,r.sheetName,r.summary,r.rows,r.specLink,t?.sungenVersion);return n}function ON(e){let t=e.features??[],n=e=>e.platform?`${e.featureBaseName}.${e.platform}`:e.featureBaseName;if(t.length>1)return t.map(t=>({basename:n(t),featureName:t.featureName,specLink:t.specLink??e.specLink,summary:t.summary,scenarios:t.scenarios,locales:t.locales,apiDetail:t.apiDetail}));let r=t[0];return[{basename:r?n(r):e.name,featureName:r?.featureName??e.featureName,specLink:r?.specLink??e.specLink,summary:r?.summary??e.summary,scenarios:r?.scenarios??e.scenarios,locales:r?.locales,apiDetail:r?.apiDetail}]}var kN=420*60*1e3;function AN(e,t){let n=IN(e,t.screens),r=VN();for(let t of n)for(let n of ON(t)){let t=n.locales&&n.locales.length>=2?n.locales.map(e=>({locale:e.locale,summary:e.summary,scenarios:e.scenarios})):[{locale:``,summary:n.summary,scenarios:n.scenarios}];for(let i of t){let t=jN(n,e.environment.sungenVersion,i.summary,i.scenarios),a=i.locale?`.${i.locale}`:``;WN(`${n.basename}-testcases${a}_${r}.csv`,t,`text/csv;charset=utf-8`)}}}function jN(e,t,n,r){let i=BN(),a=n??e.summary,o=r??e.scenarios,s=a.total||1,c=e=>`${Math.round(e/s*100)}%`,l=`${e.basename.toUpperCase()} TESTCASE`,u=e.specLink??``,d=[];d.push(UN([``,``,``,l,``,``,`No: BM-2-901-13`,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,`Version: ${t}`,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,`Issue Date: ${i}`,``,``,``,``,``,``,``,``,``])),d.push(UN([`SUN ASTERISK VIETNAM CO., LTD`,``,``,``,``,``,`ISO/IEC 27001:2022 & ISO 9001:2015`,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,`Total TCs`,`Passed`,`Failed`,`Pending`,`N/A`,`Remaining`,``,``,``,``,``,``,``,``])),d.push(UN([``,``,a.total,a.passed,a.failed,a.pending,a.na,a.pending+a.na,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,c(a.passed),c(a.failed),c(a.pending),c(a.na),c(a.pending+a.na),``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([`Spec/Design link:`,u,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([`*: Mandatory`,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([`TC ID*`,`Screen/Function`,`Big item`,`Medium item`,`Test Object`,`Pre-condition`,`Test Data`,`Steps*`,`Expected results*`,`Priority`,`Testcase type`,`Test Result*`,`Executed Date*`,`Test Executor*`,`Test Environment`,`Note
|
|
121
121
|
(Test evidence, DefectID, Actual result)`]));let f=[`Accessing`,`GUI`,`Function`],p=new Map;for(let e of o){let t=p.get(e.category2)||[];t.push(e),p.set(e.category2,t)}let m=new Set,h=(e,t)=>{d.push(UN([``,e,``,``,``,``,``,``,``,``,``,``,``,``,``,``]));for(let e of t)d.push(UN(LN(e)))};for(let e of f){let t=p.get(e);!t||t.length===0||(m.add(e),h(e,t))}for(let[e,t]of p.entries())m.has(e)||h(e,t);return``+d.join(`
|
|
122
122
|
`)+`
|
|
@@ -125,7 +125,7 @@ export function extractPriority(tags: string[]): string {
|
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
127
|
* Extract testcase type from scenario tags.
|
|
128
|
-
* Matches the bare `@manual` AND the reason-coded form `@manual:M1`..`@manual:
|
|
128
|
+
* Matches the bare `@manual` AND the reason-coded form `@manual:M1`..`@manual:M11`
|
|
129
129
|
* (the canonical way to tag manual scenarios). Without the `startsWith` check a
|
|
130
130
|
* `@manual:M1` scenario was misclassified as `Auto` → rendered "Not compiled"/"N/A"
|
|
131
131
|
* in the report instead of "Manual"/"Pending".
|
|
@@ -168,8 +168,16 @@ export function deriveVariants(inputs: Pick<BuildInputs, 'feature' | 'merged' |
|
|
|
168
168
|
// Values the scenario itself produces during the run — captured from the page
|
|
169
169
|
// or bound by a capability precondition. The compiler registers these as
|
|
170
170
|
// "captured" and skips YAML validation; the matrix does the same.
|
|
171
|
+
// Background steps count too: scenario-merger keeps them OUT of resolvedSteps
|
|
172
|
+
// (they render as Pre-condition, not Steps), so a Background `remember … as
|
|
173
|
+
// {{v}}` registered nowhere — its token then survived into every scenario's
|
|
174
|
+
// shared precondition cell and Gate D blocked the entire unit (#684).
|
|
171
175
|
const runtimeVars = runtimeVarsOf(
|
|
172
|
-
[
|
|
176
|
+
[
|
|
177
|
+
...inputs.feature.backgroundOrderedSteps.map((st) => st.text),
|
|
178
|
+
...m.resolvedSteps.map((st) => st.text),
|
|
179
|
+
...m.resolvedExpected.map((st) => st.text),
|
|
180
|
+
],
|
|
173
181
|
tags,
|
|
174
182
|
);
|
|
175
183
|
|
|
@@ -500,6 +508,10 @@ export function varyingTriggerNote(dimensions: string | undefined, count: number
|
|
|
500
508
|
// before the dash is the axis name.
|
|
501
509
|
const axis = dimensions?.split('—')[0].trim();
|
|
502
510
|
const where = axis && axis.length > 0 && axis.length <= 60 ? ` by ${axis}` : '';
|
|
511
|
+
// A single variant is reachable when an item is projected onto one execution
|
|
512
|
+
// mode (the Auto / Manual split) and only one of its variants lands there —
|
|
513
|
+
// nothing "differs" any more, so point at the one row that carries the steps.
|
|
514
|
+
if (count === 1) return `The action is the variant's own — see the row below.`;
|
|
503
515
|
return `The action differs${where} — run each of the ${count} variants below with its own steps.`;
|
|
504
516
|
}
|
|
505
517
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell-text derivation shared by the XLSX and CSV matrix renderers — the
|
|
3
|
+
* parent-row summaries (mode, result, coverage) and the small formatters that
|
|
4
|
+
* turn model arrays into readable cell content.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { DeliveryItem } from './types';
|
|
8
|
+
|
|
9
|
+
/** Mode is a coverage dimension: mixed items show both counts. */
|
|
10
|
+
export function itemModeLabel(item: DeliveryItem): string {
|
|
11
|
+
if (item.mode === 'mixed') {
|
|
12
|
+
const auto = item.variants.filter((v) => v.mode === 'auto').length;
|
|
13
|
+
return `Auto ${auto} · Manual ${item.variants.length - auto}`;
|
|
14
|
+
}
|
|
15
|
+
return item.mode === 'manual' ? 'Manual' : 'Auto';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Parent roll-up label. It must NEVER be exactly one of the variant state words
|
|
20
|
+
* (`Passed`/`Failed`/`Blocked`/`Pending`/`N/A`) — the summary band counts the
|
|
21
|
+
* Result column with exact-match COUNTIF over parent AND child rows, so a parent
|
|
22
|
+
* reading plain "Pending" was counted as an extra pending variant (109 instead
|
|
23
|
+
* of 77 on st-login).
|
|
24
|
+
*/
|
|
25
|
+
export function itemResultLabel(item: DeliveryItem): string {
|
|
26
|
+
const { passed, failed, blocked, na } = item.resultCounts;
|
|
27
|
+
const eff = item.variants.length - na;
|
|
28
|
+
const suffix = na > 0 ? ` · ${na} N/A` : '';
|
|
29
|
+
if (item.result === 'na') return 'All N/A';
|
|
30
|
+
if (item.result === 'failed') return `${passed}/${eff} Passed · ${failed} Failed${suffix}`;
|
|
31
|
+
if (item.result === 'blocked') return `${passed}/${eff} Passed · ${blocked} Blocked${suffix}`;
|
|
32
|
+
return `${passed}/${eff} Passed${suffix}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Compact coverage summary for the parent row. A declared `dimensions:` digest
|
|
37
|
+
* wins ("15 variants — required ×3 · format ×9 …"); otherwise a single variant
|
|
38
|
+
* shows its condition and a group falls back to its variant REFS. Concatenating
|
|
39
|
+
* every variant's full title turned this cell into an 800-character paragraph.
|
|
40
|
+
*
|
|
41
|
+
* On a projected item (the Auto / Manual split) the count reflects the variants
|
|
42
|
+
* present in THAT sheet — a mixed item reads "1 variant" on each side, never
|
|
43
|
+
* the item's full total.
|
|
44
|
+
*/
|
|
45
|
+
export function coverageSummary(item: DeliveryItem): string {
|
|
46
|
+
const n = item.variants.length;
|
|
47
|
+
const head = `${n} variant${n === 1 ? '' : 's'}:`;
|
|
48
|
+
if (item.dimensions) return `${head} ${item.dimensions}`;
|
|
49
|
+
if (n === 1) return `${head} ${item.variants[0].condition}`;
|
|
50
|
+
return `${head} ${item.variants.map((v) => v.ref).join(' · ')}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** ISO date (2026-08-04) — unambiguous across locales (review §9). */
|
|
54
|
+
export function isoDate(startTime: string | undefined): string {
|
|
55
|
+
if (!startTime) return '';
|
|
56
|
+
const d = new Date(startTime);
|
|
57
|
+
if (isNaN(d.getTime())) return '';
|
|
58
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function numbered(lines: string[], start = 1): string {
|
|
62
|
+
if (lines.length === 0) return '';
|
|
63
|
+
if (lines.length === 1 && start === 1) return lines[0];
|
|
64
|
+
return lines.map((l, i) => `${start + i}. ${l}`).join('\n');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Expected cell = observable outcomes; the HOW moves under a separate heading. */
|
|
68
|
+
export function expectedWithVerification(oracle: string[], verification: string[]): string {
|
|
69
|
+
const expected = numbered(oracle);
|
|
70
|
+
if (verification.length === 0) return expected;
|
|
71
|
+
return `${expected}\nVerification method: ${verification.join(' ')}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** The Testcase type cell (column K) — mode plus why it is what it is. */
|
|
75
|
+
export function variantTypeLabel(v: DeliveryItem['variants'][number]): string {
|
|
76
|
+
if (v.mode === 'manual') return `Manual${v.manualReason ? ` (${v.manualReason})` : ''}`;
|
|
77
|
+
return v.mocked ? 'Auto · Mocked' : 'Auto';
|
|
78
|
+
}
|