Skip to content

Commit 0e6bd7c

Browse files
authored
fix: added react and react-dom to peer deps (#35)
* fix: added react and react-dom to peer deps * fix: moved component-tests related code to storybook folder * fix: renamed storybook folder to component-tests * fix: Fixed some linter errors
1 parent 46945f2 commit 0e6bd7c

File tree

18 files changed

+198
-100
lines changed

18 files changed

+198
-100
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { matchScreenshot } from 'playwright-tools/actions';
1414

1515
- [actions](./actions/README.md) — Browser actions.
1616
- [auth/storage](./auth/storage/README.md) — Authentication functions for saving and restoring browser storage snapshots.
17+
- [component-tests](./component-tests/README.md) — Utilities and fixtures for Playwright Component Testing.
1718
- [fixtures](./fixtures/README.md) — Fixtures for passing values into tests.
1819
- [har](./har/README.md) — Functions for working with HAR request dumps.
1920
- [config](./config/README.md) — Base configuration.

actions/expect-request/matchers/compare/DiffPrinter.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,40 @@ export class DiffPrinter {
4646
(acc, logItem) => {
4747
const { context, type } = logItem;
4848
const path = this.makePathFromContext(context);
49+
const existingAnnotations = acc[path] ?? [];
4950

50-
if (!acc[path]) {
51-
acc[path] = [];
52-
}
51+
let newAnnotation: PathAnnotation | undefined;
5352

5453
if (type === DiffType.ValueMismatch) {
5554
if (logItem.expected === undefined && logItem.received !== undefined) {
56-
acc[path].push({ type: PathAnnotationType.ObjectExtraProperty });
55+
newAnnotation = { type: PathAnnotationType.ObjectExtraProperty };
5756
} else {
58-
acc[path].push({
57+
newAnnotation = {
5958
type: PathAnnotationType.ValueMismatch,
6059
expected: logItem.expected,
6160
received: logItem.received,
62-
});
61+
};
6362
}
6463
} else if (type === DiffType.ObjectMissingProperty) {
65-
acc[path].push({
64+
newAnnotation = {
6665
type: PathAnnotationType.ObjectMissingProperty,
6766
expected: logItem.expected,
68-
});
67+
};
6968
} else if (type === DiffType.ArrayMissingValue) {
70-
acc[path].push({
69+
newAnnotation = {
7170
type: PathAnnotationType.ArrayMissingValue,
7271
expected: logItem.expected,
73-
});
72+
};
73+
}
74+
75+
if (!newAnnotation) {
76+
return acc;
7477
}
7578

76-
return acc;
79+
return {
80+
...acc,
81+
[path]: [...existingAnnotations, newAnnotation],
82+
};
7783
},
7884
{},
7985
);

component-tests/README.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Component Testing Utilities
2+
3+
This module provides utilities and fixtures for Playwright Component Testing.
4+
5+
## Utils
6+
7+
### createSmokeScenarios
8+
9+
A utility for generating test scenarios from component props variations. It creates a set of test cases based on a base props object and variations for each prop.
10+
11+
```ts
12+
import { createSmokeScenarios } from 'playwright-tools/component-tests';
13+
14+
const scenarios = createSmokeScenarios(
15+
// Base props
16+
{
17+
theme: 'light',
18+
size: 'medium',
19+
disabled: false,
20+
},
21+
// Prop variations
22+
{
23+
theme: ['dark'],
24+
size: ['small', 'large'],
25+
disabled: [true],
26+
},
27+
);
28+
29+
// Returns array of [scenarioName, props] tuples:
30+
// [
31+
// ['[default]', { theme: 'light', size: 'medium', disabled: false }],
32+
// ['[theme: dark]', { theme: 'dark', size: 'medium', disabled: false }],
33+
// ['[size: small]', { theme: 'light', size: 'small', disabled: false }],
34+
// ['[size: large]', { theme: 'light', size: 'large', disabled: false }],
35+
// ['[disabled: true]', { theme: 'light', size: 'medium', disabled: true }],
36+
// ]
37+
```
38+
39+
#### Named Cases
40+
41+
For complex values or custom names, use named cases:
42+
43+
```ts
44+
const scenarios = createSmokeScenarios(
45+
{ config: { mode: 'default' } },
46+
{
47+
config: [
48+
['advanced-mode', { mode: 'advanced', features: ['a', 'b'] }],
49+
['minimal-mode', { mode: 'minimal' }],
50+
],
51+
},
52+
);
53+
```
54+
55+
#### Custom Scenario Name Prefix
56+
57+
```ts
58+
const scenarios = createSmokeScenarios(
59+
{ theme: 'light' },
60+
{ theme: ['dark'] },
61+
{ scenarioName: 'Button' },
62+
);
63+
64+
// Returns:
65+
// [
66+
// [' Button [default]', { theme: 'light' }],
67+
// [' Button [theme: dark]', { theme: 'dark' }],
68+
// ]
69+
```
70+
71+
## Fixtures
72+
73+
### mount
74+
75+
Enhanced mount fixture for Playwright Component Testing that wraps React components with a styled container for better test consistency and visual testing.
76+
77+
Extend `test` in Playwright:
78+
79+
```ts
80+
import { mountFixture, type MountFn, TEST_WRAPPER_CLASS } from 'playwright-tools/component-tests';
81+
82+
export type TestExtraFixtures = {
83+
mount: MountFn;
84+
};
85+
86+
export const test = baseTest.extend<TestExtraFixtures, WorkerExtraFixtures>({
87+
mount: mountFixture,
88+
});
89+
```
90+
91+
Usage in test:
92+
93+
```ts
94+
import { MyButton } from './MyButton';
95+
96+
test('renders button correctly', async ({ mount }) => {
97+
const component = await mount(
98+
<MyButton label="Click me" />,
99+
{
100+
width: 300,
101+
rootStyle: {
102+
backgroundColor: '#f0f0f0',
103+
},
104+
}
105+
);
106+
107+
await expect(component).toBeVisible();
108+
});
109+
```
110+
111+
#### Features
112+
113+
The mount fixture enhances the base Playwright mount function with:
114+
115+
1. **Wrapper Container**: Wraps components in a styled div with 20px padding for better screenshots
116+
2. **Flexible Sizing**: Uses `fit-content` by default, or accepts custom width
117+
3. **Button Stability**: Prevents button scale animations during clicks to ensure consistent positioning
118+
4. **Identifiable Class**: Adds `TEST_WRAPPER_CLASS` (`playwright-wrapper-test`) to the wrapper for easy targeting
119+
120+
#### Mount Options
121+
122+
Extends standard Playwright mount options with:
123+
124+
```ts
125+
type MountFn = <HooksConfig>(
126+
component: React.JSX.Element,
127+
options?: MountOptions<HooksConfig> & {
128+
/**
129+
* Width of the wrapper container
130+
* When set, uses content-box sizing so padding doesn't affect the specified width
131+
* @example 300 or '300px'
132+
*/
133+
width?: number | string;
134+
135+
/**
136+
* Additional CSS styles to apply to the wrapper container
137+
* Merged with default styles (padding: 20, width: 'fit-content', height: 'fit-content')
138+
*/
139+
rootStyle?: React.CSSProperties;
140+
},
141+
) => Promise<MountResult>;
142+
```
143+
144+
#### Exported Constants
145+
146+
- `TEST_WRAPPER_CLASS` - The CSS class name applied to the wrapper div (`'playwright-wrapper-test'`)
147+

component-tests/fixtures/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export type { MountFn, MountTestArgs } from './mount';
2+
export { mountFixture, TEST_WRAPPER_CLASS } from './mount';
File renamed without changes.
File renamed without changes.

component-tests/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Utils
2+
export type { Cases, CasesWithName, Scenario, ScenarioName } from './utils';
3+
export { createSmokeScenarios } from './utils';
4+
5+
// Fixtures
6+
export type { MountFn, MountTestArgs } from './fixtures';
7+
export { mountFixture, TEST_WRAPPER_CLASS } from './fixtures';

storybook/__tests__/create-smoke-scenarios.test.ts renamed to component-tests/utils/create-smoke-scenarios/__tests__/create-smoke-scenarios.test.ts

File renamed without changes.

0 commit comments

Comments
 (0)