playwright-slack-report-burak 3.5.1 → 3.5.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.
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const fs = require('fs');
10
10
  const os = require('os');
11
11
  const path = require('path');
12
- const axios = require('axios');
13
12
  const { exec, execFileSync } = require('child_process');
14
13
  let AdmZip;
15
14
  try {
@@ -31,26 +30,19 @@ const PLAYWRIGHT_REPORT_DIR = path.join('./', 'playwright-report');
31
30
  const GITHUB_RUN_ID = process.env.GITHUB_RUN_ID || 'local';
32
31
  const GITHUB_RUN_ATTEMPT = process.env.GITHUB_RUN_ATTEMPT || '1';
33
32
 
34
- // Google Cloud Storage configuration
35
- const GCS_BUCKET_NAME = process.env.GCS_BUCKET_NAME;
36
- const GCS_SERVICE_ACCOUNT_KEY = process.env.GCS_SERVICE_ACCOUNT_KEY;
37
- const GCS_REPORTS_FOLDER_PREFIX = process.env.GCS_REPORTS_FOLDER_PREFIX;
38
- const GCS_UPLOAD_API_BASE_URL = process.env.GCS_UPLOAD_API_BASE_URL;
39
-
40
- // MinIO artifact storage configuration (artifacts uploaded by shards 2+ as
41
- // <bucket>/shard-artifacts/<run_id>-<run_attempt>/shard-<shard>.tar.zst, a zstd-compressed tar of playwright-report)
33
+ // MinIO storage configuration. Artifacts uploaded by shards 2+ as
34
+ // <bucket>/shard-artifacts/<run_id>-<run_attempt>/shard-<shard>.tar.zst (a zstd-compressed tar of playwright-report),
35
+ // merged HTML reports uploaded by shard 1 under <bucket>/playwright-reports/<run_id>-<run_attempt>/
42
36
  const MINIO_ENDPOINT = process.env.MINIO_ENDPOINT;
43
37
  const MINIO_ACCESS_KEY = process.env.MINIO_ACCESS_KEY;
44
38
  const MINIO_SECRET_KEY = process.env.MINIO_SECRET_KEY;
45
39
  const MINIO_BUCKET = process.env.MINIO_BUCKET;
46
40
  const MINIO_ALIAS = 'minio';
47
41
  const MINIO_ARTIFACTS_DIR = 'shard-artifacts';
42
+ const MINIO_REPORTS_DIR = 'playwright-reports';
48
43
 
49
44
  const getMinioObjectPath = (shard) => `${MINIO_ALIAS}/${MINIO_BUCKET}/${MINIO_ARTIFACTS_DIR}/${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}/shard-${shard}.tar.zst`;
50
-
51
- // Helper functions for report paths
52
- const getRunFolder = () => `${GCS_REPORTS_FOLDER_PREFIX}/${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}`;
53
- const getGcsObjectPath = (relativePath) => `${getRunFolder()}/${relativePath}`;
45
+ const getMinioReportsPath = () => `${MINIO_ALIAS}/${MINIO_BUCKET}/${MINIO_REPORTS_DIR}/${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}`;
54
46
 
55
47
  // ============================================================================
56
48
 
@@ -185,7 +177,7 @@ class ResultsParser {
185
177
  }
186
178
 
187
179
  await this.mergeReports();
188
- await this.pushReportsToGCS();
180
+ await this.pushReportsToMinio();
189
181
  } else if (singleShardNoBlob) {
190
182
  // Single shard without blob (e.g. different reporter config): use node summary for Slack report
191
183
  const nodeSummaryFile = path.join(SUMMARIES_DIR, 'node_summary_1.json');
@@ -573,130 +565,32 @@ class ResultsParser {
573
565
  }
574
566
  }
575
567
 
576
- async getGcsAccessToken() {
577
- if (!GCS_SERVICE_ACCOUNT_KEY) {
578
- throw new Error('GCS_SERVICE_ACCOUNT_KEY environment variable is required');
568
+ async pushReportsToMinio() {
569
+ if (!process.env.CI) {
570
+ console.log('Skipping MinIO push: not in CI');
571
+ return;
579
572
  }
580
-
581
- let serviceAccount;
582
- try {
583
- serviceAccount = JSON.parse(GCS_SERVICE_ACCOUNT_KEY);
584
- } catch (e) {
585
- // Try reading from file path
586
- if (fs.existsSync(GCS_SERVICE_ACCOUNT_KEY)) {
587
- serviceAccount = JSON.parse(fs.readFileSync(GCS_SERVICE_ACCOUNT_KEY, 'utf-8'));
588
- } else {
589
- throw new Error('Invalid GCS_SERVICE_ACCOUNT_KEY: must be JSON string or file path');
590
- }
573
+ if (!MINIO_ENDPOINT || !MINIO_ACCESS_KEY || !MINIO_SECRET_KEY || !MINIO_BUCKET) {
574
+ throw new Error('MinIO configuration is required: set MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY and MINIO_BUCKET');
591
575
  }
592
-
593
- // Request OAuth2 token from Google
594
- const jwt = require('jsonwebtoken');
595
- const now = Math.floor(Date.now() / 1000);
596
- const token = jwt.sign(
597
- {
598
- iss: serviceAccount.client_email,
599
- scope: 'https://www.googleapis.com/auth/devstorage.full_control',
600
- aud: 'https://oauth2.googleapis.com/token',
601
- exp: now + 3600,
602
- iat: now
603
- },
604
- serviceAccount.private_key,
605
- { algorithm: 'RS256' }
606
- );
607
-
608
- const tokenResponse = await axios.post('https://oauth2.googleapis.com/token', {
609
- grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
610
- assertion: token
611
- });
612
-
613
- return tokenResponse.data.access_token;
614
- }
615
-
616
- async pushReportsToGCS() {
617
- // Only push in CI environment with required configuration
618
- if (!process.env.CI || !GCS_SERVICE_ACCOUNT_KEY) {
619
- console.log('Skipping GCS push: not in CI or missing GCS_SERVICE_ACCOUNT_KEY');
576
+ if (!fs.existsSync(PLAYWRIGHT_REPORT_DIR)) {
577
+ console.warn('Warning: playwright-report directory not found, nothing to upload to MinIO');
620
578
  return;
621
579
  }
622
-
580
+ const destination = getMinioReportsPath();
581
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mc-reports-'));
582
+ const mcConfigDir = path.join(tmpDir, '.mc');
623
583
  try {
624
- console.log(`Uploading playwright-report files to GCS bucket: ${GCS_BUCKET_NAME} in folder: ${getRunFolder()}`);
625
-
626
- // Get access token
627
- const accessToken = await this.getGcsAccessToken();
628
-
629
- // Collect all files from playwright-report directory
630
- const files = this.getAllFilesRecursive(PLAYWRIGHT_REPORT_DIR);
631
-
632
- // Normalize the base directory path for path replacement
633
- const baseDirPath = path.resolve(PLAYWRIGHT_REPORT_DIR);
634
-
635
- // Upload all files to GCS
636
- for (const file of files) {
637
- // Get relative path from playwright-report directory
638
- const relativePath = path.relative(baseDirPath, file).replace(/\\/g, '/');
639
- const objectPath = getGcsObjectPath(relativePath);
640
- const content = fs.readFileSync(file);
641
-
642
- // Upload file to GCS
643
- const uploadUrl = `${GCS_UPLOAD_API_BASE_URL}/b/${GCS_BUCKET_NAME}/o?uploadType=media&name=${encodeURIComponent(objectPath)}`;
644
-
645
- await axios.post(uploadUrl, content, {
646
- headers: {
647
- 'Authorization': `Bearer ${accessToken}`,
648
- 'Content-Type': this.getContentType(file)
649
- }
650
- });
651
- }
652
-
653
- console.log(`Successfully uploaded ${files.length} files to GCS bucket: ${GCS_BUCKET_NAME} in folder: ${getRunFolder()}`);
584
+ console.log(`Uploading playwright-report to MinIO: ${destination}`);
585
+ // Pass credentials as separate args (not embedded in a URL) to avoid encoding issues.
586
+ execFileSync('mc', ['--config-dir', mcConfigDir, 'alias', 'set', MINIO_ALIAS, MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY], { stdio: 'ignore' });
587
+ execFileSync('mc', ['--config-dir', mcConfigDir, 'cp', '--recursive', `${PLAYWRIGHT_REPORT_DIR}/`, `${destination}/`], { stdio: 'ignore' });
588
+ console.log(`Successfully uploaded playwright-report to MinIO: ${destination}`);
654
589
  } catch (error) {
655
- console.warn('Warning: Failed to push reports to GCS. This may not affect the overall process.', error.message);
656
- if (error.response) {
657
- console.warn('GCS API error:', error.response.data);
658
- }
659
- }
660
- }
661
-
662
- getContentType(filePath) {
663
- const ext = path.extname(filePath).toLowerCase();
664
- const contentTypes = {
665
- '.html': 'text/html',
666
- '.css': 'text/css',
667
- '.js': 'application/javascript',
668
- '.json': 'application/json',
669
- '.png': 'image/png',
670
- '.jpg': 'image/jpeg',
671
- '.jpeg': 'image/jpeg',
672
- '.gif': 'image/gif',
673
- '.svg': 'image/svg+xml',
674
- '.zip': 'application/zip',
675
- '.txt': 'text/plain',
676
- '.xml': 'application/xml'
677
- };
678
- return contentTypes[ext] || 'application/octet-stream';
679
- }
680
-
681
- getAllFilesRecursive(dir, fileList = []) {
682
- if (!fs.existsSync(dir)) {
683
- return fileList;
684
- }
685
-
686
- const files = fs.readdirSync(dir);
687
-
688
- for (const file of files) {
689
- const filePath = path.join(dir, file);
690
- const stat = fs.statSync(filePath);
691
-
692
- if (stat.isDirectory()) {
693
- this.getAllFilesRecursive(filePath, fileList);
694
- } else {
695
- fileList.push(filePath);
696
- }
590
+ console.warn('Warning: Failed to push reports to MinIO. This may not affect the overall process.', error.message);
591
+ } finally {
592
+ fs.rmSync(tmpDir, { recursive: true, force: true });
697
593
  }
698
-
699
- return fileList;
700
594
  }
701
595
  }
702
596
  exports.default = ResultsParser;
@@ -86,7 +86,7 @@ class SlackReporter {
86
86
  return;
87
87
  }
88
88
  if (this.sendResults === 'branch') {
89
- this.log('🛑 Branch mode: skipping Slack post (GCS upload completed)');
89
+ this.log('🛑 Branch mode: skipping Slack post (MinIO upload completed)');
90
90
  return;
91
91
  }
92
92
  const agent = this.proxy ? new https_proxy_agent_1.HttpsProxyAgent(this.proxy) : undefined;
package/package.json CHANGED
@@ -33,7 +33,7 @@
33
33
  "lint-fix": "npx eslint . --ext .ts --fix"
34
34
  },
35
35
  "name": "playwright-slack-report-burak",
36
- "version": "3.5.1",
36
+ "version": "3.5.3",
37
37
  "main": "index.js",
38
38
  "types": "dist/index.d.ts",
39
39
  "author": "Burak B. <burak.boluk@hotmail.com>",