import React from 'react';
import { render, screen } from '@testing-library/react';
import { Wizard, WizardStepFunctionType, WizardStep } from '../Wizard';
import { DrawerPanelContent, DrawerColorVariant, DrawerHead } from '../../../../../src/components/Drawer';
import userEvent from '@testing-library/user-event';
describe('Wizard', () => {
test('Wizard should match snapshot', () => {
const steps: WizardStep[] = [
{ name: 'A', id: 'step-A', component:
Step 1
},
{
name: 'B',
id: 'step-B',
steps: [
{
name: 'B-1',
id: 'step-B-1',
component: Step 2
,
enableNext: true
},
{
name: 'B-2',
id: 'step-B-2',
component: Step 3
,
enableNext: false
}
]
},
{ name: 'C', id: 'step-C', component: Step 4
},
{ name: 'D', id: 'step-D', component: Step 5
}
];
const onBack: WizardStepFunctionType = step => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const name = { step };
};
const { asFragment } = render(
);
expect(asFragment()).toMatchSnapshot();
});
test('Expandable Nav Wizard should match snapshot', () => {
const steps: WizardStep[] = [
{ name: 'A', component: Step 1
},
{
name: 'B',
steps: [
{
name: 'B-1',
component: Step 2
,
enableNext: true
},
{
name: 'B-2',
component: Step 3
,
enableNext: false
}
]
},
{ name: 'C', component: Step 4
},
{ name: 'D', component: Step 5
}
];
const onBack: WizardStepFunctionType = step => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const name = { step };
};
const { asFragment } = render(
);
expect(asFragment()).toMatchSnapshot();
});
test('bare wiz', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
const { asFragment } = render(
);
expect(asFragment()).toMatchSnapshot();
});
test('wiz with title', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
render();
expect(screen.getByRole('heading', { name: 'Wizard' })).toBeInTheDocument();
});
test('wiz with drawer', () => {
const wizDrawerPanelContent = (
This wizard has a drawer with drawer panel content
);
const steps: WizardStep[] = [{ name: 'A', component: Step 1
, drawerPanelContent: wizDrawerPanelContent }];
render();
expect(screen.getByRole('heading', { name: 'Wizard with drawer' })).toBeInTheDocument();
expect(screen.getByText('This wizard has a drawer with drawer panel content')).toBeInTheDocument();
});
test('wiz with title and navAriaLabel combination', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
render();
const nav = screen.getByLabelText('Some label');
expect(screen.getByRole('heading', { name: 'Wizard' })).toBeInTheDocument();
expect(nav).toBeInTheDocument();
expect(nav).toHaveAttribute('aria-labelledby', 'pf-wizard-title-5');
});
test('wiz with navAriaLabel and mainAriaLabel but without title', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
render();
expect(screen.getByLabelText('nav aria-label')).toBeInTheDocument();
});
test('wiz with navAriaLabel and navAriaLabelledby and without title', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
render(
);
const nav = screen.getByLabelText('nav aria-label');
expect(nav).toBeInTheDocument();
expect(nav).toHaveAttribute('aria-labelledby', 'nav-aria-labelledby');
});
test('wiz with title, navAriaLabelledBy, and navAriaLabel', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
render(
);
const nav = screen.getByLabelText('nav aria-label');
expect(nav).toBeInTheDocument();
expect(nav).toHaveAttribute('aria-labelledby', 'nav-aria-labelledby');
});
test('Does not render with mainAriaLabel or mainAriaLabelledby by default', () => {
const steps: WizardStep[] = [{ name: 'A', component: Step 1
}];
render(
);
const main = screen.getByTestId('wizard-test-id');
expect(main).not.toHaveAttribute('aria-labelledby');
expect(main).not.toHaveAttribute('aria-label');
});
test('wiz with onCurrentStepChanged setter', async () => {
const stepA = { name: 'A', component: Step 1
};
const stepB = { name: 'B', component: Step 2
};
const stepC = { name: 'C', component: Step 3
};
const steps: WizardStep[] = [stepA, stepB, stepC];
const setter = jest.fn();
const user = userEvent.setup();
render();
expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepA));
await user.click(screen.getByText(/next/i));
expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepB));
await user.click(screen.getByText(/next/i));
expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepC));
await user.click(screen.getByText('A'));
expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepA));
await user.click(screen.getByText(/next/i));
expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepB));
await user.click(screen.getByText(/back/i));
expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepA));
});
});
test('wiz with disabled steps', () => {
const steps: WizardStep[] = [
{ name: 'A', component: Step 1
},
{ name: 'B', component: Step 2
, isDisabled: true },
{ name: 'C', component: Step 3
},
{ name: 'E', component: Step 4
, isDisabled: true },
{ name: 'G', component: Step 5
}
];
render();
expect(screen.getByRole('button', { name: 'B' })).toBeDisabled();
expect(screen.getByRole('button', { name: 'E' })).toBeDisabled();
});
test('wiz skip the step disabled when press the next/back button', async () => {
const steps: WizardStep[] = [
{ name: 'A', component: Step 1
},
{ name: 'B', component: Step 2
, isDisabled: true },
{ name: 'C', component: Step 3
}
];
const user = userEvent.setup();
render();
await user.click(screen.getByRole('button', { name: 'Next' }));
expect(screen.getByRole('button', { name: 'C' })).toHaveClass('pf-m-current');
await user.click(screen.getByRole('button', { name: 'Back' }));
expect(screen.getByRole('button', { name: 'A' })).toHaveClass('pf-m-current');
});
test('wiz skip the step when click on the nav item disabled', async () => {
const steps: WizardStep[] = [
{ name: 'A', component: Step 1
},
{ name: 'B', component: Step 2
, isDisabled: true },
{ name: 'C', component: Step 3
}
];
const user = userEvent.setup();
render();
const navItemButton = screen.getByRole('button', { name: 'B' });
const navItemButtonSelected = screen.getByRole('button', { name: 'A' });
await user.click(navItemButton);
expect(navItemButton).not.toHaveClass('pf-m-current');
expect(navItemButtonSelected).toHaveClass('pf-m-current');
});
test('wiz with disable sub step', () => {
const steps: WizardStep[] = [
{
name: 'A',
steps: [
{ name: 'A-1', component: Substep A content
},
{ name: 'A-2', component: Substep B content
, isDisabled: true }
]
}
];
render();
expect(screen.getByRole('button', { name: 'A-2' })).toBeDisabled();
});
test('startAtStep can be used to externally control the current step of the wizard', async () => {
const WizardTest = () => {
const [step, setStep] = React.useState(1);
const incrementStep = () => {
setStep(prevStep => prevStep + 1);
};
const steps: WizardStep[] = [
{ name: 'A', component: Step 1
},
{ name: 'B', component: Step 2
},
{ name: 'C', component: Step 3
}
];
return (
<>
>
);
};
const user = userEvent.setup();
render();
expect(screen.queryByText('Step 2')).not.toBeInTheDocument();
await user.click(screen.getByRole('button', { name: 'Increment step' }));
expect(screen.getByText('Step 2')).toBeVisible();
});