@argos-ci/core 1.1.0 → 1.2.1

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.ts CHANGED
@@ -38,9 +38,13 @@ declare const upload: (params: UploadParameters) => Promise<{
38
38
  url: string;
39
39
  };
40
40
  screenshots: {
41
- metadata: import("@argos-ci/util").ScreenshotMetadata | null;
42
- optimizedPath: string;
43
41
  hash: string;
42
+ optimizedPath: string;
43
+ metadata: import("@argos-ci/util").ScreenshotMetadata | null;
44
+ pwTrace: {
45
+ path: string;
46
+ hash: string;
47
+ } | null;
44
48
  name: string;
45
49
  path: string;
46
50
  }[];
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import tmp from 'tmp';
10
10
  import { createHash } from 'node:crypto';
11
11
  import axios from 'axios';
12
12
  import { readFile } from 'node:fs/promises';
13
- import { readMetadata } from '@argos-ci/util';
13
+ import { readMetadata, getPlaywrightTracePath } from '@argos-ci/util';
14
14
 
15
15
  /**
16
16
  * Check if the current directory is a git repository.
@@ -528,7 +528,7 @@ const upload$1 = async (input)=>{
528
528
  url: input.url,
529
529
  data: file,
530
530
  headers: {
531
- "Content-Type": "image/png"
531
+ "Content-Type": input.contentType
532
532
  }
533
533
  });
534
534
  };
@@ -558,9 +558,29 @@ const getConfigFromOptions = ({ parallel, ...options })=>{
558
558
  });
559
559
  return config;
560
560
  };
561
+ async function uploadFilesToS3(files) {
562
+ debug(`Split files in chunks of ${CHUNK_SIZE}`);
563
+ const chunks = chunk(files, CHUNK_SIZE);
564
+ debug(`Starting upload of ${chunks.length} chunks`);
565
+ for(let i = 0; i < chunks.length; i++){
566
+ // Upload files
567
+ debug(`Uploading chunk ${i + 1}/${chunks.length}`);
568
+ const timeLabel = `Chunk ${i + 1}/${chunks.length}`;
569
+ debugTime(timeLabel);
570
+ await Promise.all(chunks[i].map(async ({ url, path, contentType })=>{
571
+ await upload$1({
572
+ url,
573
+ path,
574
+ contentType
575
+ });
576
+ }));
577
+ debugTimeEnd(timeLabel);
578
+ }
579
+ }
561
580
  /**
562
581
  * Upload screenshots to argos-ci.com.
563
582
  */ const upload = async (params)=>{
583
+ var _result_pwTraces;
564
584
  debug("Starting upload with params", params);
565
585
  // Read config
566
586
  const config = getConfigFromOptions(params);
@@ -580,61 +600,95 @@ const getConfigFromOptions = ({ parallel, ...options })=>{
580
600
  debug("Found screenshots", foundScreenshots);
581
601
  // Optimize & compute hashes
582
602
  const screenshots = await Promise.all(foundScreenshots.map(async (screenshot)=>{
583
- const [metadata, optimizedPath] = await Promise.all([
603
+ const [metadata, pwTracePath, optimizedPath] = await Promise.all([
584
604
  readMetadata(screenshot.path),
605
+ getPlaywrightTracePath(screenshot.path),
585
606
  optimizeScreenshot(screenshot.path)
586
607
  ]);
587
- const hash = await hashFile(optimizedPath);
608
+ const [hash, pwTraceHash] = await Promise.all([
609
+ hashFile(optimizedPath),
610
+ pwTracePath ? hashFile(pwTracePath) : null
611
+ ]);
588
612
  return {
589
613
  ...screenshot,
590
- metadata,
614
+ hash,
591
615
  optimizedPath,
592
- hash
616
+ metadata,
617
+ pwTrace: pwTracePath && pwTraceHash ? {
618
+ path: pwTracePath,
619
+ hash: pwTraceHash
620
+ } : null
593
621
  };
594
622
  }));
595
623
  // Create build
596
624
  debug("Creating build");
625
+ const [pwTraceKeys, screenshotKeys] = screenshots.reduce(([pwTraceKeys, screenshotKeys], screenshot)=>{
626
+ if (screenshot.pwTrace && !pwTraceKeys.includes(screenshot.pwTrace.hash)) {
627
+ pwTraceKeys.push(screenshot.pwTrace.hash);
628
+ }
629
+ if (!screenshotKeys.includes(screenshot.hash)) {
630
+ screenshotKeys.push(screenshot.hash);
631
+ }
632
+ return [
633
+ pwTraceKeys,
634
+ screenshotKeys
635
+ ];
636
+ }, [
637
+ [],
638
+ []
639
+ ]);
597
640
  const result = await apiClient.createBuild({
598
641
  commit: config.commit,
599
642
  branch: config.branch,
600
643
  name: config.buildName,
601
644
  parallel: config.parallel,
602
645
  parallelNonce: config.parallelNonce,
603
- screenshotKeys: Array.from(new Set(screenshots.map((screenshot)=>screenshot.hash))),
646
+ screenshotKeys,
647
+ pwTraceKeys,
604
648
  prNumber: config.prNumber,
605
649
  prHeadCommit: config.prHeadCommit,
606
650
  referenceBranch: config.referenceBranch,
607
651
  referenceCommit: config.referenceCommit
608
652
  });
609
- debug("Got screenshots", result);
610
- debug(`Split screenshots in chunks of ${CHUNK_SIZE}`);
611
- const chunks = chunk(result.screenshots, CHUNK_SIZE);
612
- debug(`Starting upload of ${chunks.length} chunks`);
613
- for(let i = 0; i < chunks.length; i++){
614
- debug(`Uploading chunk ${i + 1}/${chunks.length}`);
615
- const timeLabel = `Chunk ${i + 1}/${chunks.length}`;
616
- debugTime(timeLabel);
617
- await Promise.all(chunks[i].map(async ({ key, putUrl })=>{
653
+ debug("Got uploads url", result);
654
+ const uploadFiles = [
655
+ ...result.screenshots.map(({ key, putUrl })=>{
618
656
  const screenshot = screenshots.find((s)=>s.hash === key);
619
657
  if (!screenshot) {
620
658
  throw new Error(`Invariant: screenshot with hash ${key} not found`);
621
659
  }
622
- await upload$1({
660
+ return {
623
661
  url: putUrl,
624
- path: screenshot.optimizedPath
625
- });
626
- }));
627
- debugTimeEnd(timeLabel);
628
- }
662
+ path: screenshot.optimizedPath,
663
+ contentType: "image/png"
664
+ };
665
+ }),
666
+ ...((_result_pwTraces = result.pwTraces) === null || _result_pwTraces === void 0 ? void 0 : _result_pwTraces.map(({ key, putUrl })=>{
667
+ const screenshot = screenshots.find((s)=>s.pwTrace && s.pwTrace.hash === key);
668
+ if (!screenshot || !screenshot.pwTrace) {
669
+ throw new Error(`Invariant: trace with ${key} not found`);
670
+ }
671
+ return {
672
+ url: putUrl,
673
+ path: screenshot.pwTrace.path,
674
+ contentType: "application/json"
675
+ };
676
+ })) ?? []
677
+ ];
678
+ await uploadFilesToS3(uploadFiles);
629
679
  // Update build
630
680
  debug("Updating build");
631
681
  await apiClient.updateBuild({
632
682
  buildId: result.build.id,
633
- screenshots: screenshots.map((screenshot)=>({
683
+ screenshots: screenshots.map((screenshot)=>{
684
+ var _screenshot_pwTrace;
685
+ return {
634
686
  key: screenshot.hash,
635
687
  name: screenshot.name,
636
- metadata: screenshot.metadata
637
- })),
688
+ metadata: screenshot.metadata,
689
+ pwTraceKey: ((_screenshot_pwTrace = screenshot.pwTrace) === null || _screenshot_pwTrace === void 0 ? void 0 : _screenshot_pwTrace.hash) ?? null
690
+ };
691
+ }),
638
692
  parallel: config.parallel,
639
693
  parallelTotal: config.parallelTotal
640
694
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@argos-ci/core",
3
3
  "description": "Visual testing solution to avoid visual regression. The core component of Argos SDK that handles build creation.",
4
- "version": "1.1.0",
4
+ "version": "1.2.1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "types": "./dist/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@argos-ci/util": "1.0.0",
43
+ "@argos-ci/util": "1.1.0",
44
44
  "axios": "^1.5.0",
45
45
  "convict": "^6.2.4",
46
46
  "debug": "^4.3.4",
@@ -59,5 +59,5 @@
59
59
  "build": "rollup -c",
60
60
  "e2e": "node ./e2e/upload.cjs && node ./e2e/upload.mjs"
61
61
  },
62
- "gitHead": "08246344886ff258fab097c370b4ff29cb1121b0"
62
+ "gitHead": "366dc3bdb4a0a8ed87fc7a2cbf28db1f218567ad"
63
63
  }