Skip to content

Commit

Permalink
Merge branch 'main' into add-smoke-tests/Skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
itwillwork authored Dec 28, 2024
2 parents 057c25b + 9527d01 commit d0ccab9
Show file tree
Hide file tree
Showing 312 changed files with 3,527 additions and 29 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@
"typescript": "^5.3.3"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
"react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
},
"nano-staged": {
"*.{scss}": [
Expand Down
1 change: 1 addition & 0 deletions playwright/core/mountFixture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const mountFixture: PlaywrightFixture<MountFixture> = async ({mount: base
boxSizing: options?.width ? 'content-box' : undefined,
width: options?.width ? options.width : 'fit-content',
height: 'fit-content',
...options?.rootStyle,
}}
className="playwright-wrapper-test"
>
Expand Down
8 changes: 6 additions & 2 deletions playwright/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type * as React from 'react';
import type {MountOptions, MountResult} from '@playwright/experimental-ct-react';
import type {
Locator,
Page,
PageScreenshotOptions,
PlaywrightTestArgs,
PlaywrightTestOptions,
Expand All @@ -14,7 +15,10 @@ import type {
interface ComponentFixtures {
mount<HooksConfig>(
component: React.JSX.Element,
options?: MountOptions<HooksConfig> & {width?: number | string},
options?: MountOptions<HooksConfig> & {
width?: number | string;
rootStyle?: React.CSSProperties;
},
): Promise<MountResult>;
}

Expand All @@ -36,6 +40,6 @@ export interface ExpectScreenshotFixture {

export interface CaptureScreenshotParams extends PageScreenshotOptions {
nameSuffix?: string;
component?: Locator;
component?: Locator | Page;
themes?: Array<'light' | 'dark'>;
}
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.
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.
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.
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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {expect} from '@playwright/experimental-ct-react';

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

import {createSmokeScenarios} from '../../../stories/tests-factory/create-smoke-scenarios';
import type {ActionTooltipProps} from '../ActionTooltip';
import {ActionTooltip} from '../ActionTooltip';

import {placementCases} from './cases';

test.describe('ActionTooltip', {tag: '@ActionTooltip'}, () => {
const defaultProps: ActionTooltipProps = {
title: 'Title',
hotkey: 'mod+a',
description: 'Description',
children: <div>trigger</div>,
};

const smokeScenarios = createSmokeScenarios<ActionTooltipProps>(defaultProps, {
placement: placementCases,
});

smokeScenarios.forEach(([title, props]) => {
smokeTest(title, async ({mount, page, expectScreenshot}) => {
const root = await mount(
<div>
<h4>{title}</h4>
<div
style={{
width: '400px',
height: '400px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div>
<ActionTooltip {...props}>
<div
data-qa="trigger"
style={{
width: '200px',
height: '200px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
border: '1px tomato dotted',
}}
>
trigger block
</div>
</ActionTooltip>
</div>
</div>
</div>,
);

await root.getByTestId('trigger').hover();
await expect(page.locator("[role='tooltip']")).toBeVisible({timeout: 1000});

await expectScreenshot({
themes: ['light'],
});
});
});
});
20 changes: 20 additions & 0 deletions src/components/ActionTooltip/__tests__/cases.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type {Cases} from '../../../stories/tests-factory/models';
import type {ActionTooltipProps} from '../ActionTooltip';

export const placementCases: Cases<ActionTooltipProps['placement']> = [
'auto',
'auto-start',
'auto-end',
'top',
'bottom',
'right',
'left',
'top-start',
'top-end',
'bottom-start',
'bottom-end',
'right-start',
'right-end',
'left-start',
'left-end',
];
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.
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.
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.
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.
121 changes: 118 additions & 3 deletions src/components/Avatar/__tests__/Avatar.visual.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import {expect} from '@playwright/experimental-ct-react';

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

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

import {createSmokeScenarios} from '../../../stories/tests-factory/create-smoke-scenarios';
import {Avatar} from '../Avatar';
import type {AvatarProps} from '../types/main';

import {
backgroundColorCases,
borderColorCases,
sizeCases,
themeCases,
titleCases,
viewCases,
} from './cases';
import {TestAvatarWithIcon, TestAvatarWithImage} from './helpersPlaywright';
import {AvatarStories} from './stories';

test.describe('Avatar', () => {
test.describe('Avatar', {tag: '@Avatar'}, () => {
test('render story: <Image>', async ({mount}) => {
const component = await mount(<AvatarStories.Image />);

Expand Down Expand Up @@ -48,4 +61,106 @@ test.describe('Avatar', () => {

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

const defaultProps: AvatarProps = {};

const commonCases = {
size: sizeCases,
theme: themeCases,
view: viewCases,
backgroundColor: backgroundColorCases,
borderColor: borderColorCases,
title: titleCases,
} as const;

smokeTest('with image', async ({mount, expectScreenshot}) => {
const smokeScenarios = createSmokeScenarios(
defaultProps,
{
...commonCases,
},
{
scenarioName: 'image specific',
},
);

await mount(
<div style={{width: 400}}>
{smokeScenarios.map(([title, props]) => (
<div key={title}>
<h4>{title}</h4>
<div>
<TestAvatarWithImage {...props} />
</div>
</div>
))}
</div>,
);

await expectScreenshot({
themes: ['light'],
});
});

smokeTest('with icon', async ({mount, expectScreenshot}) => {
const smokeScenarios = createSmokeScenarios(
defaultProps,
{
...commonCases,
},
{
scenarioName: 'icon specific',
},
);

await mount(
<div style={{width: 400}}>
{smokeScenarios.map(([title, props]) => (
<div key={title}>
<h4>{title}</h4>
<div>
<TestAvatarWithIcon {...props} />
</div>
</div>
))}
</div>,
);

await expectScreenshot({
themes: ['light'],
});
});

smokeTest('with text', async ({mount, expectScreenshot}) => {
const smokeScenarios = createSmokeScenarios(
{
...defaultProps,
text: 'Text',
color: 'black',
},
{
...commonCases,
},
{
scenarioName: 'text specific',
},
);

await mount(
<div style={{width: 400}}>
{smokeScenarios.map(([title, props]) => (
<div key={title}>
<h4>{title}</h4>
<div>
<Avatar {...props} />
</div>
</div>
))}
</div>,
);

await expectScreenshot({
themes: ['light'],
});
});
});
9 changes: 9 additions & 0 deletions src/components/Avatar/__tests__/cases.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {Cases} from '../../../stories/tests-factory/models';
import type {AvatarProps} from '../types/main';

export const sizeCases: Cases<AvatarProps['size']> = ['xs', 's', 'm', 'l', 'xl'];
export const themeCases: Cases<AvatarProps['theme']> = ['normal', 'brand'];
export const viewCases: Cases<AvatarProps['view']> = ['filled', 'outlined'];
export const backgroundColorCases: Cases<AvatarProps['backgroundColor']> = ['darkblue'];
export const borderColorCases: Cases<AvatarProps['borderColor']> = ['tomato'];
export const titleCases: Cases<AvatarProps['title']> = ['Title'];
19 changes: 19 additions & 0 deletions src/components/Avatar/__tests__/helpersPlaywright.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {smokeTest, test} from '~playwright/core';

import type {ClipboardButtonProps} from '../ClipboardButton';
import {ClipboardButton} from '../ClipboardButton';

test.describe('ClipboardButton', {tag: '@ClipboardButton'}, () => {
const defaultProps: ClipboardButtonProps = {
text: 'Text',
onCopy: () => {},
};

smokeTest('', async ({mount, page, expectScreenshot}) => {
const root = await mount(
<div style={{padding: '100px'}}>
<ClipboardButton {...defaultProps} hasTooltip />
</div>,
);

await expectScreenshot({
themes: ['light'],
});

await root.locator("button[type='button']").hover();

// wait for render tooltip
await page.waitForTimeout(1000);

await expectScreenshot({
themes: ['light'],
nameSuffix: 'after hover',
});

await root.locator("button[type='button']").click();

await expectScreenshot({
themes: ['light'],
nameSuffix: 'after copy',
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {smokeTest, test} from '~playwright/core';

import {createSmokeScenarios} from '../../../stories/tests-factory/create-smoke-scenarios';
import type {DefinitionListProps} from '../types';

import {DefinitionListStories} from './stories';

test.describe('DefinitionList', {tag: '@DefinitionList'}, () => {
test('render story <Default>', async ({mount, expectScreenshot}) => {
await mount(<DefinitionListStories.Default />);

await expectScreenshot();
});

createSmokeScenarios<Omit<DefinitionListProps, 'children'>>(
{},
{
direction: ['vertical', 'horizontal'],
},
).forEach(([title, props]) => {
smokeTest(title, async ({mount, expectScreenshot}) => {
await mount(
<div>
<h4>{title}</h4>
<DefinitionListStories.Default {...props} />
</div>,
);

await expectScreenshot({
themes: ['light'],
});
});
});

createSmokeScenarios<Omit<DefinitionListProps, 'children'>>(
{
responsive: true,
},
{
nameMaxWidth: [100],
contentMaxWidth: [100],
},
{
scenarioName: 'responsive',
},
).forEach(([title, props]) => {
smokeTest(title, async ({mount, page, expectScreenshot}) => {
const size = page.viewportSize();
if (size) {
await page.setViewportSize({
width: 1000,
height: size.height,
});
}

await mount(
<div>
<h4>{title}</h4>
<DefinitionListStories.Default {...props} />
</div>,
{width: 'auto'},
);

await expectScreenshot({
themes: ['light'],
});
});
});
});
5 changes: 5 additions & 0 deletions src/components/DefinitionList/__tests__/stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {composeStories} from '@storybook/react';

import * as CSFStories from '../__stories__/DefinitionList.stories';

export const DefinitionListStories = composeStories(CSFStories);
Loading

0 comments on commit d0ccab9

Please sign in to comment.