testlens-playwright-reporter 0.3.1 → 0.3.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/index.js +127 -8
- package/index.ts +123 -13
- package/lib/index.js +119 -12
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
2
|
-
|
|
3
1
|
const { randomUUID } = require('crypto');
|
|
4
2
|
const os = require('os');
|
|
5
3
|
const path = require('path');
|
|
@@ -97,6 +95,7 @@ class TestLensReporter {
|
|
|
97
95
|
this.runMetadata = this.initializeRunMetadata();
|
|
98
96
|
this.specMap = new Map();
|
|
99
97
|
this.testMap = new Map();
|
|
98
|
+
this.runCreationFailed = false; // Track if run creation failed due to limits
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
initializeRunMetadata() {
|
|
@@ -164,6 +163,9 @@ class TestLensReporter {
|
|
|
164
163
|
}
|
|
165
164
|
|
|
166
165
|
async onTestBegin(test, result) {
|
|
166
|
+
// Log which test is starting
|
|
167
|
+
console.log(`\n▶️ Running test: ${test.title}`);
|
|
168
|
+
|
|
167
169
|
const specPath = test.location.file;
|
|
168
170
|
const specKey = `${specPath}-${test.parent.title}`;
|
|
169
171
|
|
|
@@ -496,24 +498,108 @@ class TestLensReporter {
|
|
|
496
498
|
}
|
|
497
499
|
|
|
498
500
|
async sendToApi(payload) {
|
|
501
|
+
// Skip sending if run creation already failed
|
|
502
|
+
if (this.runCreationFailed && payload.type !== 'runStart') {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
|
|
499
506
|
try {
|
|
500
507
|
const response = await this.axiosInstance.post('', payload, {
|
|
501
508
|
headers: {
|
|
502
509
|
'X-API-Key': this.config.apiKey
|
|
503
510
|
}
|
|
504
511
|
});
|
|
512
|
+
if (this.config.enableRealTimeStream) {
|
|
513
|
+
console.log(`✅ Sent ${payload.type} event to TestLens (HTTP ${response.status})`);
|
|
514
|
+
}
|
|
515
|
+
return true;
|
|
505
516
|
} catch (error) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
status: error?.response?.status,
|
|
509
|
-
data: error?.response?.data
|
|
510
|
-
});
|
|
517
|
+
const errorData = error?.response?.data;
|
|
518
|
+
const status = error?.response?.status;
|
|
511
519
|
|
|
520
|
+
// Check for limit exceeded (403)
|
|
521
|
+
if (status === 403 && errorData?.error === 'limit_exceeded') {
|
|
522
|
+
// Set flag to skip subsequent events
|
|
523
|
+
if (payload.type === 'runStart' && errorData?.limit_type === 'test_runs') {
|
|
524
|
+
this.runCreationFailed = true;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
console.error('\n' + '='.repeat(80));
|
|
528
|
+
if (errorData?.limit_type === 'test_cases') {
|
|
529
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
530
|
+
} else if (errorData?.limit_type === 'test_runs') {
|
|
531
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
532
|
+
} else {
|
|
533
|
+
console.error('❌ TESTLENS ERROR: Plan Limit Reached');
|
|
534
|
+
}
|
|
535
|
+
console.error('='.repeat(80));
|
|
536
|
+
console.error('');
|
|
537
|
+
console.error(errorData?.message || 'You have reached your plan limit.');
|
|
538
|
+
console.error('');
|
|
539
|
+
console.error(`Current usage: ${errorData?.current_usage || 'N/A'} / ${errorData?.limit || 'N/A'}`);
|
|
540
|
+
console.error('');
|
|
541
|
+
console.error('To continue, please upgrade your plan.');
|
|
542
|
+
console.error('Contact: support@alternative-path.com');
|
|
543
|
+
console.error('');
|
|
544
|
+
console.error('='.repeat(80));
|
|
545
|
+
console.error('');
|
|
546
|
+
return false; // Don't log the full error object for limit errors
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Check for trial expiration, subscription errors, or limit errors (401)
|
|
550
|
+
if (status === 401) {
|
|
551
|
+
if (errorData?.error === 'trial_expired' || errorData?.error === 'subscription_inactive' ||
|
|
552
|
+
errorData?.error === 'test_cases_limit_reached' || errorData?.error === 'test_runs_limit_reached') {
|
|
553
|
+
console.error('\n' + '='.repeat(80));
|
|
554
|
+
|
|
555
|
+
if (errorData?.error === 'test_cases_limit_reached') {
|
|
556
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
557
|
+
} else if (errorData?.error === 'test_runs_limit_reached') {
|
|
558
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
559
|
+
} else {
|
|
560
|
+
console.error('❌ TESTLENS ERROR: Your trial plan has ended');
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
console.error('='.repeat(80));
|
|
564
|
+
console.error('');
|
|
565
|
+
console.error(errorData?.message || 'Your trial period has expired.');
|
|
566
|
+
console.error('');
|
|
567
|
+
console.error('To continue using TestLens, please upgrade to Enterprise plan.');
|
|
568
|
+
console.error('Contact: ' + (errorData?.contactEmail || 'support@alternative-path.com'));
|
|
569
|
+
console.error('');
|
|
570
|
+
if (errorData?.trial_end_date) {
|
|
571
|
+
console.error(`Trial ended: ${new Date(errorData.trial_end_date).toLocaleDateString()}`);
|
|
572
|
+
console.error('');
|
|
573
|
+
}
|
|
574
|
+
console.error('='.repeat(80));
|
|
575
|
+
console.error('');
|
|
576
|
+
} else {
|
|
577
|
+
console.error(`❌ Authentication failed: ${errorData?.error || 'Invalid API key'}`);
|
|
578
|
+
}
|
|
579
|
+
} else if (status !== 403) {
|
|
580
|
+
// Log other errors (but not 403 which we handled above)
|
|
581
|
+
console.error(`❌ Failed to send ${payload.type} event to TestLens:`, {
|
|
582
|
+
message: error?.message || 'Unknown error',
|
|
583
|
+
status: status,
|
|
584
|
+
statusText: error?.response?.statusText,
|
|
585
|
+
data: errorData,
|
|
586
|
+
code: error?.code,
|
|
587
|
+
url: error?.config?.url,
|
|
588
|
+
method: error?.config?.method
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return false; // Return false on error
|
|
512
593
|
// Don't throw error to avoid breaking test execution
|
|
513
594
|
}
|
|
514
595
|
}
|
|
515
596
|
|
|
516
597
|
async processArtifacts(testId, result) {
|
|
598
|
+
// Skip artifact processing if run creation failed
|
|
599
|
+
if (this.runCreationFailed) {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
|
|
517
603
|
const attachments = result.attachments;
|
|
518
604
|
|
|
519
605
|
// Process artifacts with controlled async handling to ensure uploads complete
|
|
@@ -740,7 +826,7 @@ class TestLensReporter {
|
|
|
740
826
|
remoteUrl
|
|
741
827
|
};
|
|
742
828
|
} catch (error) {
|
|
743
|
-
|
|
829
|
+
// Silently skip git information if not in a git repository
|
|
744
830
|
return null;
|
|
745
831
|
}
|
|
746
832
|
}
|
|
@@ -863,6 +949,39 @@ class TestLensReporter {
|
|
|
863
949
|
throw new Error(`Upload confirmation failed: ${confirmResponse.data.error || 'Unknown error'}`);
|
|
864
950
|
}
|
|
865
951
|
} catch (error) {
|
|
952
|
+
// Check for trial expiration, subscription errors, or limit errors
|
|
953
|
+
if (error?.response?.status === 401) {
|
|
954
|
+
const errorData = error?.response?.data;
|
|
955
|
+
|
|
956
|
+
if (errorData?.error === 'trial_expired' || errorData?.error === 'subscription_inactive' ||
|
|
957
|
+
errorData?.error === 'test_cases_limit_reached' || errorData?.error === 'test_runs_limit_reached') {
|
|
958
|
+
console.error('\\n' + '='.repeat(80));
|
|
959
|
+
|
|
960
|
+
if (errorData?.error === 'test_cases_limit_reached') {
|
|
961
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
962
|
+
} else if (errorData?.error === 'test_runs_limit_reached') {
|
|
963
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
964
|
+
} else {
|
|
965
|
+
console.error('❌ TESTLENS ERROR: Your trial plan has ended');
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
console.error('='.repeat(80));
|
|
969
|
+
console.error('');
|
|
970
|
+
console.error(errorData?.message || 'Your trial period has expired.');
|
|
971
|
+
console.error('');
|
|
972
|
+
console.error('To continue using TestLens, please upgrade to Enterprise plan.');
|
|
973
|
+
console.error('Contact: ' + (errorData?.contactEmail || 'support@alternative-path.com'));
|
|
974
|
+
console.error('');
|
|
975
|
+
if (errorData?.trial_end_date) {
|
|
976
|
+
console.error(`Trial ended: ${new Date(errorData.trial_end_date).toLocaleDateString()}`);
|
|
977
|
+
console.error('');
|
|
978
|
+
}
|
|
979
|
+
console.error('='.repeat(80));
|
|
980
|
+
console.error('');
|
|
981
|
+
return null;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
866
985
|
// Better error messages for common issues
|
|
867
986
|
let errorMsg = error.message;
|
|
868
987
|
|
package/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
2
|
-
|
|
3
1
|
import { randomUUID } from 'crypto';
|
|
4
2
|
import * as os from 'os';
|
|
5
3
|
import * as path from 'path';
|
|
@@ -178,6 +176,7 @@ export class TestLensReporter implements Reporter {
|
|
|
178
176
|
private runMetadata: RunMetadata;
|
|
179
177
|
private specMap: Map<string, SpecData>;
|
|
180
178
|
private testMap: Map<string, TestData>;
|
|
179
|
+
private runCreationFailed: boolean = false; // Track if run creation failed due to limits
|
|
181
180
|
|
|
182
181
|
constructor(options: TestLensReporterOptions) {
|
|
183
182
|
this.config = {
|
|
@@ -259,6 +258,7 @@ export class TestLensReporter implements Reporter {
|
|
|
259
258
|
this.runMetadata = this.initializeRunMetadata();
|
|
260
259
|
this.specMap = new Map<string, SpecData>();
|
|
261
260
|
this.testMap = new Map<string, TestData>();
|
|
261
|
+
this.runCreationFailed = false;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
private initializeRunMetadata(): RunMetadata {
|
|
@@ -335,6 +335,9 @@ export class TestLensReporter implements Reporter {
|
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
async onTestBegin(test: TestCase, result: TestResult): Promise<void> {
|
|
338
|
+
// Log which test is starting
|
|
339
|
+
console.log(`\n▶️ Running test: ${test.title}`);
|
|
340
|
+
|
|
338
341
|
const specPath = test.location.file;
|
|
339
342
|
const specKey = `${specPath}-${test.parent.title}`;
|
|
340
343
|
|
|
@@ -671,8 +674,12 @@ export class TestLensReporter implements Reporter {
|
|
|
671
674
|
}
|
|
672
675
|
|
|
673
676
|
private async sendToApi(payload: any): Promise<void> {
|
|
677
|
+
// Skip sending if run creation already failed
|
|
678
|
+
if (this.runCreationFailed && payload.type !== 'runStart') {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
|
|
674
682
|
try {
|
|
675
|
-
console.log(`📤 Sending ${payload.type} event to ${this.config.apiEndpoint}`);
|
|
676
683
|
const response = await this.axiosInstance.post('', payload, {
|
|
677
684
|
headers: {
|
|
678
685
|
'X-API-Key': this.config.apiKey
|
|
@@ -682,21 +689,91 @@ export class TestLensReporter implements Reporter {
|
|
|
682
689
|
console.log(`✅ Sent ${payload.type} event to TestLens (HTTP ${response.status})`);
|
|
683
690
|
}
|
|
684
691
|
} catch (error: any) {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
692
|
+
const errorData = error?.response?.data;
|
|
693
|
+
const status = error?.response?.status;
|
|
694
|
+
|
|
695
|
+
// Check for limit exceeded (403)
|
|
696
|
+
if (status === 403 && errorData?.error === 'limit_exceeded') {
|
|
697
|
+
// Set flag to skip subsequent events
|
|
698
|
+
if (payload.type === 'runStart' && errorData?.limit_type === 'test_runs') {
|
|
699
|
+
this.runCreationFailed = true;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
console.error('\n' + '='.repeat(80));
|
|
703
|
+
if (errorData?.limit_type === 'test_cases') {
|
|
704
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
705
|
+
} else if (errorData?.limit_type === 'test_runs') {
|
|
706
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
707
|
+
} else {
|
|
708
|
+
console.error('❌ TESTLENS ERROR: Plan Limit Reached');
|
|
709
|
+
}
|
|
710
|
+
console.error('='.repeat(80));
|
|
711
|
+
console.error('');
|
|
712
|
+
console.error(errorData?.message || 'You have reached your plan limit.');
|
|
713
|
+
console.error('');
|
|
714
|
+
console.error(`Current usage: ${errorData?.current_usage || 'N/A'} / ${errorData?.limit || 'N/A'}`);
|
|
715
|
+
console.error('');
|
|
716
|
+
console.error('To continue, please upgrade your plan.');
|
|
717
|
+
console.error('Contact: support@alternative-path.com');
|
|
718
|
+
console.error('');
|
|
719
|
+
console.error('='.repeat(80));
|
|
720
|
+
console.error('');
|
|
721
|
+
return; // Don't log the full error object for limit errors
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Check for trial expiration, subscription errors, or limit errors (401)
|
|
725
|
+
if (status === 401) {
|
|
726
|
+
if (errorData?.error === 'trial_expired' || errorData?.error === 'subscription_inactive' ||
|
|
727
|
+
errorData?.error === 'test_cases_limit_reached' || errorData?.error === 'test_runs_limit_reached') {
|
|
728
|
+
console.error('\n' + '='.repeat(80));
|
|
729
|
+
|
|
730
|
+
if (errorData?.error === 'test_cases_limit_reached') {
|
|
731
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
732
|
+
} else if (errorData?.error === 'test_runs_limit_reached') {
|
|
733
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
734
|
+
} else {
|
|
735
|
+
console.error('❌ TESTLENS ERROR: Your trial plan has ended');
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
console.error('='.repeat(80));
|
|
739
|
+
console.error('');
|
|
740
|
+
console.error(errorData?.message || 'Your trial period has expired.');
|
|
741
|
+
console.error('');
|
|
742
|
+
console.error('To continue using TestLens, please upgrade to Enterprise plan.');
|
|
743
|
+
console.error('Contact: ' + (errorData?.contactEmail || 'support@alternative-path.com'));
|
|
744
|
+
console.error('');
|
|
745
|
+
if (errorData?.trial_end_date) {
|
|
746
|
+
console.error(`Trial ended: ${new Date(errorData.trial_end_date).toLocaleDateString()}`);
|
|
747
|
+
console.error('');
|
|
748
|
+
}
|
|
749
|
+
console.error('='.repeat(80));
|
|
750
|
+
console.error('');
|
|
751
|
+
} else {
|
|
752
|
+
console.error(`❌ Authentication failed: ${errorData?.error || 'Invalid API key'}`);
|
|
753
|
+
}
|
|
754
|
+
} else if (status !== 403) {
|
|
755
|
+
// Log other errors (but not 403 which we handled above)
|
|
756
|
+
console.error(`❌ Failed to send ${payload.type} event to TestLens:`, {
|
|
757
|
+
message: error?.message || 'Unknown error',
|
|
758
|
+
status: status,
|
|
759
|
+
statusText: error?.response?.statusText,
|
|
760
|
+
data: errorData,
|
|
761
|
+
code: error?.code,
|
|
762
|
+
url: error?.config?.url,
|
|
763
|
+
method: error?.config?.method
|
|
764
|
+
});
|
|
765
|
+
}
|
|
694
766
|
|
|
695
767
|
// Don't throw error to avoid breaking test execution
|
|
696
768
|
}
|
|
697
769
|
}
|
|
698
770
|
|
|
699
771
|
private async processArtifacts(testId: string, result: TestResult): Promise<void> {
|
|
772
|
+
// Skip artifact processing if run creation failed
|
|
773
|
+
if (this.runCreationFailed) {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
|
|
700
777
|
const attachments = result.attachments;
|
|
701
778
|
|
|
702
779
|
for (const attachment of attachments) {
|
|
@@ -919,7 +996,7 @@ export class TestLensReporter implements Reporter {
|
|
|
919
996
|
remoteUrl
|
|
920
997
|
};
|
|
921
998
|
} catch (error: any) {
|
|
922
|
-
|
|
999
|
+
// Silently skip git information if not in a git repository
|
|
923
1000
|
return null;
|
|
924
1001
|
}
|
|
925
1002
|
}
|
|
@@ -1040,6 +1117,39 @@ export class TestLensReporter implements Reporter {
|
|
|
1040
1117
|
throw new Error(`Upload confirmation failed: ${confirmResponse.data.error || 'Unknown error'}`);
|
|
1041
1118
|
}
|
|
1042
1119
|
} catch (error: any) {
|
|
1120
|
+
// Check for trial expiration, subscription errors, or limit errors
|
|
1121
|
+
if (error?.response?.status === 401) {
|
|
1122
|
+
const errorData = error?.response?.data;
|
|
1123
|
+
|
|
1124
|
+
if (errorData?.error === 'trial_expired' || errorData?.error === 'subscription_inactive' ||
|
|
1125
|
+
errorData?.error === 'test_cases_limit_reached' || errorData?.error === 'test_runs_limit_reached') {
|
|
1126
|
+
console.error('\\n' + '='.repeat(80));
|
|
1127
|
+
|
|
1128
|
+
if (errorData?.error === 'test_cases_limit_reached') {
|
|
1129
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
1130
|
+
} else if (errorData?.error === 'test_runs_limit_reached') {
|
|
1131
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
1132
|
+
} else {
|
|
1133
|
+
console.error('❌ TESTLENS ERROR: Your trial plan has ended');
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
console.error('='.repeat(80));
|
|
1137
|
+
console.error('');
|
|
1138
|
+
console.error(errorData?.message || 'Your trial period has expired.');
|
|
1139
|
+
console.error('');
|
|
1140
|
+
console.error('To continue using TestLens, please upgrade to Enterprise plan.');
|
|
1141
|
+
console.error('Contact: ' + (errorData?.contactEmail || 'support@alternative-path.com'));
|
|
1142
|
+
console.error('');
|
|
1143
|
+
if (errorData?.trial_end_date) {
|
|
1144
|
+
console.error(`Trial ended: ${new Date(errorData.trial_end_date).toLocaleDateString()}`);
|
|
1145
|
+
console.error('');
|
|
1146
|
+
}
|
|
1147
|
+
console.error('='.repeat(80));
|
|
1148
|
+
console.error('');
|
|
1149
|
+
return null;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1043
1153
|
// Better error messages for common issues
|
|
1044
1154
|
let errorMsg = error.message;
|
|
1045
1155
|
|
package/lib/index.js
CHANGED
|
@@ -37,7 +37,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.TestLensReporter = void 0;
|
|
40
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
41
40
|
const crypto_1 = require("crypto");
|
|
42
41
|
const os = __importStar(require("os"));
|
|
43
42
|
const path = __importStar(require("path"));
|
|
@@ -57,6 +56,7 @@ async function getMime() {
|
|
|
57
56
|
}
|
|
58
57
|
class TestLensReporter {
|
|
59
58
|
constructor(options) {
|
|
59
|
+
this.runCreationFailed = false; // Track if run creation failed due to limits
|
|
60
60
|
this.config = {
|
|
61
61
|
apiEndpoint: options.apiEndpoint || 'https://testlens.qa-path.com/api/v1/webhook/playwright',
|
|
62
62
|
apiKey: options.apiKey, // API key must come from config file
|
|
@@ -126,6 +126,7 @@ class TestLensReporter {
|
|
|
126
126
|
this.runMetadata = this.initializeRunMetadata();
|
|
127
127
|
this.specMap = new Map();
|
|
128
128
|
this.testMap = new Map();
|
|
129
|
+
this.runCreationFailed = false;
|
|
129
130
|
}
|
|
130
131
|
initializeRunMetadata() {
|
|
131
132
|
return {
|
|
@@ -196,6 +197,8 @@ class TestLensReporter {
|
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
199
|
async onTestBegin(test, result) {
|
|
200
|
+
// Log which test is starting
|
|
201
|
+
console.log(`\n▶️ Running test: ${test.title}`);
|
|
199
202
|
const specPath = test.location.file;
|
|
200
203
|
const specKey = `${specPath}-${test.parent.title}`;
|
|
201
204
|
// Create or update spec data
|
|
@@ -491,8 +494,11 @@ class TestLensReporter {
|
|
|
491
494
|
console.log(`🎯 Results: ${passedTests} passed, ${failedTests} failed (${timedOutTests} timeouts), ${skippedTests} skipped`);
|
|
492
495
|
}
|
|
493
496
|
async sendToApi(payload) {
|
|
497
|
+
// Skip sending if run creation already failed
|
|
498
|
+
if (this.runCreationFailed && payload.type !== 'runStart') {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
494
501
|
try {
|
|
495
|
-
console.log(`📤 Sending ${payload.type} event to ${this.config.apiEndpoint}`);
|
|
496
502
|
const response = await this.axiosInstance.post('', payload, {
|
|
497
503
|
headers: {
|
|
498
504
|
'X-API-Key': this.config.apiKey
|
|
@@ -503,19 +509,89 @@ class TestLensReporter {
|
|
|
503
509
|
}
|
|
504
510
|
}
|
|
505
511
|
catch (error) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
512
|
+
const errorData = error?.response?.data;
|
|
513
|
+
const status = error?.response?.status;
|
|
514
|
+
// Check for limit exceeded (403)
|
|
515
|
+
if (status === 403 && errorData?.error === 'limit_exceeded') {
|
|
516
|
+
// Set flag to skip subsequent events
|
|
517
|
+
if (payload.type === 'runStart' && errorData?.limit_type === 'test_runs') {
|
|
518
|
+
this.runCreationFailed = true;
|
|
519
|
+
}
|
|
520
|
+
console.error('\n' + '='.repeat(80));
|
|
521
|
+
if (errorData?.limit_type === 'test_cases') {
|
|
522
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
523
|
+
}
|
|
524
|
+
else if (errorData?.limit_type === 'test_runs') {
|
|
525
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
console.error('❌ TESTLENS ERROR: Plan Limit Reached');
|
|
529
|
+
}
|
|
530
|
+
console.error('='.repeat(80));
|
|
531
|
+
console.error('');
|
|
532
|
+
console.error(errorData?.message || 'You have reached your plan limit.');
|
|
533
|
+
console.error('');
|
|
534
|
+
console.error(`Current usage: ${errorData?.current_usage || 'N/A'} / ${errorData?.limit || 'N/A'}`);
|
|
535
|
+
console.error('');
|
|
536
|
+
console.error('To continue, please upgrade your plan.');
|
|
537
|
+
console.error('Contact: support@alternative-path.com');
|
|
538
|
+
console.error('');
|
|
539
|
+
console.error('='.repeat(80));
|
|
540
|
+
console.error('');
|
|
541
|
+
return; // Don't log the full error object for limit errors
|
|
542
|
+
}
|
|
543
|
+
// Check for trial expiration, subscription errors, or limit errors (401)
|
|
544
|
+
if (status === 401) {
|
|
545
|
+
if (errorData?.error === 'trial_expired' || errorData?.error === 'subscription_inactive' ||
|
|
546
|
+
errorData?.error === 'test_cases_limit_reached' || errorData?.error === 'test_runs_limit_reached') {
|
|
547
|
+
console.error('\n' + '='.repeat(80));
|
|
548
|
+
if (errorData?.error === 'test_cases_limit_reached') {
|
|
549
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
550
|
+
}
|
|
551
|
+
else if (errorData?.error === 'test_runs_limit_reached') {
|
|
552
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
console.error('❌ TESTLENS ERROR: Your trial plan has ended');
|
|
556
|
+
}
|
|
557
|
+
console.error('='.repeat(80));
|
|
558
|
+
console.error('');
|
|
559
|
+
console.error(errorData?.message || 'Your trial period has expired.');
|
|
560
|
+
console.error('');
|
|
561
|
+
console.error('To continue using TestLens, please upgrade to Enterprise plan.');
|
|
562
|
+
console.error('Contact: ' + (errorData?.contactEmail || 'support@alternative-path.com'));
|
|
563
|
+
console.error('');
|
|
564
|
+
if (errorData?.trial_end_date) {
|
|
565
|
+
console.error(`Trial ended: ${new Date(errorData.trial_end_date).toLocaleDateString()}`);
|
|
566
|
+
console.error('');
|
|
567
|
+
}
|
|
568
|
+
console.error('='.repeat(80));
|
|
569
|
+
console.error('');
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
console.error(`❌ Authentication failed: ${errorData?.error || 'Invalid API key'}`);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
else if (status !== 403) {
|
|
576
|
+
// Log other errors (but not 403 which we handled above)
|
|
577
|
+
console.error(`❌ Failed to send ${payload.type} event to TestLens:`, {
|
|
578
|
+
message: error?.message || 'Unknown error',
|
|
579
|
+
status: status,
|
|
580
|
+
statusText: error?.response?.statusText,
|
|
581
|
+
data: errorData,
|
|
582
|
+
code: error?.code,
|
|
583
|
+
url: error?.config?.url,
|
|
584
|
+
method: error?.config?.method
|
|
585
|
+
});
|
|
586
|
+
}
|
|
515
587
|
// Don't throw error to avoid breaking test execution
|
|
516
588
|
}
|
|
517
589
|
}
|
|
518
590
|
async processArtifacts(testId, result) {
|
|
591
|
+
// Skip artifact processing if run creation failed
|
|
592
|
+
if (this.runCreationFailed) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
519
595
|
const attachments = result.attachments;
|
|
520
596
|
for (const attachment of attachments) {
|
|
521
597
|
if (attachment.path) {
|
|
@@ -717,7 +793,7 @@ class TestLensReporter {
|
|
|
717
793
|
};
|
|
718
794
|
}
|
|
719
795
|
catch (error) {
|
|
720
|
-
|
|
796
|
+
// Silently skip git information if not in a git repository
|
|
721
797
|
return null;
|
|
722
798
|
}
|
|
723
799
|
}
|
|
@@ -823,6 +899,37 @@ class TestLensReporter {
|
|
|
823
899
|
}
|
|
824
900
|
}
|
|
825
901
|
catch (error) {
|
|
902
|
+
// Check for trial expiration, subscription errors, or limit errors
|
|
903
|
+
if (error?.response?.status === 401) {
|
|
904
|
+
const errorData = error?.response?.data;
|
|
905
|
+
if (errorData?.error === 'trial_expired' || errorData?.error === 'subscription_inactive' ||
|
|
906
|
+
errorData?.error === 'test_cases_limit_reached' || errorData?.error === 'test_runs_limit_reached') {
|
|
907
|
+
console.error('\\n' + '='.repeat(80));
|
|
908
|
+
if (errorData?.error === 'test_cases_limit_reached') {
|
|
909
|
+
console.error('❌ TESTLENS ERROR: Test Cases Limit Reached');
|
|
910
|
+
}
|
|
911
|
+
else if (errorData?.error === 'test_runs_limit_reached') {
|
|
912
|
+
console.error('❌ TESTLENS ERROR: Test Runs Limit Reached');
|
|
913
|
+
}
|
|
914
|
+
else {
|
|
915
|
+
console.error('❌ TESTLENS ERROR: Your trial plan has ended');
|
|
916
|
+
}
|
|
917
|
+
console.error('='.repeat(80));
|
|
918
|
+
console.error('');
|
|
919
|
+
console.error(errorData?.message || 'Your trial period has expired.');
|
|
920
|
+
console.error('');
|
|
921
|
+
console.error('To continue using TestLens, please upgrade to Enterprise plan.');
|
|
922
|
+
console.error('Contact: ' + (errorData?.contactEmail || 'support@alternative-path.com'));
|
|
923
|
+
console.error('');
|
|
924
|
+
if (errorData?.trial_end_date) {
|
|
925
|
+
console.error(`Trial ended: ${new Date(errorData.trial_end_date).toLocaleDateString()}`);
|
|
926
|
+
console.error('');
|
|
927
|
+
}
|
|
928
|
+
console.error('='.repeat(80));
|
|
929
|
+
console.error('');
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
826
933
|
// Better error messages for common issues
|
|
827
934
|
let errorMsg = error.message;
|
|
828
935
|
if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
|
package/package.json
CHANGED