codeplay-common 4.4.1 → 4.4.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.
@@ -5,11 +5,21 @@ const { spawn, spawnSync } = require('node:child_process');
5
5
 
6
6
  const screenshotDirectory = path.join(__dirname, 'Auto-Screenshot', 'Store-image-Screenshot');
7
7
  const inFrameDirectory = path.join(__dirname, 'Auto-Screenshot', 'Store-image-Frame');
8
- const amazonAssetsDirectory = path.join(__dirname, 'Auto-Screenshot', 'Amazon-assets');
9
- const samsungAssetsDirectory = path.join(__dirname, 'Auto-Screenshot', 'Samsung-assets');
8
+ const amazonAssetsDirectory = path.join(__dirname, 'Auto-Screenshot', 'Amazon-Assets');
9
+ const samsungAssetsDirectory = path.join(__dirname, 'Auto-Screenshot', 'Samsung-Assets');
10
10
  const capacitorConfigPath = path.join(__dirname, 'capacitor.config.json');
11
11
  const amazonIconPath = path.join(__dirname, 'resources', 'icon-only.png');
12
12
  const temporaryDirectory = path.join(__dirname, 'agent-temp');
13
+ const amazonAssetDefinitions = [
14
+ { fileName: 'icon-1280x720.png', type: 'icon', width: 1280, height: 720 },
15
+ { fileName: 'background-image-1920x1080.png', type: 'background-image', width: 1920, height: 1080 },
16
+ { fileName: 'featured-content-logo-640x260.png', type: 'featured-logo', width: 640, height: 260, transparent: true },
17
+ { fileName: 'featured-content-background-1920x720.png', type: 'featured-background', width: 1920, height: 720 },
18
+ ];
19
+ const samsungAssetDefinitions = [
20
+ { fileName: 'edge-screen-160x2560.png', type: 'edge-screen', width: 160, height: 2560 },
21
+ { fileName: 'edge-screen-single-550x2560.png', type: 'edge-screen-single-plus', width: 550, height: 2560 },
22
+ ];
13
23
  const browserExecutablePaths = [
14
24
  'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
15
25
  'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
@@ -430,6 +440,8 @@ function printHelp() {
430
440
  console.log(' node take-screen-image.js --samsung-assets');
431
441
  console.log(' node take-screen-image.js --dry-run');
432
442
  console.log(' node take-screen-image.js --list');
443
+ console.log('');
444
+ console.log('A normal capture automatically creates any missing Amazon and Samsung store assets.');
433
445
  }
434
446
 
435
447
  function selectProfiles(input) {
@@ -611,6 +623,11 @@ async function capturePageSnapshot(client) {
611
623
  clone.setAttribute('data-responsive-scroll-left', String(original.scrollLeft));
612
624
  }
613
625
 
626
+ if (original.classList.contains('swiper-initialized')) {
627
+ clone.setAttribute('data-responsive-swiper-width', String(original.clientWidth));
628
+ clone.setAttribute('data-responsive-swiper-height', String(original.clientHeight));
629
+ }
630
+
614
631
  if (original instanceof HTMLInputElement) {
615
632
  clone.setAttribute('value', original.value);
616
633
  clone.toggleAttribute('checked', original.checked);
@@ -698,7 +715,6 @@ async function capturePageSnapshot(client) {
698
715
 
699
716
  return {
700
717
  html: '<!doctype html>' + clonedRoot.outerHTML,
701
- scrollX,
702
718
  scrollY,
703
719
  };
704
720
  })()`,
@@ -853,7 +869,7 @@ async function closeReplayBrowser(browser) {
853
869
  }
854
870
 
855
871
  async function waitForReplayLayout(client, snapshot) {
856
- await client.send('Runtime.evaluate', {
872
+ const evaluation = await client.send('Runtime.evaluate', {
857
873
  expression: `(async () => {
858
874
  const assetWait = Promise.all([...document.images].map((image) => {
859
875
  if (image.complete) return Promise.resolve();
@@ -868,17 +884,82 @@ async function waitForReplayLayout(client, snapshot) {
868
884
  new Promise((resolve) => setTimeout(resolve, 5000)),
869
885
  ]);
870
886
 
887
+ document.querySelectorAll('[data-responsive-swiper-width]').forEach((swiper) => {
888
+ const wrapper = [...swiper.children].find((element) => (
889
+ element.classList.contains('swiper-wrapper')
890
+ ));
891
+
892
+ if (!wrapper) return;
893
+
894
+ const slides = [...wrapper.children].filter((element) => (
895
+ element.classList.contains('swiper-slide')
896
+ ));
897
+ const sourceWidth = Number(swiper.dataset.responsiveSwiperWidth);
898
+ const sourceHeight = Number(swiper.dataset.responsiveSwiperHeight);
899
+ const widthScale = sourceWidth > 0 ? swiper.clientWidth / sourceWidth : 1;
900
+ const heightScale = sourceHeight > 0 ? swiper.clientHeight / sourceHeight : 1;
901
+ const isVertical = swiper.classList.contains('swiper-vertical');
902
+
903
+ slides.forEach((slide) => {
904
+ if (!slide.dataset.responsiveSwiperWidth && slide.style.width) {
905
+ slide.dataset.responsiveSwiperWidth = String(parseFloat(slide.style.width));
906
+ }
907
+
908
+ if (!slide.dataset.responsiveSwiperHeight && slide.style.height) {
909
+ slide.dataset.responsiveSwiperHeight = String(parseFloat(slide.style.height));
910
+ }
911
+
912
+ const slideWidth = Number(slide.dataset.responsiveSwiperWidth);
913
+ const slideHeight = Number(slide.dataset.responsiveSwiperHeight);
914
+
915
+ if (Number.isFinite(slideWidth) && slideWidth > 0) {
916
+ slide.style.width = (slideWidth * widthScale) + 'px';
917
+ }
918
+
919
+ if (isVertical && Number.isFinite(slideHeight) && slideHeight > 0) {
920
+ slide.style.height = (slideHeight * heightScale) + 'px';
921
+ }
922
+ });
923
+
924
+ const activeSlide = slides.find((slide) => (
925
+ slide.classList.contains('swiper-slide-active')
926
+ )) || slides[0];
927
+
928
+ if (!activeSlide) return;
929
+
930
+ const offset = isVertical ? activeSlide.offsetTop : activeSlide.offsetLeft;
931
+ const direction = getComputedStyle(swiper).direction;
932
+ const horizontalOffset = direction === 'rtl' ? offset : -offset;
933
+ const verticalOffset = isVertical ? -offset : 0;
934
+
935
+ wrapper.style.transitionDuration = '0ms';
936
+ wrapper.style.transform = 'translate3d('
937
+ + (isVertical ? 0 : horizontalOffset) + 'px, '
938
+ + verticalOffset + 'px, 0px)';
939
+
940
+ if (swiper.classList.contains('swiper-autoheight')) {
941
+ wrapper.style.height = activeSlide.scrollHeight + 'px';
942
+ }
943
+ });
944
+
871
945
  document.querySelectorAll('[data-responsive-scroll-top]').forEach((element) => {
872
946
  element.scrollTop = Number(element.dataset.responsiveScrollTop);
873
947
  element.scrollLeft = Number(element.dataset.responsiveScrollLeft);
874
948
  });
875
- scrollTo(${Number(snapshot.scrollX) || 0}, ${Number(snapshot.scrollY) || 0});
949
+ scrollTo(0, ${Number(snapshot.scrollY) || 0});
876
950
 
877
951
  await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
952
+
953
+ return {
954
+ documentWidth: Math.max(document.documentElement.scrollWidth, document.body.scrollWidth),
955
+ viewportWidth: innerWidth,
956
+ };
878
957
  })()`,
879
958
  awaitPromise: true,
880
959
  returnByValue: true,
881
960
  });
961
+
962
+ return evaluation.result.value;
882
963
  }
883
964
 
884
965
  function getFrameAdornment(frameType) {
@@ -1441,7 +1522,7 @@ function createAmazonAssetHtml(asset, appName, iconBuffer, storeCopy) {
1441
1522
  </html>`;
1442
1523
  }
1443
1524
 
1444
- async function createAmazonAssets(client) {
1525
+ async function createAmazonAssets(client, skipExisting = false) {
1445
1526
  if (!fs.existsSync(amazonIconPath)) {
1446
1527
  throw new Error(`Amazon asset source icon was not found: ${amazonIconPath}`);
1447
1528
  }
@@ -1450,16 +1531,15 @@ async function createAmazonAssets(client) {
1450
1531
  const appName = config.appName || 'App';
1451
1532
  const storeCopy = getStoreAssetCopy(config);
1452
1533
  const iconBuffer = fs.readFileSync(amazonIconPath);
1453
- const assets = [
1454
- { fileName: 'icon-1280x720.png', type: 'icon', width: 1280, height: 720 },
1455
- { fileName: 'background-image-1920x1080.png', type: 'background-image', width: 1920, height: 1080 },
1456
- { fileName: 'featured-content-logo-640x260.png', type: 'featured-logo', width: 640, height: 260, transparent: true },
1457
- { fileName: 'featured-content-background-1920x720.png', type: 'featured-background', width: 1920, height: 720 },
1458
- ];
1459
-
1460
1534
  fs.mkdirSync(amazonAssetsDirectory, { recursive: true });
1461
1535
 
1462
- for (const asset of assets) {
1536
+ for (const asset of amazonAssetDefinitions) {
1537
+ const outputPath = path.join(amazonAssetsDirectory, asset.fileName);
1538
+
1539
+ if (skipExisting && fs.existsSync(outputPath)) {
1540
+ continue;
1541
+ }
1542
+
1463
1543
  await client.send('Emulation.setDeviceMetricsOverride', {
1464
1544
  width: asset.width,
1465
1545
  height: asset.height,
@@ -1493,7 +1573,6 @@ async function createAmazonAssets(client) {
1493
1573
  captureBeyondViewport: false,
1494
1574
  omitBackground: Boolean(asset.transparent),
1495
1575
  });
1496
- const outputPath = path.join(amazonAssetsDirectory, asset.fileName);
1497
1576
  fs.writeFileSync(outputPath, Buffer.from(screenshot.data, 'base64'));
1498
1577
  console.log(`Saved Amazon asset ${asset.width}x${asset.height}: ${outputPath}`);
1499
1578
  }
@@ -1604,7 +1683,7 @@ function createSamsungAssetHtml(asset, appName, iconBuffer, storeCopy) {
1604
1683
  </html>`;
1605
1684
  }
1606
1685
 
1607
- async function createSamsungAssets(client) {
1686
+ async function createSamsungAssets(client, skipExisting = false) {
1608
1687
  if (!fs.existsSync(amazonIconPath)) {
1609
1688
  throw new Error(`Samsung asset source icon was not found: ${amazonIconPath}`);
1610
1689
  }
@@ -1613,15 +1692,17 @@ async function createSamsungAssets(client) {
1613
1692
  const appName = config.appName || 'App';
1614
1693
  const storeCopy = getStoreAssetCopy(config);
1615
1694
  const iconBuffer = fs.readFileSync(amazonIconPath);
1616
- const assets = [
1617
- { fileName: 'edge-screen-160x2560.png', type: 'edge-screen', width: 160, height: 2560 },
1618
- { fileName: 'edge-screen-single-plus-550x2560.png', type: 'edge-screen-single-plus', width: 550, height: 2560 },
1619
- ];
1620
1695
  const maximumFileSize = 1024 * 1024;
1621
1696
 
1622
1697
  fs.mkdirSync(samsungAssetsDirectory, { recursive: true });
1623
1698
 
1624
- for (const asset of assets) {
1699
+ for (const asset of samsungAssetDefinitions) {
1700
+ const outputPath = path.join(samsungAssetsDirectory, asset.fileName);
1701
+
1702
+ if (skipExisting && fs.existsSync(outputPath)) {
1703
+ continue;
1704
+ }
1705
+
1625
1706
  await client.send('Emulation.setDeviceMetricsOverride', {
1626
1707
  width: asset.width,
1627
1708
  height: asset.height,
@@ -1650,7 +1731,6 @@ async function createSamsungAssets(client) {
1650
1731
  fromSurface: true,
1651
1732
  captureBeyondViewport: false,
1652
1733
  });
1653
- const outputPath = path.join(samsungAssetsDirectory, asset.fileName);
1654
1734
  const outputBuffer = Buffer.from(screenshot.data, 'base64');
1655
1735
 
1656
1736
  if (outputBuffer.length >= maximumFileSize) {
@@ -1667,6 +1747,41 @@ async function createSamsungAssets(client) {
1667
1747
  }
1668
1748
  }
1669
1749
 
1750
+ async function createMissingStoreAssets() {
1751
+ const hasMissingAmazonAssets = amazonAssetDefinitions.some((asset) => (
1752
+ !fs.existsSync(path.join(amazonAssetsDirectory, asset.fileName))
1753
+ ));
1754
+ const hasMissingSamsungAssets = samsungAssetDefinitions.some((asset) => (
1755
+ !fs.existsSync(path.join(samsungAssetsDirectory, asset.fileName))
1756
+ ));
1757
+
1758
+ if (!hasMissingAmazonAssets && !hasMissingSamsungAssets) {
1759
+ console.log('Amazon and Samsung store assets already exist.');
1760
+ return;
1761
+ }
1762
+
1763
+ let browser;
1764
+ let client;
1765
+
1766
+ try {
1767
+ browser = await launchReplayBrowser();
1768
+ client = await createReplayPage(browser);
1769
+
1770
+ if (hasMissingAmazonAssets) {
1771
+ await createAmazonAssets(client, true);
1772
+ }
1773
+
1774
+ if (hasMissingSamsungAssets) {
1775
+ await createSamsungAssets(client, true);
1776
+ }
1777
+ } finally {
1778
+ if (client) client.close();
1779
+ if (browser) await closeReplayBrowser(browser);
1780
+ }
1781
+
1782
+ console.log('Missing Amazon and Samsung store assets created.');
1783
+ }
1784
+
1670
1785
  async function captureFramedScreenshot(
1671
1786
  client,
1672
1787
  screenshotBuffer,
@@ -1750,7 +1865,14 @@ async function captureProfile(client, snapshot, profile, screenshotFileName) {
1750
1865
  frameId: frameTree.frameTree.frame.id,
1751
1866
  html: snapshot.html,
1752
1867
  });
1753
- await waitForReplayLayout(client, snapshot);
1868
+ const replayLayout = await waitForReplayLayout(client, snapshot);
1869
+
1870
+ if (replayLayout.documentWidth > replayLayout.viewportWidth + 1) {
1871
+ console.warn(
1872
+ `Warning: ${profile.label} replay is ${replayLayout.documentWidth}px wide `
1873
+ + `inside a ${replayLayout.viewportWidth}px viewport.`,
1874
+ );
1875
+ }
1754
1876
 
1755
1877
  const screenshot = await client.send('Page.captureScreenshot', {
1756
1878
  format: 'png',
@@ -1961,6 +2083,10 @@ async function main() {
1961
2083
  return;
1962
2084
  }
1963
2085
 
2086
+ if (!options.dryRun) {
2087
+ await createMissingStoreAssets();
2088
+ }
2089
+
1964
2090
  const selectedProfiles = selectProfiles(options.profiles);
1965
2091
 
1966
2092
  if (options.frameExisting) {