@sun-asterisk/sungen 2.5.2 → 2.6.1
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/cli/commands/add-flow.d.ts +3 -0
- package/dist/cli/commands/add-flow.d.ts.map +1 -0
- package/dist/cli/commands/add-flow.js +27 -0
- package/dist/cli/commands/add-flow.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +95 -60
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +38 -6
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +16 -0
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +3 -0
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -2
- package/dist/generators/test-generator/adapters/playwright/templates/scenario.hbs +20 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/route-assertion.hbs +1 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-timeout.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +84 -4
- package/dist/generators/test-generator/code-generator.d.ts +2 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +105 -17
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +22 -3
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.js +8 -3
- package/dist/generators/test-generator/patterns/navigation-patterns.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +4 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +7 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +14 -0
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +1 -1
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.d.ts +3 -20
- package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.js +23 -66
- package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts +2 -6
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +18 -80
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +4 -0
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/flow-manager.d.ts +22 -0
- package/dist/orchestrator/flow-manager.d.ts.map +1 -0
- package/dist/orchestrator/flow-manager.js +251 -0
- package/dist/orchestrator/flow-manager.js.map +1 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +1 -0
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +3 -1
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-flow.md +88 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +11 -8
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +8 -6
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +15 -11
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +41 -10
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +12 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-delivery.md +19 -18
- package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +12 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +122 -10
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +31 -3
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +45 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +92 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +30 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +86 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +13 -10
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +16 -15
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +9 -7
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +21 -17
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +40 -9
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +12 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +19 -18
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +12 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +122 -10
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +31 -3
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +45 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +93 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +30 -0
- package/dist/orchestrator/templates/playwright.config.d.ts.map +1 -1
- package/dist/orchestrator/templates/playwright.config.js +3 -1
- package/dist/orchestrator/templates/playwright.config.js.map +1 -1
- package/dist/orchestrator/templates/playwright.config.ts +4 -1
- package/dist/orchestrator/templates/specs-base.d.ts +3 -4
- package/dist/orchestrator/templates/specs-base.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-base.js +60 -91
- package/dist/orchestrator/templates/specs-base.js.map +1 -1
- package/dist/orchestrator/templates/specs-base.ts +61 -101
- package/dist/orchestrator/templates/specs-test-data.d.ts +3 -1
- package/dist/orchestrator/templates/specs-test-data.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-test-data.js +53 -2
- package/dist/orchestrator/templates/specs-test-data.js.map +1 -1
- package/dist/orchestrator/templates/specs-test-data.ts +56 -2
- package/package.json +1 -1
- package/src/cli/commands/add-flow.ts +25 -0
- package/src/cli/commands/delivery.ts +109 -58
- package/src/cli/commands/generate.ts +43 -6
- package/src/cli/index.ts +3 -1
- package/src/generators/test-generator/adapters/adapter-interface.ts +6 -1
- package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -2
- package/src/generators/test-generator/adapters/playwright/templates/scenario.hbs +20 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-accept-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-dismiss-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/alert-fill-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/alert-text-assertion.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/route-assertion.hbs +1 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-timeout.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +84 -4
- package/src/generators/test-generator/code-generator.ts +119 -20
- package/src/generators/test-generator/patterns/interaction-patterns.ts +25 -3
- package/src/generators/test-generator/patterns/navigation-patterns.ts +8 -3
- package/src/generators/test-generator/step-mapper.ts +8 -0
- package/src/generators/test-generator/template-engine.ts +5 -2
- package/src/generators/test-generator/utils/data-resolver.ts +25 -77
- package/src/generators/test-generator/utils/selector-resolver.ts +23 -109
- package/src/orchestrator/ai-rules-updater.ts +5 -0
- package/src/orchestrator/flow-manager.ts +243 -0
- package/src/orchestrator/project-initializer.ts +1 -0
- package/src/orchestrator/screen-manager.ts +3 -1
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-flow.md +88 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +11 -8
- package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +8 -6
- package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +15 -11
- package/src/orchestrator/templates/ai-instructions/claude-config.md +41 -10
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +12 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +19 -18
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +12 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +122 -10
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +31 -3
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +45 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +92 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +30 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +86 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +13 -10
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +16 -15
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +9 -7
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +21 -17
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +40 -9
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +12 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +19 -18
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +12 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +122 -10
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +31 -3
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +45 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +93 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +30 -0
- package/src/orchestrator/templates/playwright.config.ts +4 -1
- package/src/orchestrator/templates/specs-base.ts +61 -101
- package/src/orchestrator/templates/specs-test-data.ts +56 -2
- package/dist/utils/feature-finder.d.ts +0 -9
- package/dist/utils/feature-finder.d.ts.map +0 -1
- package/dist/utils/feature-finder.js +0 -67
- package/dist/utils/feature-finder.js.map +0 -1
- package/dist/utils/screen-paths.d.ts +0 -10
- package/dist/utils/screen-paths.d.ts.map +0 -1
- package/dist/utils/screen-paths.js +0 -73
- package/dist/utils/screen-paths.js.map +0 -1
- package/dist/utils/selector-loader.d.ts +0 -6
- package/dist/utils/selector-loader.d.ts.map +0 -1
- package/dist/utils/selector-loader.js +0 -20
- package/dist/utils/selector-loader.js.map +0 -1
- package/dist/utils/test-data-loader.d.ts +0 -6
- package/dist/utils/test-data-loader.d.ts.map +0 -1
- package/dist/utils/test-data-loader.js +0 -20
- package/dist/utils/test-data-loader.js.map +0 -1
- package/src/utils/feature-finder.ts +0 -33
- package/src/utils/screen-paths.ts +0 -37
- package/src/utils/selector-loader.ts +0 -23
- package/src/utils/test-data-loader.ts +0 -23
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { test as base, expect } from '@playwright/test';
|
|
2
|
-
import type { BrowserContext, Page } from '@playwright/test';
|
|
1
|
+
import { test as base, expect, type Page } from '@playwright/test';
|
|
3
2
|
|
|
4
3
|
type CleanupConfig = {
|
|
5
4
|
overlay?: boolean;
|
|
@@ -8,114 +7,75 @@ type CleanupConfig = {
|
|
|
8
7
|
storage?: boolean;
|
|
9
8
|
};
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
async function cleanupPage(page: Page, config: CleanupConfig): Promise<void> {
|
|
11
|
+
if (config.overlay) {
|
|
12
|
+
await page.keyboard.press('Escape').catch(() => {});
|
|
13
|
+
await page.locator('body').click({ position: { x: 1, y: 1 }, force: true }).catch(() => {});
|
|
14
|
+
const hasOverlay = await page.evaluate(`(() => {
|
|
15
|
+
const el = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2);
|
|
16
|
+
if (!el) return false;
|
|
17
|
+
let current = el;
|
|
18
|
+
while (current && current !== document.body) {
|
|
19
|
+
if (getComputedStyle(current).position === 'fixed') return true;
|
|
20
|
+
current = current.parentElement;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
})()`).catch(() => false);
|
|
24
|
+
if (hasOverlay) {
|
|
25
|
+
await page.keyboard.press('Escape').catch(() => {});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (config.forms) {
|
|
29
|
+
await page.evaluate(`(() => {
|
|
30
|
+
const inputSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;
|
|
31
|
+
const textareaSetter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set;
|
|
32
|
+
document.querySelectorAll('input:not([type=hidden]):not([type=submit]):not([type=checkbox]):not([type=radio])').forEach(el => {
|
|
33
|
+
inputSetter?.call(el, '');
|
|
34
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
35
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
36
|
+
});
|
|
37
|
+
document.querySelectorAll('textarea').forEach(el => {
|
|
38
|
+
textareaSetter?.call(el, '');
|
|
39
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
40
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
41
|
+
});
|
|
42
|
+
document.querySelectorAll('select').forEach(el => {
|
|
43
|
+
el.selectedIndex = 0;
|
|
44
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
45
|
+
});
|
|
46
|
+
document.querySelectorAll('input[type=checkbox]').forEach(el => {
|
|
47
|
+
if (el.checked !== el.defaultChecked) {
|
|
48
|
+
el.checked = el.defaultChecked;
|
|
49
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
document.querySelectorAll('form').forEach(f => f.reset());
|
|
53
|
+
})()`).catch(() => {});
|
|
54
|
+
}
|
|
55
|
+
if (config.scroll) {
|
|
56
|
+
await page.evaluate('window.scrollTo(0, 0)').catch(() => {});
|
|
57
|
+
}
|
|
58
|
+
if (config.storage) {
|
|
59
|
+
await page.evaluate('sessionStorage.clear()').catch(() => {});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
15
62
|
|
|
16
63
|
const test = base.extend<{
|
|
17
|
-
autoCleanup: CleanupConfig;
|
|
18
64
|
screenshotOnFailure: boolean;
|
|
19
|
-
_autoCleanup: void;
|
|
20
65
|
_autoScreenshot: void;
|
|
21
66
|
}>({
|
|
22
|
-
autoCleanup: [{}, { option: true }],
|
|
23
67
|
screenshotOnFailure: [false, { option: true }],
|
|
24
68
|
|
|
25
69
|
page: async ({ browser, storageState }, use) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
cached = { context, page };
|
|
34
|
-
contextCache.set(cacheKey, cached);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const page = cached.page;
|
|
38
|
-
|
|
39
|
-
// Patch goto once: skip navigation if already on the target path
|
|
40
|
-
if (!(page as any)[GOTO_PATCHED]) {
|
|
41
|
-
const originalGoto = page.goto.bind(page);
|
|
42
|
-
page.goto = async function (url: string, options?: any) {
|
|
43
|
-
try {
|
|
44
|
-
const currentPath = new URL(page.url()).pathname;
|
|
45
|
-
if (currentPath === url || currentPath === url + '/') {
|
|
46
|
-
const hasOverlay = await page.evaluate(`(() => {
|
|
47
|
-
const el = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2);
|
|
48
|
-
if (!el) return false;
|
|
49
|
-
let current = el;
|
|
50
|
-
while (current && current !== document.body) {
|
|
51
|
-
if (getComputedStyle(current).position === 'fixed') return true;
|
|
52
|
-
current = current.parentElement;
|
|
53
|
-
}
|
|
54
|
-
return false;
|
|
55
|
-
})()`).catch(() => true);
|
|
56
|
-
|
|
57
|
-
if (hasOverlay) {
|
|
58
|
-
return originalGoto(url, options);
|
|
59
|
-
}
|
|
60
|
-
return null as any;
|
|
61
|
-
}
|
|
62
|
-
} catch {
|
|
63
|
-
// page.url() might be about:blank on first run
|
|
64
|
-
}
|
|
65
|
-
return originalGoto(url, options);
|
|
66
|
-
};
|
|
67
|
-
(page as any)[GOTO_PATCHED] = true;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
await use(page);
|
|
71
|
-
} else {
|
|
72
|
-
// No storageState: fresh context (e.g., unauthenticated tests)
|
|
73
|
-
const context = await browser.newContext();
|
|
74
|
-
const page = await context.newPage();
|
|
75
|
-
await use(page);
|
|
76
|
-
await page.close();
|
|
77
|
-
await context.close();
|
|
78
|
-
}
|
|
70
|
+
const context = storageState
|
|
71
|
+
? await browser.newContext({ storageState })
|
|
72
|
+
: await browser.newContext();
|
|
73
|
+
const page = await context.newPage();
|
|
74
|
+
await use(page);
|
|
75
|
+
await page.close();
|
|
76
|
+
await context.close();
|
|
79
77
|
},
|
|
80
78
|
|
|
81
|
-
// Auto-cleanup fixture: runs teardown after each test based on @cleanup:* tags
|
|
82
|
-
_autoCleanup: [async ({ page, autoCleanup }, use) => {
|
|
83
|
-
await use();
|
|
84
|
-
|
|
85
|
-
if (autoCleanup.overlay) {
|
|
86
|
-
await page.keyboard.press('Escape').catch(() => {});
|
|
87
|
-
await page.locator('body').click({ position: { x: 1, y: 1 }, force: true }).catch(() => {});
|
|
88
|
-
// Dismiss persistent fixed overlays (modals, dialogs)
|
|
89
|
-
const hasOverlay = await page.evaluate(`(() => {
|
|
90
|
-
const el = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2);
|
|
91
|
-
if (!el) return false;
|
|
92
|
-
let current = el;
|
|
93
|
-
while (current && current !== document.body) {
|
|
94
|
-
if (getComputedStyle(current).position === 'fixed') return true;
|
|
95
|
-
current = current.parentElement;
|
|
96
|
-
}
|
|
97
|
-
return false;
|
|
98
|
-
})()`).catch(() => false);
|
|
99
|
-
if (hasOverlay) {
|
|
100
|
-
await page.keyboard.press('Escape').catch(() => {});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (autoCleanup.forms) {
|
|
104
|
-
await page.evaluate(`(() => {
|
|
105
|
-
document.querySelectorAll('input:not([type=hidden]):not([type=submit])').forEach(el => { el.value = ''; });
|
|
106
|
-
document.querySelectorAll('textarea').forEach(el => { el.value = ''; });
|
|
107
|
-
document.querySelectorAll('select').forEach(el => { el.selectedIndex = 0; });
|
|
108
|
-
})()`).catch(() => {});
|
|
109
|
-
}
|
|
110
|
-
if (autoCleanup.scroll) {
|
|
111
|
-
await page.evaluate('window.scrollTo(0, 0)').catch(() => {});
|
|
112
|
-
}
|
|
113
|
-
if (autoCleanup.storage) {
|
|
114
|
-
await page.evaluate('sessionStorage.clear()').catch(() => {});
|
|
115
|
-
}
|
|
116
|
-
}, { auto: true }],
|
|
117
|
-
|
|
118
|
-
// Auto-screenshot fixture: captures screenshot on test failure
|
|
119
79
|
_autoScreenshot: [async ({ page, screenshotOnFailure }, use, testInfo) => {
|
|
120
80
|
await use();
|
|
121
81
|
|
|
@@ -128,4 +88,4 @@ const test = base.extend<{
|
|
|
128
88
|
}, { auto: true }],
|
|
129
89
|
});
|
|
130
90
|
|
|
131
|
-
export { test, expect };
|
|
91
|
+
export { test, expect, cleanupPage };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import * as crypto from 'crypto';
|
|
3
4
|
import yaml from 'yaml';
|
|
4
5
|
|
|
5
6
|
export class TestDataLoader {
|
|
@@ -10,14 +11,21 @@ export class TestDataLoader {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
* Load test data for a screen/feature combination.
|
|
14
|
+
* Load test data for a screen/feature or flow/feature combination.
|
|
14
15
|
*
|
|
15
16
|
* Priority (later wins):
|
|
16
17
|
* 1. {feature}.yaml — base data
|
|
17
18
|
* 2. {feature}.{SUNGEN_ENV}.yaml — environment-specific (if SUNGEN_ENV set)
|
|
19
|
+
*
|
|
20
|
+
* Paths: screenName starting with "flows/" loads from qa/flows/, otherwise qa/screens/
|
|
18
21
|
*/
|
|
19
22
|
static load(screenName: string, featureName: string): TestDataLoader {
|
|
20
|
-
|
|
23
|
+
let baseDir: string;
|
|
24
|
+
if (screenName.startsWith('flows/')) {
|
|
25
|
+
baseDir = path.join(process.cwd(), 'qa', screenName, 'test-data');
|
|
26
|
+
} else {
|
|
27
|
+
baseDir = path.join(process.cwd(), 'qa', 'screens', screenName, 'test-data');
|
|
28
|
+
}
|
|
21
29
|
const env = process.env.SUNGEN_ENV;
|
|
22
30
|
|
|
23
31
|
let data = loadYamlSync(path.join(baseDir, `${featureName}.yaml`)) || {};
|
|
@@ -27,6 +35,8 @@ export class TestDataLoader {
|
|
|
27
35
|
if (envData) data = deepMerge(data, envData);
|
|
28
36
|
}
|
|
29
37
|
|
|
38
|
+
data = resolveDynamicVars(data);
|
|
39
|
+
|
|
30
40
|
return new TestDataLoader(data);
|
|
31
41
|
}
|
|
32
42
|
|
|
@@ -64,3 +74,47 @@ function deepMerge(base: Record<string, any>, override: Record<string, any>): Re
|
|
|
64
74
|
}
|
|
65
75
|
return result;
|
|
66
76
|
}
|
|
77
|
+
|
|
78
|
+
function resolveDynamicVars(data: Record<string, any>): Record<string, any> {
|
|
79
|
+
const ts = String(Date.now());
|
|
80
|
+
const uid = crypto.randomUUID();
|
|
81
|
+
const now = new Date();
|
|
82
|
+
const date = now.toISOString().split('T')[0];
|
|
83
|
+
const datetime = now.toISOString();
|
|
84
|
+
|
|
85
|
+
function resolveValue(value: any): any {
|
|
86
|
+
if (typeof value === 'string') {
|
|
87
|
+
return value.replace(/\{\{\$(\w+)(?::([^}]*))?\}\}/g, (match, name, args) => {
|
|
88
|
+
switch (name) {
|
|
89
|
+
case 'timestamp':
|
|
90
|
+
return ts;
|
|
91
|
+
case 'uuid':
|
|
92
|
+
return uid;
|
|
93
|
+
case 'random': {
|
|
94
|
+
const [min, max] = (args || '1:9999').split(':').map(Number);
|
|
95
|
+
return String(Math.floor(Math.random() * (max - min + 1)) + min);
|
|
96
|
+
}
|
|
97
|
+
case 'date':
|
|
98
|
+
return date;
|
|
99
|
+
case 'datetime':
|
|
100
|
+
return datetime;
|
|
101
|
+
default:
|
|
102
|
+
return match;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (Array.isArray(value)) {
|
|
107
|
+
return value.map(resolveValue);
|
|
108
|
+
}
|
|
109
|
+
if (value && typeof value === 'object') {
|
|
110
|
+
const resolved: Record<string, any> = {};
|
|
111
|
+
for (const [k, v] of Object.entries(value)) {
|
|
112
|
+
resolved[k] = resolveValue(v);
|
|
113
|
+
}
|
|
114
|
+
return resolved;
|
|
115
|
+
}
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return resolveValue(data);
|
|
120
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Find all .feature files for a specific screen.
|
|
3
|
-
*/
|
|
4
|
-
export declare function findFeatureFiles(screensRoot: string, screenName: string): string[];
|
|
5
|
-
/**
|
|
6
|
-
* Find all .feature files across all screens.
|
|
7
|
-
*/
|
|
8
|
-
export declare function findAllFeatureFiles(screensRoot: string): string[];
|
|
9
|
-
//# sourceMappingURL=feature-finder.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"feature-finder.d.ts","sourceRoot":"","sources":["../../src/utils/feature-finder.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAQlF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAYjE"}
|
|
@@ -1,67 +0,0 @@
|
|
|
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.findFeatureFiles = findFeatureFiles;
|
|
37
|
-
exports.findAllFeatureFiles = findAllFeatureFiles;
|
|
38
|
-
const fs = __importStar(require("fs"));
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const screen_paths_1 = require("./screen-paths");
|
|
41
|
-
/**
|
|
42
|
-
* Find all .feature files for a specific screen.
|
|
43
|
-
*/
|
|
44
|
-
function findFeatureFiles(screensRoot, screenName) {
|
|
45
|
-
const featuresDir = (0, screen_paths_1.getFeaturesDir)(screensRoot, screenName);
|
|
46
|
-
if (!fs.existsSync(featuresDir)) {
|
|
47
|
-
return [];
|
|
48
|
-
}
|
|
49
|
-
return fs.readdirSync(featuresDir)
|
|
50
|
-
.filter(f => f.endsWith('.feature'))
|
|
51
|
-
.map(f => path.join(featuresDir, f));
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Find all .feature files across all screens.
|
|
55
|
-
*/
|
|
56
|
-
function findAllFeatureFiles(screensRoot) {
|
|
57
|
-
if (!fs.existsSync(screensRoot)) {
|
|
58
|
-
return [];
|
|
59
|
-
}
|
|
60
|
-
const files = [];
|
|
61
|
-
const screens = fs.readdirSync(screensRoot).filter(d => fs.statSync(path.join(screensRoot, d)).isDirectory());
|
|
62
|
-
for (const screen of screens) {
|
|
63
|
-
files.push(...findFeatureFiles(screensRoot, screen));
|
|
64
|
-
}
|
|
65
|
-
return files;
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=feature-finder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"feature-finder.js","sourceRoot":"","sources":["../../src/utils/feature-finder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,4CAQC;AAKD,kDAYC;AAhCD,uCAAyB;AACzB,2CAA6B;AAC7B,iDAAgD;AAEhD;;GAEG;AACH,SAAgB,gBAAgB,CAAC,WAAmB,EAAE,UAAkB;IACtE,MAAM,WAAW,GAAG,IAAA,6BAAc,EAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,WAAmB;IACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACrD,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CACrD,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare function getScreenDir(screensRoot: string, screenName: string): string;
|
|
2
|
-
export declare function getFeaturesDir(screensRoot: string, screenName: string): string;
|
|
3
|
-
export declare function getSelectorsDir(screensRoot: string, screenName: string): string;
|
|
4
|
-
export declare function getTestDataDir(screensRoot: string, screenName: string): string;
|
|
5
|
-
export declare function getSelectorBasePath(screensRoot: string, screenName: string, featureName: string): string;
|
|
6
|
-
export declare function getSelectorOverridePath(screensRoot: string, screenName: string, featureName: string): string;
|
|
7
|
-
export declare function getTestDataBasePath(screensRoot: string, screenName: string, featureName: string): string;
|
|
8
|
-
export declare function getTestDataOverridePath(screensRoot: string, screenName: string, featureName: string): string;
|
|
9
|
-
export declare function getLiveScanPath(screensRoot: string, screenName: string, featureName: string): string;
|
|
10
|
-
//# sourceMappingURL=screen-paths.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"screen-paths.d.ts","sourceRoot":"","sources":["../../src/utils/screen-paths.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAExG;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5G;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAExG;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5G;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpG"}
|
|
@@ -1,73 +0,0 @@
|
|
|
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.getScreenDir = getScreenDir;
|
|
37
|
-
exports.getFeaturesDir = getFeaturesDir;
|
|
38
|
-
exports.getSelectorsDir = getSelectorsDir;
|
|
39
|
-
exports.getTestDataDir = getTestDataDir;
|
|
40
|
-
exports.getSelectorBasePath = getSelectorBasePath;
|
|
41
|
-
exports.getSelectorOverridePath = getSelectorOverridePath;
|
|
42
|
-
exports.getTestDataBasePath = getTestDataBasePath;
|
|
43
|
-
exports.getTestDataOverridePath = getTestDataOverridePath;
|
|
44
|
-
exports.getLiveScanPath = getLiveScanPath;
|
|
45
|
-
const path = __importStar(require("path"));
|
|
46
|
-
function getScreenDir(screensRoot, screenName) {
|
|
47
|
-
return path.join(screensRoot, screenName);
|
|
48
|
-
}
|
|
49
|
-
function getFeaturesDir(screensRoot, screenName) {
|
|
50
|
-
return path.join(screensRoot, screenName, 'features');
|
|
51
|
-
}
|
|
52
|
-
function getSelectorsDir(screensRoot, screenName) {
|
|
53
|
-
return path.join(screensRoot, screenName, 'selectors');
|
|
54
|
-
}
|
|
55
|
-
function getTestDataDir(screensRoot, screenName) {
|
|
56
|
-
return path.join(screensRoot, screenName, 'test-data');
|
|
57
|
-
}
|
|
58
|
-
function getSelectorBasePath(screensRoot, screenName, featureName) {
|
|
59
|
-
return path.join(screensRoot, screenName, 'selectors', `${featureName}.yaml`);
|
|
60
|
-
}
|
|
61
|
-
function getSelectorOverridePath(screensRoot, screenName, featureName) {
|
|
62
|
-
return path.join(screensRoot, screenName, 'selectors', `${featureName}.override.yaml`);
|
|
63
|
-
}
|
|
64
|
-
function getTestDataBasePath(screensRoot, screenName, featureName) {
|
|
65
|
-
return path.join(screensRoot, screenName, 'test-data', `${featureName}.yaml`);
|
|
66
|
-
}
|
|
67
|
-
function getTestDataOverridePath(screensRoot, screenName, featureName) {
|
|
68
|
-
return path.join(screensRoot, screenName, 'test-data', `${featureName}.override.yaml`);
|
|
69
|
-
}
|
|
70
|
-
function getLiveScanPath(screensRoot, screenName, featureName) {
|
|
71
|
-
return path.join(screensRoot, screenName, 'selectors', `${featureName}.live-scan.yaml`);
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=screen-paths.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"screen-paths.js","sourceRoot":"","sources":["../../src/utils/screen-paths.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,oCAEC;AAED,wCAEC;AAED,0CAEC;AAED,wCAEC;AAED,kDAEC;AAED,0DAEC;AAED,kDAEC;AAED,0DAEC;AAED,0CAEC;AApCD,2CAA6B;AAE7B,SAAgB,YAAY,CAAC,WAAmB,EAAE,UAAkB;IAClE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,cAAc,CAAC,WAAmB,EAAE,UAAkB;IACpE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AACxD,CAAC;AAED,SAAgB,eAAe,CAAC,WAAmB,EAAE,UAAkB;IACrE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC;AAED,SAAgB,cAAc,CAAC,WAAmB,EAAE,UAAkB;IACpE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC;AAED,SAAgB,mBAAmB,CAAC,WAAmB,EAAE,UAAkB,EAAE,WAAmB;IAC9F,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,OAAO,CAAC,CAAC;AAChF,CAAC;AAED,SAAgB,uBAAuB,CAAC,WAAmB,EAAE,UAAkB,EAAE,WAAmB;IAClG,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,gBAAgB,CAAC,CAAC;AACzF,CAAC;AAED,SAAgB,mBAAmB,CAAC,WAAmB,EAAE,UAAkB,EAAE,WAAmB;IAC9F,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,OAAO,CAAC,CAAC;AAChF,CAAC;AAED,SAAgB,uBAAuB,CAAC,WAAmB,EAAE,UAAkB,EAAE,WAAmB;IAClG,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,gBAAgB,CAAC,CAAC;AACzF,CAAC;AAED,SAAgB,eAAe,CAAC,WAAmB,EAAE,UAAkB,EAAE,WAAmB;IAC1F,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,iBAAiB,CAAC,CAAC;AAC1F,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load selectors for a feature, merging base and override files.
|
|
3
|
-
* Returns empty object if no files found.
|
|
4
|
-
*/
|
|
5
|
-
export declare function loadSelectors<T = Record<string, any>>(screensRoot: string, screenName: string, featureName: string): T;
|
|
6
|
-
//# sourceMappingURL=selector-loader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"selector-loader.d.ts","sourceRoot":"","sources":["../../src/utils/selector-loader.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACnD,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,CAAC,CAWH"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadSelectors = loadSelectors;
|
|
4
|
-
const yaml_io_1 = require("./yaml-io");
|
|
5
|
-
const screen_paths_1 = require("./screen-paths");
|
|
6
|
-
/**
|
|
7
|
-
* Load selectors for a feature, merging base and override files.
|
|
8
|
-
* Returns empty object if no files found.
|
|
9
|
-
*/
|
|
10
|
-
function loadSelectors(screensRoot, screenName, featureName) {
|
|
11
|
-
const basePath = (0, screen_paths_1.getSelectorBasePath)(screensRoot, screenName, featureName);
|
|
12
|
-
const overridePath = (0, screen_paths_1.getSelectorOverridePath)(screensRoot, screenName, featureName);
|
|
13
|
-
const base = (0, yaml_io_1.readYamlIfExists)(basePath) || {};
|
|
14
|
-
const override = (0, yaml_io_1.readYamlIfExists)(overridePath);
|
|
15
|
-
if (override) {
|
|
16
|
-
return { ...base, ...override };
|
|
17
|
-
}
|
|
18
|
-
return base;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=selector-loader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"selector-loader.js","sourceRoot":"","sources":["../../src/utils/selector-loader.ts"],"names":[],"mappings":";;AAOA,sCAeC;AAtBD,uCAA6C;AAC7C,iDAA8E;AAE9E;;;GAGG;AACH,SAAgB,aAAa,CAC3B,WAAmB,EACnB,UAAkB,EAClB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,IAAA,kCAAmB,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,IAAA,sCAAuB,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAEnF,MAAM,IAAI,GAAG,IAAA,0BAAgB,EAAI,QAAQ,CAAC,IAAI,EAAO,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAA,0BAAgB,EAAI,YAAY,CAAC,CAAC;IAEnD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load test data for a feature, merging base and override files.
|
|
3
|
-
* Returns empty object if no files found.
|
|
4
|
-
*/
|
|
5
|
-
export declare function loadTestData<T = Record<string, any>>(screensRoot: string, screenName: string, featureName: string): T;
|
|
6
|
-
//# sourceMappingURL=test-data-loader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-data-loader.d.ts","sourceRoot":"","sources":["../../src/utils/test-data-loader.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClD,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,CAAC,CAWH"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadTestData = loadTestData;
|
|
4
|
-
const yaml_io_1 = require("./yaml-io");
|
|
5
|
-
const screen_paths_1 = require("./screen-paths");
|
|
6
|
-
/**
|
|
7
|
-
* Load test data for a feature, merging base and override files.
|
|
8
|
-
* Returns empty object if no files found.
|
|
9
|
-
*/
|
|
10
|
-
function loadTestData(screensRoot, screenName, featureName) {
|
|
11
|
-
const basePath = (0, screen_paths_1.getTestDataBasePath)(screensRoot, screenName, featureName);
|
|
12
|
-
const overridePath = (0, screen_paths_1.getTestDataOverridePath)(screensRoot, screenName, featureName);
|
|
13
|
-
const base = (0, yaml_io_1.readYamlIfExists)(basePath) || {};
|
|
14
|
-
const override = (0, yaml_io_1.readYamlIfExists)(overridePath);
|
|
15
|
-
if (override) {
|
|
16
|
-
return { ...base, ...override };
|
|
17
|
-
}
|
|
18
|
-
return base;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=test-data-loader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-data-loader.js","sourceRoot":"","sources":["../../src/utils/test-data-loader.ts"],"names":[],"mappings":";;AAOA,oCAeC;AAtBD,uCAA6C;AAC7C,iDAA8E;AAE9E;;;GAGG;AACH,SAAgB,YAAY,CAC1B,WAAmB,EACnB,UAAkB,EAClB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,IAAA,kCAAmB,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,IAAA,sCAAuB,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAEnF,MAAM,IAAI,GAAG,IAAA,0BAAgB,EAAI,QAAQ,CAAC,IAAI,EAAO,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAA,0BAAgB,EAAI,YAAY,CAAC,CAAC;IAEnD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { getFeaturesDir } from './screen-paths';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Find all .feature files for a specific screen.
|
|
7
|
-
*/
|
|
8
|
-
export function findFeatureFiles(screensRoot: string, screenName: string): string[] {
|
|
9
|
-
const featuresDir = getFeaturesDir(screensRoot, screenName);
|
|
10
|
-
if (!fs.existsSync(featuresDir)) {
|
|
11
|
-
return [];
|
|
12
|
-
}
|
|
13
|
-
return fs.readdirSync(featuresDir)
|
|
14
|
-
.filter(f => f.endsWith('.feature'))
|
|
15
|
-
.map(f => path.join(featuresDir, f));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Find all .feature files across all screens.
|
|
20
|
-
*/
|
|
21
|
-
export function findAllFeatureFiles(screensRoot: string): string[] {
|
|
22
|
-
if (!fs.existsSync(screensRoot)) {
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
const files: string[] = [];
|
|
26
|
-
const screens = fs.readdirSync(screensRoot).filter(d =>
|
|
27
|
-
fs.statSync(path.join(screensRoot, d)).isDirectory()
|
|
28
|
-
);
|
|
29
|
-
for (const screen of screens) {
|
|
30
|
-
files.push(...findFeatureFiles(screensRoot, screen));
|
|
31
|
-
}
|
|
32
|
-
return files;
|
|
33
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as path from 'path';
|
|
2
|
-
|
|
3
|
-
export function getScreenDir(screensRoot: string, screenName: string): string {
|
|
4
|
-
return path.join(screensRoot, screenName);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function getFeaturesDir(screensRoot: string, screenName: string): string {
|
|
8
|
-
return path.join(screensRoot, screenName, 'features');
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function getSelectorsDir(screensRoot: string, screenName: string): string {
|
|
12
|
-
return path.join(screensRoot, screenName, 'selectors');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function getTestDataDir(screensRoot: string, screenName: string): string {
|
|
16
|
-
return path.join(screensRoot, screenName, 'test-data');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function getSelectorBasePath(screensRoot: string, screenName: string, featureName: string): string {
|
|
20
|
-
return path.join(screensRoot, screenName, 'selectors', `${featureName}.yaml`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function getSelectorOverridePath(screensRoot: string, screenName: string, featureName: string): string {
|
|
24
|
-
return path.join(screensRoot, screenName, 'selectors', `${featureName}.override.yaml`);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function getTestDataBasePath(screensRoot: string, screenName: string, featureName: string): string {
|
|
28
|
-
return path.join(screensRoot, screenName, 'test-data', `${featureName}.yaml`);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function getTestDataOverridePath(screensRoot: string, screenName: string, featureName: string): string {
|
|
32
|
-
return path.join(screensRoot, screenName, 'test-data', `${featureName}.override.yaml`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function getLiveScanPath(screensRoot: string, screenName: string, featureName: string): string {
|
|
36
|
-
return path.join(screensRoot, screenName, 'selectors', `${featureName}.live-scan.yaml`);
|
|
37
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { readYamlIfExists } from './yaml-io';
|
|
2
|
-
import { getSelectorBasePath, getSelectorOverridePath } from './screen-paths';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Load selectors for a feature, merging base and override files.
|
|
6
|
-
* Returns empty object if no files found.
|
|
7
|
-
*/
|
|
8
|
-
export function loadSelectors<T = Record<string, any>>(
|
|
9
|
-
screensRoot: string,
|
|
10
|
-
screenName: string,
|
|
11
|
-
featureName: string
|
|
12
|
-
): T {
|
|
13
|
-
const basePath = getSelectorBasePath(screensRoot, screenName, featureName);
|
|
14
|
-
const overridePath = getSelectorOverridePath(screensRoot, screenName, featureName);
|
|
15
|
-
|
|
16
|
-
const base = readYamlIfExists<T>(basePath) || {} as T;
|
|
17
|
-
const override = readYamlIfExists<T>(overridePath);
|
|
18
|
-
|
|
19
|
-
if (override) {
|
|
20
|
-
return { ...base, ...override };
|
|
21
|
-
}
|
|
22
|
-
return base;
|
|
23
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { readYamlIfExists } from './yaml-io';
|
|
2
|
-
import { getTestDataBasePath, getTestDataOverridePath } from './screen-paths';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Load test data for a feature, merging base and override files.
|
|
6
|
-
* Returns empty object if no files found.
|
|
7
|
-
*/
|
|
8
|
-
export function loadTestData<T = Record<string, any>>(
|
|
9
|
-
screensRoot: string,
|
|
10
|
-
screenName: string,
|
|
11
|
-
featureName: string
|
|
12
|
-
): T {
|
|
13
|
-
const basePath = getTestDataBasePath(screensRoot, screenName, featureName);
|
|
14
|
-
const overridePath = getTestDataOverridePath(screensRoot, screenName, featureName);
|
|
15
|
-
|
|
16
|
-
const base = readYamlIfExists<T>(basePath) || {} as T;
|
|
17
|
-
const override = readYamlIfExists<T>(overridePath);
|
|
18
|
-
|
|
19
|
-
if (override) {
|
|
20
|
-
return { ...base, ...override };
|
|
21
|
-
}
|
|
22
|
-
return base;
|
|
23
|
-
}
|