@appliqation/automation-sdk 2.1.1 → 2.1.2
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/package.json +9 -1
- package/src/playwright/global-setup.js +66 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appliqation/automation-sdk",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Appliqation Automation SDK with API key authentication, custom run titles, and framework-specific reporters",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -13,6 +13,14 @@
|
|
|
13
13
|
"require": "./src/reporters/playwright/index.js",
|
|
14
14
|
"import": "./src/reporters/playwright/index.js"
|
|
15
15
|
},
|
|
16
|
+
"./playwright/global-setup": {
|
|
17
|
+
"require": "./src/playwright/global-setup.js",
|
|
18
|
+
"import": "./src/playwright/global-setup.js"
|
|
19
|
+
},
|
|
20
|
+
"./playwright/fixture": {
|
|
21
|
+
"require": "./src/playwright/fixture.js",
|
|
22
|
+
"import": "./src/playwright/fixture.js"
|
|
23
|
+
},
|
|
16
24
|
"./cypress": {
|
|
17
25
|
"require": "./src/reporters/cypress/index.js",
|
|
18
26
|
"import": "./src/reporters/cypress/index.js"
|
|
@@ -140,12 +140,13 @@ function extractSDKConfig(config) {
|
|
|
140
140
|
* Get JWT token from Appliqation API
|
|
141
141
|
*
|
|
142
142
|
* @param {Object} sdkConfig - SDK configuration
|
|
143
|
-
* @returns {Promise<Object>} JWT data { jwt_token, run_id }
|
|
143
|
+
* @returns {Promise<Object>} JWT data { jwt_token, run_id, user_id, project_id }
|
|
144
144
|
*/
|
|
145
145
|
async function getJWTToken(sdkConfig) {
|
|
146
|
-
|
|
146
|
+
// STEP 1: Create automation run
|
|
147
|
+
const createRunEndpoint = `${sdkConfig.baseUrl.replace(/\/$/, '')}/api/automation/run/create`;
|
|
147
148
|
|
|
148
|
-
const
|
|
149
|
+
const runPayload = {
|
|
149
150
|
project_key: sdkConfig.projectKey,
|
|
150
151
|
scenario_id: sdkConfig.scenarioId || 0,
|
|
151
152
|
environment: sdkConfig.environment,
|
|
@@ -156,7 +157,7 @@ async function getJWTToken(sdkConfig) {
|
|
|
156
157
|
};
|
|
157
158
|
|
|
158
159
|
try {
|
|
159
|
-
const
|
|
160
|
+
const runResponse = await axios.post(createRunEndpoint, runPayload, {
|
|
160
161
|
headers: {
|
|
161
162
|
'Content-Type': 'application/json',
|
|
162
163
|
'X-API-Key': sdkConfig.apiKey,
|
|
@@ -167,14 +168,39 @@ async function getJWTToken(sdkConfig) {
|
|
|
167
168
|
validateStatus: (status) => status < 500,
|
|
168
169
|
});
|
|
169
170
|
|
|
170
|
-
if (
|
|
171
|
-
throw new Error(`
|
|
171
|
+
if (runResponse.status !== 200 && runResponse.status !== 201) {
|
|
172
|
+
throw new Error(`Run creation failed: ${runResponse.status} - ${runResponse.data?.message || 'Unknown error'}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const runId = runResponse.data.run_id;
|
|
176
|
+
|
|
177
|
+
// STEP 2: Get browser session JWT token
|
|
178
|
+
const jwtEndpoint = `${sdkConfig.baseUrl.replace(/\/$/, '')}/api/auth/jwt/browser`;
|
|
179
|
+
|
|
180
|
+
const jwtPayload = {
|
|
181
|
+
api_key: sdkConfig.apiKey
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const jwtResponse = await axios.post(jwtEndpoint, jwtPayload, {
|
|
185
|
+
headers: {
|
|
186
|
+
'Content-Type': 'application/json',
|
|
187
|
+
},
|
|
188
|
+
httpsAgent: new https.Agent({
|
|
189
|
+
rejectUnauthorized: false, // Allow self-signed certs in dev
|
|
190
|
+
}),
|
|
191
|
+
validateStatus: (status) => status < 500,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
if (jwtResponse.status !== 200) {
|
|
195
|
+
throw new Error(`JWT generation failed: ${jwtResponse.status} - ${jwtResponse.data?.message || 'Unknown error'}`);
|
|
172
196
|
}
|
|
173
197
|
|
|
174
198
|
return {
|
|
175
|
-
jwt_token:
|
|
176
|
-
run_id:
|
|
177
|
-
|
|
199
|
+
jwt_token: jwtResponse.data.jwt_token,
|
|
200
|
+
run_id: runId,
|
|
201
|
+
user_id: jwtResponse.data.user_id,
|
|
202
|
+
project_id: jwtResponse.data.project_id,
|
|
203
|
+
expires_in: jwtResponse.data.expires_in,
|
|
178
204
|
};
|
|
179
205
|
|
|
180
206
|
} catch (error) {
|
|
@@ -197,25 +223,40 @@ async function setupBrowserWithJWT(sdkConfig, jwtToken) {
|
|
|
197
223
|
headless: true,
|
|
198
224
|
});
|
|
199
225
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
226
|
+
try {
|
|
227
|
+
// Extract domain from baseUrl for cookie
|
|
228
|
+
const baseUrl = sdkConfig.baseUrl.replace(/\/$/, '');
|
|
229
|
+
const urlObj = new URL(baseUrl);
|
|
230
|
+
const domain = urlObj.hostname;
|
|
231
|
+
|
|
232
|
+
// Create context with JWT cookie BEFORE navigating
|
|
233
|
+
const context = await browser.newContext({
|
|
234
|
+
ignoreHTTPSErrors: true, // Allow self-signed certs in dev
|
|
235
|
+
});
|
|
203
236
|
|
|
204
|
-
|
|
237
|
+
// Set JWT cookie
|
|
238
|
+
await context.addCookies([{
|
|
239
|
+
name: 'appliqation_jwt',
|
|
240
|
+
value: jwtToken,
|
|
241
|
+
domain: domain,
|
|
242
|
+
path: '/',
|
|
243
|
+
httpOnly: true,
|
|
244
|
+
secure: baseUrl.startsWith('https'),
|
|
245
|
+
sameSite: 'Lax'
|
|
246
|
+
}]);
|
|
205
247
|
|
|
206
|
-
|
|
207
|
-
// Navigate to app with JWT token in query parameter
|
|
208
|
-
const appUrl = sdkConfig.appUrl.replace(/\/$/, '');
|
|
209
|
-
const separator = appUrl.includes('?') ? '&' : '?';
|
|
210
|
-
const urlWithToken = `${appUrl}${separator}qonsole_token=${encodeURIComponent(jwtToken)}`;
|
|
248
|
+
console.log(` ✓ JWT cookie set for domain: ${domain}`);
|
|
211
249
|
|
|
212
|
-
|
|
213
|
-
|
|
250
|
+
const page = await context.newPage();
|
|
251
|
+
|
|
252
|
+
// Navigate to app (no query parameter needed)
|
|
253
|
+
console.log(` Navigating to: ${baseUrl}...`);
|
|
254
|
+
await page.goto(baseUrl, {
|
|
214
255
|
waitUntil: 'networkidle',
|
|
215
256
|
timeout: 30000,
|
|
216
257
|
});
|
|
217
258
|
|
|
218
|
-
// Wait
|
|
259
|
+
// Wait for authentication to be processed
|
|
219
260
|
await page.waitForTimeout(2000);
|
|
220
261
|
|
|
221
262
|
// Verify authentication worked
|
|
@@ -224,14 +265,16 @@ async function setupBrowserWithJWT(sdkConfig, jwtToken) {
|
|
|
224
265
|
throw new Error('JWT authentication failed - redirected to login page');
|
|
225
266
|
}
|
|
226
267
|
|
|
227
|
-
|
|
268
|
+
console.log(' ✓ Browser authenticated successfully');
|
|
269
|
+
|
|
270
|
+
// Save authenticated state with cookie
|
|
228
271
|
const authDir = path.resolve('.auth');
|
|
229
272
|
if (!fs.existsSync(authDir)) {
|
|
230
273
|
fs.mkdirSync(authDir, { recursive: true });
|
|
231
274
|
}
|
|
232
275
|
|
|
233
276
|
await context.storageState({ path: '.auth/jwt.json' });
|
|
234
|
-
console.log(' ✓ Authenticated state saved');
|
|
277
|
+
console.log(' ✓ Authenticated state saved to .auth/jwt.json');
|
|
235
278
|
|
|
236
279
|
} catch (error) {
|
|
237
280
|
throw new Error(`Browser setup failed: ${error.message}`);
|