-
-
Notifications
You must be signed in to change notification settings - Fork 302
Convert accessibility options unit tests to Vue Testing Library #5794 #5889
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
base: unstable
Are you sure you want to change the base?
Changes from all commits
64a8f15
f5ab93e
f194408
72edd5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,101 +1,134 @@ | ||
| import { shallowMount, mount } from '@vue/test-utils'; | ||
| import { render, screen, configure } from '@testing-library/vue'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import AccessibilityOptions from '../AccessibilityOptions.vue'; | ||
| import { AccessibilityCategories } from 'shared/constants'; | ||
|
|
||
| beforeAll(() => { | ||
| configure({ testIdAttribute: 'data-test' }); | ||
| }); | ||
|
|
||
| afterAll(() => { | ||
| configure({ testIdAttribute: 'data-testid' }); | ||
| }); | ||
|
|
||
| describe('AccessibilityOptions', () => { | ||
| it('smoke test', () => { | ||
| const wrapper = shallowMount(AccessibilityOptions, { | ||
| propsData: { | ||
| const mockMetadataMixin = { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Neither mock is necessary. import { metadataStrings } from 'shared/strings/metadataStrings';
// Instead of { name: /altText/i }:
screen.getByRole('checkbox', { name: metadataStrings.$tr('altText') });
// → 'Includes alternative text descriptions for images'
screen.getByRole('checkbox', { name: metadataStrings.$tr('highContrast') });
// → 'Includes high contrast text for learners with low vision'This also means the |
||
| methods: { | ||
| translateMetadataString: str => str, | ||
| }, | ||
| }; | ||
|
|
||
| const renderComponent = props => { | ||
| return render(AccessibilityOptions, { | ||
| props: { | ||
| kind: 'document', | ||
| value: [], | ||
| ...props, | ||
| }, | ||
| routes: [], | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| mixins: [mockMetadataMixin], | ||
| mocks: { | ||
| $tr: key => key, | ||
| }, | ||
| }); | ||
| expect(wrapper.exists()).toBe(true); | ||
| }; | ||
|
|
||
| it('renders successfully', () => { | ||
| renderComponent(); | ||
| expect(screen.getAllByRole('checkbox').length).toBeGreaterThan(0); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This smoke test is made redundant by the |
||
| }); | ||
|
|
||
| it('should display the correct list of accessibility options if resource is a document', () => { | ||
| const wrapper = mount(AccessibilityOptions, { | ||
| propsData: { | ||
| kind: 'document', | ||
| }, | ||
| }); | ||
| it('shows document-specific accessibility options to the user', () => { | ||
|
LightCreator1007 marked this conversation as resolved.
|
||
| renderComponent({ kind: 'document' }); | ||
|
|
||
| expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false); | ||
| const checkboxes = screen.getAllByRole('checkbox'); | ||
| expect(checkboxes).toHaveLength(3); | ||
|
|
||
| expect(screen.getByRole('checkbox', { name: /altText/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('checkbox', { name: /highContrast/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('checkbox', { name: /taggedPdf/i })).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('should display the correct list of accessibility options if resource is a video', () => { | ||
| const wrapper = mount(AccessibilityOptions, { | ||
| propsData: { | ||
| kind: 'video', | ||
| }, | ||
| }); | ||
| it('shows video-specific accessibility options to the user', () => { | ||
| renderComponent({ kind: 'video' }); | ||
|
|
||
| const checkboxes = screen.getAllByRole('checkbox'); | ||
| expect(checkboxes).toHaveLength(3); | ||
|
|
||
| expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-captionsSubtitles"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="tooltip-captionsSubtitles"]').exists()).toBe(false); | ||
| expect(screen.getByRole('checkbox', { name: /signLanguage/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('checkbox', { name: /audioDescription/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('checkbox', { name: /captionsSubtitles/i })).toBeInTheDocument(); | ||
|
|
||
| expect(screen.queryByTestId('tooltip-captionsSubtitles')).not.toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('should display the correct list of accessibility options if resource is an exercise/practice', () => { | ||
| const wrapper = mount(AccessibilityOptions, { | ||
| propsData: { | ||
| kind: 'exercise', | ||
| }, | ||
| }); | ||
| it('shows exercise-specific accessibility options to the user', () => { | ||
| renderComponent({ kind: 'exercise' }); | ||
|
|
||
| expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false); | ||
| const checkboxes = screen.getAllByRole('checkbox'); | ||
| expect(checkboxes).toHaveLength(1); | ||
| expect(screen.getByRole('checkbox', { name: /altText/i })).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('should display the correct list of accessibility options if resource is html5/zip', () => { | ||
| const wrapper = mount(AccessibilityOptions, { | ||
| propsData: { | ||
| kind: 'html5', | ||
| }, | ||
| }); | ||
| it('shows HTML5-specific accessibility options to the user', () => { | ||
| renderComponent({ kind: 'html5' }); | ||
|
|
||
| expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false); | ||
| const checkboxes = screen.getAllByRole('checkbox'); | ||
| expect(checkboxes).toHaveLength(2); | ||
| expect(screen.getByRole('checkbox', { name: /altText/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('checkbox', { name: /highContrast/i })).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('should display the correct list of accessibility options if resource is an audio', () => { | ||
| const wrapper = mount(AccessibilityOptions, { | ||
| propsData: { | ||
| kind: 'audio', | ||
| }, | ||
| }); | ||
| it('shows audio-specific accessibility options to the user', () => { | ||
|
LightCreator1007 marked this conversation as resolved.
|
||
| renderComponent({ kind: 'audio' }); | ||
|
|
||
| expect(wrapper.findComponent('[data-test="checkbox-captionsSubtitles"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="tooltip-captionsSubtitles"]').exists()).toBe(false); | ||
| const checkboxes = screen.getAllByRole('checkbox'); | ||
| expect(checkboxes).toHaveLength(1); | ||
| expect(screen.getByRole('checkbox', { name: /captionsSubtitles/i })).toBeInTheDocument(); | ||
| expect(screen.queryByTestId('tooltip-captionsSubtitles')).not.toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('should render appropriate tooltips along with the checkbox', () => { | ||
| const wrapper = mount(AccessibilityOptions, { | ||
| propsData: { | ||
| kind: 'document', | ||
| }, | ||
| it('renders informative tooltips next to the corresponding options', () => { | ||
| renderComponent({ kind: 'document' }); | ||
|
|
||
| expect(screen.getByTestId('tooltip-altText')).toBeInTheDocument(); | ||
| expect(screen.getByTestId('tooltip-highContrast')).toBeInTheDocument(); | ||
| expect(screen.getByTestId('tooltip-taggedPdf')).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| describe('User Interactions', () => { | ||
| it('emits an input event with the updated array when a user checks an option', async () => { | ||
|
LightCreator1007 marked this conversation as resolved.
|
||
| const { emitted } = renderComponent({ kind: 'document', value: [] }); | ||
|
|
||
| const altTextCheckbox = screen.getByRole('checkbox', { name: /altText/i }); | ||
|
LightCreator1007 marked this conversation as resolved.
|
||
| await userEvent.click(altTextCheckbox); | ||
|
|
||
| expect(emitted()).toHaveProperty('input'); | ||
| expect(emitted().input[0][0]).toEqual([AccessibilityCategories.ALT_TEXT]); | ||
| }); | ||
|
|
||
| expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="tooltip-altText"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="tooltip-highContrast"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="tooltip-taggedPdf"]').exists()).toBe(true); | ||
| expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="tooltip-signLanguage"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false); | ||
| expect(wrapper.findComponent('[data-test="tooltip-audioDescription"]').exists()).toBe(false); | ||
| it('emits an updated array with the item removed when a user unchecks a pre-checked option', async () => { | ||
| const { emitted } = renderComponent({ | ||
| kind: 'video', | ||
| value: [AccessibilityCategories.SIGN_LANGUAGE], | ||
| }); | ||
|
|
||
| const signLanguageCheckbox = screen.getByRole('checkbox', { name: /signLanguage/i }); | ||
| await userEvent.click(signLanguageCheckbox); | ||
|
|
||
| expect(emitted()).toHaveProperty('input'); | ||
| expect(emitted().input[0][0]).toEqual([]); | ||
| }); | ||
|
|
||
| it('renders correctly when accessibility options are pre-checked via v-model', () => { | ||
| renderComponent({ | ||
| kind: 'video', | ||
| value: [AccessibilityCategories.SIGN_LANGUAGE, AccessibilityCategories.CAPTIONS_SUBTITLES], | ||
| }); | ||
|
|
||
| expect(screen.getByRole('checkbox', { name: /signLanguage/i })).toBeChecked(); | ||
| expect(screen.getByRole('checkbox', { name: /captionsSubtitles/i })).toBeChecked(); | ||
| expect(screen.getByRole('checkbox', { name: /audioDescription/i })).not.toBeChecked(); | ||
| }); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configure({ testIdAttribute: 'data-test' })should be called at module scope, not insidebeforeAll. Jest can initialize parts of the test infrastructure beforebeforeAllruns, so testId queries that fire during module loading would miss the configuration. TheafterAllrestore is also risky — if a test throws beforeafterAllexecutes,data-testidis never restored, silently breaking other test files that run after this one.Replace both blocks with a single module-scope call: