Skip to content

Commit

Permalink
Merge 01affd8 into bdc506d
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesfan committed Feb 7, 2020
2 parents bdc506d + 01affd8 commit ff4f316
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 23 deletions.
52 changes: 52 additions & 0 deletions cypress/integration/Select.spec.ts
Original file line number Diff line number Diff line change
@@ -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');
});
});
});
48 changes: 47 additions & 1 deletion modules/form-field/react/stories/stories_Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -208,3 +209,48 @@ storiesOf('Components|Inputs/Select/React/Left Label', module)
)}
</FormField>
));

storiesOf('Components|Inputs/Select/React/Visual Testing', module)
.addParameters({component: Select})
.addDecorator(withReadme(README))
.add('States', () => (
<StaticStates>
<ComponentStatesTable
rowProps={[
{label: 'Default', props: {}},
{label: 'Alert', props: {error: Select.ErrorType.Alert}},
{label: 'Error', props: {error: Select.ErrorType.Error}},
]}
columnProps={permutateProps(
{
className: [
{label: 'Default', value: ''},
{label: 'Hover', value: 'hover'},
{label: 'Focus', value: 'focus'},
{label: 'Focus Hover', value: 'focus hover'},
{label: 'Active', value: 'active'},
{label: 'Active Hover', value: 'active hover'},
],
disabled: [{label: '', value: false}, {label: 'Disabled', value: true}],
},
props => {
if (props.disabled && !['', 'hover'].includes(props.className)) {
return false;
}
return true;
}
)}
>
{props => (
<Select
{...props}
style={{minWidth: 60, width: 100}}
onChange={() => {}} // eslint-disable-line no-empty-function
>
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
)}
</ComponentStatesTable>
</StaticStates>
));
96 changes: 74 additions & 22 deletions modules/select/react/spec/Select.spec.tsx
Original file line number Diff line number Diff line change
@@ -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(
<Select name="contact">
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
describe('when rendered with an id', () => {
it('should render a select with id', () => {
const id = 'mySelect';
const {getByRole} = render(
<Select id={id} onChange={cb}>
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
expect(getByRole(role)).toHaveAttribute('id', id);
});
});

describe('when rendered with disabled attribute', () => {
it('should render a disabled select', () => {
const {getByRole} = render(
<Select disabled={true} onChange={cb}>
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
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(
<Select onChange={cb} value={selectedValue}>
<SelectOption value="email" label="E-mail" />
<SelectOption value={selectedValue} label={selectedValue} />
</Select>
);
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(
<Select data-propspread={attr} onChange={cb}>
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
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(
<Select onChange={cb}>
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
expect(getAllByRole('option')).toHaveLength(2);
});
});

test('Select should spread extra props', () => {
const component = mount(
<Select name="contact" data-propspread="test">
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
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(
<Select onChange={cb}>
<SelectOption value="email" label="E-mail" />
<SelectOption value="phone" label="Phone" />
</Select>
);
fireEvent.change(getByRole(role));
expect(cb).toHaveBeenCalledTimes(1);
});
});
});

0 comments on commit ff4f316

Please sign in to comment.