@testdino/playwright 1.0.10 → 1.0.11
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/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +93 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -274,7 +274,11 @@ var WebSocketClient = class {
|
|
|
274
274
|
total: Number(details.total) || 0,
|
|
275
275
|
resetDate: details.resetDate?.toString(),
|
|
276
276
|
canPartialSubmit: Boolean(details.canPartialSubmit),
|
|
277
|
-
allowedCount: Number(details.allowedCount) || 0
|
|
277
|
+
allowedCount: Number(details.allowedCount) || 0,
|
|
278
|
+
projectName: details.projectName?.toString(),
|
|
279
|
+
projectLimit: details.projectLimit != null ? Number(details.projectLimit) : void 0,
|
|
280
|
+
projectUsed: details.projectUsed != null ? Number(details.projectUsed) : void 0,
|
|
281
|
+
projectBorrowed: details.projectBorrowed != null ? Number(details.projectBorrowed) : void 0
|
|
278
282
|
})
|
|
279
283
|
);
|
|
280
284
|
} else if (errorCode === "QUOTA_EXHAUSTED" && errorObj.details && typeof errorObj.details === "object") {
|
|
@@ -426,6 +430,14 @@ var HttpClient = class {
|
|
|
426
430
|
await this.client.post("/events", { events });
|
|
427
431
|
return;
|
|
428
432
|
} catch (error) {
|
|
433
|
+
if (axios.isAxiosError(error) && error.response?.status === 402) {
|
|
434
|
+
const data = error.response.data;
|
|
435
|
+
const details = data?.details;
|
|
436
|
+
if (data?.error === "QUOTA_EXCEEDED" && details) {
|
|
437
|
+
throw new QuotaExceededError(data.message || "Quota exceeded", details);
|
|
438
|
+
}
|
|
439
|
+
throw new QuotaExhaustedError(data?.message || "Quota exceeded", details);
|
|
440
|
+
}
|
|
429
441
|
lastError = new Error(this.getErrorMessage(error));
|
|
430
442
|
if (attempt < this.options.maxRetries - 1) {
|
|
431
443
|
const delay = this.options.retryDelay * Math.pow(2, attempt);
|
|
@@ -2361,6 +2373,7 @@ var TestdinoReporter = class {
|
|
|
2361
2373
|
isShuttingDown = false;
|
|
2362
2374
|
// Quota tracking
|
|
2363
2375
|
quotaExceeded = false;
|
|
2376
|
+
pendingQuotaError = null;
|
|
2364
2377
|
// Session ID from HTTP auth, passed to WebSocket for session reuse
|
|
2365
2378
|
sessionId = null;
|
|
2366
2379
|
// Artifact upload
|
|
@@ -2523,7 +2536,7 @@ var TestdinoReporter = class {
|
|
|
2523
2536
|
if (!this.quotaExceeded) {
|
|
2524
2537
|
this.quotaExceeded = true;
|
|
2525
2538
|
this.initFailed = true;
|
|
2526
|
-
this.
|
|
2539
|
+
this.pendingQuotaError = error;
|
|
2527
2540
|
}
|
|
2528
2541
|
} else {
|
|
2529
2542
|
this.log.error(`WebSocket error: ${error.message}`);
|
|
@@ -2563,7 +2576,7 @@ var TestdinoReporter = class {
|
|
|
2563
2576
|
this.initFailed = true;
|
|
2564
2577
|
if (error instanceof Error && "code" in error && isQuotaError(error)) {
|
|
2565
2578
|
this.quotaExceeded = true;
|
|
2566
|
-
this.
|
|
2579
|
+
this.pendingQuotaError = error;
|
|
2567
2580
|
} else if (errorMessage.includes("Authentication failed") || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
|
|
2568
2581
|
this.printConfigurationError("Authentication failed - Invalid or expired token", [
|
|
2569
2582
|
"Verify your token is correct",
|
|
@@ -2787,6 +2800,9 @@ var TestdinoReporter = class {
|
|
|
2787
2800
|
if (this.pendingTestEndPromises.size > 0) {
|
|
2788
2801
|
await Promise.allSettled(Array.from(this.pendingTestEndPromises));
|
|
2789
2802
|
}
|
|
2803
|
+
if (this.pendingQuotaError) {
|
|
2804
|
+
this.printQuotaError(this.pendingQuotaError);
|
|
2805
|
+
}
|
|
2790
2806
|
this.log.success("Tests completed (quota limit reached; not streamed to TestDino)");
|
|
2791
2807
|
this.wsClient?.close();
|
|
2792
2808
|
this.removeSignalHandlers();
|
|
@@ -2875,8 +2891,15 @@ var TestdinoReporter = class {
|
|
|
2875
2891
|
this.log.success("All events sent (HTTP fallback)");
|
|
2876
2892
|
delivered = true;
|
|
2877
2893
|
} catch (httpError) {
|
|
2878
|
-
const
|
|
2879
|
-
|
|
2894
|
+
const isQuota = isQuotaError(httpError) || httpError instanceof Error && "code" in httpError && (httpError.code === "QUOTA_EXCEEDED" || httpError.code === "QUOTA_EXHAUSTED");
|
|
2895
|
+
if (isQuota) {
|
|
2896
|
+
this.quotaExceeded = true;
|
|
2897
|
+
this.pendingQuotaError = httpError;
|
|
2898
|
+
this.printQuotaError(httpError);
|
|
2899
|
+
} else {
|
|
2900
|
+
const httpErrorMessage = httpError instanceof Error ? httpError.message : String(httpError);
|
|
2901
|
+
this.log.error(`HTTP fallback also failed: ${httpErrorMessage}`);
|
|
2902
|
+
}
|
|
2880
2903
|
}
|
|
2881
2904
|
} else if (!delivered) {
|
|
2882
2905
|
this.log.warn("Server did not acknowledge run:end in time, events may be pending");
|
|
@@ -3183,45 +3206,75 @@ var TestdinoReporter = class {
|
|
|
3183
3206
|
const details = errorData.details;
|
|
3184
3207
|
const planName = details?.planName || "Unknown";
|
|
3185
3208
|
const resetDate = details?.resetDate;
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
Used: ${details.used || "Unknown"} executions`;
|
|
3195
|
-
if (resetDate) {
|
|
3196
|
-
message += `
|
|
3197
|
-
Limit Resets: ${new Date(resetDate).toLocaleDateString()}`;
|
|
3198
|
-
}
|
|
3199
|
-
} else if (errorData.code === "QUOTA_EXCEEDED") {
|
|
3209
|
+
const formattedResetDate = resetDate ? new Date(resetDate).toLocaleDateString("en-US", {
|
|
3210
|
+
day: "2-digit",
|
|
3211
|
+
month: "short",
|
|
3212
|
+
year: "numeric"
|
|
3213
|
+
}) : void 0;
|
|
3214
|
+
console.error("");
|
|
3215
|
+
console.error(border);
|
|
3216
|
+
if (errorData.code === "QUOTA_EXCEEDED") {
|
|
3200
3217
|
const exceeded = details;
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3218
|
+
const orgRemaining = (exceeded.total ?? 0) - (exceeded.used ?? 0);
|
|
3219
|
+
const effectiveLimit = (exceeded.projectLimit ?? 0) + (exceeded.projectBorrowed ?? 0);
|
|
3220
|
+
console.error(" \u274C TestDino Project Execution Limit Reached");
|
|
3221
|
+
console.error(border);
|
|
3222
|
+
console.error("");
|
|
3223
|
+
console.error(" The test case limit allocated to this project has been exceeded.");
|
|
3224
|
+
console.error("");
|
|
3225
|
+
console.error(" Project Usage:");
|
|
3226
|
+
if (exceeded.projectName) {
|
|
3227
|
+
console.error(` Project: ${exceeded.projectName}`);
|
|
3228
|
+
}
|
|
3229
|
+
if (exceeded.projectLimit != null) {
|
|
3230
|
+
console.error(
|
|
3231
|
+
` Limit: ${effectiveLimit} test cases${exceeded.projectBorrowed ? ` (${exceeded.projectLimit} allocated + ${exceeded.projectBorrowed} borrowed)` : ""}`
|
|
3232
|
+
);
|
|
3213
3233
|
}
|
|
3234
|
+
if (exceeded.projectUsed != null) {
|
|
3235
|
+
console.error(` Used: ${exceeded.projectUsed}`);
|
|
3236
|
+
}
|
|
3237
|
+
console.error(` This run: ${exceeded.totalTests || "Unknown"} test cases`);
|
|
3238
|
+
console.error(" Status: Project quota exhausted");
|
|
3239
|
+
console.error("");
|
|
3240
|
+
console.error(" Organization Usage:");
|
|
3241
|
+
console.error(` Plan: ${planName} (${exceeded.total || "Unknown"} test cases / month)`);
|
|
3242
|
+
console.error(` Used: ${exceeded.used || "Unknown"}`);
|
|
3243
|
+
console.error(` Remaining: ${orgRemaining}`);
|
|
3244
|
+
if (orgRemaining > 0) {
|
|
3245
|
+
console.error("");
|
|
3246
|
+
console.error(" Note:");
|
|
3247
|
+
console.error(` Your organization still has ${orgRemaining} test cases available,`);
|
|
3248
|
+
console.error(" but they are not allocated to this project.");
|
|
3249
|
+
}
|
|
3250
|
+
console.error("");
|
|
3251
|
+
console.error(" Solutions:");
|
|
3252
|
+
console.error(" 1. Allocate more test case quota to this project in");
|
|
3253
|
+
console.error(" Settings \u2192 Billing & Usage \u2192 Test Limits");
|
|
3254
|
+
console.error(" 2. Enable Auto Allocation to automatically distribute");
|
|
3255
|
+
console.error(" remaining organization quota");
|
|
3256
|
+
} else if (errorData.code === "QUOTA_EXHAUSTED") {
|
|
3257
|
+
console.error(" \u274C TestDino Organization Execution Limit Reached");
|
|
3258
|
+
console.error(border);
|
|
3259
|
+
console.error("");
|
|
3260
|
+
console.error(" Your organization has exhausted its monthly test case limit.");
|
|
3261
|
+
console.error("");
|
|
3262
|
+
console.error(" Organization Usage:");
|
|
3263
|
+
console.error(` Plan: ${planName} (${details.totalLimit || "Unknown"} test cases / month)`);
|
|
3264
|
+
console.error(` Used: ${details.used || "Unknown"}`);
|
|
3265
|
+
console.error(" Remaining: 0");
|
|
3266
|
+
console.error("");
|
|
3267
|
+
console.error(" Solutions:");
|
|
3268
|
+
console.error(" 1. Upgrade your plan to increase monthly test case limit");
|
|
3269
|
+
}
|
|
3270
|
+
if (formattedResetDate) {
|
|
3271
|
+
console.error("");
|
|
3272
|
+
console.error(" Monthly Reset:");
|
|
3273
|
+
console.error(` ${formattedResetDate}`);
|
|
3214
3274
|
}
|
|
3215
3275
|
console.error("");
|
|
3216
|
-
console.error(
|
|
3217
|
-
console.error("
|
|
3218
|
-
console.error(border);
|
|
3219
|
-
console.error(` ${message}`);
|
|
3220
|
-
console.error("");
|
|
3221
|
-
console.error(" Solutions:");
|
|
3222
|
-
console.error(" 1. Upgrade your plan to increase monthly limit");
|
|
3223
|
-
console.error(" 2. Wait for monthly limit reset");
|
|
3224
|
-
console.error(" 3. Visit https://testdino.com/pricing for plan options");
|
|
3276
|
+
console.error(" Docs: https://docs.testdino.com/platform/billing-and-usage/test-limits");
|
|
3277
|
+
console.error(" Pricing: https://testdino.com/pricing");
|
|
3225
3278
|
console.error(border);
|
|
3226
3279
|
console.error("");
|
|
3227
3280
|
}
|