samaro-uitest 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +336 -0
- package/bin/samaro-allure.js +172 -0
- package/bin/samaro-init.js +278 -0
- package/bin/samaro-test.js +36 -0
- package/config/index.d.ts +4 -0
- package/config/index.d.ts.map +1 -0
- package/config/index.js +11 -0
- package/config/index.js.map +1 -0
- package/config/index.ts +3 -0
- package/config/playwright.component.config.d.ts +12 -0
- package/config/playwright.component.config.d.ts.map +1 -0
- package/config/playwright.component.config.js +42 -0
- package/config/playwright.component.config.js.map +1 -0
- package/config/playwright.component.config.ts +60 -0
- package/config/playwright.config.d.ts +14 -0
- package/config/playwright.config.d.ts.map +1 -0
- package/config/playwright.config.js +53 -0
- package/config/playwright.config.js.map +1 -0
- package/config/playwright.config.ts +76 -0
- package/config/test-setup.ts +17 -0
- package/config/vitest.config.d.ts +13 -0
- package/config/vitest.config.d.ts.map +1 -0
- package/config/vitest.config.js +53 -0
- package/config/vitest.config.js.map +1 -0
- package/config/vitest.config.ts +64 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/playwright.component.config.d.ts +12 -0
- package/dist/config/playwright.component.config.d.ts.map +1 -0
- package/dist/config/playwright.component.config.js +39 -0
- package/dist/config/playwright.component.config.js.map +1 -0
- package/dist/config/playwright.config.d.ts +14 -0
- package/dist/config/playwright.config.d.ts.map +1 -0
- package/dist/config/playwright.config.js +50 -0
- package/dist/config/playwright.config.js.map +1 -0
- package/dist/config/test-setup.d.ts +3 -0
- package/dist/config/test-setup.d.ts.map +1 -0
- package/dist/config/test-setup.js +17 -0
- package/dist/config/test-setup.js.map +1 -0
- package/dist/config/vitest.config.d.ts +13 -0
- package/dist/config/vitest.config.d.ts.map +1 -0
- package/dist/config/vitest.config.js +46 -0
- package/dist/config/vitest.config.js.map +1 -0
- package/dist/helpers/api.d.ts +69 -0
- package/dist/helpers/api.d.ts.map +1 -0
- package/dist/helpers/api.js +154 -0
- package/dist/helpers/api.js.map +1 -0
- package/dist/helpers/auth.d.ts +35 -0
- package/dist/helpers/auth.d.ts.map +1 -0
- package/dist/helpers/auth.js +96 -0
- package/dist/helpers/auth.js.map +1 -0
- package/dist/helpers/config.d.ts +34 -0
- package/dist/helpers/config.d.ts.map +1 -0
- package/dist/helpers/config.js +63 -0
- package/dist/helpers/config.js.map +1 -0
- package/dist/helpers/debug.d.ts +48 -0
- package/dist/helpers/debug.d.ts.map +1 -0
- package/dist/helpers/debug.js +76 -0
- package/dist/helpers/debug.js.map +1 -0
- package/dist/helpers/index.d.ts +6 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +11 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/setup.d.ts +50 -0
- package/dist/helpers/setup.d.ts.map +1 -0
- package/dist/helpers/setup.js +95 -0
- package/dist/helpers/setup.js.map +1 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +38 -0
- package/dist/src/index.js.map +1 -0
- package/helpers/api.d.ts +69 -0
- package/helpers/api.d.ts.map +1 -0
- package/helpers/api.js +163 -0
- package/helpers/api.js.map +1 -0
- package/helpers/api.ts +224 -0
- package/helpers/auth.d.ts +35 -0
- package/helpers/auth.d.ts.map +1 -0
- package/helpers/auth.js +104 -0
- package/helpers/auth.js.map +1 -0
- package/helpers/auth.ts +125 -0
- package/helpers/config.d.ts +34 -0
- package/helpers/config.d.ts.map +1 -0
- package/helpers/config.js +70 -0
- package/helpers/config.js.map +1 -0
- package/helpers/config.ts +80 -0
- package/helpers/debug.d.ts +48 -0
- package/helpers/debug.d.ts.map +1 -0
- package/helpers/debug.js +86 -0
- package/helpers/debug.js.map +1 -0
- package/helpers/debug.ts +111 -0
- package/helpers/index.d.ts +6 -0
- package/helpers/index.d.ts.map +1 -0
- package/helpers/index.js +47 -0
- package/helpers/index.js.map +1 -0
- package/helpers/index.ts +62 -0
- package/helpers/setup.d.ts +50 -0
- package/helpers/setup.d.ts.map +1 -0
- package/helpers/setup.js +137 -0
- package/helpers/setup.js.map +1 -0
- package/helpers/setup.ts +144 -0
- package/package.json +94 -0
- package/schematics/collection.json +11 -0
- package/schematics/ng-add/index.js +121 -0
- package/schematics/ng-add/schema.json +26 -0
- package/scripts/check-allure-results.js +269 -0
- package/types/allure.d.ts +76 -0
- package/types/global.d.ts +49 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const colors = {
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
bright: '\x1b[1m',
|
|
10
|
+
green: '\x1b[32m',
|
|
11
|
+
yellow: '\x1b[33m',
|
|
12
|
+
blue: '\x1b[34m',
|
|
13
|
+
cyan: '\x1b[36m',
|
|
14
|
+
red: '\x1b[31m',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function log(message, color = 'reset') {
|
|
18
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createDirectory(dirPath) {
|
|
22
|
+
if (!fs.existsSync(dirPath)) {
|
|
23
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
24
|
+
log(` ✓ Created ${dirPath}/`, 'green');
|
|
25
|
+
} else {
|
|
26
|
+
log(` ⚠ ${dirPath}/ already exists`, 'yellow');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function copyFile(source, dest) {
|
|
31
|
+
try {
|
|
32
|
+
fs.copyFileSync(source, dest);
|
|
33
|
+
log(` ✓ Created ${path.basename(dest)}`, 'green');
|
|
34
|
+
} catch (error) {
|
|
35
|
+
log(` ✗ Failed to create ${path.basename(dest)}: ${error.message}`, 'red');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function writeFile(filePath, content) {
|
|
40
|
+
try {
|
|
41
|
+
fs.writeFileSync(filePath, content);
|
|
42
|
+
log(` ✓ Created ${path.basename(filePath)}`, 'green');
|
|
43
|
+
} catch (error) {
|
|
44
|
+
log(` ✗ Failed to create ${path.basename(filePath)}: ${error.message}`, 'red');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function checkConflictingDependencies() {
|
|
49
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
50
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
51
|
+
log('⚠ No package.json found. Make sure you run this in an Angular project.', 'yellow');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
56
|
+
const conflicts = [];
|
|
57
|
+
|
|
58
|
+
const testingPackages = ['jest', 'karma', 'jasmine-core', 'protractor'];
|
|
59
|
+
|
|
60
|
+
const allDeps = {
|
|
61
|
+
...packageJson.dependencies,
|
|
62
|
+
...packageJson.devDependencies,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
for (const pkg of testingPackages) {
|
|
66
|
+
if (allDeps[pkg]) {
|
|
67
|
+
conflicts.push(pkg);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (conflicts.length > 0) {
|
|
72
|
+
log(`\n⚠️ Warning: Found potentially conflicting packages: ${conflicts.join(', ')}`, 'yellow');
|
|
73
|
+
log('You may need to remove these or configure them to work together.\n', 'yellow');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function detectWorkspace() {
|
|
78
|
+
if (fs.existsSync('nx.json')) return 'nx';
|
|
79
|
+
if (fs.existsSync('lerna.json')) return 'lerna';
|
|
80
|
+
if (fs.existsSync('pnpm-workspace.yaml')) return 'pnpm';
|
|
81
|
+
return 'standard';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function initProject() {
|
|
85
|
+
log('\n🚀 Initializing SamaroUItest in your project...\n', 'bright');
|
|
86
|
+
|
|
87
|
+
const projectRoot = process.cwd();
|
|
88
|
+
const workspaceType = detectWorkspace();
|
|
89
|
+
|
|
90
|
+
if (workspaceType !== 'standard') {
|
|
91
|
+
log(`Detected ${workspaceType} workspace. Applying workspace-specific configuration...\n`, 'cyan');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Check for conflicting dependencies
|
|
95
|
+
checkConflictingDependencies();
|
|
96
|
+
|
|
97
|
+
// Create directories
|
|
98
|
+
log('Creating directories...', 'cyan');
|
|
99
|
+
createDirectory(path.join(projectRoot, 'e2e'));
|
|
100
|
+
createDirectory(path.join(projectRoot, 'e2e', 'helpers'));
|
|
101
|
+
createDirectory(path.join(projectRoot, 'ct-tests'));
|
|
102
|
+
|
|
103
|
+
// Create configuration files
|
|
104
|
+
log('\nCreating configuration files...', 'cyan');
|
|
105
|
+
|
|
106
|
+
const packageDir = path.join(__dirname, '..');
|
|
107
|
+
|
|
108
|
+
// Create vitest.config.ts
|
|
109
|
+
writeFile(
|
|
110
|
+
path.join(projectRoot, 'vitest.config.ts'),
|
|
111
|
+
`import { createVitestConfig } from 'samaro-uitest/config';
|
|
112
|
+
|
|
113
|
+
export default createVitestConfig({
|
|
114
|
+
projectRoot: __dirname,
|
|
115
|
+
testGlob: 'src/**/*.spec.ts',
|
|
116
|
+
resultsDir: 'allure-unit-results',
|
|
117
|
+
});
|
|
118
|
+
`
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Create playwright.config.ts
|
|
122
|
+
writeFile(
|
|
123
|
+
path.join(projectRoot, 'playwright.config.ts'),
|
|
124
|
+
`import { createPlaywrightConfig } from 'samaro-uitest/config';
|
|
125
|
+
|
|
126
|
+
export default createPlaywrightConfig({
|
|
127
|
+
baseURL: 'http://localhost:4200',
|
|
128
|
+
testDir: './e2e',
|
|
129
|
+
resultsDir: 'allure-e2e-results',
|
|
130
|
+
webServerCommand: 'npm run start',
|
|
131
|
+
webServerPort: 4200,
|
|
132
|
+
});
|
|
133
|
+
`
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Create playwright.component.config.ts
|
|
137
|
+
writeFile(
|
|
138
|
+
path.join(projectRoot, 'playwright.component.config.ts'),
|
|
139
|
+
`import { createComponentConfig } from 'samaro-uitest/config';
|
|
140
|
+
|
|
141
|
+
export default createComponentConfig({
|
|
142
|
+
baseURL: 'http://localhost:4200',
|
|
143
|
+
testDir: './ct-tests',
|
|
144
|
+
resultsDir: 'allure-ct-results',
|
|
145
|
+
});
|
|
146
|
+
`
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Create src/test-setup.ts if src directory exists
|
|
150
|
+
const srcDir = path.join(projectRoot, 'src');
|
|
151
|
+
if (fs.existsSync(srcDir)) {
|
|
152
|
+
writeFile(
|
|
153
|
+
path.join(srcDir, 'test-setup.ts'),
|
|
154
|
+
`import 'zone.js';
|
|
155
|
+
import 'zone.js/testing';
|
|
156
|
+
import { getTestBed } from '@angular/core/testing';
|
|
157
|
+
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
|
158
|
+
|
|
159
|
+
getTestBed().initTestEnvironment(
|
|
160
|
+
BrowserDynamicTestingModule,
|
|
161
|
+
platformBrowserDynamicTesting()
|
|
162
|
+
);
|
|
163
|
+
`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Create example test files
|
|
168
|
+
log('\nCreating example test files...', 'cyan');
|
|
169
|
+
|
|
170
|
+
writeFile(
|
|
171
|
+
path.join(projectRoot, 'e2e', 'example.spec.ts'),
|
|
172
|
+
`import { test, expect } from '@playwright/test';
|
|
173
|
+
import { generateUniqueUser, register } from 'samaro-uitest/helpers';
|
|
174
|
+
|
|
175
|
+
test.describe('Example Tests', () => {
|
|
176
|
+
test('homepage has title', async ({ page }) => {
|
|
177
|
+
await page.goto('/');
|
|
178
|
+
await expect(page).toHaveTitle(/Angular/);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('user can register', async ({ page }) => {
|
|
182
|
+
const user = generateUniqueUser();
|
|
183
|
+
|
|
184
|
+
await register(page, user.username, user.email, user.password);
|
|
185
|
+
|
|
186
|
+
await expect(page).toHaveURL('/');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
`
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
writeFile(
|
|
193
|
+
path.join(projectRoot, 'ct-tests', 'example.spec.ts'),
|
|
194
|
+
`import { test, expect } from '@playwright/test';
|
|
195
|
+
|
|
196
|
+
test.describe('Component Example', () => {
|
|
197
|
+
test('renders component', async ({ page }) => {
|
|
198
|
+
await page.goto('/');
|
|
199
|
+
await expect(page.locator('app-root')).toBeVisible();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
`
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Update package.json scripts
|
|
206
|
+
log('\nUpdating package.json scripts...', 'cyan');
|
|
207
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
208
|
+
|
|
209
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
210
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
211
|
+
|
|
212
|
+
packageJson.scripts = {
|
|
213
|
+
...packageJson.scripts,
|
|
214
|
+
'test': 'samaro-test vitest',
|
|
215
|
+
'test:run': 'samaro-test "vitest --run"',
|
|
216
|
+
'test:ui': 'samaro-test "vitest --ui"',
|
|
217
|
+
'test:coverage': 'samaro-test "vitest --coverage"',
|
|
218
|
+
'test:e2e': 'samaro-test "playwright test"',
|
|
219
|
+
'test:e2e:ui': 'samaro-test "playwright test --ui"',
|
|
220
|
+
'test:e2e:headed': 'samaro-test "playwright test --headed"',
|
|
221
|
+
'test:e2e:debug': 'samaro-test "playwright test --debug"',
|
|
222
|
+
'test:ct': 'samaro-test "playwright test --config playwright.component.config.ts"',
|
|
223
|
+
'test:ct:ui': 'samaro-test "playwright test --config playwright.component.config.ts --ui"',
|
|
224
|
+
'allure:generate': 'samaro-allure generate',
|
|
225
|
+
'allure:open': 'samaro-allure open',
|
|
226
|
+
'allure:clean': 'samaro-allure clean',
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
230
|
+
log(' ✓ Updated package.json', 'green');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Create .gitignore entries
|
|
234
|
+
log('\nUpdating .gitignore...', 'cyan');
|
|
235
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
236
|
+
const gitignoreEntries = [
|
|
237
|
+
'\n# SamaroUItest',
|
|
238
|
+
'allure-*-results/',
|
|
239
|
+
'allure-reports/',
|
|
240
|
+
'playwright-report/',
|
|
241
|
+
'playwright-component-report/',
|
|
242
|
+
'test-results/',
|
|
243
|
+
'coverage/',
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
if (fs.existsSync(gitignorePath)) {
|
|
247
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
248
|
+
if (!gitignoreContent.includes('SamaroUItest')) {
|
|
249
|
+
fs.appendFileSync(gitignorePath, gitignoreEntries.join('\n'));
|
|
250
|
+
log(' ✓ Updated .gitignore', 'green');
|
|
251
|
+
} else {
|
|
252
|
+
log(' ⚠ .gitignore already contains SamaroUItest entries', 'yellow');
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
fs.writeFileSync(gitignorePath, gitignoreEntries.join('\n'));
|
|
256
|
+
log(' ✓ Created .gitignore', 'green');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
log('\n' + '='.repeat(60), 'cyan');
|
|
260
|
+
log('✅ Initialization complete!', 'green');
|
|
261
|
+
log('='.repeat(60), 'cyan');
|
|
262
|
+
|
|
263
|
+
log('\n📋 Next steps:', 'bright');
|
|
264
|
+
log(' 1. Install dependencies: npm install', 'yellow');
|
|
265
|
+
log(' 2. Install Playwright: npx playwright install chromium', 'yellow');
|
|
266
|
+
log(' 3. Run unit tests: npm run test', 'yellow');
|
|
267
|
+
log(' 4. Run E2E tests: npm run test:e2e', 'yellow');
|
|
268
|
+
log(' 5. View reports: npm run allure:generate && npm run allure:open\n', 'yellow');
|
|
269
|
+
|
|
270
|
+
log('📚 Documentation:', 'bright');
|
|
271
|
+
log(' - https://github.com/samaro/samaro-uitest#readme\n', 'blue');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Run initialization
|
|
275
|
+
initProject().catch((error) => {
|
|
276
|
+
console.error('❌ Initialization failed:', error);
|
|
277
|
+
process.exit(1);
|
|
278
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const spawn = require('cross-spawn');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const checkAllureScript = path.join(__dirname, '..', 'scripts', 'check-allure-results.js');
|
|
7
|
+
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
|
|
10
|
+
if (args.length === 0) {
|
|
11
|
+
console.error('❌ Error: No test command provided');
|
|
12
|
+
console.error('Usage: samaro-test "<test-command>"');
|
|
13
|
+
console.error('');
|
|
14
|
+
console.error('Examples:');
|
|
15
|
+
console.error(' samaro-test vitest');
|
|
16
|
+
console.error(' samaro-test "vitest --run"');
|
|
17
|
+
console.error(' samaro-test "playwright test"');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const command = args.join(' ');
|
|
22
|
+
|
|
23
|
+
// Run the check-allure-results script with the test command
|
|
24
|
+
const child = spawn('node', [checkAllureScript, command], {
|
|
25
|
+
stdio: 'inherit',
|
|
26
|
+
shell: true,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
child.on('close', (code) => {
|
|
30
|
+
process.exit(code);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
child.on('error', (error) => {
|
|
34
|
+
console.error('❌ Failed to run test command:', error.message);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createVitestConfig, mergeConfig, type SamaroVitestOptions } from './vitest.config';
|
|
2
|
+
export { createPlaywrightConfig, type SamaroPlaywrightOptions } from './playwright.config';
|
|
3
|
+
export { createComponentConfig, type SamaroComponentOptions } from './playwright.component.config';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,qBAAqB,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC"}
|
package/config/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createComponentConfig = exports.createPlaywrightConfig = exports.mergeConfig = exports.createVitestConfig = void 0;
|
|
4
|
+
var vitest_config_1 = require("./vitest.config");
|
|
5
|
+
Object.defineProperty(exports, "createVitestConfig", { enumerable: true, get: function () { return vitest_config_1.createVitestConfig; } });
|
|
6
|
+
Object.defineProperty(exports, "mergeConfig", { enumerable: true, get: function () { return vitest_config_1.mergeConfig; } });
|
|
7
|
+
var playwright_config_1 = require("./playwright.config");
|
|
8
|
+
Object.defineProperty(exports, "createPlaywrightConfig", { enumerable: true, get: function () { return playwright_config_1.createPlaywrightConfig; } });
|
|
9
|
+
var playwright_component_config_1 = require("./playwright.component.config");
|
|
10
|
+
Object.defineProperty(exports, "createComponentConfig", { enumerable: true, get: function () { return playwright_component_config_1.createComponentConfig; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,iDAA4F;AAAnF,mHAAA,kBAAkB,OAAA;AAAE,4GAAA,WAAW,OAAA;AACxC,yDAA2F;AAAlF,2HAAA,sBAAsB,OAAA;AAC/B,6EAAmG;AAA1F,oIAAA,qBAAqB,OAAA"}
|
package/config/index.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createVitestConfig, mergeConfig, type SamaroVitestOptions } from './vitest.config';
|
|
2
|
+
export { createPlaywrightConfig, type SamaroPlaywrightOptions } from './playwright.config';
|
|
3
|
+
export { createComponentConfig, type SamaroComponentOptions } from './playwright.component.config';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PlaywrightTestConfig } from '@playwright/test';
|
|
2
|
+
export interface SamaroComponentOptions {
|
|
3
|
+
baseURL?: string;
|
|
4
|
+
testDir?: string;
|
|
5
|
+
resultsDir?: string;
|
|
6
|
+
webServerCommand?: string;
|
|
7
|
+
webServerPort?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function createComponentConfig(options?: SamaroComponentOptions): PlaywrightTestConfig;
|
|
10
|
+
declare const _default: PlaywrightTestConfig;
|
|
11
|
+
export default _default;
|
|
12
|
+
//# sourceMappingURL=playwright.component.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.component.config.d.ts","sourceRoot":"","sources":["playwright.component.config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,oBAAoB,CA8ChG;;AAED,wBAAuC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createComponentConfig = createComponentConfig;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
function createComponentConfig(options = {}) {
|
|
6
|
+
const { baseURL = 'http://localhost:4200', testDir = './ct-tests', resultsDir = 'allure-ct-results', webServerCommand = 'npm run start', webServerPort = 4200, } = options;
|
|
7
|
+
return (0, test_1.defineConfig)({
|
|
8
|
+
testDir,
|
|
9
|
+
fullyParallel: true,
|
|
10
|
+
forbidOnly: !!process.env.CI,
|
|
11
|
+
retries: process.env.CI ? 2 : 0,
|
|
12
|
+
workers: process.env.CI ? 1 : undefined,
|
|
13
|
+
reporter: [
|
|
14
|
+
['allure-playwright', {
|
|
15
|
+
resultsDir,
|
|
16
|
+
detail: true,
|
|
17
|
+
suiteTitle: true,
|
|
18
|
+
}],
|
|
19
|
+
['html', { outputFolder: 'playwright-component-report' }],
|
|
20
|
+
['list'],
|
|
21
|
+
],
|
|
22
|
+
use: {
|
|
23
|
+
baseURL,
|
|
24
|
+
trace: 'on-first-retry',
|
|
25
|
+
screenshot: 'only-on-failure',
|
|
26
|
+
},
|
|
27
|
+
projects: [
|
|
28
|
+
{
|
|
29
|
+
name: 'chromium',
|
|
30
|
+
use: { ...test_1.devices['Desktop Chrome'] },
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
webServer: {
|
|
34
|
+
command: webServerCommand,
|
|
35
|
+
url: `http://localhost:${webServerPort}`,
|
|
36
|
+
reuseExistingServer: !process.env.CI,
|
|
37
|
+
timeout: 120000,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
exports.default = createComponentConfig();
|
|
42
|
+
//# sourceMappingURL=playwright.component.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.component.config.js","sourceRoot":"","sources":["playwright.component.config.ts"],"names":[],"mappings":";;AAWA,sDA8CC;AAzDD,2CAAyD;AAWzD,SAAgB,qBAAqB,CAAC,UAAkC,EAAE;IACxE,MAAM,EACJ,OAAO,GAAG,uBAAuB,EACjC,OAAO,GAAG,YAAY,EACtB,UAAU,GAAG,mBAAmB,EAChC,gBAAgB,GAAG,eAAe,EAClC,aAAa,GAAG,IAAI,GACrB,GAAG,OAAO,CAAC;IAEZ,OAAO,IAAA,mBAAY,EAAC;QAClB,OAAO;QACP,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC5B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAEvC,QAAQ,EAAE;YACR,CAAC,mBAAmB,EAAE;oBACpB,UAAU;oBACV,MAAM,EAAE,IAAI;oBACZ,UAAU,EAAE,IAAI;iBACjB,CAAC;YACF,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,6BAA6B,EAAE,CAAC;YACzD,CAAC,MAAM,CAAC;SACT;QAED,GAAG,EAAE;YACH,OAAO;YACP,KAAK,EAAE,gBAAgB;YACvB,UAAU,EAAE,iBAAiB;SAC9B;QAED,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,UAAU;gBAChB,GAAG,EAAE,EAAE,GAAG,cAAO,CAAC,gBAAgB,CAAC,EAAE;aACtC;SACF;QAED,SAAS,EAAE;YACT,OAAO,EAAE,gBAAgB;YACzB,GAAG,EAAE,oBAAoB,aAAa,EAAE;YACxC,mBAAmB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACpC,OAAO,EAAE,MAAO;SACjB;KACF,CAAC,CAAC;AACL,CAAC;AAED,kBAAe,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
import type { PlaywrightTestConfig } from '@playwright/test';
|
|
3
|
+
|
|
4
|
+
export interface SamaroComponentOptions {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
testDir?: string;
|
|
7
|
+
resultsDir?: string;
|
|
8
|
+
webServerCommand?: string;
|
|
9
|
+
webServerPort?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createComponentConfig(options: SamaroComponentOptions = {}): PlaywrightTestConfig {
|
|
13
|
+
const {
|
|
14
|
+
baseURL = 'http://localhost:4200',
|
|
15
|
+
testDir = './ct-tests',
|
|
16
|
+
resultsDir = 'allure-ct-results',
|
|
17
|
+
webServerCommand = 'npm run start',
|
|
18
|
+
webServerPort = 4200,
|
|
19
|
+
} = options;
|
|
20
|
+
|
|
21
|
+
return defineConfig({
|
|
22
|
+
testDir,
|
|
23
|
+
fullyParallel: true,
|
|
24
|
+
forbidOnly: !!process.env.CI,
|
|
25
|
+
retries: process.env.CI ? 2 : 0,
|
|
26
|
+
workers: process.env.CI ? 1 : undefined,
|
|
27
|
+
|
|
28
|
+
reporter: [
|
|
29
|
+
['allure-playwright', {
|
|
30
|
+
resultsDir,
|
|
31
|
+
detail: true,
|
|
32
|
+
suiteTitle: true,
|
|
33
|
+
}],
|
|
34
|
+
['html', { outputFolder: 'playwright-component-report' }],
|
|
35
|
+
['list'],
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
use: {
|
|
39
|
+
baseURL,
|
|
40
|
+
trace: 'on-first-retry',
|
|
41
|
+
screenshot: 'only-on-failure',
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
projects: [
|
|
45
|
+
{
|
|
46
|
+
name: 'chromium',
|
|
47
|
+
use: { ...devices['Desktop Chrome'] },
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
webServer: {
|
|
52
|
+
command: webServerCommand,
|
|
53
|
+
url: `http://localhost:${webServerPort}`,
|
|
54
|
+
reuseExistingServer: !process.env.CI,
|
|
55
|
+
timeout: 120_000,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default createComponentConfig();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PlaywrightTestConfig } from '@playwright/test';
|
|
2
|
+
export interface SamaroPlaywrightOptions {
|
|
3
|
+
baseURL?: string;
|
|
4
|
+
testDir?: string;
|
|
5
|
+
resultsDir?: string;
|
|
6
|
+
webServerCommand?: string;
|
|
7
|
+
webServerPort?: number;
|
|
8
|
+
webServerTimeout?: number;
|
|
9
|
+
timeout?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function createPlaywrightConfig(options?: SamaroPlaywrightOptions): PlaywrightTestConfig;
|
|
12
|
+
declare const _default: PlaywrightTestConfig<{}, {}>;
|
|
13
|
+
export default _default;
|
|
14
|
+
//# sourceMappingURL=playwright.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.config.d.ts","sourceRoot":"","sources":["playwright.config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,oBAAoB,CA4DlG;;AAED,wBAAsD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPlaywrightConfig = createPlaywrightConfig;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
function createPlaywrightConfig(options = {}) {
|
|
6
|
+
const { baseURL = 'http://localhost:4200', testDir = './e2e', resultsDir = 'allure-e2e-results', webServerCommand = 'npm run start', webServerPort = 4200, webServerTimeout = 120000, timeout = 15000, } = options;
|
|
7
|
+
return {
|
|
8
|
+
testDir,
|
|
9
|
+
fullyParallel: false,
|
|
10
|
+
forbidOnly: !!process.env.CI,
|
|
11
|
+
retries: process.env.CI ? 2 : 1,
|
|
12
|
+
workers: 1,
|
|
13
|
+
timeout,
|
|
14
|
+
reporter: [
|
|
15
|
+
['allure-playwright', {
|
|
16
|
+
resultsDir,
|
|
17
|
+
detail: true,
|
|
18
|
+
suiteTitle: true,
|
|
19
|
+
environmentInfo: {
|
|
20
|
+
framework: 'playwright',
|
|
21
|
+
os_platform: process.platform,
|
|
22
|
+
node_version: process.version,
|
|
23
|
+
},
|
|
24
|
+
}],
|
|
25
|
+
['html', { outputFolder: 'playwright-report' }],
|
|
26
|
+
['list'],
|
|
27
|
+
],
|
|
28
|
+
use: {
|
|
29
|
+
baseURL,
|
|
30
|
+
trace: 'on-first-retry',
|
|
31
|
+
screenshot: 'only-on-failure',
|
|
32
|
+
actionTimeout: 5000,
|
|
33
|
+
navigationTimeout: 10000,
|
|
34
|
+
},
|
|
35
|
+
expect: {
|
|
36
|
+
timeout: 5000,
|
|
37
|
+
},
|
|
38
|
+
projects: [
|
|
39
|
+
{
|
|
40
|
+
name: 'chromium',
|
|
41
|
+
use: { ...test_1.devices['Desktop Chrome'] },
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
webServer: {
|
|
45
|
+
command: webServerCommand,
|
|
46
|
+
url: `http://localhost:${webServerPort}`,
|
|
47
|
+
reuseExistingServer: !process.env.CI,
|
|
48
|
+
timeout: webServerTimeout,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
exports.default = (0, test_1.defineConfig)(createPlaywrightConfig());
|
|
53
|
+
//# sourceMappingURL=playwright.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.config.js","sourceRoot":"","sources":["playwright.config.ts"],"names":[],"mappings":";;AAaA,wDA4DC;AAzED,2CAAyD;AAazD,SAAgB,sBAAsB,CAAC,UAAmC,EAAE;IAC1E,MAAM,EACJ,OAAO,GAAG,uBAAuB,EACjC,OAAO,GAAG,OAAO,EACjB,UAAU,GAAG,oBAAoB,EACjC,gBAAgB,GAAG,eAAe,EAClC,aAAa,GAAG,IAAI,EACpB,gBAAgB,GAAG,MAAO,EAC1B,OAAO,GAAG,KAAM,GACjB,GAAG,OAAO,CAAC;IAEZ,OAAO;QACL,OAAO;QACP,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC5B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,OAAO,EAAE,CAAC;QACV,OAAO;QAEP,QAAQ,EAAE;YACR,CAAC,mBAAmB,EAAE;oBACpB,UAAU;oBACV,MAAM,EAAE,IAAI;oBACZ,UAAU,EAAE,IAAI;oBAChB,eAAe,EAAE;wBACf,SAAS,EAAE,YAAY;wBACvB,WAAW,EAAE,OAAO,CAAC,QAAQ;wBAC7B,YAAY,EAAE,OAAO,CAAC,OAAO;qBAC9B;iBACF,CAAC;YACF,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC;YAC/C,CAAC,MAAM,CAAC;SACT;QAED,GAAG,EAAE;YACH,OAAO;YACP,KAAK,EAAE,gBAAgB;YACvB,UAAU,EAAE,iBAAiB;YAC7B,aAAa,EAAE,IAAK;YACpB,iBAAiB,EAAE,KAAM;SAC1B;QAED,MAAM,EAAE;YACN,OAAO,EAAE,IAAK;SACf;QAED,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,UAAU;gBAChB,GAAG,EAAE,EAAE,GAAG,cAAO,CAAC,gBAAgB,CAAC,EAAE;aACtC;SACF;QAED,SAAS,EAAE;YACT,OAAO,EAAE,gBAAgB;YACzB,GAAG,EAAE,oBAAoB,aAAa,EAAE;YACxC,mBAAmB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACpC,OAAO,EAAE,gBAAgB;SAC1B;KACF,CAAC;AACJ,CAAC;AAED,kBAAe,IAAA,mBAAY,EAAC,sBAAsB,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
import type { PlaywrightTestConfig } from '@playwright/test';
|
|
3
|
+
|
|
4
|
+
export interface SamaroPlaywrightOptions {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
testDir?: string;
|
|
7
|
+
resultsDir?: string;
|
|
8
|
+
webServerCommand?: string;
|
|
9
|
+
webServerPort?: number;
|
|
10
|
+
webServerTimeout?: number;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function createPlaywrightConfig(options: SamaroPlaywrightOptions = {}): PlaywrightTestConfig {
|
|
15
|
+
const {
|
|
16
|
+
baseURL = 'http://localhost:4200',
|
|
17
|
+
testDir = './e2e',
|
|
18
|
+
resultsDir = 'allure-e2e-results',
|
|
19
|
+
webServerCommand = 'npm run start',
|
|
20
|
+
webServerPort = 4200,
|
|
21
|
+
webServerTimeout = 120_000,
|
|
22
|
+
timeout = 15_000,
|
|
23
|
+
} = options;
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
testDir,
|
|
27
|
+
fullyParallel: false,
|
|
28
|
+
forbidOnly: !!process.env.CI,
|
|
29
|
+
retries: process.env.CI ? 2 : 1,
|
|
30
|
+
workers: 1,
|
|
31
|
+
timeout,
|
|
32
|
+
|
|
33
|
+
reporter: [
|
|
34
|
+
['allure-playwright', {
|
|
35
|
+
resultsDir,
|
|
36
|
+
detail: true,
|
|
37
|
+
suiteTitle: true,
|
|
38
|
+
environmentInfo: {
|
|
39
|
+
framework: 'playwright',
|
|
40
|
+
os_platform: process.platform,
|
|
41
|
+
node_version: process.version,
|
|
42
|
+
},
|
|
43
|
+
}],
|
|
44
|
+
['html', { outputFolder: 'playwright-report' }],
|
|
45
|
+
['list'],
|
|
46
|
+
],
|
|
47
|
+
|
|
48
|
+
use: {
|
|
49
|
+
baseURL,
|
|
50
|
+
trace: 'on-first-retry',
|
|
51
|
+
screenshot: 'only-on-failure',
|
|
52
|
+
actionTimeout: 5_000,
|
|
53
|
+
navigationTimeout: 10_000,
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
expect: {
|
|
57
|
+
timeout: 5_000,
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
projects: [
|
|
61
|
+
{
|
|
62
|
+
name: 'chromium',
|
|
63
|
+
use: { ...devices['Desktop Chrome'] },
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
|
|
67
|
+
webServer: {
|
|
68
|
+
command: webServerCommand,
|
|
69
|
+
url: `http://localhost:${webServerPort}`,
|
|
70
|
+
reuseExistingServer: !process.env.CI,
|
|
71
|
+
timeout: webServerTimeout,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default defineConfig(createPlaywrightConfig());
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import 'zone.js';
|
|
2
|
+
import 'zone.js/testing';
|
|
3
|
+
import { getTestBed } from '@angular/core/testing';
|
|
4
|
+
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
|
5
|
+
|
|
6
|
+
console.log('🚀 SamaroUItest - Test setup file is being loaded!');
|
|
7
|
+
|
|
8
|
+
// Initialize the Angular testing environment once
|
|
9
|
+
try {
|
|
10
|
+
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
|
|
11
|
+
teardown: { destroyAfterEach: true },
|
|
12
|
+
});
|
|
13
|
+
console.log('✅ TestBed initialized successfully');
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error('❌ TestBed initialization failed:', error);
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { mergeConfig } from 'vitest/config';
|
|
2
|
+
export interface SamaroVitestOptions {
|
|
3
|
+
projectRoot?: string;
|
|
4
|
+
testGlob?: string | string[];
|
|
5
|
+
resultsDir?: string;
|
|
6
|
+
setupFiles?: string[];
|
|
7
|
+
alias?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
export declare function createVitestConfig(options?: SamaroVitestOptions): import("vite").UserConfig;
|
|
10
|
+
export { mergeConfig };
|
|
11
|
+
declare const _default: import("vite").UserConfig;
|
|
12
|
+
export default _default;
|
|
13
|
+
//# sourceMappingURL=vitest.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["vitest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,WAAW,EAAE,MAAM,eAAe,CAAC;AAK1D,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,6BA+CnE;AAED,OAAO,EAAE,WAAW,EAAE,CAAC;;AACvB,wBAAoC"}
|