diff --git a/cypress/integration/Select.spec.ts b/cypress/integration/Select.spec.ts new file mode 100644 index 0000000000..ec800b0f5a --- /dev/null +++ b/cypress/integration/Select.spec.ts @@ -0,0 +1,52 @@ +import * as h from '../helpers'; + +const getSelect = () => { + return cy.get(`select`); +}; + +const selectedValue = 'mail'; + +describe('Select', () => { + before(() => { + h.stories.visit(); + }); + ['Plain', 'Alert', 'Error'].forEach(story => { + context(`given the '${story}' story is rendered`, () => { + beforeEach(() => { + h.stories.load('Components|Inputs/Select/React/Top Label', story); + }); + + it('should pass accessibility checks', () => { + cy.checkA11y(); + }); + + context(`when '${selectedValue}' is selected`, () => { + beforeEach(() => { + getSelect().select(selectedValue); + }); + + it('should be focused', () => { + getSelect().should('be.focused'); + }); + + it(`should have a value of '${selectedValue}'`, () => { + getSelect().should('have.value', selectedValue); + }); + }); + }); + }); + + context(`given the 'Disabled' story is rendered`, () => { + beforeEach(() => { + h.stories.load('Components|Inputs/Select/React/Top Label', 'Disabled'); + }); + + it('should pass accessibility checks', () => { + cy.checkA11y(); + }); + + it('should be disabled', () => { + getSelect().should('be.disabled'); + }); + }); +}); diff --git a/modules/form-field/react/stories/stories_Select.tsx b/modules/form-field/react/stories/stories_Select.tsx index 4d6f4e1716..af227332c7 100644 --- a/modules/form-field/react/stories/stories_Select.tsx +++ b/modules/form-field/react/stories/stories_Select.tsx @@ -2,7 +2,8 @@ import * as React from 'react'; import {storiesOf} from '@storybook/react'; import withReadme from 'storybook-readme/with-readme'; -import {controlComponent} from '../../../../utils/storybook'; +import {StaticStates} from '@workday/canvas-kit-labs-react-core'; +import {controlComponent, ComponentStatesTable, permutateProps} from '../../../../utils/storybook'; import FormField from '..'; import README from '../../../select/react/README.md'; @@ -208,3 +209,48 @@ storiesOf('Components|Inputs/Select/React/Left Label', module) )} )); + +storiesOf('Components|Inputs/Select/React/Visual Testing', module) + .addParameters({component: Select}) + .addDecorator(withReadme(README)) + .add('States', () => ( + + { + if (props.disabled && !['', 'hover'].includes(props.className)) { + return false; + } + return true; + } + )} + > + {props => ( + + )} + + + )); diff --git a/modules/select/react/spec/Select.spec.tsx b/modules/select/react/spec/Select.spec.tsx index b3014e7e81..5a8eaad4b2 100644 --- a/modules/select/react/spec/Select.spec.tsx +++ b/modules/select/react/spec/Select.spec.tsx @@ -1,38 +1,90 @@ import * as React from 'react'; -import {mount} from 'enzyme'; +import {render, fireEvent} from '@testing-library/react'; import SelectOption from '../lib/SelectOption'; import Select from '../lib/Select'; describe('Select', () => { const cb = jest.fn(); + + const role = 'listbox'; + afterEach(() => { cb.mockReset(); }); - test('renders two select options as expected', () => { - const component = mount( - - ); + describe('when rendered with an id', () => { + it('should render a select with id', () => { + const id = 'mySelect'; + const {getByRole} = render( + + ); + expect(getByRole(role)).toHaveAttribute('id', id); + }); + }); + + describe('when rendered with disabled attribute', () => { + it('should render a disabled select', () => { + const {getByRole} = render( + + ); + expect(getByRole(role)).toHaveProperty('disabled', true); + }); + }); + + describe('when rendered with a value', () => { + it('it should render a select whose selected option matches value', () => { + const selectedValue = 'phone'; + const {getByDisplayValue} = render( + + ); + expect(getByDisplayValue(selectedValue)).toBeDefined(); + }); + }); - const options = component.find('option'); + describe('when rendered with extra, arbitrary props', () => { + it('should spread extra props onto the select', () => { + const attr = 'test'; + const {getByRole} = render( + + ); + expect(getByRole(role)).toHaveAttribute('data-propspread', attr); + }); + }); - expect(options.length).toEqual(2); + describe('when rendered with two select options as children', () => { + it('should render two options', () => { + const {getAllByRole} = render( + + ); + expect(getAllByRole('option')).toHaveLength(2); + }); }); - test('Select should spread extra props', () => { - const component = mount( - - ); - const select = component - .find('select') // TODO: Standardize on prop spread location (see #150) - .getDOMNode(); - expect(select.getAttribute('data-propspread')).toBe('test'); - component.unmount(); + describe('when changed', () => { + it('should call a callback function', () => { + const {getByRole} = render( + + ); + fireEvent.change(getByRole(role)); + expect(cb).toHaveBeenCalledTimes(1); + }); }); });