-
-
Notifications
You must be signed in to change notification settings - Fork 301
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
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 mockConstantsMixin = {}; | ||
| const mockMetadataMixin = { | ||
| methods: { | ||
| translateMetadataString: str => str, | ||
| }, | ||
| }; | ||
|
|
||
| const renderComponent = props => { | ||
| return render(AccessibilityOptions, { | ||
| props: { | ||
| kind: 'document', | ||
| value: [], | ||
| ...props, | ||
| }, | ||
| routes: [], | ||
| mixins: [mockConstantsMixin, mockMetadataMixin], | ||
| mocks: { | ||
| $tr: key => key, | ||
| }, | ||
| }); | ||
| expect(wrapper.exists()).toBe(true); | ||
| }; | ||
|
|
||
| it('renders successfully', () => { | ||
| renderComponent(); | ||
| expect(screen.getAllByRole('checkbox').length).toBeGreaterThan(0); | ||
| }); | ||
|
|
||
| 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', () => { | ||
|
Contributor
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. praise: Good adherence to VTL's query priority — |
||
| 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', () => { | ||
|
Contributor
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. suggestion: The original test for audio explicitly verified that |
||
| 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(); | ||
| }); | ||
|
|
||
| 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 and v-model', () => { | ||
|
Contributor
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. nitpick: |
||
| it('emits an input event with the updated array when a user checks an option', async () => { | ||
|
Contributor
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. praise: The new interaction sub-suite (check, uncheck, pre-checked state) goes beyond mechanical migration — it's coverage that the original never had and that directly exercises the v-model contract. Good addition. |
||
| const { emitted } = renderComponent({ kind: 'document', value: [] }); | ||
|
|
||
| const altTextCheckbox = screen.getByRole('checkbox', { name: /altText/i }); | ||
| 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.
suggestion:
mockConstantsMixin = {}is an empty object — when applied as a mixin it adds nothing, soconstantsTranslationMixinfrom the component still runs unmodified. If you intend to let the real mixin run (which is fine, since the tests pass), remove this from themixinsarray entirely to make that explicit. If you ever need to suppress its methods, populate it with actual stubs.