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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +336 -0
  3. package/bin/samaro-allure.js +172 -0
  4. package/bin/samaro-init.js +278 -0
  5. package/bin/samaro-test.js +36 -0
  6. package/config/index.d.ts +4 -0
  7. package/config/index.d.ts.map +1 -0
  8. package/config/index.js +11 -0
  9. package/config/index.js.map +1 -0
  10. package/config/index.ts +3 -0
  11. package/config/playwright.component.config.d.ts +12 -0
  12. package/config/playwright.component.config.d.ts.map +1 -0
  13. package/config/playwright.component.config.js +42 -0
  14. package/config/playwright.component.config.js.map +1 -0
  15. package/config/playwright.component.config.ts +60 -0
  16. package/config/playwright.config.d.ts +14 -0
  17. package/config/playwright.config.d.ts.map +1 -0
  18. package/config/playwright.config.js +53 -0
  19. package/config/playwright.config.js.map +1 -0
  20. package/config/playwright.config.ts +76 -0
  21. package/config/test-setup.ts +17 -0
  22. package/config/vitest.config.d.ts +13 -0
  23. package/config/vitest.config.d.ts.map +1 -0
  24. package/config/vitest.config.js +53 -0
  25. package/config/vitest.config.js.map +1 -0
  26. package/config/vitest.config.ts +64 -0
  27. package/dist/config/index.d.ts +4 -0
  28. package/dist/config/index.d.ts.map +1 -0
  29. package/dist/config/index.js +4 -0
  30. package/dist/config/index.js.map +1 -0
  31. package/dist/config/playwright.component.config.d.ts +12 -0
  32. package/dist/config/playwright.component.config.d.ts.map +1 -0
  33. package/dist/config/playwright.component.config.js +39 -0
  34. package/dist/config/playwright.component.config.js.map +1 -0
  35. package/dist/config/playwright.config.d.ts +14 -0
  36. package/dist/config/playwright.config.d.ts.map +1 -0
  37. package/dist/config/playwright.config.js +50 -0
  38. package/dist/config/playwright.config.js.map +1 -0
  39. package/dist/config/test-setup.d.ts +3 -0
  40. package/dist/config/test-setup.d.ts.map +1 -0
  41. package/dist/config/test-setup.js +17 -0
  42. package/dist/config/test-setup.js.map +1 -0
  43. package/dist/config/vitest.config.d.ts +13 -0
  44. package/dist/config/vitest.config.d.ts.map +1 -0
  45. package/dist/config/vitest.config.js +46 -0
  46. package/dist/config/vitest.config.js.map +1 -0
  47. package/dist/helpers/api.d.ts +69 -0
  48. package/dist/helpers/api.d.ts.map +1 -0
  49. package/dist/helpers/api.js +154 -0
  50. package/dist/helpers/api.js.map +1 -0
  51. package/dist/helpers/auth.d.ts +35 -0
  52. package/dist/helpers/auth.d.ts.map +1 -0
  53. package/dist/helpers/auth.js +96 -0
  54. package/dist/helpers/auth.js.map +1 -0
  55. package/dist/helpers/config.d.ts +34 -0
  56. package/dist/helpers/config.d.ts.map +1 -0
  57. package/dist/helpers/config.js +63 -0
  58. package/dist/helpers/config.js.map +1 -0
  59. package/dist/helpers/debug.d.ts +48 -0
  60. package/dist/helpers/debug.d.ts.map +1 -0
  61. package/dist/helpers/debug.js +76 -0
  62. package/dist/helpers/debug.js.map +1 -0
  63. package/dist/helpers/index.d.ts +6 -0
  64. package/dist/helpers/index.d.ts.map +1 -0
  65. package/dist/helpers/index.js +11 -0
  66. package/dist/helpers/index.js.map +1 -0
  67. package/dist/helpers/setup.d.ts +50 -0
  68. package/dist/helpers/setup.d.ts.map +1 -0
  69. package/dist/helpers/setup.js +95 -0
  70. package/dist/helpers/setup.js.map +1 -0
  71. package/dist/src/index.d.ts +16 -0
  72. package/dist/src/index.d.ts.map +1 -0
  73. package/dist/src/index.js +38 -0
  74. package/dist/src/index.js.map +1 -0
  75. package/helpers/api.d.ts +69 -0
  76. package/helpers/api.d.ts.map +1 -0
  77. package/helpers/api.js +163 -0
  78. package/helpers/api.js.map +1 -0
  79. package/helpers/api.ts +224 -0
  80. package/helpers/auth.d.ts +35 -0
  81. package/helpers/auth.d.ts.map +1 -0
  82. package/helpers/auth.js +104 -0
  83. package/helpers/auth.js.map +1 -0
  84. package/helpers/auth.ts +125 -0
  85. package/helpers/config.d.ts +34 -0
  86. package/helpers/config.d.ts.map +1 -0
  87. package/helpers/config.js +70 -0
  88. package/helpers/config.js.map +1 -0
  89. package/helpers/config.ts +80 -0
  90. package/helpers/debug.d.ts +48 -0
  91. package/helpers/debug.d.ts.map +1 -0
  92. package/helpers/debug.js +86 -0
  93. package/helpers/debug.js.map +1 -0
  94. package/helpers/debug.ts +111 -0
  95. package/helpers/index.d.ts +6 -0
  96. package/helpers/index.d.ts.map +1 -0
  97. package/helpers/index.js +47 -0
  98. package/helpers/index.js.map +1 -0
  99. package/helpers/index.ts +62 -0
  100. package/helpers/setup.d.ts +50 -0
  101. package/helpers/setup.d.ts.map +1 -0
  102. package/helpers/setup.js +137 -0
  103. package/helpers/setup.js.map +1 -0
  104. package/helpers/setup.ts +144 -0
  105. package/package.json +94 -0
  106. package/schematics/collection.json +11 -0
  107. package/schematics/ng-add/index.js +121 -0
  108. package/schematics/ng-add/schema.json +26 -0
  109. package/scripts/check-allure-results.js +269 -0
  110. package/types/allure.d.ts +76 -0
  111. package/types/global.d.ts +49 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Samaro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,336 @@
1
+ # SamaroUItest
2
+
3
+ <p align="center">
4
+ <strong>Comprehensive Testing Framework for Angular</strong>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/samaro-uitest">
9
+ <img src="https://img.shields.io/npm/v/samaro-uitest.svg" alt="npm version">
10
+ </a>
11
+ <a href="https://github.com/samaro/samaro-uitest/blob/main/LICENSE">
12
+ <img src="https://img.shields.io/npm/l/samaro-uitest.svg" alt="license">
13
+ </a>
14
+ <a href="https://angular.io">
15
+ <img src="https://img.shields.io/badge/Angular-15%2B-red.svg" alt="Angular 15+">
16
+ </a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ ๐Ÿš€ <strong>Vitest</strong> + ๐ŸŽญ <strong>Playwright</strong> + ๐Ÿ“Š <strong>Allure</strong>
21
+ </p>
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - โœ… **One-Command Setup** - Get started in minutes with `ng add samaro-uitest`
28
+ - โšก **Lightning Fast** - Vitest for rapid unit testing feedback
29
+ - ๐ŸŽญ **Real Browser Testing** - Playwright for E2E and component tests
30
+ - ๐Ÿ“Š **Beautiful Reports** - Allure integration for all test types
31
+ - ๐Ÿ”ง **Pre-Configured** - Works out of the box with Angular
32
+ - ๐Ÿ› ๏ธ **Helper Library** - Common testing utilities included
33
+ - ๐Ÿ” **Debug Interface** - Access Angular app state in tests
34
+ - ๐Ÿš€ **CI/CD Ready** - GitHub Actions, GitLab CI, Azure DevOps support
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ ### Using Angular CLI (Recommended)
41
+
42
+ ```bash
43
+ ng add samaro-uitest
44
+ ```
45
+
46
+ ### Using npm
47
+
48
+ ```bash
49
+ npm install --save-dev samaro-uitest
50
+ npx samaro-init
51
+ ```
52
+
53
+ ### Install Playwright Browsers
54
+
55
+ ```bash
56
+ npx playwright install chromium
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Quick Start
62
+
63
+ After installation, you can immediately start testing:
64
+
65
+ ```bash
66
+ # Run unit tests
67
+ npm run test
68
+
69
+ # Run E2E tests
70
+ npm run test:e2e
71
+
72
+ # Run component tests
73
+ npm run test:ct
74
+
75
+ # Generate and view reports
76
+ npm run allure:generate
77
+ npm run allure:open
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Available Scripts
83
+
84
+ | Script | Description |
85
+ |--------|-------------|
86
+ | `npm run test` | Run unit tests with Vitest |
87
+ | `npm run test:run` | Run unit tests once (CI mode) |
88
+ | `npm run test:ui` | Run unit tests with UI |
89
+ | `npm run test:coverage` | Run unit tests with coverage |
90
+ | `npm run test:e2e` | Run E2E tests with Playwright |
91
+ | `npm run test:e2e:ui` | Run E2E tests with Playwright UI |
92
+ | `npm run test:e2e:headed` | Run E2E tests in headed mode |
93
+ | `npm run test:ct` | Run component tests |
94
+ | `npm run allure:generate` | Generate Allure reports |
95
+ | `npm run allure:open` | Open Allure reports |
96
+ | `npm run allure:clean` | Clean Allure results |
97
+
98
+ ---
99
+
100
+ ## Writing Tests
101
+
102
+ ### Unit Tests
103
+
104
+ ```typescript
105
+ // src/app/services/user.service.spec.ts
106
+ import { describe, it, expect, beforeEach } from 'vitest';
107
+ import { TestBed } from '@angular/core/testing';
108
+ import { UserService } from './user.service';
109
+
110
+ describe('UserService', () => {
111
+ let service: UserService;
112
+
113
+ beforeEach(() => {
114
+ TestBed.configureTestingModule({});
115
+ service = TestBed.inject(UserService);
116
+ });
117
+
118
+ it('should be created', () => {
119
+ expect(service).toBeTruthy();
120
+ });
121
+ });
122
+ ```
123
+
124
+ ### E2E Tests
125
+
126
+ ```typescript
127
+ // e2e/auth.spec.ts
128
+ import { test, expect } from '@playwright/test';
129
+ import { generateUniqueUser, register } from 'samaro-uitest/helpers';
130
+
131
+ test('user can register', async ({ page }) => {
132
+ const user = generateUniqueUser();
133
+
134
+ await register(page, user.username, user.email, user.password);
135
+
136
+ await expect(page).toHaveURL('/');
137
+ });
138
+ ```
139
+
140
+ ### Component Tests
141
+
142
+ ```typescript
143
+ // ct-tests/button.spec.ts
144
+ import { test, expect } from '@playwright/test';
145
+
146
+ test('button renders correctly', async ({ page }) => {
147
+ await page.goto('/button-test');
148
+
149
+ const button = page.locator('app-button');
150
+ await expect(button).toBeVisible();
151
+ });
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Test Helpers
157
+
158
+ ### Debug Interface
159
+
160
+ Access your Angular app's state during tests:
161
+
162
+ ```typescript
163
+ import { getToken, getAuthState, waitForAuthState } from 'samaro-uitest/helpers';
164
+
165
+ test('user login', async ({ page }) => {
166
+ await login(page, 'user@example.com', 'password');
167
+
168
+ // Wait for auth state
169
+ await waitForAuthState(page, 'authenticated');
170
+
171
+ // Get token
172
+ const token = await getToken(page);
173
+ expect(token).toBeTruthy();
174
+ });
175
+ ```
176
+
177
+ ### Authentication
178
+
179
+ ```typescript
180
+ import { generateUniqueUser, register, login, logout } from 'samaro-uitest/helpers';
181
+
182
+ const user = generateUniqueUser();
183
+ await register(page, user.username, user.email, user.password);
184
+ await logout(page);
185
+ await login(page, user.email, user.password);
186
+ ```
187
+
188
+ ### API Helpers
189
+
190
+ Speed up tests by using APIs for setup:
191
+
192
+ ```typescript
193
+ import { registerUserViaAPI } from 'samaro-uitest/helpers';
194
+
195
+ test('create article', async ({ page, request }) => {
196
+ const { token } = await registerUserViaAPI(request, {
197
+ username: 'testuser',
198
+ email: 'test@example.com',
199
+ password: 'password123',
200
+ });
201
+
202
+ // Use token for authenticated requests
203
+ });
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Configuration
209
+
210
+ ### Vitest Configuration
211
+
212
+ ```typescript
213
+ // vitest.config.ts
214
+ import { createVitestConfig, mergeConfig } from 'samaro-uitest/config';
215
+
216
+ export default mergeConfig(
217
+ createVitestConfig({
218
+ testGlob: 'src/**/*.spec.ts',
219
+ }),
220
+ {
221
+ test: {
222
+ coverage: {
223
+ exclude: ['**/legacy/**'],
224
+ },
225
+ },
226
+ }
227
+ );
228
+ ```
229
+
230
+ ### Playwright Configuration
231
+
232
+ ```typescript
233
+ // playwright.config.ts
234
+ import { createPlaywrightConfig } from 'samaro-uitest/config';
235
+
236
+ export default createPlaywrightConfig({
237
+ baseURL: 'http://localhost:4200',
238
+ testDir: './e2e',
239
+ webServerCommand: 'npm run start',
240
+ webServerPort: 4200,
241
+ });
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Environment Variables
247
+
248
+ | Variable | Description | Default |
249
+ |----------|-------------|---------|
250
+ | `API_MODE` | Use API for setup operations | `true` |
251
+ | `API_BASE` | Base URL for API calls | `http://localhost:4200/api` |
252
+ | `DEBUG_INTERFACE_NAME` | Name of debug interface | `__app_debug__` |
253
+ | `CI` | CI mode (auto-clean results) | `false` |
254
+
255
+ ---
256
+
257
+ ## CI/CD Integration
258
+
259
+ ### GitHub Actions
260
+
261
+ ```yaml
262
+ name: Tests
263
+ on: [push, pull_request]
264
+
265
+ jobs:
266
+ test:
267
+ runs-on: ubuntu-latest
268
+ steps:
269
+ - uses: actions/checkout@v4
270
+ - uses: actions/setup-node@v4
271
+ with:
272
+ node-version: '20'
273
+ - run: npm ci
274
+ - run: npx playwright install chromium
275
+ - run: npm run test:run
276
+ - run: npm run test:e2e
277
+ - run: npm run allure:generate
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Troubleshooting
283
+
284
+ ### Playwright browsers not installed
285
+
286
+ ```bash
287
+ npx playwright install chromium
288
+ ```
289
+
290
+ ### Tests fail with timeout
291
+
292
+ Increase timeout in configuration:
293
+
294
+ ```typescript
295
+ export default createPlaywrightConfig({
296
+ webServer: {
297
+ timeout: 180_000,
298
+ },
299
+ });
300
+ ```
301
+
302
+ ### Debug interface not available
303
+
304
+ Implement debug interface in your Angular app:
305
+
306
+ ```typescript
307
+ // app.component.ts
308
+ if (typeof window !== 'undefined') {
309
+ window.__app_debug__ = {
310
+ getToken: () => this.authService.getToken(),
311
+ getAuthState: () => this.authService.getAuthState(),
312
+ getCurrentUser: () => this.authService.getCurrentUser(),
313
+ };
314
+ }
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Documentation
320
+
321
+ - [Vitest Documentation](https://vitest.dev/)
322
+ - [Playwright Documentation](https://playwright.dev/)
323
+ - [Allure Documentation](https://docs.qameta.io/allure/)
324
+ - [Angular Testing Guide](https://angular.io/guide/testing)
325
+
326
+ ---
327
+
328
+ ## License
329
+
330
+ MIT ยฉ [Samaro](https://github.com/samaro)
331
+
332
+ ---
333
+
334
+ <p align="center">
335
+ Made with โค๏ธ for the Angular community
336
+ </p>
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require('child_process');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const colors = {
8
+ reset: '\x1b[0m',
9
+ bright: '\x1b[1m',
10
+ green: '\x1b[32m',
11
+ yellow: '\x1b[33m',
12
+ red: '\x1b[31m',
13
+ cyan: '\x1b[36m',
14
+ };
15
+
16
+ const ALLURE_DIRS = [
17
+ { name: 'Unit Tests', dir: 'allure-unit-results', type: 'unit' },
18
+ { name: 'E2E Tests', dir: 'allure-e2e-results', type: 'e2e' },
19
+ { name: 'Component Tests', dir: 'allure-ct-results', type: 'ct' },
20
+ ];
21
+
22
+ function log(message, color = 'reset') {
23
+ console.log(`${colors[color]}${message}${colors.reset}`);
24
+ }
25
+
26
+ function generateReports() {
27
+ log('\n๐Ÿ“Š Generating Allure reports...\n', 'bright');
28
+
29
+ let generatedCount = 0;
30
+
31
+ for (const { name, dir, type } of ALLURE_DIRS) {
32
+ const resultsPath = path.join(process.cwd(), dir);
33
+ const reportPath = path.join(process.cwd(), 'allure-reports', type);
34
+
35
+ if (fs.existsSync(resultsPath)) {
36
+ try {
37
+ execSync(`npx allure generate "${resultsPath}" --output "${reportPath}" --clean`, {
38
+ stdio: 'pipe',
39
+ });
40
+ log(` โœ“ Generated ${name} report`, 'green');
41
+ generatedCount++;
42
+ } catch (error) {
43
+ log(` โœ— Failed to generate ${name} report`, 'red');
44
+ }
45
+ } else {
46
+ log(` โš  No results found for ${name}`, 'yellow');
47
+ }
48
+ }
49
+
50
+ if (generatedCount > 0) {
51
+ log(`\nโœ… Generated ${generatedCount} report(s)`, 'green');
52
+ log(`๐Ÿ“‚ Reports location: ${path.join(process.cwd(), 'allure-reports')}\n`, 'cyan');
53
+ } else {
54
+ log('\nโš  No reports generated. Run tests first.\n', 'yellow');
55
+ }
56
+ }
57
+
58
+ function openReports() {
59
+ log('\n๐ŸŒ Opening Allure reports...\n', 'bright');
60
+
61
+ const reportsPath = path.join(process.cwd(), 'allure-reports');
62
+ if (!fs.existsSync(reportsPath)) {
63
+ log(' โœ— No reports found. Run "samaro-allure generate" first.\n', 'red');
64
+ return;
65
+ }
66
+
67
+ // Check available reports
68
+ const availableReports = fs.readdirSync(reportsPath).filter(name => {
69
+ return fs.statSync(path.join(reportsPath, name)).isDirectory();
70
+ });
71
+
72
+ if (availableReports.length === 0) {
73
+ log(' โœ— No reports found.\n', 'red');
74
+ return;
75
+ }
76
+
77
+ // Open unit report by default, or the first available
78
+ const reportToOpen = availableReports.includes('unit') ? 'unit' : availableReports[0];
79
+ const reportPath = path.join(reportsPath, reportToOpen);
80
+
81
+ try {
82
+ log(` Opening ${reportToOpen} report...`, 'cyan');
83
+ execSync(`npx allure open "${reportPath}"`, { stdio: 'inherit' });
84
+ } catch (error) {
85
+ log(` โœ— Failed to open report: ${error.message}\n`, 'red');
86
+ }
87
+ }
88
+
89
+ function cleanResults() {
90
+ log('\n๐Ÿงน Cleaning Allure results and reports...\n', 'bright');
91
+
92
+ let cleanedCount = 0;
93
+
94
+ for (const { dir } of ALLURE_DIRS) {
95
+ const fullPath = path.join(process.cwd(), dir);
96
+ if (fs.existsSync(fullPath)) {
97
+ try {
98
+ fs.rmSync(fullPath, { recursive: true, force: true });
99
+ log(` โœ“ Removed ${dir}/`, 'green');
100
+ cleanedCount++;
101
+ } catch (error) {
102
+ log(` โœ— Failed to remove ${dir}/: ${error.message}`, 'red');
103
+ }
104
+ }
105
+ }
106
+
107
+ // Also clean the reports directory
108
+ const reportsPath = path.join(process.cwd(), 'allure-reports');
109
+ if (fs.existsSync(reportsPath)) {
110
+ try {
111
+ fs.rmSync(reportsPath, { recursive: true, force: true });
112
+ log(` โœ“ Removed allure-reports/`, 'green');
113
+ cleanedCount++;
114
+ } catch (error) {
115
+ log(` โœ— Failed to remove allure-reports/: ${error.message}`, 'red');
116
+ }
117
+ }
118
+
119
+ if (cleanedCount > 0) {
120
+ log('\nโœ… Cleanup complete!\n', 'green');
121
+ } else {
122
+ log('\nโ„น Nothing to clean\n', 'yellow');
123
+ }
124
+ }
125
+
126
+ function showHelp() {
127
+ console.log(`
128
+ SamaroUItest Allure Manager
129
+
130
+ Usage: samaro-allure [command]
131
+
132
+ Commands:
133
+ generate Generate Allure reports from test results
134
+ open Open Allure reports in browser
135
+ clean Remove all Allure results and reports
136
+ help Show this help message
137
+
138
+ Examples:
139
+ samaro-allure generate
140
+ samaro-allure open
141
+ samaro-allure clean
142
+ `);
143
+ }
144
+
145
+ const command = process.argv[2];
146
+
147
+ switch (command) {
148
+ case 'generate':
149
+ generateReports();
150
+ break;
151
+ case 'open':
152
+ openReports();
153
+ break;
154
+ case 'clean':
155
+ cleanResults();
156
+ break;
157
+ case 'help':
158
+ case '--help':
159
+ case '-h':
160
+ showHelp();
161
+ break;
162
+ default:
163
+ if (!command) {
164
+ console.error('โŒ Error: No command provided');
165
+ showHelp();
166
+ process.exit(1);
167
+ } else {
168
+ console.error(`โŒ Unknown command: ${command}`);
169
+ showHelp();
170
+ process.exit(1);
171
+ }
172
+ }