diff --git a/src/components/Address/AddressInput.tsx b/src/components/Address/AddressInput.tsx index b434d7682..a3d117dfa 100644 --- a/src/components/Address/AddressInput.tsx +++ b/src/components/Address/AddressInput.tsx @@ -140,6 +140,7 @@ const AddressInput = ({ > { return ( - {options.map((option) => { + {options.map((option, index) => { const id = `option-${option.label}-${groupId}`; + const dataTestId = `react-gears-checkboxgroup-${groupId}-${index}`; return ( handleCheckboxChange(ev.target.checked, option.value)} diff --git a/src/components/Combobox/Combobox.spec.js b/src/components/Combobox/Combobox.spec.js index 5ba14cdf4..1a8887d23 100644 --- a/src/components/Combobox/Combobox.spec.js +++ b/src/components/Combobox/Combobox.spec.js @@ -22,43 +22,49 @@ describe('', () => { it('should render with empty options array', () => { const combobox = render(); - combobox.getByTestId('combobox-input'); + combobox.getByTestId('react-gears-combobox-input'); }); it('should show options when focused', () => { const combobox = render(); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); }); it('should pass inputClassName to Input', () => { const innerClassName = 'js-no-autofocus'; const combobox = render(); - assert(combobox.getByTestId('combobox-input').classList.contains(innerClassName)); + assert(combobox.getByTestId('react-gears-combobox-input').classList.contains(innerClassName)); }); it('should have "search" as default Input type', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); assert.strictEqual(input.type, 'search'); }); it('should pass type to Input', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); assert.strictEqual(input.type, 'text'); }); it('should show all options when there is a selected option', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); OPTIONS.forEach((o) => { @@ -70,7 +76,7 @@ describe('', () => { const mockOnChange = sinon.spy(); const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); const option = combobox.getByText('D-O'); @@ -83,43 +89,57 @@ describe('', () => { it('should close menu on blur', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); fireEvent.blur(input); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); }); it('should not close menu when menu container is focused', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); - const dropdown = combobox.getByTestId('combobox-dropdown'); - const menu = combobox.getByTestId('combobox-menu'); + const dropdown = combobox.getByTestId('react-gears-combobox-dropdown'); + const menu = combobox.getByTestId('react-gears-combobox-dropdownmenu'); fireEvent.blur(dropdown, { relatedTarget: menu }); - expect(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden')).toEqual('false'); + expect( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden') + ).toEqual('false'); }); it('should close menu on blur of caret button', () => { const combobox = render(); - const caret = combobox.getByTestId('combobox-caret'); + const caret = combobox.getByTestId('react-gears-combobox-button'); fireEvent.mouseDown(caret); - assert.strictEqual(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.strictEqual( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); fireEvent.blur(caret); - assert.strictEqual(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.strictEqual( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); }); it('should blur input on close', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); input.focus(); let option = combobox.getByText('D-O'); @@ -141,7 +161,7 @@ describe('', () => { it('should navigate options by up/down keys', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); assert(combobox.getByText('R2-D2').classList.contains('active')); @@ -168,7 +188,7 @@ describe('', () => { /> ); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.click(input); assert.strictEqual(input.value, 'bar'); @@ -178,7 +198,7 @@ describe('', () => { const mockOnChange = sinon.spy(); const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); fireEvent.keyDown(input, { key: 'ArrowDown', code: 40 }); @@ -186,7 +206,10 @@ describe('', () => { fireEvent.keyDown(input, { key: 'Enter', code: 13 }); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); sinon.assert.called(mockOnChange); sinon.assert.calledWith(mockOnChange, OPTIONS[1].value); }); @@ -197,7 +220,7 @@ describe('', () => { value = v; }; let combobox = render(); - let input = combobox.getByTestId('combobox-input'); + let input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); const option = combobox.getByText('D-O'); @@ -207,7 +230,7 @@ describe('', () => { cleanup(); combobox = render(); - input = combobox.getByTestId('combobox-input'); + input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.mouseDown(input); fireEvent.keyDown(input, { key: 'Backspace', code: 8 }); @@ -218,55 +241,79 @@ describe('', () => { it('should open options with down key', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); - const caret = combobox.getByTestId('combobox-caret'); + const caret = combobox.getByTestId('react-gears-combobox-button'); fireEvent.mouseDown(caret); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); fireEvent.keyDown(input, { key: 'ArrowDown', code: 40 }); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); }); it('should open options if input is clicked', async () => { const combobox = render(); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.mouseDown(input); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); }); it('should open/close options with dropdown toggle', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); - const caret = combobox.getByTestId('combobox-caret'); + const caret = combobox.getByTestId('react-gears-combobox-button'); fireEvent.mouseDown(caret); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'true'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'true' + ); fireEvent.mouseDown(caret); - assert.equal(combobox.getByTestId('combobox-menu').getAttribute('aria-hidden'), 'false'); + assert.equal( + combobox.getByTestId('react-gears-combobox-dropdownmenu').getAttribute('aria-hidden'), + 'false' + ); }); describe('default filterOptions ', () => { it('should filter by input (case insensitive)', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); fireEvent.change(input, { target: { value: 'bb8' } }); @@ -278,7 +325,7 @@ describe('', () => { it('should update filtered options when input is updated', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); fireEvent.change(input, { target: { value: 'd2' } }); @@ -306,7 +353,7 @@ describe('', () => { const combobox = render(); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); const droidLabel = combobox.getByText('Droids'); @@ -335,7 +382,7 @@ describe('', () => { ); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); userEvent.type(input, 'new option'); @@ -360,18 +407,20 @@ describe('', () => { /> ); - const input = combobox.getByTestId('combobox-input'); + const input = combobox.getByTestId('react-gears-combobox-input'); userEvent.type(input, 'new option'); - let newOptionButton = combobox.getByTestId('create-new-option'); + let newOptionButton = combobox.getByTestId( + 'react-gears-combobox-dropdownitem-create-new-option' + ); assert(newOptionButton.hasAttribute('disabled')); input.setSelectionRange(0, 'new option'.length); userEvent.type(input, 'foobar'); - newOptionButton = combobox.getByTestId('create-new-option'); + newOptionButton = combobox.getByTestId('react-gears-combobox-dropdownitem-create-new-option'); assert(!newOptionButton.hasAttribute('disabled')); }); @@ -393,7 +442,7 @@ describe('', () => { let combobox = render( ); - let input = combobox.getByTestId('combobox-input'); + let input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.focus(input); const option1 = combobox.getByText('D-O'); @@ -409,7 +458,7 @@ describe('', () => { cleanup(); combobox = render(); - input = combobox.getByTestId('combobox-input'); + input = combobox.getByTestId('react-gears-combobox-input'); fireEvent.keyDown(input, { key: 'Backspace', code: 8 }); diff --git a/src/components/Combobox/Combobox.tsx b/src/components/Combobox/Combobox.tsx index a0521df80..6284537a0 100644 --- a/src/components/Combobox/Combobox.tsx +++ b/src/components/Combobox/Combobox.tsx @@ -269,6 +269,7 @@ function Combobox({ ({ const renderGroupedOptions = (groups: OptionGroup[]) => groups.map((group, i) => ( <> - {group.label} + + {group.label} + {renderOptions(group.options)} {i !== groups.length - 1 && } > @@ -305,7 +308,7 @@ function Combobox({ return ( { ev.preventDefault(); @@ -353,7 +356,7 @@ function Combobox({ )} {}} @@ -368,7 +371,7 @@ function Combobox({ ({ /> ) => { @@ -423,7 +426,7 @@ function Combobox({ = ({ return ( - - + + = ({ } return ( - - $ + + $ ); diff --git a/src/components/Input/DateInput.js b/src/components/Input/DateInput.js index 46693280f..43a3e3732 100644 --- a/src/components/Input/DateInput.js +++ b/src/components/Input/DateInput.js @@ -326,6 +326,7 @@ export default class DateInput extends React.Component { { this.inputEl = el; }} @@ -340,6 +341,7 @@ export default class DateInput extends React.Component { /> - this.prevYear()}> + this.prevYear()} + > Previous Year - this.prevMonth()}> + this.prevMonth()} + > Previous Month @@ -370,11 +382,21 @@ export default class DateInput extends React.Component { - this.nextMonth()}> + this.nextMonth()} + > Next Month - this.nextYear()}> + this.nextYear()} + > Next Year @@ -384,6 +406,7 @@ export default class DateInput extends React.Component { - + Today - + Clear diff --git a/src/components/Input/MonthInput.js b/src/components/Input/MonthInput.js index a7a533de9..a8fd17f8f 100644 --- a/src/components/Input/MonthInput.js +++ b/src/components/Input/MonthInput.js @@ -272,6 +272,7 @@ export default class MonthInput extends React.Component { { this.inputEl = el; }} @@ -284,6 +285,7 @@ export default class MonthInput extends React.Component { disabled={disabled} /> - this.prevYear()}> + this.prevYear()} + > Previous Year this.prevMonth()} > @@ -323,11 +331,21 @@ export default class MonthInput extends React.Component { {format(date, 'MMMM YYYY')} - this.nextMonth()}> + this.nextMonth()} + > Next Month - this.nextYear()}> + this.nextYear()} + > Next Year @@ -336,6 +354,7 @@ export default class MonthInput extends React.Component { )} - + Today diff --git a/src/components/Input/PatternInput.js b/src/components/Input/PatternInput.js index d14ca867e..76bea74a5 100644 --- a/src/components/Input/PatternInput.js +++ b/src/components/Input/PatternInput.js @@ -33,6 +33,11 @@ export default class PatternInput extends React.Component { render() { /* eslint-disable-next-line @typescript-eslint/no-unused-vars -- This should go away when converting to function component */ const { pattern, restrictInput, ...inputProps } = this.props; + + if (inputProps && !inputProps['data-testid']) { + inputProps['data-testid'] = 'react-gears-patterninput-input'; + } + return ( ( - + {children} ); diff --git a/src/components/MultiSelectCombobox/ComboboxItems.tsx b/src/components/MultiSelectCombobox/ComboboxItems.tsx index ef454d07b..6c51e9afe 100644 --- a/src/components/MultiSelectCombobox/ComboboxItems.tsx +++ b/src/components/MultiSelectCombobox/ComboboxItems.tsx @@ -13,6 +13,7 @@ const defaultProps = { maxHeight: '12rem' }; const ComboboxItems = ({ children, maxHeight = defaultProps.maxHeight }: ComboboxItemsProps) => ( { return ( onFilterChange?.(e.target.value)} tabIndex={0} diff --git a/src/components/Radio/RadioGroup.tsx b/src/components/Radio/RadioGroup.tsx index b75d10892..946b88bc1 100644 --- a/src/components/Radio/RadioGroup.tsx +++ b/src/components/Radio/RadioGroup.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useState } from 'react'; +import { v4 as uuidv4 } from 'uuid'; import FormGroup from '../Form/FormGroup'; import Input from '../Input/Input'; import Label from '../Label/Label'; @@ -15,23 +16,28 @@ export interface RadioGroupProps { name?: string; } -const RadioGroup = ({ options, onChange, selected, name }: RadioGroupProps) => ( - - {options.map((option) => ( - - - e.target.checked && onChange(option.value)} - name={name} - />{' '} - {option.label} - - - ))} - -); +const RadioGroup = ({ options, onChange, selected, name }: RadioGroupProps) => { + const [groupId] = useState(uuidv4()); + + return ( + + {options.map((option, index) => ( + + + e.target.checked && onChange(option.value)} + name={name} + />{' '} + {option.label} + + + ))} + + ); +}; RadioGroup.displayName = 'RadioGroup'; diff --git a/src/components/Tree/Tree.spec.js b/src/components/Tree/Tree.spec.js index bd6e69c7b..cc253f93e 100644 --- a/src/components/Tree/Tree.spec.js +++ b/src/components/Tree/Tree.spec.js @@ -82,7 +82,7 @@ describe('', () => { expect(screen.queryAllByTestId('js-item-label').length).toEqual(10); expect(screen.queryByText('Regular is selected')).toBeInTheDocument(); expect(screen.queryByText('Chicken is not selected')).toBeInTheDocument(); - fireEvent.click(screen.queryAllByTestId('tree-item-checkbox-input')[1]); + fireEvent.click(screen.queryAllByTestId('react-gears-treeitem-input-checkbox')[1]); expect(updateOption).toHaveBeenCalled(); }); }); diff --git a/src/components/Tree/TreeItem.tsx b/src/components/Tree/TreeItem.tsx index da675a120..78345e562 100644 --- a/src/components/Tree/TreeItem.tsx +++ b/src/components/Tree/TreeItem.tsx @@ -67,6 +67,7 @@ function TreeItem({ updateOption(option, { expanded: !option.expanded })} > @@ -84,7 +85,7 @@ function TreeItem({ updateOption(option, { children, selected: newSelection }); }} type="checkbox" - data-testid="tree-item-checkbox-input" + data-testid="react-gears-treeitem-input-checkbox" /> )} {label(option.item, option)}