angular-uitest 1.0.3
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.mjs +178 -0
- package/bin/samaro-init.mjs +407 -0
- package/bin/samaro-test.mjs +119 -0
- package/dist/cjs/config/index.d.ts +4 -0
- package/dist/cjs/config/index.d.ts.map +1 -0
- package/dist/cjs/config/index.js +11 -0
- package/dist/cjs/config/index.js.map +1 -0
- package/dist/cjs/config/playwright.component.config.d.ts +12 -0
- package/dist/cjs/config/playwright.component.config.d.ts.map +1 -0
- package/dist/cjs/config/playwright.component.config.js +42 -0
- package/dist/cjs/config/playwright.component.config.js.map +1 -0
- package/dist/cjs/config/playwright.config.d.ts +14 -0
- package/dist/cjs/config/playwright.config.d.ts.map +1 -0
- package/dist/cjs/config/playwright.config.js +53 -0
- package/dist/cjs/config/playwright.config.js.map +1 -0
- package/dist/cjs/config/vitest.config.d.ts +12 -0
- package/dist/cjs/config/vitest.config.d.ts.map +1 -0
- package/dist/cjs/config/vitest.config.js +60 -0
- package/dist/cjs/config/vitest.config.js.map +1 -0
- package/dist/cjs/helpers/allure.d.ts +141 -0
- package/dist/cjs/helpers/allure.d.ts.map +1 -0
- package/dist/cjs/helpers/allure.js +331 -0
- package/dist/cjs/helpers/allure.js.map +1 -0
- package/dist/cjs/helpers/api.d.ts +69 -0
- package/dist/cjs/helpers/api.d.ts.map +1 -0
- package/dist/cjs/helpers/api.js +163 -0
- package/dist/cjs/helpers/api.js.map +1 -0
- package/dist/cjs/helpers/auth.d.ts +35 -0
- package/dist/cjs/helpers/auth.d.ts.map +1 -0
- package/dist/cjs/helpers/auth.js +104 -0
- package/dist/cjs/helpers/auth.js.map +1 -0
- package/dist/cjs/helpers/config.d.ts +34 -0
- package/dist/cjs/helpers/config.d.ts.map +1 -0
- package/dist/cjs/helpers/config.js +70 -0
- package/dist/cjs/helpers/config.js.map +1 -0
- package/dist/cjs/helpers/debug.d.ts +48 -0
- package/dist/cjs/helpers/debug.d.ts.map +1 -0
- package/dist/cjs/helpers/debug.js +86 -0
- package/dist/cjs/helpers/debug.js.map +1 -0
- package/dist/cjs/helpers/index.d.ts +8 -0
- package/dist/cjs/helpers/index.d.ts.map +1 -0
- package/dist/cjs/helpers/index.js +76 -0
- package/dist/cjs/helpers/index.js.map +1 -0
- package/dist/cjs/helpers/setup.d.ts +50 -0
- package/dist/cjs/helpers/setup.d.ts.map +1 -0
- package/dist/cjs/helpers/setup.js +137 -0
- package/dist/cjs/helpers/setup.js.map +1 -0
- package/dist/cjs/src/index.d.ts +17 -0
- package/dist/cjs/src/index.d.ts.map +1 -0
- package/dist/cjs/src/index.js +99 -0
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/esm/config/index.d.ts +4 -0
- package/dist/esm/config/index.d.ts.map +1 -0
- package/dist/esm/config/index.mjs +4 -0
- package/dist/esm/config/index.mjs.map +1 -0
- package/dist/esm/config/playwright.component.config.d.ts +12 -0
- package/dist/esm/config/playwright.component.config.d.ts.map +1 -0
- package/dist/esm/config/playwright.component.config.mjs +39 -0
- package/dist/esm/config/playwright.component.config.mjs.map +1 -0
- package/dist/esm/config/playwright.config.d.ts +14 -0
- package/dist/esm/config/playwright.config.d.ts.map +1 -0
- package/dist/esm/config/playwright.config.mjs +50 -0
- package/dist/esm/config/playwright.config.mjs.map +1 -0
- package/dist/esm/config/vitest.config.d.ts +12 -0
- package/dist/esm/config/vitest.config.d.ts.map +1 -0
- package/dist/esm/config/vitest.config.mjs +56 -0
- package/dist/esm/config/vitest.config.mjs.map +1 -0
- package/dist/esm/helpers/allure.d.ts +141 -0
- package/dist/esm/helpers/allure.d.ts.map +1 -0
- package/dist/esm/helpers/allure.mjs +306 -0
- package/dist/esm/helpers/allure.mjs.map +1 -0
- package/dist/esm/helpers/api.d.ts +69 -0
- package/dist/esm/helpers/api.d.ts.map +1 -0
- package/dist/esm/helpers/api.mjs +154 -0
- package/dist/esm/helpers/api.mjs.map +1 -0
- package/dist/esm/helpers/auth.d.ts +35 -0
- package/dist/esm/helpers/auth.d.ts.map +1 -0
- package/dist/esm/helpers/auth.mjs +96 -0
- package/dist/esm/helpers/auth.mjs.map +1 -0
- package/dist/esm/helpers/config.d.ts +34 -0
- package/dist/esm/helpers/config.d.ts.map +1 -0
- package/dist/esm/helpers/config.mjs +63 -0
- package/dist/esm/helpers/config.mjs.map +1 -0
- package/dist/esm/helpers/debug.d.ts +48 -0
- package/dist/esm/helpers/debug.d.ts.map +1 -0
- package/dist/esm/helpers/debug.mjs +76 -0
- package/dist/esm/helpers/debug.mjs.map +1 -0
- package/dist/esm/helpers/index.d.ts +8 -0
- package/dist/esm/helpers/index.d.ts.map +1 -0
- package/dist/esm/helpers/index.mjs +19 -0
- package/dist/esm/helpers/index.mjs.map +1 -0
- package/dist/esm/helpers/setup.d.ts +50 -0
- package/dist/esm/helpers/setup.d.ts.map +1 -0
- package/dist/esm/helpers/setup.mjs +95 -0
- package/dist/esm/helpers/setup.mjs.map +1 -0
- package/dist/esm/src/index.d.ts +17 -0
- package/dist/esm/src/index.d.ts.map +1 -0
- package/dist/esm/src/index.mjs +40 -0
- package/dist/esm/src/index.mjs.map +1 -0
- package/dist/types/config/index.d.ts +4 -0
- package/dist/types/config/index.d.ts.map +1 -0
- package/dist/types/config/playwright.component.config.d.ts +12 -0
- package/dist/types/config/playwright.component.config.d.ts.map +1 -0
- package/dist/types/config/playwright.config.d.ts +14 -0
- package/dist/types/config/playwright.config.d.ts.map +1 -0
- package/dist/types/config/vitest.config.d.ts +12 -0
- package/dist/types/config/vitest.config.d.ts.map +1 -0
- package/dist/types/helpers/allure.d.ts +141 -0
- package/dist/types/helpers/allure.d.ts.map +1 -0
- package/dist/types/helpers/api.d.ts +69 -0
- package/dist/types/helpers/api.d.ts.map +1 -0
- package/dist/types/helpers/auth.d.ts +35 -0
- package/dist/types/helpers/auth.d.ts.map +1 -0
- package/dist/types/helpers/config.d.ts +34 -0
- package/dist/types/helpers/config.d.ts.map +1 -0
- package/dist/types/helpers/debug.d.ts +48 -0
- package/dist/types/helpers/debug.d.ts.map +1 -0
- package/dist/types/helpers/index.d.ts +8 -0
- package/dist/types/helpers/index.d.ts.map +1 -0
- package/dist/types/helpers/setup.d.ts +50 -0
- package/dist/types/helpers/setup.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +17 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/package.json +140 -0
- package/schematics/collection.json +11 -0
- package/schematics/ng-add/index.js +126 -0
- package/schematics/ng-add/schema.json +26 -0
- package/scripts/check-allure-results.mjs +300 -0
- package/scripts/rename-esm-files.mjs +76 -0
- package/types/allure.d.ts +76 -0
- package/types/global.d.ts +49 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAPIConfig = getAPIConfig;
|
|
4
|
+
exports.registerUserViaAPI = registerUserViaAPI;
|
|
5
|
+
exports.loginUserViaAPI = loginUserViaAPI;
|
|
6
|
+
exports.createArticleViaAPI = createArticleViaAPI;
|
|
7
|
+
exports.deleteArticleViaAPI = deleteArticleViaAPI;
|
|
8
|
+
exports.updateUserViaAPI = updateUserViaAPI;
|
|
9
|
+
exports.getCurrentUserViaAPI = getCurrentUserViaAPI;
|
|
10
|
+
/**
|
|
11
|
+
* Get API configuration from environment variables
|
|
12
|
+
*/
|
|
13
|
+
function getAPIConfig() {
|
|
14
|
+
return {
|
|
15
|
+
baseURL: process.env.API_BASE || process.env.NG_API_URL || 'http://localhost:4200/api',
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Register a user via API
|
|
20
|
+
*/
|
|
21
|
+
async function registerUserViaAPI(request, user) {
|
|
22
|
+
const config = getAPIConfig();
|
|
23
|
+
try {
|
|
24
|
+
const response = await request.post(`${config.baseURL}/users`, {
|
|
25
|
+
data: { user },
|
|
26
|
+
headers: {
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok()) {
|
|
31
|
+
const errorText = await response.text();
|
|
32
|
+
throw new Error(`API registration failed (${response.status()}): ${errorText}`);
|
|
33
|
+
}
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
return {
|
|
36
|
+
token: data.user.token,
|
|
37
|
+
username: data.user.username,
|
|
38
|
+
email: data.user.email,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new Error(`Failed to register user via API: ${error}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Login a user via API
|
|
47
|
+
*/
|
|
48
|
+
async function loginUserViaAPI(request, email, password) {
|
|
49
|
+
const config = getAPIConfig();
|
|
50
|
+
try {
|
|
51
|
+
const response = await request.post(`${config.baseURL}/users/login`, {
|
|
52
|
+
data: { user: { email, password } },
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok()) {
|
|
58
|
+
const errorText = await response.text();
|
|
59
|
+
throw new Error(`API login failed (${response.status()}): ${errorText}`);
|
|
60
|
+
}
|
|
61
|
+
const data = await response.json();
|
|
62
|
+
return {
|
|
63
|
+
token: data.user.token,
|
|
64
|
+
username: data.user.username,
|
|
65
|
+
email: data.user.email,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error(`Failed to login user via API: ${error}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create an article via API
|
|
74
|
+
*/
|
|
75
|
+
async function createArticleViaAPI(request, token, article) {
|
|
76
|
+
const config = getAPIConfig();
|
|
77
|
+
try {
|
|
78
|
+
const response = await request.post(`${config.baseURL}/articles`, {
|
|
79
|
+
data: { article },
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json',
|
|
82
|
+
'Authorization': `Token ${token}`,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok()) {
|
|
86
|
+
const errorText = await response.text();
|
|
87
|
+
throw new Error(`API article creation failed (${response.status()}): ${errorText}`);
|
|
88
|
+
}
|
|
89
|
+
const data = await response.json();
|
|
90
|
+
return {
|
|
91
|
+
slug: data.article.slug,
|
|
92
|
+
title: data.article.title,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw new Error(`Failed to create article via API: ${error}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Delete an article via API
|
|
101
|
+
*/
|
|
102
|
+
async function deleteArticleViaAPI(request, token, slug) {
|
|
103
|
+
const config = getAPIConfig();
|
|
104
|
+
try {
|
|
105
|
+
const response = await request.delete(`${config.baseURL}/articles/${slug}`, {
|
|
106
|
+
headers: {
|
|
107
|
+
'Authorization': `Token ${token}`,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
if (!response.ok()) {
|
|
111
|
+
const errorText = await response.text();
|
|
112
|
+
throw new Error(`API article deletion failed (${response.status()}): ${errorText}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`Failed to delete article via API: ${error}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Update user via API
|
|
121
|
+
*/
|
|
122
|
+
async function updateUserViaAPI(request, token, updates) {
|
|
123
|
+
const config = getAPIConfig();
|
|
124
|
+
try {
|
|
125
|
+
const response = await request.put(`${config.baseURL}/user`, {
|
|
126
|
+
data: { user: updates },
|
|
127
|
+
headers: {
|
|
128
|
+
'Content-Type': 'application/json',
|
|
129
|
+
'Authorization': `Token ${token}`,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
if (!response.ok()) {
|
|
133
|
+
const errorText = await response.text();
|
|
134
|
+
throw new Error(`API user update failed (${response.status()}): ${errorText}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new Error(`Failed to update user via API: ${error}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get current user via API
|
|
143
|
+
*/
|
|
144
|
+
async function getCurrentUserViaAPI(request, token) {
|
|
145
|
+
const config = getAPIConfig();
|
|
146
|
+
try {
|
|
147
|
+
const response = await request.get(`${config.baseURL}/user`, {
|
|
148
|
+
headers: {
|
|
149
|
+
'Authorization': `Token ${token}`,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
if (!response.ok()) {
|
|
153
|
+
const errorText = await response.text();
|
|
154
|
+
throw new Error(`API get user failed (${response.status()}): ${errorText}`);
|
|
155
|
+
}
|
|
156
|
+
const data = await response.json();
|
|
157
|
+
return data.user;
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
throw new Error(`Failed to get current user via API: ${error}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../helpers/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Page } from '@playwright/test';
|
|
2
|
+
export interface UserCredentials {
|
|
3
|
+
username: string;
|
|
4
|
+
email: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AuthResult {
|
|
8
|
+
success: boolean;
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register a new user via UI
|
|
13
|
+
*/
|
|
14
|
+
export declare function register(page: Page, username: string, email: string, password: string): Promise<AuthResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Login a user via UI
|
|
17
|
+
*/
|
|
18
|
+
export declare function login(page: Page, email: string, password: string): Promise<AuthResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Logout a user via UI
|
|
21
|
+
*/
|
|
22
|
+
export declare function logout(page: Page): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Generate unique user credentials to avoid conflicts
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateUniqueUser(): UserCredentials;
|
|
27
|
+
/**
|
|
28
|
+
* Check if user is logged in
|
|
29
|
+
*/
|
|
30
|
+
export declare function isLoggedIn(page: Page): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Get current username if logged in
|
|
33
|
+
*/
|
|
34
|
+
export declare function getCurrentUsername(page: Page): Promise<string | null>;
|
|
35
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../helpers/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAmBrB;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAkBrB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAQpD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAM7D;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM3E"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.register = register;
|
|
4
|
+
exports.login = login;
|
|
5
|
+
exports.logout = logout;
|
|
6
|
+
exports.generateUniqueUser = generateUniqueUser;
|
|
7
|
+
exports.isLoggedIn = isLoggedIn;
|
|
8
|
+
exports.getCurrentUsername = getCurrentUsername;
|
|
9
|
+
/**
|
|
10
|
+
* Register a new user via UI
|
|
11
|
+
*/
|
|
12
|
+
async function register(page, username, email, password) {
|
|
13
|
+
await page.goto('/register', { waitUntil: 'networkidle' });
|
|
14
|
+
await page.fill('input[name="username"]', username);
|
|
15
|
+
await page.fill('input[name="email"]', email);
|
|
16
|
+
await page.fill('input[name="password"]', password);
|
|
17
|
+
try {
|
|
18
|
+
await Promise.all([
|
|
19
|
+
page.waitForURL('/', { timeout: 10000 }),
|
|
20
|
+
page.click('button[type="submit"]')
|
|
21
|
+
]);
|
|
22
|
+
return { success: true };
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
const errorMsg = await page.locator('.error-messages, [data-testid="error-message"]').textContent().catch(() => '');
|
|
26
|
+
if (errorMsg) {
|
|
27
|
+
return { success: false, error: `Registration failed: ${errorMsg.trim()}` };
|
|
28
|
+
}
|
|
29
|
+
return { success: false, error: `Registration failed: ${error}` };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Login a user via UI
|
|
34
|
+
*/
|
|
35
|
+
async function login(page, email, password) {
|
|
36
|
+
await page.goto('/login', { waitUntil: 'networkidle' });
|
|
37
|
+
await page.fill('input[name="email"]', email);
|
|
38
|
+
await page.fill('input[name="password"]', password);
|
|
39
|
+
try {
|
|
40
|
+
await Promise.all([
|
|
41
|
+
page.waitForURL('/', { timeout: 10000 }),
|
|
42
|
+
page.click('button[type="submit"]')
|
|
43
|
+
]);
|
|
44
|
+
return { success: true };
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const errorMsg = await page.locator('.error-messages, [data-testid="error-message"]').textContent().catch(() => '');
|
|
48
|
+
if (errorMsg) {
|
|
49
|
+
return { success: false, error: `Login failed: ${errorMsg.trim()}` };
|
|
50
|
+
}
|
|
51
|
+
return { success: false, error: `Login failed: ${error}` };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Logout a user via UI
|
|
56
|
+
*/
|
|
57
|
+
async function logout(page) {
|
|
58
|
+
// Try different logout patterns
|
|
59
|
+
const settingsLink = page.locator('a[href="/settings"], a:has-text("Settings"), [data-testid="settings-link"]').first();
|
|
60
|
+
if (await settingsLink.isVisible().catch(() => false)) {
|
|
61
|
+
await settingsLink.click();
|
|
62
|
+
await page.waitForURL('/settings', { timeout: 5000 });
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
await page.goto('/settings');
|
|
66
|
+
}
|
|
67
|
+
const logoutButton = page.locator('button:has-text("logout"), button:has-text("Logout"), [data-testid="logout-button"]').first();
|
|
68
|
+
await Promise.all([
|
|
69
|
+
page.waitForURL('/', { timeout: 10000 }),
|
|
70
|
+
logoutButton.click()
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Generate unique user credentials to avoid conflicts
|
|
75
|
+
*/
|
|
76
|
+
function generateUniqueUser() {
|
|
77
|
+
const timestamp = Date.now();
|
|
78
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
79
|
+
return {
|
|
80
|
+
username: `testuser_${timestamp}_${random}`,
|
|
81
|
+
email: `test_${timestamp}_${random}@example.com`,
|
|
82
|
+
password: 'TestPassword123!',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check if user is logged in
|
|
87
|
+
*/
|
|
88
|
+
async function isLoggedIn(page) {
|
|
89
|
+
// Check for logout button or user-specific elements
|
|
90
|
+
const logoutVisible = await page.locator('a[href="/settings"], [data-testid="logout-button"]').isVisible().catch(() => false);
|
|
91
|
+
const loginVisible = await page.locator('a[href="/login"]').isVisible().catch(() => false);
|
|
92
|
+
return logoutVisible && !loginVisible;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get current username if logged in
|
|
96
|
+
*/
|
|
97
|
+
async function getCurrentUsername(page) {
|
|
98
|
+
const usernameElement = page.locator('[data-testid="username"], .user-name, .username').first();
|
|
99
|
+
if (await usernameElement.isVisible().catch(() => false)) {
|
|
100
|
+
return usernameElement.textContent();
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../helpers/auth.ts"],"names":[],"mappings":";;AAgBA,4BAwBC;AAKD,sBAsBC;AAKD,wBAiBC;AAKD,gDAQC;AAKD,gCAMC;AAKD,gDAMC;AA/GD;;GAEG;AACI,KAAK,UAAU,QAAQ,CAC5B,IAAU,EACV,QAAgB,EAChB,KAAa,EACb,QAAgB;IAEhB,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;IAC3D,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC;SACpC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACpH,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;QAC9E,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,KAAK,EAAE,EAAE,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,KAAK,CACzB,IAAU,EACV,KAAa,EACb,QAAgB;IAEhB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;IACxD,MAAM,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC;SACpC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACpH,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;QACvE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,KAAK,EAAE,EAAE,CAAC;IAC7D,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,MAAM,CAAC,IAAU;IACrC,gCAAgC;IAChC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,4EAA4E,CAAC,CAAC,KAAK,EAAE,CAAC;IAExH,IAAI,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,qFAAqF,CAAC,CAAC,KAAK,EAAE,CAAC;IAEjI,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACxC,YAAY,CAAC,KAAK,EAAE;KACrB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO;QACL,QAAQ,EAAE,YAAY,SAAS,IAAI,MAAM,EAAE;QAC3C,KAAK,EAAE,QAAQ,SAAS,IAAI,MAAM,cAAc;QAChD,QAAQ,EAAE,kBAAkB;KAC7B,CAAC;AACJ,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,IAAU;IACzC,oDAAoD;IACpD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9H,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAE3F,OAAO,aAAa,IAAI,CAAC,YAAY,CAAC;AACxC,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CAAC,IAAU;IACjD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,KAAK,EAAE,CAAC;IAChG,IAAI,MAAM,eAAe,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,eAAe,CAAC,WAAW,EAAE,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration helpers for SamaroUItest
|
|
3
|
+
*/
|
|
4
|
+
export interface SamaroConfig {
|
|
5
|
+
apiMode: boolean;
|
|
6
|
+
apiBase: string;
|
|
7
|
+
debugInterfaceName: string;
|
|
8
|
+
timeouts: {
|
|
9
|
+
navigation: number;
|
|
10
|
+
action: number;
|
|
11
|
+
expectation: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get SamaroUItest configuration from environment variables
|
|
16
|
+
*/
|
|
17
|
+
export declare function getConfig(): SamaroConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Check if running in CI environment
|
|
20
|
+
*/
|
|
21
|
+
export declare function isCI(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if running in debug mode
|
|
24
|
+
*/
|
|
25
|
+
export declare function isDebug(): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get browser launch options based on environment
|
|
28
|
+
*/
|
|
29
|
+
export declare function getBrowserLaunchOptions(): Record<string, any>;
|
|
30
|
+
/**
|
|
31
|
+
* Set environment variables for test configuration
|
|
32
|
+
*/
|
|
33
|
+
export declare function setTestEnv(vars: Partial<SamaroConfig>): void;
|
|
34
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../helpers/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAWxC;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAE9B;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,wBAgBtC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAU5D"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration helpers for SamaroUItest
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getConfig = getConfig;
|
|
7
|
+
exports.isCI = isCI;
|
|
8
|
+
exports.isDebug = isDebug;
|
|
9
|
+
exports.getBrowserLaunchOptions = getBrowserLaunchOptions;
|
|
10
|
+
exports.setTestEnv = setTestEnv;
|
|
11
|
+
/**
|
|
12
|
+
* Get SamaroUItest configuration from environment variables
|
|
13
|
+
*/
|
|
14
|
+
function getConfig() {
|
|
15
|
+
return {
|
|
16
|
+
apiMode: process.env.API_MODE?.toLowerCase() !== 'false',
|
|
17
|
+
apiBase: process.env.API_BASE || process.env.NG_API_URL || 'http://localhost:4200/api',
|
|
18
|
+
debugInterfaceName: process.env.DEBUG_INTERFACE_NAME || '__app_debug__',
|
|
19
|
+
timeouts: {
|
|
20
|
+
navigation: parseInt(process.env.TIMEOUT_NAVIGATION || '10000', 10),
|
|
21
|
+
action: parseInt(process.env.TIMEOUT_ACTION || '5000', 10),
|
|
22
|
+
expectation: parseInt(process.env.TIMEOUT_EXPECTATION || '5000', 10),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if running in CI environment
|
|
28
|
+
*/
|
|
29
|
+
function isCI() {
|
|
30
|
+
return !!process.env.CI;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if running in debug mode
|
|
34
|
+
*/
|
|
35
|
+
function isDebug() {
|
|
36
|
+
return process.env.DEBUG === 'true' || process.env.PWDEBUG === '1';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get browser launch options based on environment
|
|
40
|
+
*/
|
|
41
|
+
function getBrowserLaunchOptions() {
|
|
42
|
+
const options = {
|
|
43
|
+
headless: !isDebug(),
|
|
44
|
+
};
|
|
45
|
+
if (isCI()) {
|
|
46
|
+
options.args = [
|
|
47
|
+
'--no-sandbox',
|
|
48
|
+
'--disable-setuid-sandbox',
|
|
49
|
+
'--disable-dev-shm-usage',
|
|
50
|
+
'--disable-accelerated-2d-canvas',
|
|
51
|
+
'--disable-gpu',
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
return options;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Set environment variables for test configuration
|
|
58
|
+
*/
|
|
59
|
+
function setTestEnv(vars) {
|
|
60
|
+
if (vars.apiMode !== undefined) {
|
|
61
|
+
process.env.API_MODE = vars.apiMode.toString();
|
|
62
|
+
}
|
|
63
|
+
if (vars.apiBase) {
|
|
64
|
+
process.env.API_BASE = vars.apiBase;
|
|
65
|
+
}
|
|
66
|
+
if (vars.debugInterfaceName) {
|
|
67
|
+
process.env.DEBUG_INTERFACE_NAME = vars.debugInterfaceName;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../helpers/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAgBH,8BAWC;AAKD,oBAEC;AAKD,0BAEC;AAKD,0DAgBC;AAKD,gCAUC;AAhED;;GAEG;AACH,SAAgB,SAAS;IACvB,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,OAAO;QACxD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,2BAA2B;QACtF,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,eAAe;QACvE,QAAQ,EAAE;YACR,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,EAAE,EAAE,CAAC;YACnE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,EAAE,EAAE,CAAC;YAC1D,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,MAAM,EAAE,EAAE,CAAC;SACrE;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,IAAI;IAClB,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAgB,OAAO;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB;IACrC,MAAM,OAAO,GAAwB;QACnC,QAAQ,EAAE,CAAC,OAAO,EAAE;KACrB,CAAC;IAEF,IAAI,IAAI,EAAE,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,GAAG;YACb,cAAc;YACd,0BAA0B;YAC1B,yBAAyB;YACzB,iCAAiC;YACjC,eAAe;SAChB,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,IAA2B;IACpD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;IACtC,CAAC;IACD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Page } from '@playwright/test';
|
|
2
|
+
export type AuthState = 'authenticated' | 'unauthenticated' | 'unavailable' | 'loading';
|
|
3
|
+
export interface User {
|
|
4
|
+
username: string;
|
|
5
|
+
email: string;
|
|
6
|
+
bio: string | null;
|
|
7
|
+
image: string | null;
|
|
8
|
+
token: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function setDebugInterfaceName(name: string): void;
|
|
11
|
+
export declare function getDebugInterfaceName(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Get the current JWT token from the app's debug interface.
|
|
14
|
+
* Returns null if no token is set or debug interface is not available.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getToken(page: Page): Promise<string | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Get the current authentication state from the app's debug interface.
|
|
19
|
+
* Returns undefined if debug interface is not available.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getAuthState(page: Page): Promise<AuthState | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Get the current user from the app's debug interface.
|
|
24
|
+
* Returns null if not authenticated or debug interface is not available.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getCurrentUser(page: Page): Promise<User | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Wait for a specific auth state to be reached.
|
|
29
|
+
* Useful for waiting after login/logout operations.
|
|
30
|
+
*/
|
|
31
|
+
export declare function waitForAuthState(page: Page, expectedState: AuthState, options?: {
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if the debug interface is available.
|
|
36
|
+
* Can be used to skip tests if implementation doesn't support it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isDebugInterfaceAvailable(page: Page): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Get all debug data at once (token, auth state, user)
|
|
41
|
+
*/
|
|
42
|
+
export declare function getDebugData(page: Page): Promise<{
|
|
43
|
+
token: string | null;
|
|
44
|
+
authState: AuthState | undefined;
|
|
45
|
+
user: User | null;
|
|
46
|
+
available: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../helpers/debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,iBAAiB,GAAG,aAAa,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAExD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKjE;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAK7E;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAKrE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,SAAS,EACxB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAI5E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAcD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setDebugInterfaceName = setDebugInterfaceName;
|
|
4
|
+
exports.getDebugInterfaceName = getDebugInterfaceName;
|
|
5
|
+
exports.getToken = getToken;
|
|
6
|
+
exports.getAuthState = getAuthState;
|
|
7
|
+
exports.getCurrentUser = getCurrentUser;
|
|
8
|
+
exports.waitForAuthState = waitForAuthState;
|
|
9
|
+
exports.isDebugInterfaceAvailable = isDebugInterfaceAvailable;
|
|
10
|
+
exports.getDebugData = getDebugData;
|
|
11
|
+
/**
|
|
12
|
+
* Configure the debug interface name (defaults to __app_debug__)
|
|
13
|
+
*/
|
|
14
|
+
let DEBUG_INTERFACE_NAME = '__app_debug__';
|
|
15
|
+
function setDebugInterfaceName(name) {
|
|
16
|
+
DEBUG_INTERFACE_NAME = name;
|
|
17
|
+
}
|
|
18
|
+
function getDebugInterfaceName() {
|
|
19
|
+
return DEBUG_INTERFACE_NAME;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the current JWT token from the app's debug interface.
|
|
23
|
+
* Returns null if no token is set or debug interface is not available.
|
|
24
|
+
*/
|
|
25
|
+
async function getToken(page) {
|
|
26
|
+
return page.evaluate((name) => {
|
|
27
|
+
const debug = window[name];
|
|
28
|
+
return debug?.getToken ? debug.getToken() : null;
|
|
29
|
+
}, DEBUG_INTERFACE_NAME);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the current authentication state from the app's debug interface.
|
|
33
|
+
* Returns undefined if debug interface is not available.
|
|
34
|
+
*/
|
|
35
|
+
async function getAuthState(page) {
|
|
36
|
+
return page.evaluate((name) => {
|
|
37
|
+
const debug = window[name];
|
|
38
|
+
return debug?.getAuthState ? debug.getAuthState() : undefined;
|
|
39
|
+
}, DEBUG_INTERFACE_NAME);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the current user from the app's debug interface.
|
|
43
|
+
* Returns null if not authenticated or debug interface is not available.
|
|
44
|
+
*/
|
|
45
|
+
async function getCurrentUser(page) {
|
|
46
|
+
return page.evaluate((name) => {
|
|
47
|
+
const debug = window[name];
|
|
48
|
+
return debug?.getCurrentUser ? debug.getCurrentUser() : null;
|
|
49
|
+
}, DEBUG_INTERFACE_NAME);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Wait for a specific auth state to be reached.
|
|
53
|
+
* Useful for waiting after login/logout operations.
|
|
54
|
+
*/
|
|
55
|
+
async function waitForAuthState(page, expectedState, options = {}) {
|
|
56
|
+
const timeout = options.timeout ?? 5000;
|
|
57
|
+
await page.waitForFunction(({ state, name }) => {
|
|
58
|
+
const debug = window[name];
|
|
59
|
+
return debug?.getAuthState ? debug.getAuthState() === state : false;
|
|
60
|
+
}, { state: expectedState, name: DEBUG_INTERFACE_NAME }, { timeout });
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if the debug interface is available.
|
|
64
|
+
* Can be used to skip tests if implementation doesn't support it.
|
|
65
|
+
*/
|
|
66
|
+
async function isDebugInterfaceAvailable(page) {
|
|
67
|
+
return page.evaluate((name) => {
|
|
68
|
+
return typeof window[name] !== 'undefined';
|
|
69
|
+
}, DEBUG_INTERFACE_NAME);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get all debug data at once (token, auth state, user)
|
|
73
|
+
*/
|
|
74
|
+
async function getDebugData(page) {
|
|
75
|
+
const available = await isDebugInterfaceAvailable(page);
|
|
76
|
+
if (!available) {
|
|
77
|
+
return { token: null, authState: undefined, user: null, available: false };
|
|
78
|
+
}
|
|
79
|
+
const [token, authState, user] = await Promise.all([
|
|
80
|
+
getToken(page),
|
|
81
|
+
getAuthState(page),
|
|
82
|
+
getCurrentUser(page),
|
|
83
|
+
]);
|
|
84
|
+
return { token, authState, user, available: true };
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../../helpers/debug.ts"],"names":[],"mappings":";;AAiBA,sDAEC;AAED,sDAEC;AAMD,4BAKC;AAMD,oCAKC;AAMD,wCAKC;AAMD,4CAcC;AAMD,8DAIC;AAKD,oCAmBC;AAlGD;;GAEG;AACH,IAAI,oBAAoB,GAAG,eAAe,CAAC;AAE3C,SAAgB,qBAAqB,CAAC,IAAY;IAChD,oBAAoB,GAAG,IAAI,CAAC;AAC9B,CAAC;AAED,SAAgB,qBAAqB;IACnC,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,QAAQ,CAAC,IAAU;IACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAI,MAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,YAAY,CAAC,IAAU;IAC3C,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAI,MAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,cAAc,CAAC,IAAU;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAI,MAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,gBAAgB,CACpC,IAAU,EACV,aAAwB,EACxB,UAAgC,EAAE;IAElC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IACxC,MAAM,IAAI,CAAC,eAAe,CACxB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAsC,EAAE,EAAE;QACtD,MAAM,KAAK,GAAI,MAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IACtE,CAAC,EACD,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,EACpD,EAAE,OAAO,EAAE,CACZ,CAAC;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,yBAAyB,CAAC,IAAU;IACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,OAAO,OAAQ,MAAc,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC;IACtD,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,YAAY,CAAC,IAAU;IAM3C,MAAM,SAAS,GAAG,MAAM,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAExD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC7E,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC;QACd,YAAY,CAAC,IAAI,CAAC;QAClB,cAAc,CAAC,IAAI,CAAC;KACrB,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { setDebugInterfaceName, getDebugInterfaceName, getToken, getAuthState, getCurrentUser, waitForAuthState, isDebugInterfaceAvailable, getDebugData, type AuthState, type User, } from './debug.js';
|
|
2
|
+
export { register, login, logout, generateUniqueUser, isLoggedIn, getCurrentUsername, type UserCredentials, type AuthResult, } from './auth.js';
|
|
3
|
+
export { getAPIConfig, registerUserViaAPI, loginUserViaAPI, createArticleViaAPI, deleteArticleViaAPI, updateUserViaAPI, getCurrentUserViaAPI, type APIConfig, type APIUser, type APIAuthResponse, } from './api.js';
|
|
4
|
+
export { createUserInIsolation, createUserViaAPI, setupAuthenticatedPage, createManyArticles, cleanupTestData, waitForAngular, safeGoto, type TestUser, type IsolatedUserContext, } from './setup.js';
|
|
5
|
+
export { getConfig, isCI, isDebug, getBrowserLaunchOptions, setTestEnv, type SamaroConfig, } from './config.js';
|
|
6
|
+
export { severity, tag, epic, feature, story, owner, description, descriptionHtml, link, issue, tms, allure, allureMeta, addLabel, addLink, addAttachment, attachScreenshot, attachJson, attachText, attachHtml, allureStep, getAllureMetadata, getAllureMetadataKeys, type Severity, type LinkType, type LabelName, type AllureMetadataOptions, } from './allure.js';
|
|
7
|
+
export type { Label, Link, Parameter, Attachment, Status, StatusDetails, StepResult, TestResult, TestResultContainer, } from 'allure-js-commons';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../helpers/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,IAAI,GACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,SAAS,EACT,IAAI,EACJ,OAAO,EACP,uBAAuB,EACvB,UAAU,EACV,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAEL,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,OAAO,EACP,KAAK,EACL,KAAK,EACL,WAAW,EACX,eAAe,EACf,IAAI,EACJ,KAAK,EACL,GAAG,EACH,MAAM,EAGN,UAAU,EACV,QAAQ,EACR,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EAGV,iBAAiB,EACjB,qBAAqB,EAGrB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,KAAK,EACL,IAAI,EACJ,SAAS,EACT,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,UAAU,EACV,mBAAmB,GACpB,MAAM,mBAAmB,CAAC"}
|