@chromatic-com/playwright 0.13.2 → 0.13.3-8256a68-20260428060550

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
@@ -2,6 +2,12 @@ import * as playwright_test from 'playwright/test';
2
2
  import { Page, TestInfo } from '@playwright/test';
3
3
  export { expect } from '@playwright/test';
4
4
 
5
+ declare global {
6
+ interface Window {
7
+ FontFace: typeof FontFace;
8
+ }
9
+ }
10
+
5
11
  interface ChromaticConfig {
6
12
  delay?: number;
7
13
  diffIncludeAntiAliasing?: boolean;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,12 @@ import * as playwright_test from 'playwright/test';
2
2
  import { Page, TestInfo } from '@playwright/test';
3
3
  export { expect } from '@playwright/test';
4
4
 
5
+ declare global {
6
+ interface Window {
7
+ FontFace: typeof FontFace;
8
+ }
9
+ }
10
+
5
11
  interface ChromaticConfig {
6
12
  delay?: number;
7
13
  diffIncludeAntiAliasing?: boolean;
package/dist/index.js CHANGED
@@ -3699,18 +3699,23 @@ var import_srcset = __toESM(require_srcset());
3699
3699
  var CSS_URL_REGEX = /url\((?!['"]?(?:data):)['"]?([^'")]*)['"]?\)/gi;
3700
3700
  var _a3;
3701
3701
  var _DOMSnapshot = (_a3 = class {
3702
- constructor(snapshot) {
3702
+ constructor({ snapshot, pseudoClassIds }) {
3703
3703
  __publicField(this, "snapshot");
3704
+ __publicField(this, "pseudoClassIds");
3704
3705
  if (Buffer.isBuffer(snapshot)) {
3705
3706
  const bufferAsString = snapshot.toString("utf-8");
3706
3707
  this.snapshot = JSON.parse(bufferAsString);
3707
3708
  } else {
3708
3709
  this.snapshot = JSON.parse(snapshot);
3709
3710
  }
3711
+ this.pseudoClassIds = pseudoClassIds;
3710
3712
  }
3711
3713
  async mapAssetPaths(sourceMap) {
3712
- const transformedSnapshot = await this.mapNode(this.snapshot, sourceMap);
3713
- return JSON.stringify(transformedSnapshot);
3714
+ const savedSnapshot = {
3715
+ snapshot: await this.mapNode(this.snapshot, sourceMap),
3716
+ pseudoClassIds: this.pseudoClassIds
3717
+ };
3718
+ return JSON.stringify(savedSnapshot);
3714
3719
  }
3715
3720
  async mapNode(node, sourceMap) {
3716
3721
  node = this.mapNodeAttributes(node, sourceMap);
@@ -3961,10 +3966,10 @@ async function writeTestResult(e2eTestInfo, domSnapshots, archive, chromaticStor
3961
3966
  }
3962
3967
  await outputFile(path2.join(archiveDir, fileSystemPath), response.body);
3963
3968
  }));
3964
- await Promise.all(Object.entries(domSnapshots).map(async ([name, { snapshot: domSnapshot, viewport }]) => {
3969
+ await Promise.all(Object.entries(domSnapshots).map(async ([name, domSnapshot]) => {
3965
3970
  const snapshot = new DOMSnapshot(domSnapshot);
3966
3971
  const mappedSnapshot = await snapshot.mapAssetPaths(sourceMap);
3967
- const snapshotFile = snapshotFileName(snapshotId(title, name), viewport);
3972
+ const snapshotFile = snapshotFileName(snapshotId(title, name), domSnapshot.viewport);
3968
3973
  await outputFile(path2.join(archiveDir, snapshotFile), mappedSnapshot);
3969
3974
  }));
3970
3975
  const storiesFile = storiesFileName(title);
@@ -4030,14 +4035,24 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4030
4035
  page.on("console", (msg) => {
4031
4036
  logger.log(`CONSOLE: "${msg.text()}"`);
4032
4037
  });
4033
- const domSnapshot = await page.evaluate(tsDedent.dedent`
4038
+ const { domSnapshot, pseudoClassIds } = await page.evaluate(tsDedent.dedent`
4034
4039
  ${rrweb};
4035
4040
 
4036
4041
  // this code was erroring the page.evaluate() when it was passed as a function to page.evaluate(),
4037
4042
  // so for now it is being passed as a string until that can be resolved.
4038
4043
  const doPostProcessing = (rrwebSnapshotInstance, documentToSnapshot) => {
4039
4044
  return new Promise((resolve) => {
4040
- const domSnapshot = rrwebSnapshotInstance.snapshot(documentToSnapshot, { recordCanvas: true });
4045
+ const mirror = rrwebSnapshotInstance.createMirror();
4046
+ const domSnapshot = rrwebSnapshotInstance.snapshot(documentToSnapshot, { recordCanvas: true, mirror });
4047
+
4048
+ const pseudoClassIds = {};
4049
+
4050
+ for (const className of [':hover', ':focus', ':focus-visible', ':active']) {
4051
+ const elements = documentToSnapshot.querySelectorAll(className);
4052
+ const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
4053
+ pseudoClassIds[className] = ids;
4054
+ }
4055
+
4041
4056
  // do some post-processing on the snapshot
4042
4057
  const toDataURL = async (url) => {
4043
4058
  // read contents of the blob URL
@@ -4069,7 +4084,7 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4069
4084
  };
4070
4085
 
4071
4086
  replaceBlobUrls(domSnapshot).then(() => {
4072
- resolve(domSnapshot);
4087
+ resolve({ domSnapshot, pseudoClassIds });
4073
4088
  });
4074
4089
  });
4075
4090
  };
@@ -4104,7 +4119,8 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4104
4119
  viewport: page.viewportSize() || {
4105
4120
  width: 1280,
4106
4121
  height: 720
4107
- }
4122
+ },
4123
+ pseudoClassIds
4108
4124
  });
4109
4125
  }
4110
4126
  __name(takeSnapshot, "takeSnapshot");
package/dist/index.mjs CHANGED
@@ -3693,18 +3693,23 @@ var import_srcset = __toESM(require_srcset());
3693
3693
  var CSS_URL_REGEX = /url\((?!['"]?(?:data):)['"]?([^'")]*)['"]?\)/gi;
3694
3694
  var _a3;
3695
3695
  var _DOMSnapshot = (_a3 = class {
3696
- constructor(snapshot) {
3696
+ constructor({ snapshot, pseudoClassIds }) {
3697
3697
  __publicField(this, "snapshot");
3698
+ __publicField(this, "pseudoClassIds");
3698
3699
  if (Buffer.isBuffer(snapshot)) {
3699
3700
  const bufferAsString = snapshot.toString("utf-8");
3700
3701
  this.snapshot = JSON.parse(bufferAsString);
3701
3702
  } else {
3702
3703
  this.snapshot = JSON.parse(snapshot);
3703
3704
  }
3705
+ this.pseudoClassIds = pseudoClassIds;
3704
3706
  }
3705
3707
  async mapAssetPaths(sourceMap) {
3706
- const transformedSnapshot = await this.mapNode(this.snapshot, sourceMap);
3707
- return JSON.stringify(transformedSnapshot);
3708
+ const savedSnapshot = {
3709
+ snapshot: await this.mapNode(this.snapshot, sourceMap),
3710
+ pseudoClassIds: this.pseudoClassIds
3711
+ };
3712
+ return JSON.stringify(savedSnapshot);
3708
3713
  }
3709
3714
  async mapNode(node, sourceMap) {
3710
3715
  node = this.mapNodeAttributes(node, sourceMap);
@@ -3955,10 +3960,10 @@ async function writeTestResult(e2eTestInfo, domSnapshots, archive, chromaticStor
3955
3960
  }
3956
3961
  await outputFile(join(archiveDir, fileSystemPath), response.body);
3957
3962
  }));
3958
- await Promise.all(Object.entries(domSnapshots).map(async ([name, { snapshot: domSnapshot, viewport }]) => {
3963
+ await Promise.all(Object.entries(domSnapshots).map(async ([name, domSnapshot]) => {
3959
3964
  const snapshot = new DOMSnapshot(domSnapshot);
3960
3965
  const mappedSnapshot = await snapshot.mapAssetPaths(sourceMap);
3961
- const snapshotFile = snapshotFileName(snapshotId(title, name), viewport);
3966
+ const snapshotFile = snapshotFileName(snapshotId(title, name), domSnapshot.viewport);
3962
3967
  await outputFile(join(archiveDir, snapshotFile), mappedSnapshot);
3963
3968
  }));
3964
3969
  const storiesFile = storiesFileName(title);
@@ -4024,14 +4029,24 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4024
4029
  page.on("console", (msg) => {
4025
4030
  logger.log(`CONSOLE: "${msg.text()}"`);
4026
4031
  });
4027
- const domSnapshot = await page.evaluate(dedent`
4032
+ const { domSnapshot, pseudoClassIds } = await page.evaluate(dedent`
4028
4033
  ${rrweb};
4029
4034
 
4030
4035
  // this code was erroring the page.evaluate() when it was passed as a function to page.evaluate(),
4031
4036
  // so for now it is being passed as a string until that can be resolved.
4032
4037
  const doPostProcessing = (rrwebSnapshotInstance, documentToSnapshot) => {
4033
4038
  return new Promise((resolve) => {
4034
- const domSnapshot = rrwebSnapshotInstance.snapshot(documentToSnapshot, { recordCanvas: true });
4039
+ const mirror = rrwebSnapshotInstance.createMirror();
4040
+ const domSnapshot = rrwebSnapshotInstance.snapshot(documentToSnapshot, { recordCanvas: true, mirror });
4041
+
4042
+ const pseudoClassIds = {};
4043
+
4044
+ for (const className of [':hover', ':focus', ':focus-visible', ':active']) {
4045
+ const elements = documentToSnapshot.querySelectorAll(className);
4046
+ const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
4047
+ pseudoClassIds[className] = ids;
4048
+ }
4049
+
4035
4050
  // do some post-processing on the snapshot
4036
4051
  const toDataURL = async (url) => {
4037
4052
  // read contents of the blob URL
@@ -4063,7 +4078,7 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4063
4078
  };
4064
4079
 
4065
4080
  replaceBlobUrls(domSnapshot).then(() => {
4066
- resolve(domSnapshot);
4081
+ resolve({ domSnapshot, pseudoClassIds });
4067
4082
  });
4068
4083
  });
4069
4084
  };
@@ -4098,7 +4113,8 @@ async function takeSnapshot(page, nameOrTestInfo, maybeTestInfo) {
4098
4113
  viewport: page.viewportSize() || {
4099
4114
  width: 1280,
4100
4115
  height: 720
4101
- }
4116
+ },
4117
+ pseudoClassIds
4102
4118
  });
4103
4119
  }
4104
4120
  __name(takeSnapshot, "takeSnapshot");
@@ -1,4 +1,4 @@
1
- import { rebuild } from '@chromaui/rrweb-snapshot';
1
+ import { createMirror, rebuild, createCache } from '@chromaui/rrweb-snapshot';
2
2
 
3
3
  var __defProp = Object.defineProperty;
4
4
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -55,11 +55,22 @@ async function fetchSnapshot(context) {
55
55
  }
56
56
  __name(fetchSnapshot, "fetchSnapshot");
57
57
  var renderToCanvas = /* @__PURE__ */ __name(async (context) => {
58
- const snapshot = await fetchSnapshot(context);
58
+ const { snapshot, pseudoClassIds } = await fetchSnapshot(context);
59
59
  const htmlNode = findHtmlNode(snapshot);
60
- const html = await rebuild(htmlNode, {
61
- doc: document
60
+ const mirror = createMirror();
61
+ const html = rebuild(htmlNode, {
62
+ doc: document,
63
+ mirror,
64
+ cache: createCache()
62
65
  });
66
+ for (const [className, ids] of Object.entries(pseudoClassIds)) {
67
+ for (const id of ids) {
68
+ const el = mirror.getNode(id);
69
+ if (el?.classList) {
70
+ el.classList.add(className);
71
+ }
72
+ }
73
+ }
63
74
  document.replaceChild(html, document.children[0]);
64
75
  document.head.innerHTML += '<script id="storybook-root"><\/script><script id="storybook-docs"><\/script>';
65
76
  context.showMain();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chromatic-com/playwright",
3
- "version": "0.13.2",
3
+ "version": "0.13.3-8256a68-20260428060550",
4
4
  "description": "Chromatic Visual Regression Testing for Playwright",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,7 +46,7 @@
46
46
  "test:unit": "yarn workspace @chromaui/chromatic-e2e test:unit --project Playwright"
47
47
  },
48
48
  "dependencies": {
49
- "@chromaui/rrweb-snapshot": "2.0.0-alpha.18-noAbsolute",
49
+ "@chromaui/rrweb-snapshot": "2.0.0-alpha.19-noAbsolute",
50
50
  "@segment/analytics-node": "2.1.3",
51
51
  "storybook": "10.2.13",
52
52
  "ts-dedent": "^2.2.0"