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/helpers/api.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { APIRequestContext } from '@playwright/test';
|
|
2
|
+
export interface APIConfig {
|
|
3
|
+
baseURL: string;
|
|
4
|
+
}
|
|
5
|
+
export interface APIUser {
|
|
6
|
+
username: string;
|
|
7
|
+
email: string;
|
|
8
|
+
password: string;
|
|
9
|
+
}
|
|
10
|
+
export interface APIAuthResponse {
|
|
11
|
+
user: {
|
|
12
|
+
email: string;
|
|
13
|
+
token: string;
|
|
14
|
+
username: string;
|
|
15
|
+
bio: string | null;
|
|
16
|
+
image: string | null;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get API configuration from environment variables
|
|
21
|
+
*/
|
|
22
|
+
export declare function getAPIConfig(): APIConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Register a user via API
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerUserViaAPI(request: APIRequestContext, user: APIUser): Promise<{
|
|
27
|
+
token: string;
|
|
28
|
+
username: string;
|
|
29
|
+
email: string;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Login a user via API
|
|
33
|
+
*/
|
|
34
|
+
export declare function loginUserViaAPI(request: APIRequestContext, email: string, password: string): Promise<{
|
|
35
|
+
token: string;
|
|
36
|
+
username: string;
|
|
37
|
+
email: string;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Create an article via API
|
|
41
|
+
*/
|
|
42
|
+
export declare function createArticleViaAPI(request: APIRequestContext, token: string, article: {
|
|
43
|
+
title: string;
|
|
44
|
+
description: string;
|
|
45
|
+
body: string;
|
|
46
|
+
tagList?: string[];
|
|
47
|
+
}): Promise<{
|
|
48
|
+
slug: string;
|
|
49
|
+
title: string;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Delete an article via API
|
|
53
|
+
*/
|
|
54
|
+
export declare function deleteArticleViaAPI(request: APIRequestContext, token: string, slug: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Update user via API
|
|
57
|
+
*/
|
|
58
|
+
export declare function updateUserViaAPI(request: APIRequestContext, token: string, updates: {
|
|
59
|
+
email?: string;
|
|
60
|
+
bio?: string;
|
|
61
|
+
image?: string;
|
|
62
|
+
username?: string;
|
|
63
|
+
password?: string;
|
|
64
|
+
}): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Get current user via API
|
|
67
|
+
*/
|
|
68
|
+
export declare function getCurrentUserViaAPI(request: APIRequestContext, token: string): Promise<APIAuthResponse['user']>;
|
|
69
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAIxC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAyB7D;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAyB7D;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAyB1C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAoBlC"}
|
package/helpers/api.js
ADDED
|
@@ -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":["api.ts"],"names":[],"mappings":"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"}
|
package/helpers/api.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { APIRequestContext } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export interface APIConfig {
|
|
4
|
+
baseURL: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface APIUser {
|
|
8
|
+
username: string;
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface APIAuthResponse {
|
|
14
|
+
user: {
|
|
15
|
+
email: string;
|
|
16
|
+
token: string;
|
|
17
|
+
username: string;
|
|
18
|
+
bio: string | null;
|
|
19
|
+
image: string | null;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get API configuration from environment variables
|
|
25
|
+
*/
|
|
26
|
+
export function getAPIConfig(): APIConfig {
|
|
27
|
+
return {
|
|
28
|
+
baseURL: process.env.API_BASE || process.env.NG_API_URL || 'http://localhost:4200/api',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Register a user via API
|
|
34
|
+
*/
|
|
35
|
+
export async function registerUserViaAPI(
|
|
36
|
+
request: APIRequestContext,
|
|
37
|
+
user: APIUser
|
|
38
|
+
): Promise<{ token: string; username: string; email: string }> {
|
|
39
|
+
const config = getAPIConfig();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const response = await request.post(`${config.baseURL}/users`, {
|
|
43
|
+
data: { user },
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (!response.ok()) {
|
|
50
|
+
const errorText = await response.text();
|
|
51
|
+
throw new Error(`API registration failed (${response.status()}): ${errorText}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const data = await response.json() as APIAuthResponse;
|
|
55
|
+
return {
|
|
56
|
+
token: data.user.token,
|
|
57
|
+
username: data.user.username,
|
|
58
|
+
email: data.user.email,
|
|
59
|
+
};
|
|
60
|
+
} catch (error) {
|
|
61
|
+
throw new Error(`Failed to register user via API: ${error}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Login a user via API
|
|
67
|
+
*/
|
|
68
|
+
export async function loginUserViaAPI(
|
|
69
|
+
request: APIRequestContext,
|
|
70
|
+
email: string,
|
|
71
|
+
password: string
|
|
72
|
+
): Promise<{ token: string; username: string; email: string }> {
|
|
73
|
+
const config = getAPIConfig();
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const response = await request.post(`${config.baseURL}/users/login`, {
|
|
77
|
+
data: { user: { email, password } },
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': 'application/json',
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (!response.ok()) {
|
|
84
|
+
const errorText = await response.text();
|
|
85
|
+
throw new Error(`API login failed (${response.status()}): ${errorText}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const data = await response.json() as APIAuthResponse;
|
|
89
|
+
return {
|
|
90
|
+
token: data.user.token,
|
|
91
|
+
username: data.user.username,
|
|
92
|
+
email: data.user.email,
|
|
93
|
+
};
|
|
94
|
+
} catch (error) {
|
|
95
|
+
throw new Error(`Failed to login user via API: ${error}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Create an article via API
|
|
101
|
+
*/
|
|
102
|
+
export async function createArticleViaAPI(
|
|
103
|
+
request: APIRequestContext,
|
|
104
|
+
token: string,
|
|
105
|
+
article: {
|
|
106
|
+
title: string;
|
|
107
|
+
description: string;
|
|
108
|
+
body: string;
|
|
109
|
+
tagList?: string[];
|
|
110
|
+
}
|
|
111
|
+
): Promise<{ slug: string; title: string }> {
|
|
112
|
+
const config = getAPIConfig();
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const response = await request.post(`${config.baseURL}/articles`, {
|
|
116
|
+
data: { article },
|
|
117
|
+
headers: {
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
'Authorization': `Token ${token}`,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (!response.ok()) {
|
|
124
|
+
const errorText = await response.text();
|
|
125
|
+
throw new Error(`API article creation failed (${response.status()}): ${errorText}`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const data = await response.json();
|
|
129
|
+
return {
|
|
130
|
+
slug: data.article.slug,
|
|
131
|
+
title: data.article.title,
|
|
132
|
+
};
|
|
133
|
+
} catch (error) {
|
|
134
|
+
throw new Error(`Failed to create article via API: ${error}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Delete an article via API
|
|
140
|
+
*/
|
|
141
|
+
export async function deleteArticleViaAPI(
|
|
142
|
+
request: APIRequestContext,
|
|
143
|
+
token: string,
|
|
144
|
+
slug: string
|
|
145
|
+
): Promise<void> {
|
|
146
|
+
const config = getAPIConfig();
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
const response = await request.delete(`${config.baseURL}/articles/${slug}`, {
|
|
150
|
+
headers: {
|
|
151
|
+
'Authorization': `Token ${token}`,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (!response.ok()) {
|
|
156
|
+
const errorText = await response.text();
|
|
157
|
+
throw new Error(`API article deletion failed (${response.status()}): ${errorText}`);
|
|
158
|
+
}
|
|
159
|
+
} catch (error) {
|
|
160
|
+
throw new Error(`Failed to delete article via API: ${error}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Update user via API
|
|
166
|
+
*/
|
|
167
|
+
export async function updateUserViaAPI(
|
|
168
|
+
request: APIRequestContext,
|
|
169
|
+
token: string,
|
|
170
|
+
updates: {
|
|
171
|
+
email?: string;
|
|
172
|
+
bio?: string;
|
|
173
|
+
image?: string;
|
|
174
|
+
username?: string;
|
|
175
|
+
password?: string;
|
|
176
|
+
}
|
|
177
|
+
): Promise<void> {
|
|
178
|
+
const config = getAPIConfig();
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const response = await request.put(`${config.baseURL}/user`, {
|
|
182
|
+
data: { user: updates },
|
|
183
|
+
headers: {
|
|
184
|
+
'Content-Type': 'application/json',
|
|
185
|
+
'Authorization': `Token ${token}`,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (!response.ok()) {
|
|
190
|
+
const errorText = await response.text();
|
|
191
|
+
throw new Error(`API user update failed (${response.status()}): ${errorText}`);
|
|
192
|
+
}
|
|
193
|
+
} catch (error) {
|
|
194
|
+
throw new Error(`Failed to update user via API: ${error}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get current user via API
|
|
200
|
+
*/
|
|
201
|
+
export async function getCurrentUserViaAPI(
|
|
202
|
+
request: APIRequestContext,
|
|
203
|
+
token: string
|
|
204
|
+
): Promise<APIAuthResponse['user']> {
|
|
205
|
+
const config = getAPIConfig();
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const response = await request.get(`${config.baseURL}/user`, {
|
|
209
|
+
headers: {
|
|
210
|
+
'Authorization': `Token ${token}`,
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (!response.ok()) {
|
|
215
|
+
const errorText = await response.text();
|
|
216
|
+
throw new Error(`API get user failed (${response.status()}): ${errorText}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const data = await response.json();
|
|
220
|
+
return data.user;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw new Error(`Failed to get current user via API: ${error}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -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":["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"}
|
package/helpers/auth.js
ADDED
|
@@ -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":["auth.ts"],"names":[],"mappings":"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"}
|