Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(PlaywrightNewScreenshot): added the expectScreenshot fixture #1192

Merged
merged 8 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
});
});
Loading