Skip to content

Commit

Permalink
Merge ebb4da5 into 117d69f
Browse files Browse the repository at this point in the history
  • Loading branch information
mannycarrera4 committed Mar 13, 2020
2 parents 117d69f + ebb4da5 commit 68b563a
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 148 deletions.
54 changes: 54 additions & 0 deletions cypress/integration/FormField.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as h from '../helpers';

const getInput = () => {
return cy.get(`input`);
};

describe('Form Field', () => {
before(() => {
h.stories.visit();
});

context(`given the Default story is rendered`, () => {
beforeEach(() => {
h.stories.load('Components|Inputs/Form Field/React', 'Default');
});

it('should pass accessibility checks', () => {
cy.checkA11y();
});

context('when clicking on the label', () => {
beforeEach(() => {
cy.findByLabelText('Label').click();
});

it('should focus the input', () => {
getInput().should('be.focused');
});
});
});

['Hint Alert', 'Hint Error'].forEach(story => {
context(`given the '${story}' story is rendered`, () => {
beforeEach(() => {
h.stories.load('Components|Inputs/Form Field/React', story);
});

it('should pass accessibility and connect the input with the hint text', () => {
cy.checkA11y();
getInput().should('have.attr', 'aria-describedby');
});
});
});

context(`given the Label Required story is rendered`, () => {
beforeEach(() => {
h.stories.load('Components|Inputs/Form Field/React', 'Label Required');
});

it('should pass accessibility and connect the input with the hint text', () => {
cy.get('abbr').should('have.attr', 'title', 'required');
});
});
});
247 changes: 114 additions & 133 deletions modules/form-field/react/spec/FormField.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,152 +1,133 @@
import * as React from 'react';
import {mount} from 'enzyme';
import {GrowthBehavior} from '@workday/canvas-kit-react-common';
import FormField, {FormFieldErrorBehavior} from '../lib/FormField';
import {render} from '@testing-library/react';
import FormField from '../lib/FormField';
import {ErrorType} from '@workday/canvas-kit-react-common';

describe('FormField', () => {
test('Set a string label', () => {
const label = 'Label';
const component = mount(
<FormField label={label}>
<input type="text" />
</FormField>
);

expect(component.find('label').text()).toBe(label);

component.unmount();
const cb = jest.fn();
afterEach(() => {
cb.mockReset();
});

test('Set a custom component', () => {
const label = <label>Custom Label</label>;
const component = mount(
<FormField label={label}>
<input type="text" />
</FormField>
);

expect(component.contains(label)).toBeDefined();

component.unmount();
describe('when rendered', () => {
it('should render a label with text Label', () => {
const label = 'Label';
const {getByText} = render(
<FormField label={label}>
<input type="text" />
</FormField>
);

expect(getByText('Label')).toContainHTML(label);
});
});

test('Set hint text', () => {
const hintText = 'Hint Text';
const component = mount(
<FormField hintText={hintText}>
<input type="text" />
</FormField>
);

expect(component.render().text()).toEqual(expect.stringContaining(hintText));

component.unmount();
describe('when rendered with hint text', () => {
it('should render text below the input component', () => {
const label = 'Label';
const hintText = 'Helpful text goes here.';
const {container} = render(
<FormField hintText={hintText} label={label}>
<input type="text" />
</FormField>
);

expect(container.querySelector('p')).toContainHTML(hintText);
});
});

test('Set aria-describedby', () => {
const InputComponent: React.FunctionComponent<GrowthBehavior> = () => <input type="text" />;
const hintText = 'Hint Text';
const hintId = 'hint-id';
const component = mount(
<FormField error={FormField.ErrorType.Error} hintText={hintText} hintId={hintId}>
<InputComponent />
</FormField>
);

expect(
component
.find('Hint')
.at(0)
.prop('id')
).toEqual(hintId);
expect(component.find(InputComponent).prop('aria-describedby')).toEqual(hintId);

component.unmount();
describe('when rendered as required', () => {
it('should add a required element to the label to indicate that it is required', () => {
const label = 'Label';
const {getByText} = render(
<FormField label={label} required={true}>
<input type="text" />
</FormField>
);

expect(getByText('*')).toHaveAttribute('title', 'required');
});
});

test('Sets id on input & htmlFor on label', () => {
const InputComponent: React.FunctionComponent = () => <input type="text" />;
const inputId = 'input-id';

const component = mount(
<FormField inputId={inputId} label="Label">
<InputComponent />
</FormField>
);

expect(component.find(InputComponent).prop('id')).toEqual(inputId);
expect(component.find('Label').prop('htmlFor')).toEqual(inputId);

component.unmount();
describe('when rendered with useFieldset set to true', () => {
it('should render the FormField using a fieldset and a legend instead of a div and a label', () => {
const label = 'Label';
const {container} = render(
<FormField useFieldset={true} label={label} required={true}>
<input type="text" />
</FormField>
);

const fieldset = container.querySelector('fieldset');
expect(container).toContainElement(fieldset);
expect(container).toContainHTML('legend');
});
});

test('Sets grow prop', () => {
const InputComponent: React.FunctionComponent<GrowthBehavior> = () => <input type="text" />;

const component = mount(
<FormField grow={true}>
<InputComponent />
</FormField>
);

expect(component.find(InputComponent).props().grow).toEqual(true);

component.unmount();
describe('when rendered with extra, arbitrary props', () => {
it('should spread extra props onto the form field', () => {
const attr = 'test';
const label = 'Label';
const {container} = render(
<FormField label={label} data-propspread={attr}>
<input type="text" />
</FormField>
);

expect(container.querySelector('div')).toHaveAttribute('data-propspread', 'test');
});
});

test('Sets error prop with aria label', () => {
const InputComponent: React.FunctionComponent<FormFieldErrorBehavior> = () => (
<input type="text" />
);

const component = mount(
<FormField error={FormField.ErrorType.Error}>
<InputComponent />
</FormField>
);

expect(component.find(InputComponent).props().error).toEqual(FormField.ErrorType.Error);
expect(component.find(InputComponent).prop('aria-invalid')).toBeTruthy();

component.unmount();
describe('when rendered a hint id', () => {
it('the input and hint text should have matching ids for accessibility', () => {
const label = 'Label';
const hintId = 'hintId';
const hintText = 'Helpful text goes here.';
const {container} = render(
<FormField error={ErrorType.Error} hintId={hintId} hintText={hintText} label={label}>
<input type="text" />
</FormField>
);

expect(container.querySelector('p')).toHaveAttribute('id', hintId);
expect(container.querySelector('input')).toHaveAttribute('aria-describedby', hintId);
});
});

test('String child', () => {
const component = mount(<FormField>Text</FormField>);

expect(component.children().text()).toBe('Text');

component.unmount();
describe('when rendered a input id', () => {
it('the input and label should have matching ids for accessibility', () => {
const label = 'Label';
const inputId = 'inputId';
const hintText = 'Helpful text goes here.';
const {container} = render(
<FormField inputId={inputId} hintText={hintText} label={label}>
<input type="text" />
</FormField>
);

expect(container.querySelector('label')).toHaveAttribute('for', inputId);
expect(container.querySelector('input')).toHaveAttribute('id', inputId);
});
});

test('Uses fieldset and legend when useFieldset=true (for RadioGroup)', () => {
const InputComponent: React.FunctionComponent<FormFieldErrorBehavior> = () => (
<input type="text" />
);

const component = mount(
<FormField useFieldset={true} label="Label">
<InputComponent />
</FormField>
);

expect(component.find('fieldset')).toHaveLength(1);
expect(component.find('legend')).toHaveLength(1);

component.unmount();
describe('when rendered with an error', () => {
it('the input should have aria-invalid for accessibility', () => {
const label = 'Label';
const {container} = render(
<FormField error={FormField.ErrorType.Error} label={label}>
<input type="text" />
</FormField>
);
expect(container.querySelector('input')).toHaveAttribute('aria-invalid', 'true');
});
});

test('FormField should spread extra props', () => {
const InputComponent: React.FunctionComponent<FormFieldErrorBehavior> = () => (
<input type="text" />
);
const component = mount(
<FormField data-propspread="test">
<InputComponent />
</FormField>
);
const container = component.at(0).getDOMNode();
expect(container.getAttribute('data-propspread')).toBe('test');
component.unmount();
describe('when rendered with no inputId', () => {
it('the input should have a unique id', () => {
const label = 'Label';
const {container} = render(
<FormField error={FormField.ErrorType.Error} label={label}>
<input type="text" />
</FormField>
);
const uniqueId = container.querySelector('input').getAttribute('id');
expect(container.querySelector('input')).toHaveAttribute('id', uniqueId);
});
});
});
Loading

0 comments on commit 68b563a

Please sign in to comment.