diff options
Diffstat (limited to 'spec/frontend/content_editor/components/toolbar_table_button_spec.js')
-rw-r--r-- | spec/frontend/content_editor/components/toolbar_table_button_spec.js | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/spec/frontend/content_editor/components/toolbar_table_button_spec.js b/spec/frontend/content_editor/components/toolbar_table_button_spec.js index 35741971488..be6e47e067f 100644 --- a/spec/frontend/content_editor/components/toolbar_table_button_spec.js +++ b/spec/frontend/content_editor/components/toolbar_table_button_spec.js @@ -1,4 +1,4 @@ -import { GlDropdown, GlButton } from '@gitlab/ui'; +import { GlDisclosureDropdown, GlButton } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import ToolbarTableButton from '~/content_editor/components/toolbar_table_button.vue'; import { stubComponent } from 'helpers/stub_component'; @@ -14,12 +14,13 @@ describe('content_editor/components/toolbar_table_button', () => { tiptapEditor: editor, }, stubs: { - GlDropdown: stubComponent(GlDropdown), + GlDisclosureDropdown: stubComponent(GlDisclosureDropdown), }, }); }; - const findDropdown = () => wrapper.findComponent(GlDropdown); + const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown); + const findButton = (row, col) => wrapper.findComponent({ ref: `table-${row}-${col}` }); const getNumButtons = () => findDropdown().findAllComponents(GlButton).length; beforeEach(() => { @@ -32,32 +33,44 @@ describe('content_editor/components/toolbar_table_button', () => { editor.destroy(); }); - it('renders a grid of 5x5 buttons to create a table', () => { - expect(getNumButtons()).toBe(25); // 5x5 - }); - describe.each` row | col | numButtons | tableSize - ${3} | ${4} | ${25} | ${'3x4'} - ${4} | ${4} | ${25} | ${'4x4'} - ${4} | ${5} | ${30} | ${'4x5'} - ${5} | ${4} | ${30} | ${'5x4'} - ${5} | ${5} | ${36} | ${'5x5'} + ${3} | ${4} | ${25} | ${'3×4'} + ${4} | ${4} | ${25} | ${'4×4'} + ${4} | ${5} | ${30} | ${'4×5'} + ${5} | ${4} | ${30} | ${'5×4'} + ${5} | ${5} | ${36} | ${'5×5'} `('button($row, $col) in the table creator grid', ({ row, col, numButtons, tableSize }) => { - describe('on mouse over', () => { + describe('a11y tests', () => { + it('is in its own gridcell', () => { + expect(findButton(row, col).element.parentElement.getAttribute('role')).toBe('gridcell'); + }); + + it('has an aria-label', () => { + expect(findButton(row, col).attributes('aria-label')).toBe(`Insert a ${tableSize} table`); + }); + }); + + describe.each` + event | triggerEvent + ${'mouseover'} | ${(button) => button.trigger('mouseover')} + ${'focus'} | ${(button) => button.element.dispatchEvent(new FocusEvent('focus'))} + `('on $event', ({ triggerEvent }) => { beforeEach(async () => { - const button = wrapper.findByTestId(`table-${row}-${col}`); - await button.trigger('mouseover'); + const button = wrapper.findComponent({ ref: `table-${row}-${col}` }); + await triggerEvent(button); }); it('marks all rows and cols before it as active', () => { const prevRow = Math.max(1, row - 1); const prevCol = Math.max(1, col - 1); - expect(wrapper.findByTestId(`table-${prevRow}-${prevCol}`).element).toHaveClass('active'); + expect(wrapper.findComponent({ ref: `table-${prevRow}-${prevCol}` }).element).toHaveClass( + 'active', + ); }); it('shows a help text indicating the size of the table being inserted', () => { - expect(findDropdown().element).toHaveText(`Insert a ${tableSize} table.`); + expect(findDropdown().element).toHaveText(`Insert a ${tableSize} table`); }); it('adds another row and col of buttons to create a bigger table', () => { @@ -71,7 +84,7 @@ describe('content_editor/components/toolbar_table_button', () => { beforeEach(async () => { commands = mockChainedCommands(editor, ['focus', 'insertTable', 'run']); - const button = wrapper.findByTestId(`table-${row}-${col}`); + const button = wrapper.findComponent({ ref: `table-${row}-${col}` }); await button.trigger('mouseover'); await button.trigger('click'); }); @@ -95,8 +108,8 @@ describe('content_editor/components/toolbar_table_button', () => { expect(getNumButtons()).toBe(i * i); // eslint-disable-next-line no-await-in-loop - await wrapper.findByTestId(`table-${i}-${i}`).trigger('mouseover'); - expect(findDropdown().element).toHaveText(`Insert a ${i}x${i} table.`); + await wrapper.findComponent({ ref: `table-${i}-${i}` }).trigger('mouseover'); + expect(findDropdown().element).toHaveText(`Insert a ${i}×${i} table`); } expect(getNumButtons()).toBe(100); // 10x10 (and not 11x11) @@ -105,10 +118,50 @@ describe('content_editor/components/toolbar_table_button', () => { describe('a11y tests', () => { it('sets text, title, and text-sr-only properties to the table button dropdown', () => { expect(findDropdown().props()).toMatchObject({ - text: 'Insert table', + toggleText: 'Insert table', textSrOnly: true, }); - expect(findDropdown().attributes('title')).toBe('Insert table'); + expect(findDropdown().attributes('aria-label')).toBe('Insert table'); + }); + + it('renders a role=grid of 5x5 gridcells to create a table', () => { + expect(getNumButtons()).toBe(25); // 5x5 + expect(wrapper.find('[role="grid"]').exists()).toBe(true); + wrapper.findAll('[role="row"]').wrappers.forEach((row) => { + expect(row.findAll('[role="gridcell"]')).toHaveLength(5); + }); + }); + + it('sets aria-rowcount and aria-colcount on the dropdown contents', () => { + expect(wrapper.find('[role="grid"]').attributes()).toMatchObject({ + 'aria-rowcount': '10', + 'aria-colcount': '10', + }); + }); + + it('allows navigating the grid with the arrow keys', async () => { + const dispatchKeyboardEvent = (button, key) => + button.element.dispatchEvent(new KeyboardEvent('keydown', { key })); + + let button = findButton(3, 4); + await button.trigger('mouseover'); + expect(button.element).toHaveClass('active'); + + button = findButton(3, 5); + await dispatchKeyboardEvent(button, 'ArrowRight'); + expect(button.element).toHaveClass('active'); + + button = findButton(4, 5); + await dispatchKeyboardEvent(button, 'ArrowDown'); + expect(button.element).toHaveClass('active'); + + button = findButton(4, 4); + await dispatchKeyboardEvent(button, 'ArrowLeft'); + expect(button.element).toHaveClass('active'); + + button = findButton(3, 4); + await dispatchKeyboardEvent(button, 'ArrowUp'); + expect(button.element).toHaveClass('active'); }); }); }); |