testlens-playwright-reporter 0.3.2 → 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 -6
- package/index.ts +123 -11
- package/lib/index.js +119 -11
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -95,6 +95,7 @@ class TestLensReporter {
|
|
|
95
95
|
this.runMetadata = this.initializeRunMetadata();
|
|
96
96
|
this.specMap = new Map();
|
|
97
97
|
this.testMap = new Map();
|
|
98
|
+
this.runCreationFailed = false; // Track if run creation failed due to limits
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
initializeRunMetadata() {
|
|
@@ -162,6 +163,9 @@ class TestLensReporter {
|
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
async onTestBegin(test, result) {
|
|
166
|
+
// Log which test is starting
|
|
167
|
+
console.log(`\n▶️ Running test: ${test.title}`);
|
|
168
|
+
|
|
165
169
|
const specPath = test.location.file;
|
|
166
170
|
const specKey = `${specPath}-${test.parent.title}`;
|
|
167
171
|
|
|
@@ -494,24 +498,108 @@ class TestLensReporter {
|
|
|
494
498
|
}
|
|
495
499
|
|
|
496
500
|
async sendToApi(payload) {
|
|
501
|
+
// Skip sending if run creation already failed
|
|
502
|
+
if (this.runCreationFailed && payload.type !== 'runStart') {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
|
|
497
506
|
try {
|
|
498
507
|
const response = await this.axiosInstance.post('', payload, {
|
|
499
508
|
headers: {
|
|
500
509
|
'X-API-Key': this.config.apiKey
|
|
501
510
|
}
|
|
502
511
|
});
|
|
512
|
+
if (this.config.enableRealTimeStream) {
|
|
513
|
+
console.log(`✅ Sent ${payload.type} event to TestLens (HTTP ${response.status})`);
|
|
514
|
+
}
|
|
515
|
+
return true;
|
|
503
516
|
} catch (error) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
517
|
+
const errorData = error?.response?.data;
|
|
518
|
+
const status = error?.response?.status;
|
|
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
|
+
}
|
|
509
591
|
|
|
592
|
+
return false; // Return false on error
|
|
510
593
|
// Don't throw error to avoid breaking test execution
|
|
511
594
|
}
|
|
512
595
|
}
|
|
513
596
|
|
|
514
597
|
async processArtifacts(testId, result) {
|
|
598
|
+
// Skip artifact processing if run creation failed
|
|
599
|
+
if (this.runCreationFailed) {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
|
|
515
603
|
const attachments = result.attachments;
|
|
516
604
|
|
|
517
605
|
// Process artifacts with controlled async handling to ensure uploads complete
|
|
@@ -738,7 +826,7 @@ class TestLensReporter {
|
|
|
738
826
|
remoteUrl
|
|
739
827
|
};
|
|
740
828
|
} catch (error) {
|
|
741
|
-
|
|
829
|
+
// Silently skip git information if not in a git repository
|
|
742
830
|
return null;
|
|
743
831
|
}
|
|
744
832
|
}
|
|
@@ -861,6 +949,39 @@ class TestLensReporter {
|
|
|
861
949
|
throw new Error(`Upload confirmation failed: ${confirmResponse.data.error || 'Unknown error'}`);
|
|
862
950
|
}
|
|
863
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
|
+
|
|
864
985
|
// Better error messages for common issues
|
|
865
986
|
let errorMsg = error.message;
|
|
866
987
|
|
package/index.ts
CHANGED
|
@@ -176,6 +176,7 @@ export class TestLensReporter implements Reporter {
|
|
|
176
176
|
private runMetadata: RunMetadata;
|
|
177
177
|
private specMap: Map<string, SpecData>;
|
|
178
178
|
private testMap: Map<string, TestData>;
|
|
179
|
+
private runCreationFailed: boolean = false; // Track if run creation failed due to limits
|
|
179
180
|
|
|
180
181
|
constructor(options: TestLensReporterOptions) {
|
|
181
182
|
this.config = {
|
|
@@ -257,6 +258,7 @@ export class TestLensReporter implements Reporter {
|
|
|
257
258
|
this.runMetadata = this.initializeRunMetadata();
|
|
258
259
|
this.specMap = new Map<string, SpecData>();
|
|
259
260
|
this.testMap = new Map<string, TestData>();
|
|
261
|
+
this.runCreationFailed = false;
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
private initializeRunMetadata(): RunMetadata {
|
|
@@ -333,6 +335,9 @@ export class TestLensReporter implements Reporter {
|
|
|
333
335
|
}
|
|
334
336
|
|
|
335
337
|
async onTestBegin(test: TestCase, result: TestResult): Promise<void> {
|
|
338
|
+
// Log which test is starting
|
|
339
|
+
console.log(`\n▶️ Running test: ${test.title}`);
|
|
340
|
+
|
|
336
341
|
const specPath = test.location.file;
|
|
337
342
|
const specKey = `${specPath}-${test.parent.title}`;
|
|
338
343
|
|
|
@@ -669,8 +674,12 @@ export class TestLensReporter implements Reporter {
|
|
|
669
674
|
}
|
|
670
675
|
|
|
671
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
|
+
|
|
672
682
|
try {
|
|
673
|
-
console.log(`📤 Sending ${payload.type} event to ${this.config.apiEndpoint}`);
|
|
674
683
|
const response = await this.axiosInstance.post('', payload, {
|
|
675
684
|
headers: {
|
|
676
685
|
'X-API-Key': this.config.apiKey
|
|
@@ -680,21 +689,91 @@ export class TestLensReporter implements Reporter {
|
|
|
680
689
|
console.log(`✅ Sent ${payload.type} event to TestLens (HTTP ${response.status})`);
|
|
681
690
|
}
|
|
682
691
|
} catch (error: any) {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
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
|
+
}
|
|
692
766
|
|
|
693
767
|
// Don't throw error to avoid breaking test execution
|
|
694
768
|
}
|
|
695
769
|
}
|
|
696
770
|
|
|
697
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
|
+
|
|
698
777
|
const attachments = result.attachments;
|
|
699
778
|
|
|
700
779
|
for (const attachment of attachments) {
|
|
@@ -917,7 +996,7 @@ export class TestLensReporter implements Reporter {
|
|
|
917
996
|
remoteUrl
|
|
918
997
|
};
|
|
919
998
|
} catch (error: any) {
|
|
920
|
-
|
|
999
|
+
// Silently skip git information if not in a git repository
|
|
921
1000
|
return null;
|
|
922
1001
|
}
|
|
923
1002
|
}
|
|
@@ -1038,6 +1117,39 @@ export class TestLensReporter implements Reporter {
|
|
|
1038
1117
|
throw new Error(`Upload confirmation failed: ${confirmResponse.data.error || 'Unknown error'}`);
|
|
1039
1118
|
}
|
|
1040
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
|
+
|
|
1041
1153
|
// Better error messages for common issues
|
|
1042
1154
|
let errorMsg = error.message;
|
|
1043
1155
|
|
package/lib/index.js
CHANGED
|
@@ -56,6 +56,7 @@ async function getMime() {
|
|
|
56
56
|
}
|
|
57
57
|
class TestLensReporter {
|
|
58
58
|
constructor(options) {
|
|
59
|
+
this.runCreationFailed = false; // Track if run creation failed due to limits
|
|
59
60
|
this.config = {
|
|
60
61
|
apiEndpoint: options.apiEndpoint || 'https://testlens.qa-path.com/api/v1/webhook/playwright',
|
|
61
62
|
apiKey: options.apiKey, // API key must come from config file
|
|
@@ -125,6 +126,7 @@ class TestLensReporter {
|
|
|
125
126
|
this.runMetadata = this.initializeRunMetadata();
|
|
126
127
|
this.specMap = new Map();
|
|
127
128
|
this.testMap = new Map();
|
|
129
|
+
this.runCreationFailed = false;
|
|
128
130
|
}
|
|
129
131
|
initializeRunMetadata() {
|
|
130
132
|
return {
|
|
@@ -195,6 +197,8 @@ class TestLensReporter {
|
|
|
195
197
|
});
|
|
196
198
|
}
|
|
197
199
|
async onTestBegin(test, result) {
|
|
200
|
+
// Log which test is starting
|
|
201
|
+
console.log(`\n▶️ Running test: ${test.title}`);
|
|
198
202
|
const specPath = test.location.file;
|
|
199
203
|
const specKey = `${specPath}-${test.parent.title}`;
|
|
200
204
|
// Create or update spec data
|
|
@@ -490,8 +494,11 @@ class TestLensReporter {
|
|
|
490
494
|
console.log(`🎯 Results: ${passedTests} passed, ${failedTests} failed (${timedOutTests} timeouts), ${skippedTests} skipped`);
|
|
491
495
|
}
|
|
492
496
|
async sendToApi(payload) {
|
|
497
|
+
// Skip sending if run creation already failed
|
|
498
|
+
if (this.runCreationFailed && payload.type !== 'runStart') {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
493
501
|
try {
|
|
494
|
-
console.log(`📤 Sending ${payload.type} event to ${this.config.apiEndpoint}`);
|
|
495
502
|
const response = await this.axiosInstance.post('', payload, {
|
|
496
503
|
headers: {
|
|
497
504
|
'X-API-Key': this.config.apiKey
|
|
@@ -502,19 +509,89 @@ class TestLensReporter {
|
|
|
502
509
|
}
|
|
503
510
|
}
|
|
504
511
|
catch (error) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
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
|
+
}
|
|
514
587
|
// Don't throw error to avoid breaking test execution
|
|
515
588
|
}
|
|
516
589
|
}
|
|
517
590
|
async processArtifacts(testId, result) {
|
|
591
|
+
// Skip artifact processing if run creation failed
|
|
592
|
+
if (this.runCreationFailed) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
518
595
|
const attachments = result.attachments;
|
|
519
596
|
for (const attachment of attachments) {
|
|
520
597
|
if (attachment.path) {
|
|
@@ -716,7 +793,7 @@ class TestLensReporter {
|
|
|
716
793
|
};
|
|
717
794
|
}
|
|
718
795
|
catch (error) {
|
|
719
|
-
|
|
796
|
+
// Silently skip git information if not in a git repository
|
|
720
797
|
return null;
|
|
721
798
|
}
|
|
722
799
|
}
|
|
@@ -822,6 +899,37 @@ class TestLensReporter {
|
|
|
822
899
|
}
|
|
823
900
|
}
|
|
824
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
|
+
}
|
|
825
933
|
// Better error messages for common issues
|
|
826
934
|
let errorMsg = error.message;
|
|
827
935
|
if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
|
package/package.json
CHANGED