import type { Meta, StoryObj } from '@storybook/react-vite' import React from 'react' import { expect, screen, userEvent } from 'storybook/test' import { DocsTemplate } from '../../../.storybook' import { toast } from '../Toast/Toast' import Alert from './Alert' import { type ButtonProps } from '../ComponentTypes.models' const meta: Meta = { title: 'Components/Alert', component: Alert, parameters: { design: { type: 'figma', url: 'https://www.figma.com/design/RvhKD82948FMQnh5MyCi0o/Web-Design-System?node-id=121-333&t=47NWXExemisHjPrj-0', }, docs: { page: () => ( An Alert is system generated and contextual, and may appear without the user initiating an action. They can be dismissable. Generally, they appear within the page section/container. } infoBullets={[ The information variant should provide additional information to the user in regards to the current context or action they are about to take. , The success variant should reaffirm to the user that a prior action they have taken, often in a different location within the application, has been successful. , The warning variant should be used to display cautious information that may need the user's attention but may not be critical. , The error variant should be used to alert the user about an error in the current/prior context that needs immediate attention. , ]} /> ), }, }, } export default meta type Story = StoryObj const Template: Story = { render: ({ ...args }) => , } export const Success: Story = { ...Template, args: { type: 'success', text: 'This is an Alert!', }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertSuccess') }, } export const Error: Story = { ...Template, args: { type: 'error', text: 'This is an Alert!', }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertError') }, } export const Warning: Story = { ...Template, args: { type: 'warning', text: 'This is an Alert!', }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertWarning') }, } export const Info: Story = { ...Template, args: { type: 'info', text: 'This is an Alert!', }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertInfo') }, } export const InfoWithClose: Story = { ...Template, args: { type: 'info', text: 'This is an Alert!', close: { show: true, callout: () => { toast({ message: 'You clicked the close button!', type: 'info' }) }, }, }, play: async ({ canvas, userEvent }) => { const closeButton = canvas.getByRole('button') await userEvent.click(closeButton) await expect( canvas.getByText('You clicked the close button!'), ).toBeInTheDocument() }, } export const CloseSuccessConfirmation: Story = { ...Template, args: { type: 'info', text: 'This is an Alert!', close: { show: true, callout: () => { toast({ message: 'You clicked the close button!', type: 'info' }) }, confirmation: { type: 'green', header: 'Are you sure?', body: 'This will perform some action. Would you like to continue?', confirmCallout: () => { toast({ message: 'You did it!', type: 'success' }) }, }, }, }, } export const CloseErrorConfirmation: Story = { ...Template, args: { type: 'info', text: 'This is an Alert!', close: { show: true, callout: () => { toast({ message: 'You clicked the close button!', type: 'info' }) }, confirmation: { type: 'red', header: 'Are you sure?', body: 'This will perform some action. Would you like to continue?', confirmCallout: () => { toast({ message: 'You did it!', type: 'success' }) }, }, }, }, } export const CloseInfoConfirmation: Story = { ...Template, args: { type: 'info', text: 'This is an Alert!', close: { show: true, callout: () => { toast({ message: 'You clicked the close button!', type: 'info' }) }, confirmation: { type: 'blue', header: 'Are you sure?', body: 'This will perform some action. Would you like to continue?', confirmCallout: () => { toast({ message: 'You did it!', type: 'success' }) }, }, }, }, } const buttons = [ { as: 'link', to: '/', routerComponent: 'a', children: 'Link Button', }, { children: 'Button', onClick: () => { toast({ message: 'You clicked the button!', type: 'success' }) }, }, ] as [ButtonProps, ButtonProps?] export const ButtonsAndClose: Story = { ...Template, args: { type: 'success', text: 'This is an Alert!', buttons, close: { show: true, callout: () => { toast({ message: 'You clicked the close button!', type: 'info' }) }, }, }, play: async ({ canvas }) => { await expect(canvas.getByText('This is an Alert!')).toBeInTheDocument() const linkButton = canvas.getByText('Link Button') const actionButton = canvas.getByText('Button') const xButton = canvas.getByTestId('icon-x') await expect(linkButton).toBeInTheDocument() await expect(actionButton).toBeInTheDocument() await expect(xButton).toBeInTheDocument() await userEvent.click(actionButton) // Check for toast message after action button click const toastAction = document.body.querySelector('.Toastify__toast') await expect(toastAction).toHaveTextContent('You clicked the button!') await userEvent.click(xButton) // Check for toast message after close button click await expect( screen.getByText('You clicked the close button!'), ).toBeInTheDocument() }, } export const SuccessWithButtons: Story = { ...Template, args: { type: 'success', text: 'This is an Alert!', buttons, }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertSuccess') await expect(canvas.getByText('This is an Alert!')).toBeInTheDocument() const linkButton = canvas.getByText('Link Button') const actionButton = canvas.getByText('Button') await expect(linkButton).toBeInTheDocument() await expect(actionButton).toBeInTheDocument() await userEvent.click(actionButton) // Check for toast message after button click const toastEl = document.body.querySelector('.Toastify__toast') await expect(toastEl).toHaveTextContent('You clicked the button!') }, } export const ErrorWithButtons: Story = { ...Template, args: { type: 'error', text: 'This is an Alert!', buttons, }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertError') await expect(canvas.getByText('This is an Alert!')).toBeInTheDocument() const linkButton = canvas.getByText('Link Button') const actionButton = canvas.getByText('Button') await expect(linkButton).toBeInTheDocument() await expect(actionButton).toBeInTheDocument() await userEvent.click(actionButton) // Check for toast message after button click const toastEl = document.body.querySelector('.Toastify__toast') await expect(toastEl).toHaveTextContent('You clicked the button!') }, } export const WarningWithButtons: Story = { ...Template, args: { type: 'warning', text: 'This is an Alert!', buttons, }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertWarning') await expect(canvas.getByText('This is an Alert!')).toBeInTheDocument() const linkButton = canvas.getByText('Link Button') const actionButton = canvas.getByText('Button') await expect(linkButton).toBeInTheDocument() await expect(actionButton).toBeInTheDocument() await userEvent.click(actionButton) // Check for toast message after button click const toastEl = document.body.querySelector('.Toastify__toast') await expect(toastEl).toHaveTextContent('You clicked the button!') }, } export const InfoWithButtons: Story = { ...Template, args: { type: 'info', text: 'This is an Alert!', buttons, }, play: async ({ canvas }) => { const alertContainer = canvas.getByTestId('Alert') await expect(alertContainer).toBeInTheDocument() await expect(alertContainer?.className).toContain('alertInfo') await expect(canvas.getByText('This is an Alert!')).toBeInTheDocument() const linkButton = canvas.getByText('Link Button') const actionButton = canvas.getByText('Button') await expect(linkButton).toBeInTheDocument() await expect(actionButton).toBeInTheDocument() await userEvent.click(actionButton) // Check for toast message after confirming const toastEl = document.body.querySelector('.Toastify__toast') await expect(toastEl).toHaveTextContent('You clicked the button!') }, } export const CustomIcon: Story = { ...Template, args: { type: 'info', text: 'This is an Alert with a custom icon!', customIcon: 'calendar', }, play: async ({ canvas }) => { await expect( canvas.getByText('This is an Alert with a custom icon!'), ).toBeInTheDocument() // Test that the custom calendar icon is displayed const calendarIcon = canvas.getByTestId('icon-calendar') await expect(calendarIcon).toBeInTheDocument() }, }