@chromatic-com/playwright 0.13.4 → 0.14.0-3e73276-20260512102356

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.mts CHANGED
@@ -1,32 +1,14 @@
1
+ import { a } from './types-DBnTR0hb.js';
2
+ export { a as ChromaticConfig } from './types-DBnTR0hb.js';
1
3
  import * as playwright_test from 'playwright/test';
2
4
  import { Page, TestInfo } from '@playwright/test';
3
5
  export { expect } from '@playwright/test';
4
6
 
5
- declare global {
6
- interface Window {
7
- FontFace: typeof FontFace;
8
- }
9
- }
10
-
11
- interface ChromaticConfig {
12
- delay?: number;
13
- diffIncludeAntiAliasing?: boolean;
14
- diffThreshold?: number;
15
- disableAutoSnapshot?: boolean;
16
- forcedColors?: string;
17
- pauseAnimationAtEnd?: boolean;
18
- prefersReducedMotion?: string;
19
- resourceArchiveTimeout?: number;
20
- assetDomains?: string[];
21
- cropToViewport?: boolean;
22
- ignoreSelectors?: string[];
23
- }
24
-
25
7
  declare function takeSnapshot(page: Page, testInfo: TestInfo): Promise<void>;
26
8
  declare function takeSnapshot(page: Page, name: string, testInfo: TestInfo): Promise<void>;
27
9
 
28
- declare const test: playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & ChromaticConfig & {
10
+ declare const test: playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & a & {
29
11
  chromaticSnapshot: void;
30
12
  }, playwright_test.PlaywrightWorkerArgs & playwright_test.PlaywrightWorkerOptions>;
31
13
 
32
- export { type ChromaticConfig, takeSnapshot, test };
14
+ export { takeSnapshot, test };
package/dist/index.d.ts CHANGED
@@ -1,32 +1,14 @@
1
+ import { a } from './types-DBnTR0hb.js';
2
+ export { a as ChromaticConfig } from './types-DBnTR0hb.js';
1
3
  import * as playwright_test from 'playwright/test';
2
4
  import { Page, TestInfo } from '@playwright/test';
3
5
  export { expect } from '@playwright/test';
4
6
 
5
- declare global {
6
- interface Window {
7
- FontFace: typeof FontFace;
8
- }
9
- }
10
-
11
- interface ChromaticConfig {
12
- delay?: number;
13
- diffIncludeAntiAliasing?: boolean;
14
- diffThreshold?: number;
15
- disableAutoSnapshot?: boolean;
16
- forcedColors?: string;
17
- pauseAnimationAtEnd?: boolean;
18
- prefersReducedMotion?: string;
19
- resourceArchiveTimeout?: number;
20
- assetDomains?: string[];
21
- cropToViewport?: boolean;
22
- ignoreSelectors?: string[];
23
- }
24
-
25
7
  declare function takeSnapshot(page: Page, testInfo: TestInfo): Promise<void>;
26
8
  declare function takeSnapshot(page: Page, name: string, testInfo: TestInfo): Promise<void>;
27
9
 
28
- declare const test: playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & ChromaticConfig & {
10
+ declare const test: playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & a & {
29
11
  chromaticSnapshot: void;
30
12
  }, playwright_test.PlaywrightWorkerArgs & playwright_test.PlaywrightWorkerOptions>;
31
13
 
32
- export { type ChromaticConfig, takeSnapshot, test };
14
+ export { takeSnapshot, test };
package/dist/index.js CHANGED
@@ -3451,8 +3451,13 @@ var _ResourceArchiver = (_a = class {
3451
3451
  });
3452
3452
  }, "requestPaused"));
3453
3453
  this.client = cdpClient;
3454
- this.assetDomains = (allowedDomains || []).map((domain) => `https://${domain}`);
3455
3454
  this.httpCredentials = httpCredentials;
3455
+ this.assetDomains = (allowedDomains || []).map((domain) => {
3456
+ if (domain.startsWith("http")) {
3457
+ return domain;
3458
+ }
3459
+ return `https://${domain}`;
3460
+ });
3456
3461
  }
3457
3462
  async watch() {
3458
3463
  this.client.on("Fetch.requestPaused", this.requestPaused);
@@ -3686,16 +3691,21 @@ var _ArchiveFile = (_a2 = class {
3686
3691
  }, __name(_a2, "_ArchiveFile"), _a2);
3687
3692
  __name2(_ArchiveFile, "ArchiveFile");
3688
3693
  var ArchiveFile = _ArchiveFile;
3689
- var NodeType = /* @__PURE__ */ ((NodeType2) => {
3690
- NodeType2[NodeType2["Document"] = 0] = "Document";
3691
- NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
3692
- NodeType2[NodeType2["Element"] = 2] = "Element";
3693
- NodeType2[NodeType2["Text"] = 3] = "Text";
3694
- NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
3695
- NodeType2[NodeType2["Comment"] = 5] = "Comment";
3696
- return NodeType2;
3694
+ var NodeType = /* @__PURE__ */ ((NodeType22) => {
3695
+ NodeType22[NodeType22["Document"] = 0] = "Document";
3696
+ NodeType22[NodeType22["DocumentType"] = 1] = "DocumentType";
3697
+ NodeType22[NodeType22["Element"] = 2] = "Element";
3698
+ NodeType22[NodeType22["Text"] = 3] = "Text";
3699
+ NodeType22[NodeType22["CDATA"] = 4] = "CDATA";
3700
+ NodeType22[NodeType22["Comment"] = 5] = "Comment";
3701
+ return NodeType22;
3697
3702
  })(NodeType || {});
3698
3703
  var import_srcset = __toESM(require_srcset());
3704
+ function isIframeSerializedNode(node) {
3705
+ return node.type === NodeType.Element && node.tagName === "iframe" && "contentDocument" in node && !!node.contentDocument;
3706
+ }
3707
+ __name(isIframeSerializedNode, "isIframeSerializedNode");
3708
+ __name2(isIframeSerializedNode, "isIframeSerializedNode");
3699
3709
  var CSS_URL_REGEX = /url\((?!['"]?(?:data):)['"]?([^'")]*)['"]?\)/gi;
3700
3710
  var _a3;
3701
3711
  var _DOMSnapshot = (_a3 = class {
@@ -3725,6 +3735,9 @@ var _DOMSnapshot = (_a3 = class {
3725
3735
  return this.mapNode(childNode, sourceMap);
3726
3736
  }));
3727
3737
  }
3738
+ if (isIframeSerializedNode(node)) {
3739
+ node.contentDocument = await this.mapNode(node.contentDocument, sourceMap);
3740
+ }
3728
3741
  return node;
3729
3742
  }
3730
3743
  mapNodeAttributes(node, sourceMap) {
@@ -4035,6 +4048,19 @@ function trackComplete(properties = {}) {
4035
4048
  __name(trackComplete, "trackComplete");
4036
4049
  __name2(trackComplete, "trackComplete");
4037
4050
  var DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS = 1e4;
4051
+
4052
+ // ../../node_modules/@rrweb/types/dist/types.js
4053
+ var NodeType2 = /* @__PURE__ */ ((NodeType22) => {
4054
+ NodeType22[NodeType22["Document"] = 0] = "Document";
4055
+ NodeType22[NodeType22["DocumentType"] = 1] = "DocumentType";
4056
+ NodeType22[NodeType22["Element"] = 2] = "Element";
4057
+ NodeType22[NodeType22["Text"] = 3] = "Text";
4058
+ NodeType22[NodeType22["CDATA"] = 4] = "CDATA";
4059
+ NodeType22[NodeType22["Comment"] = 5] = "Comment";
4060
+ return NodeType22;
4061
+ })(NodeType2 || {});
4062
+
4063
+ // src/takeSnapshot.ts
4038
4064
  var rrweb = fs.readFileSync(__require.resolve("@chromaui/rrweb-snapshot"), "utf8");
4039
4065
  var chromaticSnapshots = /* @__PURE__ */ new Map();
4040
4066
  async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
@@ -4053,7 +4079,43 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4053
4079
  page.on("console", (msg) => {
4054
4080
  logger.log(`CONSOLE: "${msg.text()}"`);
4055
4081
  });
4056
- const { domSnapshot, pseudoClassIds } = await page.evaluate(tsDedent.dedent`
4082
+ const { domSnapshot, pseudoClassIds } = await executeSnapshotScript(page);
4083
+ const iframes = page.frames().slice(1);
4084
+ if (iframes.length > 0) {
4085
+ const iframeNodes = findIframes(domSnapshot);
4086
+ const usedIndexes = /* @__PURE__ */ new Set();
4087
+ for (const [index, iframe] of iframes.entries()) {
4088
+ const node = (
4089
+ // Prefer iframe with matching URL
4090
+ filterIframes(iframeNodes, iframe.url(), usedIndexes) || // Fallback to pick the iframe based on order
4091
+ iframeNodes[index]
4092
+ );
4093
+ if (!node) {
4094
+ continue;
4095
+ }
4096
+ usedIndexes.add(iframeNodes.indexOf(node));
4097
+ const iframeSnapshot = await executeSnapshotScript(iframe);
4098
+ node.contentDocument = iframeSnapshot.domSnapshot;
4099
+ node.pseudoClassIds = iframeSnapshot.pseudoClassIds;
4100
+ iframeNodes.push(...findIframes(iframeSnapshot.domSnapshot));
4101
+ }
4102
+ }
4103
+ const bufferedSnapshot = Buffer.from(JSON.stringify(domSnapshot));
4104
+ if (!chromaticSnapshots.has(testId)) {
4105
+ chromaticSnapshots.set(testId, /* @__PURE__ */ new Map());
4106
+ }
4107
+ chromaticSnapshots.get(testId).set(name, {
4108
+ snapshot: bufferedSnapshot,
4109
+ viewport: page.viewportSize() || {
4110
+ width: 1280,
4111
+ height: 720
4112
+ },
4113
+ pseudoClassIds
4114
+ });
4115
+ }
4116
+ __name(takeSnapshot, "takeSnapshot");
4117
+ async function executeSnapshotScript(context) {
4118
+ return await context.evaluate(tsDedent.dedent`
4057
4119
  ${rrweb};
4058
4120
 
4059
4121
  // this code was erroring the page.evaluate() when it was passed as a function to page.evaluate(),
@@ -4128,20 +4190,31 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4128
4190
  });
4129
4191
  }
4130
4192
  `);
4131
- const bufferedSnapshot = Buffer.from(JSON.stringify(domSnapshot));
4132
- if (!chromaticSnapshots.has(testId)) {
4133
- chromaticSnapshots.set(testId, /* @__PURE__ */ new Map());
4193
+ }
4194
+ __name(executeSnapshotScript, "executeSnapshotScript");
4195
+ function findIframes(node) {
4196
+ if (node.type === NodeType2.Element && node.tagName === "iframe") {
4197
+ return [
4198
+ node
4199
+ ];
4134
4200
  }
4135
- chromaticSnapshots.get(testId).set(name, {
4136
- snapshot: bufferedSnapshot,
4137
- viewport: page.viewportSize() || {
4138
- width: 1280,
4139
- height: 720
4140
- },
4141
- pseudoClassIds
4201
+ if ("childNodes" in node) {
4202
+ return node.childNodes.flatMap((childNode) => {
4203
+ return findIframes(childNode);
4204
+ });
4205
+ }
4206
+ return [];
4207
+ }
4208
+ __name(findIframes, "findIframes");
4209
+ function filterIframes(nodes, url, usedIndexes) {
4210
+ return nodes.find((node, index) => {
4211
+ if (usedIndexes.has(index)) {
4212
+ return false;
4213
+ }
4214
+ return node.attributes?.rr_src === url;
4142
4215
  });
4143
4216
  }
4144
- __name(takeSnapshot, "takeSnapshot");
4217
+ __name(filterIframes, "filterIframes");
4145
4218
 
4146
4219
  // src/createResourceArchive.ts
4147
4220
  var idle = /* @__PURE__ */ __name(async (page, networkTimeoutMs = DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS) => {
package/dist/index.mjs CHANGED
@@ -3445,8 +3445,13 @@ var _ResourceArchiver = (_a = class {
3445
3445
  });
3446
3446
  }, "requestPaused"));
3447
3447
  this.client = cdpClient;
3448
- this.assetDomains = (allowedDomains || []).map((domain) => `https://${domain}`);
3449
3448
  this.httpCredentials = httpCredentials;
3449
+ this.assetDomains = (allowedDomains || []).map((domain) => {
3450
+ if (domain.startsWith("http")) {
3451
+ return domain;
3452
+ }
3453
+ return `https://${domain}`;
3454
+ });
3450
3455
  }
3451
3456
  async watch() {
3452
3457
  this.client.on("Fetch.requestPaused", this.requestPaused);
@@ -3680,16 +3685,21 @@ var _ArchiveFile = (_a2 = class {
3680
3685
  }, __name(_a2, "_ArchiveFile"), _a2);
3681
3686
  __name2(_ArchiveFile, "ArchiveFile");
3682
3687
  var ArchiveFile = _ArchiveFile;
3683
- var NodeType = /* @__PURE__ */ ((NodeType2) => {
3684
- NodeType2[NodeType2["Document"] = 0] = "Document";
3685
- NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
3686
- NodeType2[NodeType2["Element"] = 2] = "Element";
3687
- NodeType2[NodeType2["Text"] = 3] = "Text";
3688
- NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
3689
- NodeType2[NodeType2["Comment"] = 5] = "Comment";
3690
- return NodeType2;
3688
+ var NodeType = /* @__PURE__ */ ((NodeType22) => {
3689
+ NodeType22[NodeType22["Document"] = 0] = "Document";
3690
+ NodeType22[NodeType22["DocumentType"] = 1] = "DocumentType";
3691
+ NodeType22[NodeType22["Element"] = 2] = "Element";
3692
+ NodeType22[NodeType22["Text"] = 3] = "Text";
3693
+ NodeType22[NodeType22["CDATA"] = 4] = "CDATA";
3694
+ NodeType22[NodeType22["Comment"] = 5] = "Comment";
3695
+ return NodeType22;
3691
3696
  })(NodeType || {});
3692
3697
  var import_srcset = __toESM(require_srcset());
3698
+ function isIframeSerializedNode(node) {
3699
+ return node.type === NodeType.Element && node.tagName === "iframe" && "contentDocument" in node && !!node.contentDocument;
3700
+ }
3701
+ __name(isIframeSerializedNode, "isIframeSerializedNode");
3702
+ __name2(isIframeSerializedNode, "isIframeSerializedNode");
3693
3703
  var CSS_URL_REGEX = /url\((?!['"]?(?:data):)['"]?([^'")]*)['"]?\)/gi;
3694
3704
  var _a3;
3695
3705
  var _DOMSnapshot = (_a3 = class {
@@ -3719,6 +3729,9 @@ var _DOMSnapshot = (_a3 = class {
3719
3729
  return this.mapNode(childNode, sourceMap);
3720
3730
  }));
3721
3731
  }
3732
+ if (isIframeSerializedNode(node)) {
3733
+ node.contentDocument = await this.mapNode(node.contentDocument, sourceMap);
3734
+ }
3722
3735
  return node;
3723
3736
  }
3724
3737
  mapNodeAttributes(node, sourceMap) {
@@ -4029,6 +4042,19 @@ function trackComplete(properties = {}) {
4029
4042
  __name(trackComplete, "trackComplete");
4030
4043
  __name2(trackComplete, "trackComplete");
4031
4044
  var DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS = 1e4;
4045
+
4046
+ // ../../node_modules/@rrweb/types/dist/types.js
4047
+ var NodeType2 = /* @__PURE__ */ ((NodeType22) => {
4048
+ NodeType22[NodeType22["Document"] = 0] = "Document";
4049
+ NodeType22[NodeType22["DocumentType"] = 1] = "DocumentType";
4050
+ NodeType22[NodeType22["Element"] = 2] = "Element";
4051
+ NodeType22[NodeType22["Text"] = 3] = "Text";
4052
+ NodeType22[NodeType22["CDATA"] = 4] = "CDATA";
4053
+ NodeType22[NodeType22["Comment"] = 5] = "Comment";
4054
+ return NodeType22;
4055
+ })(NodeType2 || {});
4056
+
4057
+ // src/takeSnapshot.ts
4032
4058
  var rrweb = readFileSync(__require.resolve("@chromaui/rrweb-snapshot"), "utf8");
4033
4059
  var chromaticSnapshots = /* @__PURE__ */ new Map();
4034
4060
  async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
@@ -4047,7 +4073,43 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4047
4073
  page.on("console", (msg) => {
4048
4074
  logger.log(`CONSOLE: "${msg.text()}"`);
4049
4075
  });
4050
- const { domSnapshot, pseudoClassIds } = await page.evaluate(dedent`
4076
+ const { domSnapshot, pseudoClassIds } = await executeSnapshotScript(page);
4077
+ const iframes = page.frames().slice(1);
4078
+ if (iframes.length > 0) {
4079
+ const iframeNodes = findIframes(domSnapshot);
4080
+ const usedIndexes = /* @__PURE__ */ new Set();
4081
+ for (const [index, iframe] of iframes.entries()) {
4082
+ const node = (
4083
+ // Prefer iframe with matching URL
4084
+ filterIframes(iframeNodes, iframe.url(), usedIndexes) || // Fallback to pick the iframe based on order
4085
+ iframeNodes[index]
4086
+ );
4087
+ if (!node) {
4088
+ continue;
4089
+ }
4090
+ usedIndexes.add(iframeNodes.indexOf(node));
4091
+ const iframeSnapshot = await executeSnapshotScript(iframe);
4092
+ node.contentDocument = iframeSnapshot.domSnapshot;
4093
+ node.pseudoClassIds = iframeSnapshot.pseudoClassIds;
4094
+ iframeNodes.push(...findIframes(iframeSnapshot.domSnapshot));
4095
+ }
4096
+ }
4097
+ const bufferedSnapshot = Buffer.from(JSON.stringify(domSnapshot));
4098
+ if (!chromaticSnapshots.has(testId)) {
4099
+ chromaticSnapshots.set(testId, /* @__PURE__ */ new Map());
4100
+ }
4101
+ chromaticSnapshots.get(testId).set(name, {
4102
+ snapshot: bufferedSnapshot,
4103
+ viewport: page.viewportSize() || {
4104
+ width: 1280,
4105
+ height: 720
4106
+ },
4107
+ pseudoClassIds
4108
+ });
4109
+ }
4110
+ __name(takeSnapshot, "takeSnapshot");
4111
+ async function executeSnapshotScript(context) {
4112
+ return await context.evaluate(dedent`
4051
4113
  ${rrweb};
4052
4114
 
4053
4115
  // this code was erroring the page.evaluate() when it was passed as a function to page.evaluate(),
@@ -4122,20 +4184,31 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4122
4184
  });
4123
4185
  }
4124
4186
  `);
4125
- const bufferedSnapshot = Buffer.from(JSON.stringify(domSnapshot));
4126
- if (!chromaticSnapshots.has(testId)) {
4127
- chromaticSnapshots.set(testId, /* @__PURE__ */ new Map());
4187
+ }
4188
+ __name(executeSnapshotScript, "executeSnapshotScript");
4189
+ function findIframes(node) {
4190
+ if (node.type === NodeType2.Element && node.tagName === "iframe") {
4191
+ return [
4192
+ node
4193
+ ];
4128
4194
  }
4129
- chromaticSnapshots.get(testId).set(name, {
4130
- snapshot: bufferedSnapshot,
4131
- viewport: page.viewportSize() || {
4132
- width: 1280,
4133
- height: 720
4134
- },
4135
- pseudoClassIds
4195
+ if ("childNodes" in node) {
4196
+ return node.childNodes.flatMap((childNode) => {
4197
+ return findIframes(childNode);
4198
+ });
4199
+ }
4200
+ return [];
4201
+ }
4202
+ __name(findIframes, "findIframes");
4203
+ function filterIframes(nodes, url, usedIndexes) {
4204
+ return nodes.find((node, index) => {
4205
+ if (usedIndexes.has(index)) {
4206
+ return false;
4207
+ }
4208
+ return node.attributes?.rr_src === url;
4136
4209
  });
4137
4210
  }
4138
- __name(takeSnapshot, "takeSnapshot");
4211
+ __name(filterIframes, "filterIframes");
4139
4212
 
4140
4213
  // src/createResourceArchive.ts
4141
4214
  var idle = /* @__PURE__ */ __name(async (page, networkTimeoutMs = DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS) => {
@@ -4,15 +4,45 @@ var __defProp = Object.defineProperty;
4
4
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
5
 
6
6
  // ../../node_modules/@rrweb/types/dist/types.js
7
- var NodeType = /* @__PURE__ */ ((NodeType2) => {
8
- NodeType2[NodeType2["Document"] = 0] = "Document";
9
- NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
10
- NodeType2[NodeType2["Element"] = 2] = "Element";
11
- NodeType2[NodeType2["Text"] = 3] = "Text";
12
- NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
13
- NodeType2[NodeType2["Comment"] = 5] = "Comment";
14
- return NodeType2;
7
+ var NodeType = /* @__PURE__ */ ((NodeType22) => {
8
+ NodeType22[NodeType22["Document"] = 0] = "Document";
9
+ NodeType22[NodeType22["DocumentType"] = 1] = "DocumentType";
10
+ NodeType22[NodeType22["Element"] = 2] = "Element";
11
+ NodeType22[NodeType22["Text"] = 3] = "Text";
12
+ NodeType22[NodeType22["CDATA"] = 4] = "CDATA";
13
+ NodeType22[NodeType22["Comment"] = 5] = "Comment";
14
+ return NodeType22;
15
15
  })(NodeType || {});
16
+
17
+ // ../shared/dist/utils/nodes.mjs
18
+ var __defProp2 = Object.defineProperty;
19
+ var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", { value, configurable: true }), "__name");
20
+ var NodeType2 = /* @__PURE__ */ ((NodeType22) => {
21
+ NodeType22[NodeType22["Document"] = 0] = "Document";
22
+ NodeType22[NodeType22["DocumentType"] = 1] = "DocumentType";
23
+ NodeType22[NodeType22["Element"] = 2] = "Element";
24
+ NodeType22[NodeType22["Text"] = 3] = "Text";
25
+ NodeType22[NodeType22["CDATA"] = 4] = "CDATA";
26
+ NodeType22[NodeType22["Comment"] = 5] = "Comment";
27
+ return NodeType22;
28
+ })(NodeType2 || {});
29
+ function isIframeSerializedNode(node) {
30
+ return node.type === NodeType2.Element && node.tagName === "iframe" && "contentDocument" in node && !!node.contentDocument;
31
+ }
32
+ __name(isIframeSerializedNode, "isIframeSerializedNode");
33
+ __name2(isIframeSerializedNode, "isIframeSerializedNode");
34
+ function isElement(node) {
35
+ return node?.nodeType === Node.ELEMENT_NODE;
36
+ }
37
+ __name(isElement, "isElement");
38
+ __name2(isElement, "isElement");
39
+ function isIframeElement(node) {
40
+ return isElement(node) && node.tagName.toLowerCase() === "iframe";
41
+ }
42
+ __name(isIframeElement, "isIframeElement");
43
+ __name2(isIframeElement, "isIframeElement");
44
+
45
+ // ../shared/storybook-config/preview.ts
16
46
  var pageUrl = new URL(window.location.href);
17
47
  pageUrl.pathname = "";
18
48
  pageUrl.search = "";
@@ -28,6 +58,20 @@ var findHtmlNode = /* @__PURE__ */ __name((node) => {
28
58
  }
29
59
  return void 0;
30
60
  }, "findHtmlNode");
61
+ var findNodeById = /* @__PURE__ */ __name((node, id) => {
62
+ if (node.id === id) {
63
+ return node;
64
+ }
65
+ if ("childNodes" in node) {
66
+ for (const childNode of node.childNodes) {
67
+ const match = findNodeById(childNode, id);
68
+ if (match) {
69
+ return match;
70
+ }
71
+ }
72
+ }
73
+ return void 0;
74
+ }, "findNodeById");
31
75
  function snapshotFileName(snapshotId, viewport) {
32
76
  const fileNameParts = [
33
77
  snapshotId,
@@ -61,12 +105,13 @@ var renderToCanvas = /* @__PURE__ */ __name(async (context) => {
61
105
  const html = rebuild(htmlNode, {
62
106
  doc: document,
63
107
  mirror,
64
- cache: createCache()
108
+ cache: createCache(),
109
+ afterAppend: afterAppendIframes(snapshot)
65
110
  });
66
111
  for (const [className, ids] of Object.entries(pseudoClassIds)) {
67
112
  for (const id of ids) {
68
113
  const el = mirror.getNode(id);
69
- if (el?.classList) {
114
+ if (isElement(el)) {
70
115
  el.classList.add(className);
71
116
  }
72
117
  }
@@ -77,6 +122,36 @@ var renderToCanvas = /* @__PURE__ */ __name(async (context) => {
77
122
  return () => {
78
123
  };
79
124
  }, "renderToCanvas");
125
+ function afterAppendIframes(snapshot) {
126
+ return /* @__PURE__ */ __name(function afterAppend(node, id) {
127
+ if (!isIframeElement(node)) {
128
+ return;
129
+ }
130
+ const serializedNode = findNodeById(snapshot, id);
131
+ if (!isIframeSerializedNode(serializedNode)) {
132
+ return;
133
+ }
134
+ node.onload = () => {
135
+ const mirror = createMirror();
136
+ rebuild(serializedNode.contentDocument, {
137
+ doc: node.contentDocument,
138
+ mirror,
139
+ cache: createCache(),
140
+ // Recursively build iframes within iframes
141
+ afterAppend: afterAppendIframes(serializedNode.contentDocument)
142
+ });
143
+ for (const [className, ids] of Object.entries(serializedNode.pseudoClassIds)) {
144
+ for (const id2 of ids) {
145
+ const el = mirror.getNode(id2);
146
+ if (isElement(el)) {
147
+ el.classList.add(className);
148
+ }
149
+ }
150
+ }
151
+ };
152
+ }, "afterAppend");
153
+ }
154
+ __name(afterAppendIframes, "afterAppendIframes");
80
155
  var preview_default = {
81
156
  renderToCanvas,
82
157
  parameters: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chromatic-com/playwright",
3
- "version": "0.13.4",
3
+ "version": "0.14.0-3e73276-20260512102356",
4
4
  "description": "Chromatic Visual Regression Testing for Playwright",
5
5
  "repository": {
6
6
  "type": "git",