@gravity-ui/playwright-tools 1.1.2 → 1.1.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.
@@ -1,3 +1,16 @@
1
1
  import type { PlaywrightTestArgs, PlaywrightTestOptions, TestFixture } from '@playwright/test';
2
2
  import type { MountFn, MountTestArgs } from './types';
3
+ /**
4
+ * Enhanced mount fixture that wraps components with styling and layout controls.
5
+ *
6
+ * This fixture intercepts the base mount function to:
7
+ * 1. Always wrap components in a div with TEST_WRAPPER_CLASS for screenshot targeting
8
+ * 2. Apply padding and fit-content sizing for better visual testing
9
+ * 3. Disable CSS transform animations that can cause flaky screenshots
10
+ * 4. Support custom width and rootStyle options
11
+ *
12
+ * The wrapper is inlined using string element types ('div', 'style') because
13
+ * Playwright blocks function components defined in test context. See mount-wrapper.ts
14
+ * for more details on this restriction.
15
+ */
3
16
  export declare const mountFixture: TestFixture<MountFn, PlaywrightTestArgs & PlaywrightTestOptions & MountTestArgs>;
@@ -1,18 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.mountFixture = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const constants_1 = require("./constants");
4
+ const mount_wrapper_1 = require("./mount-wrapper");
5
+ /**
6
+ * Enhanced mount fixture that wraps components with styling and layout controls.
7
+ *
8
+ * This fixture intercepts the base mount function to:
9
+ * 1. Always wrap components in a div with TEST_WRAPPER_CLASS for screenshot targeting
10
+ * 2. Apply padding and fit-content sizing for better visual testing
11
+ * 3. Disable CSS transform animations that can cause flaky screenshots
12
+ * 4. Support custom width and rootStyle options
13
+ *
14
+ * The wrapper is inlined using string element types ('div', 'style') because
15
+ * Playwright blocks function components defined in test context. See mount-wrapper.ts
16
+ * for more details on this restriction.
17
+ */
6
18
  const mountFixture = async ({ mount: baseMount }, use) => {
7
19
  const mount = async (component, options) => {
8
- return await baseMount((0, jsx_runtime_1.jsxs)("div", { style: {
9
- padding: 20,
10
- // When we set width we didn't expect that paddings for better screenshots would be included
11
- boxSizing: options?.width ? 'content-box' : undefined,
12
- width: options?.width ? options.width : 'fit-content',
13
- height: 'fit-content',
14
- ...options?.rootStyle,
15
- }, className: constants_1.TEST_WRAPPER_CLASS, children: [(0, jsx_runtime_1.jsx)("style", { children: '.g-button, .g-button::after { transform: scale(1) !important; }' }), component] }), options);
20
+ const { width, rootStyle, ...baseMountOptions } = options || {};
21
+ const wrapper = (0, mount_wrapper_1.createComponentWrapper)(component, { width, rootStyle });
22
+ return await baseMount(wrapper, baseMountOptions);
16
23
  };
17
24
  await use(mount);
18
25
  };
@@ -0,0 +1,29 @@
1
+ import type * as React from 'react';
2
+ /**
3
+ * Playwright JSX object structure that mimics Playwright's jsx-runtime output.
4
+ * This is the internal structure Playwright expects when mounting components.
5
+ */
6
+ type PlaywrightJsxObject<T extends keyof React.JSX.IntrinsicElements> = {
7
+ __pw_type: 'jsx';
8
+ type: T;
9
+ props: React.JSX.IntrinsicElements[T];
10
+ key: string | null;
11
+ };
12
+ /**
13
+ * Creates a wrapper around a component with styling and animation controls.
14
+ *
15
+ * This wrapper:
16
+ * 1. Wraps component in a div with TEST_WRAPPER_CLASS for screenshot targeting
17
+ * 2. Applies padding and fit-content sizing for better visual testing
18
+ * 3. Injects global styles to disable CSS transform animations
19
+ * 4. Supports custom width and rootStyle options
20
+ *
21
+ * The wrapper uses only string element types ('div', 'style') because
22
+ * Playwright blocks function components defined in test context.
23
+ * See createPlaywrightJsxObject documentation for details.
24
+ */
25
+ export declare function createComponentWrapper(component: React.JSX.Element, options?: {
26
+ width?: number | string;
27
+ rootStyle?: React.CSSProperties;
28
+ }): PlaywrightJsxObject<"div">;
29
+ export {};
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createComponentWrapper = createComponentWrapper;
4
+ const constants_1 = require("./constants");
5
+ /**
6
+ * Creates a Playwright JSX object representation.
7
+ *
8
+ * Playwright expects JSX components in a special format with __pw_type: 'jsx'.
9
+ * This mimics what Playwright's jsx-runtime creates when you write JSX in test files.
10
+ *
11
+ * IMPORTANT: The `type` parameter MUST be either:
12
+ * - A string (HTML element name like 'div', 'span', 'style')
13
+ * - An import reference resolved by Playwright's import registry
14
+ *
15
+ * Function references are explicitly blocked by Playwright's serializers.js:
16
+ * "if (value?.__pw_type === 'jsx' && typeof value.type === 'function')"
17
+ * This prevents components defined in test context from being mounted.
18
+ *
19
+ * That's why we use only string types (like 'div', 'style')
20
+ * instead of function component references.
21
+ *
22
+ * @template T - The HTML element type (e.g., 'div', 'span', 'style')
23
+ * @param type - HTML element name
24
+ * @param props - Props for the HTML element
25
+ * @returns A Playwright JSX object compatible with React.JSX.Element
26
+ */
27
+ function createPlaywrightJsxObject(type, props) {
28
+ return {
29
+ __pw_type: 'jsx',
30
+ type,
31
+ props,
32
+ key: null, // Must be null (not undefined) to match React.JSX.Element type
33
+ };
34
+ }
35
+ /**
36
+ * Creates a wrapper around a component with styling and animation controls.
37
+ *
38
+ * This wrapper:
39
+ * 1. Wraps component in a div with TEST_WRAPPER_CLASS for screenshot targeting
40
+ * 2. Applies padding and fit-content sizing for better visual testing
41
+ * 3. Injects global styles to disable CSS transform animations
42
+ * 4. Supports custom width and rootStyle options
43
+ *
44
+ * The wrapper uses only string element types ('div', 'style') because
45
+ * Playwright blocks function components defined in test context.
46
+ * See createPlaywrightJsxObject documentation for details.
47
+ */
48
+ function createComponentWrapper(component, options) {
49
+ const { width, rootStyle } = options || {};
50
+ const styleElement = createPlaywrightJsxObject('style', {
51
+ children: '.g-button, .g-button::after { transform: scale(1) !important; }',
52
+ });
53
+ const wrapper = createPlaywrightJsxObject('div', {
54
+ style: {
55
+ padding: 20,
56
+ // When width is set, padding should not affect total width
57
+ boxSizing: width ? 'content-box' : undefined,
58
+ width: width ? width : 'fit-content',
59
+ height: 'fit-content',
60
+ ...rootStyle,
61
+ },
62
+ className: constants_1.TEST_WRAPPER_CLASS,
63
+ children: [styleElement, component],
64
+ });
65
+ return wrapper;
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/playwright-tools",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Tools for Playwright Test",
5
5
  "keywords": [
6
6
  "playwright",
@@ -100,9 +100,7 @@
100
100
  },
101
101
  "peerDependencies": {
102
102
  "@playwright/experimental-ct-react": "^1.22",
103
- "@playwright/test": "^1.22",
104
- "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
105
- "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
103
+ "@playwright/test": "^1.22"
106
104
  },
107
105
  "engines": {
108
106
  "node": ">=20"