happo 6.9.0 → 6.10.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.
Files changed (95) hide show
  1. package/dist/cli/cancelJob-4I7RBUQG.js +10 -0
  2. package/dist/cli/{chunk-P4EXA4AX.js → chunk-64XRFVHC.js} +8 -4
  3. package/dist/cli/chunk-64XRFVHC.js.map +7 -0
  4. package/dist/cli/{chunk-J2EA5OBW.js → chunk-GG7D7TQZ.js} +2 -2
  5. package/dist/cli/chunk-ML3Z5Z22.js +44 -0
  6. package/dist/cli/chunk-ML3Z5Z22.js.map +7 -0
  7. package/dist/cli/{chunk-BK32666K.js → chunk-OCKO64S4.js} +3 -3
  8. package/dist/cli/{chunk-R6YURZXU.js → chunk-RJXHIGT5.js} +2 -2
  9. package/dist/cli/{chunk-BESQLM5F.js → chunk-UTRRH3WF.js} +2 -2
  10. package/dist/cli/{chunk-CVX5DVCT.js → chunk-XZTQZZFK.js} +2 -2
  11. package/dist/cli/createAsyncComparison-WLPUS2NJ.js +10 -0
  12. package/dist/cli/{createAsyncReport-4ZD53TJC.js → createAsyncReport-2ZTQOHDA.js} +4 -4
  13. package/dist/cli/createExtendsReportSnapRequest-4ZSBNCPL.js +32 -0
  14. package/dist/cli/createExtendsReportSnapRequest-4ZSBNCPL.js.map +7 -0
  15. package/dist/cli/findBaselineReport-2SHS2OH7.js +36 -0
  16. package/dist/cli/findBaselineReport-2SHS2OH7.js.map +7 -0
  17. package/dist/cli/{getFlakes-6ZGTWZTM.js → getFlakes-DLKH2VLM.js} +4 -4
  18. package/dist/cli/index.d.ts.map +1 -1
  19. package/dist/cli/main.js +160 -19
  20. package/dist/cli/main.js.map +3 -3
  21. package/dist/cli/package-TU7REKQ6.js +7 -0
  22. package/dist/cli/parseOptions.d.ts +6 -0
  23. package/dist/cli/parseOptions.d.ts.map +1 -1
  24. package/dist/cli/{prepareSnapRequests-2LHSGFZV.js → prepareSnapRequests-WBXFGB4B.js} +170 -65
  25. package/dist/cli/prepareSnapRequests-WBXFGB4B.js.map +7 -0
  26. package/dist/cli/startJob-33HGTT4N.js +10 -0
  27. package/dist/cli/{wrapper-7RE2N7Y3.js → wrapper-CCHBHKT2.js} +45 -26
  28. package/dist/cli/wrapper-CCHBHKT2.js.map +7 -0
  29. package/dist/config/index.d.ts +0 -8
  30. package/dist/config/index.d.ts.map +1 -1
  31. package/dist/config/index.js.map +2 -2
  32. package/dist/custom/index.d.ts.map +1 -1
  33. package/dist/custom/index.js +70 -14
  34. package/dist/custom/index.js.map +3 -3
  35. package/dist/cypress/chunk-TYBGAHYH.js +69 -0
  36. package/dist/cypress/chunk-TYBGAHYH.js.map +7 -0
  37. package/dist/cypress/index.d.ts.map +1 -1
  38. package/dist/cypress/index.js +14 -4
  39. package/dist/cypress/index.js.map +2 -2
  40. package/dist/cypress/task.d.ts +4 -2
  41. package/dist/cypress/task.d.ts.map +1 -1
  42. package/dist/cypress/task.js +25 -6
  43. package/dist/cypress/task.js.map +4 -4
  44. package/dist/e2e/wrapper.d.ts +1 -1
  45. package/dist/e2e/wrapper.d.ts.map +1 -1
  46. package/dist/environment/index.d.ts +2 -1
  47. package/dist/environment/index.d.ts.map +1 -1
  48. package/dist/isomorphic/parseOnly.d.ts +15 -0
  49. package/dist/isomorphic/parseOnly.d.ts.map +1 -0
  50. package/dist/isomorphic/parseSkip.d.ts +28 -0
  51. package/dist/isomorphic/parseSkip.d.ts.map +1 -0
  52. package/dist/isomorphic/types.d.ts +11 -0
  53. package/dist/isomorphic/types.d.ts.map +1 -1
  54. package/dist/network/createExtendsReportSnapRequest.d.ts +4 -0
  55. package/dist/network/createExtendsReportSnapRequest.d.ts.map +1 -0
  56. package/dist/network/findBaselineReport.d.ts +5 -0
  57. package/dist/network/findBaselineReport.d.ts.map +1 -0
  58. package/dist/network/prepareSnapRequests.d.ts +9 -1
  59. package/dist/network/prepareSnapRequests.d.ts.map +1 -1
  60. package/dist/playwright/index.d.ts.map +1 -1
  61. package/dist/playwright/index.js +59 -3
  62. package/dist/playwright/index.js.map +3 -3
  63. package/dist/storybook/browser/register.d.ts +2 -1
  64. package/dist/storybook/browser/register.d.ts.map +1 -1
  65. package/dist/storybook/browser/register.js +5 -1
  66. package/dist/storybook/browser/register.js.map +2 -2
  67. package/dist/storybook/index.d.ts +9 -1
  68. package/dist/storybook/index.d.ts.map +1 -1
  69. package/dist/storybook/index.js +134 -42
  70. package/dist/storybook/index.js.map +4 -4
  71. package/dist/storybook/isomorphic/types.d.ts +4 -0
  72. package/dist/storybook/isomorphic/types.d.ts.map +1 -1
  73. package/dist/storybook/resolveStoryFileItems.d.ts +21 -0
  74. package/dist/storybook/resolveStoryFileItems.d.ts.map +1 -0
  75. package/package.json +7 -3
  76. package/dist/cli/cancelJob-Y4WJCCU6.js +0 -10
  77. package/dist/cli/chunk-P4EXA4AX.js.map +0 -7
  78. package/dist/cli/createAsyncComparison-CQLGQXY2.js +0 -10
  79. package/dist/cli/package-4NRNRUE3.js +0 -7
  80. package/dist/cli/prepareSnapRequests-2LHSGFZV.js.map +0 -7
  81. package/dist/cli/startJob-JAO5FUA2.js +0 -10
  82. package/dist/cli/wrapper-7RE2N7Y3.js.map +0 -7
  83. package/dist/cypress/chunk-RKK2MPML.js +0 -20
  84. package/dist/cypress/chunk-RKK2MPML.js.map +0 -7
  85. /package/dist/cli/{cancelJob-Y4WJCCU6.js.map → cancelJob-4I7RBUQG.js.map} +0 -0
  86. /package/dist/cli/{chunk-J2EA5OBW.js.map → chunk-GG7D7TQZ.js.map} +0 -0
  87. /package/dist/cli/{chunk-BK32666K.js.map → chunk-OCKO64S4.js.map} +0 -0
  88. /package/dist/cli/{chunk-R6YURZXU.js.map → chunk-RJXHIGT5.js.map} +0 -0
  89. /package/dist/cli/{chunk-BESQLM5F.js.map → chunk-UTRRH3WF.js.map} +0 -0
  90. /package/dist/cli/{chunk-CVX5DVCT.js.map → chunk-XZTQZZFK.js.map} +0 -0
  91. /package/dist/cli/{createAsyncComparison-CQLGQXY2.js.map → createAsyncComparison-WLPUS2NJ.js.map} +0 -0
  92. /package/dist/cli/{createAsyncReport-4ZD53TJC.js.map → createAsyncReport-2ZTQOHDA.js.map} +0 -0
  93. /package/dist/cli/{getFlakes-6ZGTWZTM.js.map → getFlakes-DLKH2VLM.js.map} +0 -0
  94. /package/dist/cli/{package-4NRNRUE3.js.map → package-TU7REKQ6.js.map} +0 -0
  95. /package/dist/cli/{startJob-JAO5FUA2.js.map → startJob-33HGTT4N.js.map} +0 -0
package/dist/cli/main.js CHANGED
@@ -2,12 +2,15 @@
2
2
  import {
3
3
  startServer
4
4
  } from "./chunk-JTRP4JVC.js";
5
+ import {
6
+ validateSkip
7
+ } from "./chunk-ML3Z5Z22.js";
5
8
  import {
6
9
  fetchWithRetry
7
- } from "./chunk-BESQLM5F.js";
10
+ } from "./chunk-UTRRH3WF.js";
8
11
  import {
9
12
  package_default
10
- } from "./chunk-P4EXA4AX.js";
13
+ } from "./chunk-64XRFVHC.js";
11
14
 
12
15
  // src/cli/index.ts
13
16
  import path3 from "node:path";
@@ -808,7 +811,8 @@ async function resolveEnvironment(cliArgs, env = process.env) {
808
811
  fallbackShas: resolveFallbackShas(cliArgs, nonNullBeforeSha),
809
812
  githubToken: cliArgs.githubToken,
810
813
  ci: !!env.CI,
811
- skippedExamples: cliArgs.skippedExamples
814
+ skip: cliArgs.skip,
815
+ only: cliArgs.only
812
816
  };
813
817
  if (debugMode) {
814
818
  console.log("[HAPPO] Raw environment", getRawEnv(env));
@@ -817,6 +821,27 @@ async function resolveEnvironment(cliArgs, env = process.env) {
817
821
  return result;
818
822
  }
819
823
 
824
+ // src/isomorphic/parseOnly.ts
825
+ function isOnlyItem(item) {
826
+ if (typeof item !== "object" || item === null) return false;
827
+ const record = item;
828
+ const hasComponent = typeof record["component"] === "string";
829
+ const hasStoryFile = typeof record["storyFile"] === "string";
830
+ if (hasComponent && hasStoryFile) return false;
831
+ if (hasStoryFile) return record["variant"] === void 0;
832
+ if (hasComponent) return record["variant"] === void 0;
833
+ return false;
834
+ }
835
+ function validateOnly(json) {
836
+ const parsed = JSON.parse(json);
837
+ if (!Array.isArray(parsed) || !parsed.every(isOnlyItem)) {
838
+ throw new TypeError(
839
+ "--only must be a JSON array of {component} or {storyFile} objects (variant is not supported)"
840
+ );
841
+ }
842
+ return parsed;
843
+ }
844
+
820
845
  // src/cli/parseOptions.ts
821
846
  var parseOptions = {
822
847
  version: {
@@ -895,8 +920,14 @@ var parseOptions = {
895
920
  sha: {
896
921
  type: "string"
897
922
  },
923
+ skip: {
924
+ type: "string"
925
+ },
898
926
  skippedExamples: {
899
927
  type: "string"
928
+ },
929
+ only: {
930
+ type: "string"
900
931
  }
901
932
  };
902
933
 
@@ -1194,7 +1225,7 @@ function createReporter(opts = {}) {
1194
1225
 
1195
1226
  // src/cli/index.ts
1196
1227
  async function getVersion() {
1197
- const packageJson = await import("./package-4NRNRUE3.js");
1228
+ const packageJson = await import("./package-TU7REKQ6.js");
1198
1229
  return packageJson.default.version;
1199
1230
  }
1200
1231
  function parseDashdashCommandParts(rawArgs) {
@@ -1286,6 +1317,11 @@ Options:
1286
1317
  --notify <emails> One or more (comma-separated) email addresses to notify with results
1287
1318
  --nonce <nonce> Nonce to use for Cypress/Playwright comparison
1288
1319
  --githubToken <token> GitHub token to use for posting Happo statuses as comments. Use in combination with the \`githubApiUrl\` configuration option. (default: auto-detected from environment)
1320
+ --skip <json> JSON array of {component, variant} objects to skip in this run and borrow from the nearest baseline report instead
1321
+ --only <json> JSON array of {component} or {storyFile} objects to include in this run (all other stories are skipped); only supported for the Storybook integration
1322
+
1323
+ Finalize command options:
1324
+ --skippedExamples <json> JSON array of {component, variant, target} objects to skip when finalizing; borrowed from the nearest baseline report
1289
1325
 
1290
1326
  Flake command options:
1291
1327
  --allProjects List flakes across all projects (default: current project)
@@ -1314,7 +1350,8 @@ Examples:
1314
1350
 
1315
1351
  happo -- playwright test
1316
1352
 
1317
- --skippedExamples <json> JSON array of examples to skip in the finalize command (e.g. '[{"component":"Button","variant":"primary","target":"chrome"}]')
1353
+ happo --skip '[{"component":"Button","variant":"Primary"}]'
1354
+ happo --only '[{"component":"Button"},{"storyFile":"./src/Input.stories.tsx"}]'
1318
1355
 
1319
1356
  happo finalize
1320
1357
  happo finalize --nonce my-unique-nonce
@@ -1373,19 +1410,38 @@ async function main(rawArgs = process.argv, logger = console) {
1373
1410
  const environment = await resolveEnvironment(args.values);
1374
1411
  const configFilePath = makeAbsolute(args.values.config || findConfigFile());
1375
1412
  const config = await loadConfigFile(configFilePath, environment, logger);
1413
+ if (args.values.project !== void 0) {
1414
+ config.project = args.values.project;
1415
+ }
1376
1416
  const command = args.positionals[0];
1377
1417
  if (args.dashdashCommandParts) {
1418
+ let validatedSkipJSON;
1419
+ if (environment.skip) {
1420
+ try {
1421
+ validateSkip(environment.skip);
1422
+ } catch (e) {
1423
+ logger.error(
1424
+ "[HAPPO] Invalid --skip:",
1425
+ e instanceof Error ? e.message : String(e)
1426
+ );
1427
+ process.exitCode = 1;
1428
+ return;
1429
+ }
1430
+ validatedSkipJSON = environment.skip;
1431
+ }
1378
1432
  await handleE2ECommand(
1379
1433
  config,
1380
1434
  environment,
1381
1435
  args.dashdashCommandParts,
1382
1436
  configFilePath,
1383
- logger
1437
+ logger,
1438
+ validatedSkipJSON
1384
1439
  );
1385
1440
  return;
1386
1441
  }
1387
1442
  if (command === "finalize") {
1388
- await handleFinalizeCommand(config, environment, logger);
1443
+ const finalizeEnvironment = args.values.skippedExamples ? { ...environment, skip: args.values.skippedExamples } : environment;
1444
+ await handleFinalizeCommand(config, finalizeEnvironment, logger);
1389
1445
  return;
1390
1446
  }
1391
1447
  if (command === "flake") {
@@ -1439,16 +1495,100 @@ async function main(rawArgs = process.argv, logger = console) {
1439
1495
  async function handleDefaultCommand(config, environment, logger) {
1440
1496
  logger.log("Running happo tests...");
1441
1497
  const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] = await Promise.all([
1442
- (await import("./startJob-JAO5FUA2.js")).default,
1443
- (await import("./createAsyncComparison-CQLGQXY2.js")).default,
1444
- (await import("./createAsyncReport-4ZD53TJC.js")).default,
1445
- (await import("./prepareSnapRequests-2LHSGFZV.js")).default
1498
+ (await import("./startJob-33HGTT4N.js")).default,
1499
+ (await import("./createAsyncComparison-WLPUS2NJ.js")).default,
1500
+ (await import("./createAsyncReport-2ZTQOHDA.js")).default,
1501
+ (await import("./prepareSnapRequests-WBXFGB4B.js")).default
1446
1502
  ]);
1447
1503
  await startJob(config, environment, logger);
1448
1504
  try {
1449
- const snapRequestIds = await prepareSnapRequests(config);
1505
+ let skip;
1506
+ let baselineSha;
1507
+ if (environment.skip) {
1508
+ const supportedTypes = ["storybook", "custom"];
1509
+ if (!supportedTypes.includes(config.integration.type)) {
1510
+ logger.error(
1511
+ `[HAPPO] --skip is not supported for integration type '${config.integration.type}'. Supported types: ${supportedTypes.join(", ")}`
1512
+ );
1513
+ process.exitCode = 1;
1514
+ return;
1515
+ }
1516
+ try {
1517
+ skip = validateSkip(environment.skip);
1518
+ } catch (e) {
1519
+ logger.error(
1520
+ "[HAPPO] Invalid --skip:",
1521
+ e instanceof Error ? e.message : String(e)
1522
+ );
1523
+ process.exitCode = 1;
1524
+ return;
1525
+ }
1526
+ if (config.integration.type !== "storybook" && skip.some((item) => "storyFile" in item)) {
1527
+ logger.error(
1528
+ `[HAPPO] storyFile items in --skip are only supported for the storybook integration (current integration: '${config.integration.type}')`
1529
+ );
1530
+ process.exitCode = 1;
1531
+ return;
1532
+ }
1533
+ const findBaselineReport = (await import("./findBaselineReport-2SHS2OH7.js")).default;
1534
+ baselineSha = await findBaselineReport(environment, config, logger);
1535
+ if (!baselineSha) {
1536
+ logger.log(
1537
+ "[HAPPO] No baseline report found for --skip run. Generating a full report instead."
1538
+ );
1539
+ skip = void 0;
1540
+ }
1541
+ }
1542
+ let only;
1543
+ if (environment.only) {
1544
+ if (config.integration.type !== "storybook") {
1545
+ logger.error(
1546
+ `[HAPPO] --only is not supported for integration type '${config.integration.type}'. Supported types: storybook`
1547
+ );
1548
+ process.exitCode = 1;
1549
+ return;
1550
+ }
1551
+ try {
1552
+ only = validateOnly(environment.only);
1553
+ } catch (e) {
1554
+ logger.error(
1555
+ "[HAPPO] Invalid --only:",
1556
+ e instanceof Error ? e.message : String(e)
1557
+ );
1558
+ process.exitCode = 1;
1559
+ return;
1560
+ }
1561
+ if (!baselineSha) {
1562
+ const findBaselineReport = (await import("./findBaselineReport-2SHS2OH7.js")).default;
1563
+ baselineSha = await findBaselineReport(environment, config, logger);
1564
+ if (!baselineSha) {
1565
+ logger.log(
1566
+ "[HAPPO] No baseline report found for --only run. Excluded stories will not be borrowed from a baseline."
1567
+ );
1568
+ }
1569
+ }
1570
+ }
1571
+ const { snapRequestIds, resolvedSkip } = await prepareSnapRequests(config, skip, only);
1572
+ let allSnapRequestIds = snapRequestIds;
1573
+ if (skip && baselineSha) {
1574
+ const createExtendsReportSnapRequest = (await import("./createExtendsReportSnapRequest-4ZSBNCPL.js")).default;
1575
+ const extendsRequestId = await createExtendsReportSnapRequest(
1576
+ baselineSha,
1577
+ resolvedSkip ?? skip,
1578
+ config
1579
+ );
1580
+ allSnapRequestIds = [...snapRequestIds, extendsRequestId];
1581
+ } else if (only && baselineSha && resolvedSkip && resolvedSkip.length > 0) {
1582
+ const createExtendsReportSnapRequest = (await import("./createExtendsReportSnapRequest-4ZSBNCPL.js")).default;
1583
+ const extendsRequestId = await createExtendsReportSnapRequest(
1584
+ baselineSha,
1585
+ resolvedSkip,
1586
+ config
1587
+ );
1588
+ allSnapRequestIds = [...snapRequestIds, extendsRequestId];
1589
+ }
1450
1590
  const asyncReport = await createAsyncReport(
1451
- snapRequestIds,
1591
+ allSnapRequestIds,
1452
1592
  config,
1453
1593
  environment,
1454
1594
  logger
@@ -1475,7 +1615,7 @@ async function handleDefaultCommand(config, environment, logger) {
1475
1615
  } catch (e) {
1476
1616
  const message = e instanceof Error ? e.message : String(e);
1477
1617
  logger.error(`${config.integration.type} run failed: ${message}`, e);
1478
- const cancelJob = (await import("./cancelJob-Y4WJCCU6.js")).default;
1618
+ const cancelJob = (await import("./cancelJob-4I7RBUQG.js")).default;
1479
1619
  await cancelJob("failure", message, config, environment, logger);
1480
1620
  process.exitCode = 1;
1481
1621
  return;
@@ -1486,7 +1626,7 @@ async function handleFinalizeCommand(config, environment, logger) {
1486
1626
  logger.log("Config:", config);
1487
1627
  logger.log("Environment:", environment);
1488
1628
  try {
1489
- const finalizeAll = (await import("./wrapper-7RE2N7Y3.js")).finalizeAll;
1629
+ const finalizeAll = (await import("./wrapper-CCHBHKT2.js")).finalizeAll;
1490
1630
  await finalizeAll({ happoConfig: config, environment, logger });
1491
1631
  } catch (e) {
1492
1632
  logger.error(e instanceof Error ? e.message : String(e), e);
@@ -1514,7 +1654,7 @@ async function handleFlakeCommand(config, {
1514
1654
  process.exitCode = 1;
1515
1655
  return;
1516
1656
  }
1517
- const { default: getFlakes, formatFlakeOutput } = await import("./getFlakes-6ZGTWZTM.js");
1657
+ const { default: getFlakes, formatFlakeOutput } = await import("./getFlakes-DLKH2VLM.js");
1518
1658
  const project = allProjects ? void 0 : projectOverride ?? config.project;
1519
1659
  const flakes = await getFlakes(
1520
1660
  {
@@ -1538,7 +1678,7 @@ async function handleFlakeCommand(config, {
1538
1678
  process.exitCode = 0;
1539
1679
  }
1540
1680
  var E2E_INTEGRATION_TYPES = ["cypress", "playwright"];
1541
- async function handleE2ECommand(config, environment, dashdashCommandParts, configFilePath, logger) {
1681
+ async function handleE2ECommand(config, environment, dashdashCommandParts, configFilePath, logger, skipJSON) {
1542
1682
  if (!E2E_INTEGRATION_TYPES.includes(config.integration.type)) {
1543
1683
  logger.error(
1544
1684
  `Unsupported integration type used for e2e command: ${config.integration.type}. Supported integration types for e2e are: ${E2E_INTEGRATION_TYPES.join(", ")}`
@@ -1556,13 +1696,14 @@ async function handleE2ECommand(config, environment, dashdashCommandParts, confi
1556
1696
  logger.log("Config:", config);
1557
1697
  logger.log("Environment:", environment);
1558
1698
  logger.log("Dashdash command parts:", dashdashCommandParts);
1559
- const runWithWrapper = (await import("./wrapper-7RE2N7Y3.js")).default;
1699
+ const runWithWrapper = (await import("./wrapper-CCHBHKT2.js")).default;
1560
1700
  const exitCode = await runWithWrapper(
1561
1701
  dashdashCommandParts,
1562
1702
  config,
1563
1703
  environment,
1564
1704
  logger,
1565
- configFilePath
1705
+ configFilePath,
1706
+ skipJSON
1566
1707
  );
1567
1708
  process.exitCode = exitCode;
1568
1709
  }