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);
+ });
});
});