Skip to content

Commit

Permalink
Merge branch 'main' into get-body-class-names
Browse files Browse the repository at this point in the history
  • Loading branch information
Raubzeug authored Dec 25, 2023
2 parents 85809a5 + 533ded1 commit c2b16c9
Show file tree
Hide file tree
Showing 69 changed files with 203 additions and 81 deletions.
80 changes: 59 additions & 21 deletions playwright/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,72 @@
2. Inside the component folder, create the `__tests__` folder and create a file inside it with the following name `<ComponentName>.visual.test.tsx`
3. Writing a test:

Capture a screenshot, by default in light theme only:

```ts
import React from 'react';

import {expect} from '@playwright/experimental-ct-react';

import {MyTestedComponent} from '../MyTestedComponent';
import {MyComponent} from '../MyComponent';

import {test} from '~playwright/core';

test('Name test', async ({mount}) => {
//mounting a component
const component = await mount(<MyTestedComponent props={props} />);
test('test description', async ({mount}) => {
// mount the component
const component = await mount(<MyComponent props={props} />);

//screenshot
// capture the screenshot
await expect(component).toHaveScreenshot();
});
```

Group of tests.
You can also capture screenshots both in dark and light themes:

```ts
import React from 'react';

import {MyComponent} from '../MyComponent';

import {test} from '~playwright/core';

test('test description', async ({mount, expectScreenshot}) => {
// mount the component
await mount(<MyComponent props={props} />);

// capture the screenshot
await expectScreenshot();
});
```

If you need to do any actions with the component:

```ts
import React from 'react';

import {MyComponent} from '../MyComponent';

import {test} from '~playwright/core';

test('test description', async ({mount, expectScreenshot}) => {
// mount the component
const component = await mount(<MyComponent props={props} />);

// capture the screenshot
await expectScreenshot({component});
});
```

Group of tests.

```ts
test.describe('Name group tests', () => {
test('1', ...);
test('2', ...);
...
test('10', ...)
});
```
```ts
test.describe('Name group tests', () => {
test('1', ...);
test('2', ...);
...
test('10', ...)
});
```

4. Run tests

Expand All @@ -52,15 +90,15 @@ test.describe('Name group tests', () => {
5. Update screenshots if needed

```shell
npm run playwright:update
```
```shell
npm run playwright:update
```

Or
Or

```shell
npm run playwright:docker:update
```
```shell
npm run playwright:docker:update
```

6. In the folder `__snapshots__`, which is on the same level as the `__tests__` folder, the folder `<Component name>.visual.test.tsx-snapshots`, will contain screenshots

Expand Down
40 changes: 40 additions & 0 deletions playwright/core/expectScreenshotFixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {expect} from '@playwright/experimental-ct-react';

import type {ExpectScreenshotFixture, PlaywrightFixture} from './types';

export const expectScreenshotFixture: PlaywrightFixture<ExpectScreenshotFixture> = async (
{page},
use,
testInfo,
) => {
const expectScreenshot: ExpectScreenshotFixture = async ({
component,
screenshotName,
...pageScreenshotOptions
} = {}) => {
const captureScreenshot = async (theme: string) => {
const root = page.locator('#root');

await root.evaluate((el, newTheme) => {
el.setAttribute('class', `g-root g-root_theme_${newTheme}`);
}, theme);

return (component || page.locator('.playwright-wrapper-test')).screenshot({
animations: 'disabled',
...pageScreenshotOptions,
});
};

const nameScreenshot = testInfo.titlePath.slice(1).join(' ');

expect(await captureScreenshot('dark')).toMatchSnapshot({
name: `${screenshotName || nameScreenshot} dark.png`,
});

expect(await captureScreenshot('light')).toMatchSnapshot({
name: `${screenshotName || nameScreenshot} light.png`,
});
};

await use(expectScreenshot);
};
10 changes: 10 additions & 0 deletions playwright/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {test as base} from '@playwright/experimental-ct-react';

import {expectScreenshotFixture} from './expectScreenshotFixture';
import {mountFixture} from './mountFixture';
import type {Fixtures} from './types';

export const test = base.extend<Fixtures>({
mount: mountFixture,
expectScreenshot: expectScreenshotFixture,
});
26 changes: 0 additions & 26 deletions playwright/core/index.tsx

This file was deleted.

25 changes: 25 additions & 0 deletions playwright/core/mountFixture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';

import type {JsonObject} from '@playwright/experimental-ct-core/types/component';
import type {MountOptions} from '@playwright/experimental-ct-react';

import type {MountFixture, PlaywrightFixture} from './types';

export const mountFixture: PlaywrightFixture<MountFixture> = async ({mount: baseMount}, use) => {
const mount = async (
component: JSX.Element,
options?: MountOptions<JsonObject> | undefined,
) => {
return await baseMount(
<div
style={{padding: 20, width: 'fit-content', height: 'fit-content'}}
className="playwright-wrapper-test"
>
{component}
</div>,
options,
);
};

await use(mount);
};
31 changes: 31 additions & 0 deletions playwright/core/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type {ComponentFixtures} from '@playwright/experimental-ct-react';
import type {
Locator,
PageScreenshotOptions,
PlaywrightTestArgs,
PlaywrightTestOptions,
PlaywrightWorkerArgs,
PlaywrightWorkerOptions,
TestFixture,
} from '@playwright/test';

type PlaywrightTestFixtures = PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures;
type PlaywrightWorkerFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions;
type PlaywrightFixtures = PlaywrightTestFixtures & PlaywrightWorkerFixtures;
export type PlaywrightFixture<T> = TestFixture<T, PlaywrightFixtures>;

export type Fixtures = {
mount: MountFixture;
expectScreenshot: ExpectScreenshotFixture;
};

export type MountFixture = ComponentFixtures['mount'];

export interface ExpectScreenshotFixture {
(props?: CaptureScreenshotParams): Promise<void>;
}

interface CaptureScreenshotParams extends PageScreenshotOptions {
screenshotName?: string;
component?: Locator;
}
10 changes: 8 additions & 2 deletions playwright/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,17 @@ const config: PlaywrightTestConfig = {
projects: [
{
name: 'chromium',
use: {...devices['Desktop Chrome']},
use: {
...devices['Desktop Chrome'],
deviceScaleFactor: 2,
},
},
{
name: 'webkit',
use: {...devices['Desktop Safari']},
use: {
...devices['Desktop Safari'],
deviceScaleFactor: 2,
},
},
],
};
Expand Down
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
62 changes: 30 additions & 32 deletions src/components/Button/__tests__/Button.visual.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React from 'react';

import {expect} from '@playwright/experimental-ct-react';

import {
Default,
Disabled,
Expand All @@ -18,63 +16,63 @@ import {
import {test} from '~playwright/core';

test.describe('Button', () => {
test('render story: <Default>', async ({mount}) => {
const component = await mount(<Default />);
test('render story: <Default>', async ({mount, expectScreenshot}) => {
await mount(<Default />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Selected>', async ({mount}) => {
const component = await mount(<Selected />);
test('render story: <Selected>', async ({mount, expectScreenshot}) => {
await mount(<Selected />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Size>', async ({mount}) => {
const component = await mount(<Size />);
test('render story: <Size>', async ({mount, expectScreenshot}) => {
await mount(<Size />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Icon>', async ({mount}) => {
const component = await mount(<Icon />);
test('render story: <Icon>', async ({mount, expectScreenshot}) => {
await mount(<Icon />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <View', async ({mount}) => {
const component = await mount(<View />);
test('render story: <View>', async ({mount, expectScreenshot}) => {
await mount(<View />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Disabled>', async ({mount}) => {
const component = await mount(<Disabled />);
test('render story: <Disabled>', async ({mount, expectScreenshot}) => {
await mount(<Disabled />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Link>', async ({mount}) => {
const component = await mount(<Link />);
test('render story: <Link>', async ({mount, expectScreenshot}) => {
await mount(<Link />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Loading>', async ({mount}) => {
const component = await mount(<Loading />);
test('render story: <Loading>', async ({mount, expectScreenshot}) => {
await mount(<Loading />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Pin>', async ({mount}) => {
const component = await mount(<Pin />);
test('render story: <Pin>', async ({mount, expectScreenshot}) => {
await mount(<Pin />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});

test('render story: <Width>', async ({mount}) => {
const component = await mount(<Width />);
test('render story: <Width>', async ({mount, expectScreenshot}) => {
await mount(<Width />);

await expect(component).toHaveScreenshot();
await expectScreenshot();
});
});

0 comments on commit c2b16c9

Please sign in to comment.