@oalacea/daemon 0.5.0 → 0.5.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/CHANGELOG.md +46 -38
- package/LICENSE +23 -23
- package/README.md +147 -141
- package/agents/deps-analyzer.js +366 -366
- package/agents/detector.js +570 -570
- package/agents/fix-engine.js +305 -305
- package/agents/lighthouse-scanner.js +405 -405
- package/agents/perf-analyzer.js +294 -294
- package/agents/perf-front-analyzer.js +229 -229
- package/agents/test-generator.js +387 -387
- package/agents/test-runner.js +318 -318
- package/bin/Dockerfile +75 -74
- package/bin/cli.js +449 -449
- package/lib/config.js +250 -250
- package/lib/docker.js +207 -207
- package/lib/reporter.js +297 -297
- package/package.json +34 -34
- package/prompts/DEPS_EFFICIENCY.md +558 -558
- package/prompts/E2E.md +491 -491
- package/prompts/EXECUTE.md +1060 -1060
- package/prompts/INTEGRATION_API.md +484 -484
- package/prompts/INTEGRATION_DB.md +425 -425
- package/prompts/PERF_API.md +433 -433
- package/prompts/PERF_DB.md +430 -430
- package/prompts/PERF_FRONT.md +357 -357
- package/prompts/REMEDIATION.md +482 -482
- package/prompts/UNIT.md +260 -260
- package/scripts/dev.js +106 -106
- package/templates/README.md +38 -38
- package/templates/k6/load-test.js +54 -54
- package/templates/playwright/e2e.spec.ts +61 -61
- package/templates/vitest/angular-component.test.ts +38 -38
- package/templates/vitest/api.test.ts +51 -51
- package/templates/vitest/component.test.ts +27 -27
- package/templates/vitest/hook.test.ts +36 -36
- package/templates/vitest/solid-component.test.ts +34 -34
- package/templates/vitest/svelte-component.test.ts +33 -33
- package/templates/vitest/vue-component.test.ts +39 -39
package/scripts/dev.js
CHANGED
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Daemon Development Script
|
|
5
|
-
*
|
|
6
|
-
* For local development and testing of the Daemon CLI.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { execSync } = require('child_process');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
|
|
12
|
-
const command = process.argv[2] || 'help';
|
|
13
|
-
|
|
14
|
-
const commands = {
|
|
15
|
-
help: () => {
|
|
16
|
-
console.log(`
|
|
17
|
-
Daemon Development Commands
|
|
18
|
-
|
|
19
|
-
Usage: node scripts/dev.js <command>
|
|
20
|
-
|
|
21
|
-
Commands:
|
|
22
|
-
test Run detector test
|
|
23
|
-
build Build Docker image
|
|
24
|
-
start Start container
|
|
25
|
-
stop Stop container
|
|
26
|
-
clean Remove container and image
|
|
27
|
-
logs Show container logs
|
|
28
|
-
shell Open shell in container
|
|
29
|
-
link Link package globally for testing
|
|
30
|
-
`);
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
test: () => {
|
|
34
|
-
console.log('Testing detector...');
|
|
35
|
-
const detector = require('../agents/detector.js');
|
|
36
|
-
detector.analyze(process.cwd())
|
|
37
|
-
.then((context) => {
|
|
38
|
-
console.log(JSON.stringify(context, null, 2));
|
|
39
|
-
})
|
|
40
|
-
.catch((err) => {
|
|
41
|
-
console.error('Detection failed:', err);
|
|
42
|
-
process.exit(1);
|
|
43
|
-
});
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
build: () => {
|
|
47
|
-
console.log('Building Docker image...');
|
|
48
|
-
const dockerfile = path.join(__dirname, '..', 'bin', 'Dockerfile');
|
|
49
|
-
execSync(`docker build -t daemon-tools -f "${dockerfile}" "${path.dirname(dockerfile)}"`, {
|
|
50
|
-
stdio: 'inherit',
|
|
51
|
-
});
|
|
52
|
-
console.log('✓ Build complete');
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
start: () => {
|
|
56
|
-
console.log('Starting container...');
|
|
57
|
-
try {
|
|
58
|
-
execSync('docker start daemon-tools', { stdio: 'inherit' });
|
|
59
|
-
console.log('✓ Container started');
|
|
60
|
-
} catch {
|
|
61
|
-
const isLinux = process.platform === 'linux';
|
|
62
|
-
const networkFlag = isLinux ? '--network=host' : '';
|
|
63
|
-
execSync(`docker run -d --name daemon-tools ${networkFlag} daemon-tools`, {
|
|
64
|
-
stdio: 'inherit',
|
|
65
|
-
});
|
|
66
|
-
console.log('✓ Container created');
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
stop: () => {
|
|
71
|
-
console.log('Stopping container...');
|
|
72
|
-
execSync('docker stop daemon-tools', { stdio: 'inherit' });
|
|
73
|
-
console.log('✓ Container stopped');
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
clean: () => {
|
|
77
|
-
console.log('Removing container...');
|
|
78
|
-
execSync('docker rm -f daemon-tools', { stdio: 'inherit', timeout: 5000 }).catch(() => {});
|
|
79
|
-
console.log('Removing image...');
|
|
80
|
-
execSync('docker rmi daemon-tools', { stdio: 'inherit', timeout: 30000 }).catch(() => {});
|
|
81
|
-
console.log('✓ Clean complete');
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
logs: () => {
|
|
85
|
-
execSync('docker logs -f daemon-tools', { stdio: 'inherit' });
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
shell: () => {
|
|
89
|
-
console.log('Opening shell in container...');
|
|
90
|
-
execSync('docker exec -it daemon-tools bash', { stdio: 'inherit' });
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
link: () => {
|
|
94
|
-
console.log('Linking package globally...');
|
|
95
|
-
execSync('npm link', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
|
|
96
|
-
console.log('✓ Package linked globally');
|
|
97
|
-
console.log('You can now run: daemon');
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
if (commands[command]) {
|
|
102
|
-
commands[command]();
|
|
103
|
-
} else {
|
|
104
|
-
console.log(`Unknown command: ${command}`);
|
|
105
|
-
commands.help();
|
|
106
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Daemon Development Script
|
|
5
|
+
*
|
|
6
|
+
* For local development and testing of the Daemon CLI.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { execSync } = require('child_process');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const command = process.argv[2] || 'help';
|
|
13
|
+
|
|
14
|
+
const commands = {
|
|
15
|
+
help: () => {
|
|
16
|
+
console.log(`
|
|
17
|
+
Daemon Development Commands
|
|
18
|
+
|
|
19
|
+
Usage: node scripts/dev.js <command>
|
|
20
|
+
|
|
21
|
+
Commands:
|
|
22
|
+
test Run detector test
|
|
23
|
+
build Build Docker image
|
|
24
|
+
start Start container
|
|
25
|
+
stop Stop container
|
|
26
|
+
clean Remove container and image
|
|
27
|
+
logs Show container logs
|
|
28
|
+
shell Open shell in container
|
|
29
|
+
link Link package globally for testing
|
|
30
|
+
`);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
test: () => {
|
|
34
|
+
console.log('Testing detector...');
|
|
35
|
+
const detector = require('../agents/detector.js');
|
|
36
|
+
detector.analyze(process.cwd())
|
|
37
|
+
.then((context) => {
|
|
38
|
+
console.log(JSON.stringify(context, null, 2));
|
|
39
|
+
})
|
|
40
|
+
.catch((err) => {
|
|
41
|
+
console.error('Detection failed:', err);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
build: () => {
|
|
47
|
+
console.log('Building Docker image...');
|
|
48
|
+
const dockerfile = path.join(__dirname, '..', 'bin', 'Dockerfile');
|
|
49
|
+
execSync(`docker build -t daemon-tools -f "${dockerfile}" "${path.dirname(dockerfile)}"`, {
|
|
50
|
+
stdio: 'inherit',
|
|
51
|
+
});
|
|
52
|
+
console.log('✓ Build complete');
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
start: () => {
|
|
56
|
+
console.log('Starting container...');
|
|
57
|
+
try {
|
|
58
|
+
execSync('docker start daemon-tools', { stdio: 'inherit' });
|
|
59
|
+
console.log('✓ Container started');
|
|
60
|
+
} catch {
|
|
61
|
+
const isLinux = process.platform === 'linux';
|
|
62
|
+
const networkFlag = isLinux ? '--network=host' : '';
|
|
63
|
+
execSync(`docker run -d --name daemon-tools ${networkFlag} daemon-tools`, {
|
|
64
|
+
stdio: 'inherit',
|
|
65
|
+
});
|
|
66
|
+
console.log('✓ Container created');
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
stop: () => {
|
|
71
|
+
console.log('Stopping container...');
|
|
72
|
+
execSync('docker stop daemon-tools', { stdio: 'inherit' });
|
|
73
|
+
console.log('✓ Container stopped');
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
clean: () => {
|
|
77
|
+
console.log('Removing container...');
|
|
78
|
+
execSync('docker rm -f daemon-tools', { stdio: 'inherit', timeout: 5000 }).catch(() => {});
|
|
79
|
+
console.log('Removing image...');
|
|
80
|
+
execSync('docker rmi daemon-tools', { stdio: 'inherit', timeout: 30000 }).catch(() => {});
|
|
81
|
+
console.log('✓ Clean complete');
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
logs: () => {
|
|
85
|
+
execSync('docker logs -f daemon-tools', { stdio: 'inherit' });
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
shell: () => {
|
|
89
|
+
console.log('Opening shell in container...');
|
|
90
|
+
execSync('docker exec -it daemon-tools bash', { stdio: 'inherit' });
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
link: () => {
|
|
94
|
+
console.log('Linking package globally...');
|
|
95
|
+
execSync('npm link', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
|
|
96
|
+
console.log('✓ Package linked globally');
|
|
97
|
+
console.log('You can now run: daemon');
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (commands[command]) {
|
|
102
|
+
commands[command]();
|
|
103
|
+
} else {
|
|
104
|
+
console.log(`Unknown command: ${command}`);
|
|
105
|
+
commands.help();
|
|
106
|
+
}
|
package/templates/README.md
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
# Daemon Templates
|
|
2
|
-
|
|
3
|
-
This directory contains test templates for different frameworks and tools.
|
|
4
|
-
|
|
5
|
-
## Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
templates/
|
|
9
|
-
├── vitest/ # Vitest test templates
|
|
10
|
-
│ ├── component.test.ts # React component template
|
|
11
|
-
│ ├── vue-component.test.ts # Vue component template
|
|
12
|
-
│ ├── solid-component.test.ts # Solid component template
|
|
13
|
-
│ ├── svelte-component.test.ts # Svelte component template
|
|
14
|
-
│ ├── angular-component.test.ts # Angular component template
|
|
15
|
-
│ ├── hook.test.ts # React hooks template
|
|
16
|
-
│ └── api.test.ts # API route template
|
|
17
|
-
├── playwright/ # Playwright E2E templates
|
|
18
|
-
│ ├── auth.spec.ts
|
|
19
|
-
│ └── crud.spec.ts
|
|
20
|
-
├── k6/ # k6 backend performance templates
|
|
21
|
-
│ └── load-test.js
|
|
22
|
-
└── lighthouse/ # Lighthouse frontend performance (via CLI)
|
|
23
|
-
└── (run directly with npx lighthouse)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Framework Support
|
|
27
|
-
|
|
28
|
-
| Framework | Template | Testing Library |
|
|
29
|
-
|-----------|----------|-----------------|
|
|
30
|
-
| React | `component.test.ts` | `@testing-library/react` |
|
|
31
|
-
| Vue | `vue-component.test.ts` | `@vue/test-utils` |
|
|
32
|
-
| Solid | `solid-component.test.ts` | `@solidjs/testing-library` |
|
|
33
|
-
| Svelte | `svelte-component.test.ts` | `@testing-library/svelte` |
|
|
34
|
-
| Angular | `angular-component.test.ts` | `@angular/core/testing` |
|
|
35
|
-
|
|
36
|
-
## Usage
|
|
37
|
-
|
|
38
|
-
Templates are used by the test generator agent to create new test files based on the detected framework and patterns.
|
|
1
|
+
# Daemon Templates
|
|
2
|
+
|
|
3
|
+
This directory contains test templates for different frameworks and tools.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
templates/
|
|
9
|
+
├── vitest/ # Vitest test templates
|
|
10
|
+
│ ├── component.test.ts # React component template
|
|
11
|
+
│ ├── vue-component.test.ts # Vue component template
|
|
12
|
+
│ ├── solid-component.test.ts # Solid component template
|
|
13
|
+
│ ├── svelte-component.test.ts # Svelte component template
|
|
14
|
+
│ ├── angular-component.test.ts # Angular component template
|
|
15
|
+
│ ├── hook.test.ts # React hooks template
|
|
16
|
+
│ └── api.test.ts # API route template
|
|
17
|
+
├── playwright/ # Playwright E2E templates
|
|
18
|
+
│ ├── auth.spec.ts
|
|
19
|
+
│ └── crud.spec.ts
|
|
20
|
+
├── k6/ # k6 backend performance templates
|
|
21
|
+
│ └── load-test.js
|
|
22
|
+
└── lighthouse/ # Lighthouse frontend performance (via CLI)
|
|
23
|
+
└── (run directly with npx lighthouse)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Framework Support
|
|
27
|
+
|
|
28
|
+
| Framework | Template | Testing Library |
|
|
29
|
+
|-----------|----------|-----------------|
|
|
30
|
+
| React | `component.test.ts` | `@testing-library/react` |
|
|
31
|
+
| Vue | `vue-component.test.ts` | `@vue/test-utils` |
|
|
32
|
+
| Solid | `solid-component.test.ts` | `@solidjs/testing-library` |
|
|
33
|
+
| Svelte | `svelte-component.test.ts` | `@testing-library/svelte` |
|
|
34
|
+
| Angular | `angular-component.test.ts` | `@angular/core/testing` |
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
Templates are used by the test generator agent to create new test files based on the detected framework and patterns.
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import http from 'k6/http';
|
|
2
|
-
import { check, sleep } from 'k6';
|
|
3
|
-
|
|
4
|
-
// Configuration
|
|
5
|
-
export const options = {
|
|
6
|
-
stages: [
|
|
7
|
-
{ duration: '30s', target: 20 }, // Ramp up to 20 users
|
|
8
|
-
{ duration: '1m', target: 20 }, // Stay at 20 users
|
|
9
|
-
{ duration: '30s', target: 50 }, // Ramp up to 50 users
|
|
10
|
-
{ duration: '1m', target: 50 }, // Stay at 50 users
|
|
11
|
-
{ duration: '30s', target: 0 }, // Ramp down
|
|
12
|
-
],
|
|
13
|
-
thresholds: {
|
|
14
|
-
http_req_duration: ['p(95)<200', 'p(99)<500'],
|
|
15
|
-
http_req_failed: ['rate<0.01'],
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const BASE_URL = __ENV.BASE_URL || 'http://host.docker.internal:3000';
|
|
20
|
-
|
|
21
|
-
export default function () {
|
|
22
|
-
// Test homepage
|
|
23
|
-
let res = http.get(`${BASE_URL}/`);
|
|
24
|
-
check(res, {
|
|
25
|
-
'homepage status 200': (r) => r.status === 200,
|
|
26
|
-
'homepage response time < 200ms': (r) => r.timings.duration < 200,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
sleep(1);
|
|
30
|
-
|
|
31
|
-
// Test API endpoint
|
|
32
|
-
res = http.get(`${BASE_URL}/api/users`);
|
|
33
|
-
check(res, {
|
|
34
|
-
'users API status 200': (r) => r.status === 200,
|
|
35
|
-
'users response time < 200ms': (r) => r.timings.duration < 200,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
sleep(1);
|
|
39
|
-
|
|
40
|
-
// Test POST endpoint
|
|
41
|
-
res = http.post(`${BASE_URL}/api/contact`, JSON.stringify({
|
|
42
|
-
name: 'Test User',
|
|
43
|
-
email: 'test@example.com',
|
|
44
|
-
message: 'Test message',
|
|
45
|
-
}), {
|
|
46
|
-
headers: { 'Content-Type': 'application/json' },
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
check(res, {
|
|
50
|
-
'contact API status 200': (r) => r.status === 200,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
sleep(1);
|
|
54
|
-
}
|
|
1
|
+
import http from 'k6/http';
|
|
2
|
+
import { check, sleep } from 'k6';
|
|
3
|
+
|
|
4
|
+
// Configuration
|
|
5
|
+
export const options = {
|
|
6
|
+
stages: [
|
|
7
|
+
{ duration: '30s', target: 20 }, // Ramp up to 20 users
|
|
8
|
+
{ duration: '1m', target: 20 }, // Stay at 20 users
|
|
9
|
+
{ duration: '30s', target: 50 }, // Ramp up to 50 users
|
|
10
|
+
{ duration: '1m', target: 50 }, // Stay at 50 users
|
|
11
|
+
{ duration: '30s', target: 0 }, // Ramp down
|
|
12
|
+
],
|
|
13
|
+
thresholds: {
|
|
14
|
+
http_req_duration: ['p(95)<200', 'p(99)<500'],
|
|
15
|
+
http_req_failed: ['rate<0.01'],
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const BASE_URL = __ENV.BASE_URL || 'http://host.docker.internal:3000';
|
|
20
|
+
|
|
21
|
+
export default function () {
|
|
22
|
+
// Test homepage
|
|
23
|
+
let res = http.get(`${BASE_URL}/`);
|
|
24
|
+
check(res, {
|
|
25
|
+
'homepage status 200': (r) => r.status === 200,
|
|
26
|
+
'homepage response time < 200ms': (r) => r.timings.duration < 200,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
sleep(1);
|
|
30
|
+
|
|
31
|
+
// Test API endpoint
|
|
32
|
+
res = http.get(`${BASE_URL}/api/users`);
|
|
33
|
+
check(res, {
|
|
34
|
+
'users API status 200': (r) => r.status === 200,
|
|
35
|
+
'users response time < 200ms': (r) => r.timings.duration < 200,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
sleep(1);
|
|
39
|
+
|
|
40
|
+
// Test POST endpoint
|
|
41
|
+
res = http.post(`${BASE_URL}/api/contact`, JSON.stringify({
|
|
42
|
+
name: 'Test User',
|
|
43
|
+
email: 'test@example.com',
|
|
44
|
+
message: 'Test message',
|
|
45
|
+
}), {
|
|
46
|
+
headers: { 'Content-Type': 'application/json' },
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
check(res, {
|
|
50
|
+
'contact API status 200': (r) => r.status === 200,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
sleep(1);
|
|
54
|
+
}
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
test.describe('Authentication Flow', () => {
|
|
4
|
-
test.beforeEach(async ({ page }) => {
|
|
5
|
-
await page.goto('/login');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
test('should login with valid credentials', async ({ page }) => {
|
|
9
|
-
await page.fill('input[name="email"]', 'test@example.com');
|
|
10
|
-
await page.fill('input[name="password"]', 'password123');
|
|
11
|
-
await page.click('button[type="submit"]');
|
|
12
|
-
|
|
13
|
-
// Should redirect to dashboard
|
|
14
|
-
await expect(page).toHaveURL(/\/dashboard/);
|
|
15
|
-
await expect(page.locator('h1')).toContainText('Dashboard');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('should show error with invalid credentials', async ({ page }) => {
|
|
19
|
-
await page.fill('input[name="email"]', 'test@example.com');
|
|
20
|
-
await page.fill('input[name="password"]', 'wrong-password');
|
|
21
|
-
await page.click('button[type="submit"]');
|
|
22
|
-
|
|
23
|
-
await expect(page.locator('.error')).toContainText('Invalid credentials');
|
|
24
|
-
await expect(page).toHaveURL('/login');
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test.describe('Navigation', () => {
|
|
29
|
-
test('should navigate between pages', async ({ page }) => {
|
|
30
|
-
await page.goto('/');
|
|
31
|
-
|
|
32
|
-
await page.click('text=About');
|
|
33
|
-
await expect(page).toHaveURL('/about');
|
|
34
|
-
|
|
35
|
-
await page.goBack();
|
|
36
|
-
await expect(page).toHaveURL('/');
|
|
37
|
-
|
|
38
|
-
await page.goForward();
|
|
39
|
-
await expect(page).toHaveURL('/about');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test.describe('Form Interaction', () => {
|
|
44
|
-
test('should submit form successfully', async ({ page }) => {
|
|
45
|
-
await page.goto('/form');
|
|
46
|
-
|
|
47
|
-
await page.fill('input[name="name"]', 'Test User');
|
|
48
|
-
await page.fill('input[name="email"]', 'test@example.com');
|
|
49
|
-
await page.click('button[type="submit"]');
|
|
50
|
-
|
|
51
|
-
await expect(page.locator('.success')).toContainText('Form submitted');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('should show validation errors', async ({ page }) => {
|
|
55
|
-
await page.goto('/form');
|
|
56
|
-
await page.click('button[type="submit"]');
|
|
57
|
-
|
|
58
|
-
await expect(page.locator('input[name="name"]')).toHaveAttribute('aria-invalid', 'true');
|
|
59
|
-
await expect(page.locator('input[name="email"]')).toHaveAttribute('aria-invalid', 'true');
|
|
60
|
-
});
|
|
61
|
-
});
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test.describe('Authentication Flow', () => {
|
|
4
|
+
test.beforeEach(async ({ page }) => {
|
|
5
|
+
await page.goto('/login');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test('should login with valid credentials', async ({ page }) => {
|
|
9
|
+
await page.fill('input[name="email"]', 'test@example.com');
|
|
10
|
+
await page.fill('input[name="password"]', 'password123');
|
|
11
|
+
await page.click('button[type="submit"]');
|
|
12
|
+
|
|
13
|
+
// Should redirect to dashboard
|
|
14
|
+
await expect(page).toHaveURL(/\/dashboard/);
|
|
15
|
+
await expect(page.locator('h1')).toContainText('Dashboard');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('should show error with invalid credentials', async ({ page }) => {
|
|
19
|
+
await page.fill('input[name="email"]', 'test@example.com');
|
|
20
|
+
await page.fill('input[name="password"]', 'wrong-password');
|
|
21
|
+
await page.click('button[type="submit"]');
|
|
22
|
+
|
|
23
|
+
await expect(page.locator('.error')).toContainText('Invalid credentials');
|
|
24
|
+
await expect(page).toHaveURL('/login');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test.describe('Navigation', () => {
|
|
29
|
+
test('should navigate between pages', async ({ page }) => {
|
|
30
|
+
await page.goto('/');
|
|
31
|
+
|
|
32
|
+
await page.click('text=About');
|
|
33
|
+
await expect(page).toHaveURL('/about');
|
|
34
|
+
|
|
35
|
+
await page.goBack();
|
|
36
|
+
await expect(page).toHaveURL('/');
|
|
37
|
+
|
|
38
|
+
await page.goForward();
|
|
39
|
+
await expect(page).toHaveURL('/about');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test.describe('Form Interaction', () => {
|
|
44
|
+
test('should submit form successfully', async ({ page }) => {
|
|
45
|
+
await page.goto('/form');
|
|
46
|
+
|
|
47
|
+
await page.fill('input[name="name"]', 'Test User');
|
|
48
|
+
await page.fill('input[name="email"]', 'test@example.com');
|
|
49
|
+
await page.click('button[type="submit"]');
|
|
50
|
+
|
|
51
|
+
await expect(page.locator('.success')).toContainText('Form submitted');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('should show validation errors', async ({ page }) => {
|
|
55
|
+
await page.goto('/form');
|
|
56
|
+
await page.click('button[type="submit"]');
|
|
57
|
+
|
|
58
|
+
await expect(page.locator('input[name="name"]')).toHaveAttribute('aria-invalid', 'true');
|
|
59
|
+
await expect(page.locator('input[name="email"]')).toHaveAttribute('aria-invalid', 'true');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
-
|
|
4
|
-
// TODO: Import your component
|
|
5
|
-
// import { ComponentName } from '@/components/component-name.component';
|
|
6
|
-
|
|
7
|
-
describe('ComponentName', () => {
|
|
8
|
-
let component: ComponentFixture<any>;
|
|
9
|
-
|
|
10
|
-
beforeEach(async () => {
|
|
11
|
-
// TODO: Configure TestBed
|
|
12
|
-
// await TestBed.configureTestingModule({
|
|
13
|
-
// imports: [ComponentName],
|
|
14
|
-
// }).compileComponents();
|
|
15
|
-
|
|
16
|
-
// component = TestBed.createComponent(ComponentName);
|
|
17
|
-
// component.detectChanges();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should create', () => {
|
|
21
|
-
// TODO: Test component creation
|
|
22
|
-
// expect(component.componentInstance).toBeTruthy();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should render title', () => {
|
|
26
|
-
// TODO: Test rendered content
|
|
27
|
-
// const compiled = component.nativeElement as HTMLElement;
|
|
28
|
-
// expect(compiled.querySelector('h1')?.textContent).toContain('Test');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should handle user interaction', () => {
|
|
32
|
-
// TODO: Test events
|
|
33
|
-
// const button = component.nativeElement.querySelector('button');
|
|
34
|
-
// button.click();
|
|
35
|
-
// component.detectChanges();
|
|
36
|
-
// expect(component.instance.value).toBe('updated');
|
|
37
|
-
});
|
|
38
|
-
});
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
|
|
4
|
+
// TODO: Import your component
|
|
5
|
+
// import { ComponentName } from '@/components/component-name.component';
|
|
6
|
+
|
|
7
|
+
describe('ComponentName', () => {
|
|
8
|
+
let component: ComponentFixture<any>;
|
|
9
|
+
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
// TODO: Configure TestBed
|
|
12
|
+
// await TestBed.configureTestingModule({
|
|
13
|
+
// imports: [ComponentName],
|
|
14
|
+
// }).compileComponents();
|
|
15
|
+
|
|
16
|
+
// component = TestBed.createComponent(ComponentName);
|
|
17
|
+
// component.detectChanges();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should create', () => {
|
|
21
|
+
// TODO: Test component creation
|
|
22
|
+
// expect(component.componentInstance).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should render title', () => {
|
|
26
|
+
// TODO: Test rendered content
|
|
27
|
+
// const compiled = component.nativeElement as HTMLElement;
|
|
28
|
+
// expect(compiled.querySelector('h1')?.textContent).toContain('Test');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should handle user interaction', () => {
|
|
32
|
+
// TODO: Test events
|
|
33
|
+
// const button = component.nativeElement.querySelector('button');
|
|
34
|
+
// button.click();
|
|
35
|
+
// component.detectChanges();
|
|
36
|
+
// expect(component.instance.value).toBe('updated');
|
|
37
|
+
});
|
|
38
|
+
});
|