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

Storybook tests #2016

Merged
merged 9 commits into from
Jul 1, 2024
Merged
2 changes: 1 addition & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = {
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-a11y",
"storybook-dark-mode",
"storybook-dark-mode"
],
"framework": {
name: "@storybook/nextjs",
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"lint-sass:fix": "stylelint --fix **/*.scss",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test:browser": "playwright test"
"test:browser": "playwright test",
"test-storybook": "test-storybook"
},
"eslintConfig": {
"extends": [
Expand Down Expand Up @@ -63,13 +64,15 @@
"@storybook/addon-a11y": "^8.0.0",
"@storybook/addon-actions": "^8.0.0",
"@storybook/addon-essentials": "^8.0.0",
"@storybook/addon-interactions": "^8.0.0",
"@storybook/addon-interactions": "^8.1.10",
"@storybook/addon-links": "^8.0.0",
"@storybook/addon-viewport": "^8.1.2",
"@storybook/cli": "^8.0.0",
"@storybook/nextjs": "^8.0.0",
"@storybook/node-logger": "^8.0.0",
"@storybook/react": "^8.0.0",
"@storybook/test": "^8.1.10",
"@storybook/test-runner": "^0.19.0",
"@storybook/testing-library": "^0.2.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^15.0.0",
Expand Down
34 changes: 27 additions & 7 deletions src/components/atoms/authors/authors.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import { StoryFn, Meta } from '@storybook/react';
import { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';

import { Authors } from './authors';
import { authors } from '../../../utils/mocks';

export default {
const meta: Meta<typeof Authors> = {
title: 'Atoms/Authors',
component: Authors,
} as Meta<typeof Authors>;
};

export default meta;
type Story = StoryObj<typeof Authors>;

export const AuthorList: Story = {
args: {
authors,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('show', { exact: false });

const initialAuthors = Array.from(document.querySelectorAll('.authors-list li')).filter((node) => node.checkVisibility());
expect(initialAuthors).toHaveLength(10);

await userEvent.click(canvas.getByText('show', { exact: false }));

const expandedAuthors = Array.from(document.querySelectorAll('.authors-list li')).filter((node) => node.checkVisibility());
expect(expandedAuthors).toHaveLength(15);

const Template: StoryFn<typeof Authors> = (args) => <Authors {...args} />;
await userEvent.click(canvas.getByText('show', { exact: false }));

export const AuthorList = Template.bind({});
AuthorList.args = {
authors,
const collapsedAuthors = Array.from(document.querySelectorAll('.authors-list li')).filter((node) => node.checkVisibility());
expect(collapsedAuthors).toHaveLength(10);
},
};
51 changes: 35 additions & 16 deletions src/components/atoms/institutions/institutions.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
import { StoryFn, Meta } from '@storybook/react';

import { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
import { Institutions } from './institutions';

export default {
const meta: Meta<typeof Institutions> = {
title: 'Atoms/Institutions',
component: Institutions,
} as Meta<typeof Institutions>;

const Template: StoryFn<typeof Institutions> = (args) => <Institutions {...args} />;

export const InstitutionList = Template.bind({});
InstitutionList.args = {
institutions: [
{ name: 'Charles Xavier\'s School for Gifted Youngsters', address: { addressCountry: 'West Chester' } },
{ name: 'Star Labs', address: { addressCountry: 'Star City' } },
{ name: 'Avengers Tower', address: { addressCountry: 'New York' } },
{ name: 'Bat Cave', address: { addressCountry: 'Gotham' } },
{ name: 'Arrow Cave', address: { addressCountry: 'Central City' } },
],
};

export default meta;
type Story = StoryObj<typeof Institutions>;

export const InstitutionList: Story = {
args: {
institutions: [
{ name: 'Charles Xavier\'s School for Gifted Youngsters', address: { addressCountry: 'West Chester' } },
{ name: 'Star Labs', address: { addressCountry: 'Star City' } },
{ name: 'Avengers Tower', address: { addressCountry: 'New York' } },
{ name: 'Bat Cave', address: { addressCountry: 'Gotham' } },
{ name: 'Arrow Cave', address: { addressCountry: 'Central City' } },
],
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('show', { exact: false });

const initialInstitutions = Array.from(document.querySelectorAll('.institutions-list li')).filter((node) => node.checkVisibility());
expect(initialInstitutions).toHaveLength(3);

await userEvent.click(canvas.getByText('show', { exact: false }));

const expandedInstitutions = Array.from(document.querySelectorAll('.institutions-list li')).filter((node) => node.checkVisibility());
expect(expandedInstitutions).toHaveLength(5);

await userEvent.click(canvas.getByText('show', { exact: false }));

const collapsedInstitutions = Array.from(document.querySelectorAll('.institutions-list li')).filter((node) => node.checkVisibility());
expect(collapsedInstitutions).toHaveLength(3);
},
};
112 changes: 77 additions & 35 deletions src/components/molecules/modal/modal.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,76 @@
import {
useState,
} from 'react';
import { StoryFn, Meta } from '@storybook/react';
import { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
import { Modal } from './modal';
import { Socials } from '../../atoms/socials/socials';
import { Clipboard } from '../../atoms/clipboard/clipboard';
import { citation, references } from '../../../utils/mocks';
import { Reference as ReferenceData } from '../../../types';
import { Citation } from '../../atoms/citation/citation';

export default {
const meta: Meta<typeof Modal> = {
title: 'Molecules/Modal',
component: Modal,
} as Meta<typeof Modal>;
render: (args) => {
const [showModal, setShowModal] = useState(false);

const Template: StoryFn<typeof Modal> = (args) => {
const [showModal, setShowModal] = useState(false);

return (
<>
<button onClick={() => { setShowModal(true); }}>Modal Link</button>
<Modal {...args} open={showModal} onModalClose={() => { setShowModal(false); }} />
</>
);
return (
<>
<button onClick={() => { setShowModal(true); }}>Modal Link</button>
<Modal {...args} open={showModal} onModalClose={() => { setShowModal(false); }} />
</>
);
},
};

export const ModalContainer = Template.bind({});
ModalContainer.args = {
modalTitle: 'This is a title',
children: (<>This is content</>),
export default meta;
type Story = StoryObj<typeof Modal>;

export const ModalContainer: Story = {
args: {
modalTitle: 'This is a title',
children: (<>This is content</>),
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('Modal Link');

expect(await canvas.findByText('This is a title')).not.toBeVisible();

await userEvent.click(canvas.getByText('Modal Link'));
expect(canvas.getByText('This is a title')).toBeVisible();

await userEvent.click(canvas.getByText('Close'));
expect(await canvas.findByText('This is a title')).not.toBeVisible();
},
};

export const ModalShare = Template.bind({});
ModalShare.args = {
modalTitle: 'Share this article',
modalLayout: 'share',
children: (<>
<div className="form-item">
<input type="input" className="text-field text-field--clipboard" value={'https://doi.org/10.7554/eLife.09560'} />
</div>
<Clipboard text={'https://doi.org/10.7554/eLife.09560'} />
<Socials doi='www.google.com' title='I am a title' />
</>),
export const ModalShare: Story = {
args: {
modalTitle: 'Share this article',
modalLayout: 'share',
children: (<>
<div className="form-item">
<input type="input" className="text-field text-field--clipboard" value={'https://doi.org/10.7554/eLife.09560'} />
</div>
<Clipboard text={'https://doi.org/10.7554/eLife.09560'} />
<Socials doi='www.google.com' title='I am a title' />
</>),
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('Modal Link');

expect(await canvas.findByText('Share this article')).not.toBeVisible();

await userEvent.click(canvas.getByText('Modal Link'));
expect(canvas.getByText('Share this article')).toBeVisible();

await userEvent.click(canvas.getByText('Close'));
expect(await canvas.findByText('Share this article')).not.toBeVisible();
},
};

const formatReference = (reference: ReferenceData): string => {
Expand All @@ -53,12 +82,25 @@ const formatReference = (reference: ReferenceData): string => {
return `${authors} (${year}) ${reference.title}${journal ? ` ${journal}` : ''}${doiIdentifier ? `\n\nhttps://doi.org/${doiIdentifier.value}` : ''}`;
};

export const ModalCite = Template.bind({});
ModalCite.args = {
modalTitle: 'Cite this article',
modalLayout: 'cite',
children: (<>
<Citation citation={citation} />
<Clipboard text={formatReference(references[0])} />
</>),
export const ModalCite: Story = {
args: {
modalTitle: 'Cite this article',
modalLayout: 'cite',
children: (<>
<Citation citation={citation} />
<Clipboard text={formatReference(references[0])} />
</>),
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('Modal Link');

expect(await canvas.findByText('Cite this article')).not.toBeVisible();

await userEvent.click(canvas.getByText('Modal Link'));
expect(canvas.getByText('Cite this article')).toBeVisible();

await userEvent.click(canvas.getByText('Close'));
expect(await canvas.findByText('Cite this article')).not.toBeVisible();
},
};
Loading