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
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
|
+
}
|