@salesforce/design-system-react
Version:
Salesforce Lightning Design System for React
390 lines (326 loc) • 9.44 kB
JSX
/* eslint-disable react/no-render-return-value */
import React from 'react';
import ReactDOM from 'react-dom';
import chai, { expect } from 'chai';
import chaiEnzyme from 'chai-enzyme';
import assign from 'lodash.assign';
import TestUtils from 'react-dom/test-utils';
import { mount } from 'enzyme';
/* Enzyme Helpers that can mount and unmount React component instances to
* the DOM and set `this.wrapper` and `this.dom` within Mocha's `this`
* context [full source here](tests/enzyme-helpers.js). `this` can
* only be referenced if inside `function () {}`.
*/
import {
createMountNode,
destroyMountNode,
} from '../../../tests/enzyme-helpers';
import Slider from '../../slider';
/* Set Chai to use chaiEnzyme for enzyme compatible assertions:
* https://github.com/producthunt/chai-enzyme
*/
chai.use(chaiEnzyme());
const {
findRenderedDOMComponentWithTag,
findRenderedDOMComponentWithClass,
} = TestUtils;
describe('SLDSSlider', () => {
const defaultProps = {};
let body;
let body2;
const renderSlider = (instance) => {
body = document.createElement('div');
document.body.appendChild(body);
return ReactDOM.render(instance, body); // deepscan-disable-line REACT_ASYNC_RENDER_RETURN_VALUE
};
const renderSecondSlider = (instance) => {
body2 = document.createElement('div');
document.body.appendChild(body2);
return ReactDOM.render(instance, body2); // deepscan-disable-line REACT_ASYNC_RENDER_RETURN_VALUE
};
function removeSlider() {
ReactDOM.unmountComponentAtNode(body);
document.body.removeChild(body);
if (body2 && body2.firstChild) {
ReactDOM.unmountComponentAtNode(body2);
document.body.removeChild(body2);
}
}
const createSlider = (props) =>
React.createElement(Slider, assign({}, defaultProps, props));
const getSlider = (props) => renderSlider(createSlider(props));
const getSecondSlider = (props) => renderSecondSlider(createSlider(props));
describe('Standard Slider with Label', () => {
let component;
let wrapper;
let slider;
let label;
let labelText;
beforeEach(() => {
component = getSlider({ label: 'Slider Label', id: 'custom-id' });
wrapper = findRenderedDOMComponentWithClass(
component,
'slds-form-element'
);
slider = findRenderedDOMComponentWithTag(component, 'input');
label = findRenderedDOMComponentWithClass(
component,
'slds-form-element__label'
);
labelText = findRenderedDOMComponentWithClass(
component,
'slds-slider-label__label'
);
});
afterEach(() => {
removeSlider();
});
it('has type of "range"', () => {
expect(slider.getAttribute('type')).to.equal('range');
});
it('is wrapped in div with class "slds-form-element"', () => {
expect(wrapper.className).to.include('slds-form-element');
});
it('renders label', () => {
expect(labelText.textContent).to.equal('Slider Label');
});
it('renders slider element with class "slds-slider"', () => {
expect(slider.className).to.include('slds-slider');
});
it('has an id', () => {
expect(slider.getAttribute('id')).to.be.ok;
});
it('can pass custom id', () => {
expect(slider.getAttribute('id')).to.equal('custom-id');
});
it('has associated label for tag pointing to id of slider', () => {
const labelForTag = label.getAttribute('for');
const sliderId = slider.getAttribute('id');
expect(labelForTag).to.equal(sliderId);
});
});
describe('Component basic props', () => {
let component;
let slider;
let labelRange;
let sliderValue;
beforeEach(() => {
component = getSlider({
label: 'Slider Label',
id: 'custom-id',
value: 200,
min: 0,
max: 400,
step: 100,
});
slider = findRenderedDOMComponentWithTag(component, 'input');
labelRange = findRenderedDOMComponentWithClass(
component,
'slds-slider-label__range'
);
sliderValue = findRenderedDOMComponentWithClass(
component,
'slds-slider__value'
);
});
afterEach(() => {
removeSlider();
});
it('has min', () => {
expect(slider.getAttribute('min')).to.equal('0');
});
it('has max', () => {
expect(slider.getAttribute('max')).to.equal('400');
});
it('min/max matches label range', () => {
expect(labelRange.textContent).to.equal('0 - 400');
});
it('has step', () => {
expect(slider.getAttribute('step')).to.equal('100');
});
it('has value', () => {
expect(slider.getAttribute('value')).to.equal('200');
});
it('value matches slider value label', () => {
expect(slider.value).to.equal(sliderValue.textContent);
});
});
describe('onInput, onChange callbacks are set', function () {
let mountNode;
let wrapper;
beforeEach(() => {
mountNode = createMountNode({ context: this });
});
afterEach(() => {
destroyMountNode({ wrapper, mountNode });
});
it('onChange trigged callback', function (done) {
wrapper = mount(
<Slider
value={200}
min={0}
max={400}
step={100}
onChange={(e, { value }) => {
expect(value).to.equal(300);
done();
}}
/>,
{ attachTo: mountNode }
);
const trigger = wrapper.find('input');
trigger.simulate('change', { target: { value: 300 } });
});
it('onInput trigged callback', function (done) {
wrapper = mount(
<Slider
value={200}
min={0}
max={400}
step={100}
onInput={(e, { value }) => {
expect(value).to.equal(300);
done();
}}
/>,
{ attachTo: mountNode }
);
const trigger = wrapper.find('input');
trigger.simulate('input', { target: { value: '300' } });
});
});
describe('Slider with Assistive Text Label', () => {
let component;
let slider;
let label;
let labelText;
beforeEach(() => {
component = getSlider({ assistiveText: { label: 'Assistive Label' } });
slider = findRenderedDOMComponentWithTag(component, 'input');
label = findRenderedDOMComponentWithClass(
component,
'slds-form-element__label'
);
labelText = findRenderedDOMComponentWithClass(
component,
'slds-slider-label__label'
);
});
afterEach(() => {
removeSlider();
});
it('renders label (assitive)', () => {
expect(labelText.textContent).to.equal('Assistive Label');
});
it('label has class "slds-assistive-text"', () => {
expect(label.className).to.include('slds-assistive-text');
});
it('has associated label for tag pointing to id of slider', () => {
const labelForTag = label.getAttribute('for');
const sliderId = slider.getAttribute('id');
expect(labelForTag).to.equal(sliderId);
});
});
describe('Disabled slider', () => {
let component;
let slider;
beforeEach(() => {
component = getSlider({ label: 'Slider Label', disabled: true });
slider = findRenderedDOMComponentWithTag(component, 'input');
});
afterEach(() => {
removeSlider();
});
it('slider has attribute "disabled"', () => {
expect(slider.getAttribute('disabled')).to.exist;
});
});
describe('Slider size', () => {
let component;
let container;
beforeEach(() => {
component = getSlider({
id: 'custom-id',
label: 'Slider Label',
size: 'medium',
});
container = findRenderedDOMComponentWithClass(component, 'slds-slider');
});
afterEach(() => {
removeSlider();
});
it('renders size class', () => {
expect(container.className).to.include('slds-size_medium');
});
});
describe('Multiple sliders', () => {
let component1;
let component2;
let slider1;
let slider2;
beforeEach(() => {
component1 = getSlider({ label: 'Slider One' });
component2 = getSecondSlider({ label: 'Slider Two' });
slider1 = findRenderedDOMComponentWithTag(component1, 'input');
slider2 = findRenderedDOMComponentWithTag(component2, 'input');
});
afterEach(() => {
removeSlider();
});
it('each slider has unique generated id', () => {
expect(slider1.getAttribute('id')).to.not.equal(
slider2.getAttribute('id')
);
});
});
describe('Required slider in Error State', () => {
let component;
let wrapper;
let error;
let slider;
beforeEach(() => {
component = getSlider({
label: 'Slider Label',
required: true,
errorText: 'Error Message',
});
wrapper = findRenderedDOMComponentWithClass(
component,
'slds-form-element'
);
error = findRenderedDOMComponentWithClass(
component,
'slds-form-element__help'
);
slider = findRenderedDOMComponentWithTag(component, 'input');
});
afterEach(() => {
removeSlider();
});
it('slider wrapper has class "slds-has-error"', () => {
expect(wrapper.className).to.include('slds-has-error');
});
it('renders error message', () => {
expect(error.textContent).to.equal('Error Message');
});
it('has associated aria-describedby pointing to id of error message', () => {
const sliderDescribedBy = slider.getAttribute('aria-describedby');
const errorId = error.getAttribute('id');
expect(sliderDescribedBy).to.equal(errorId);
});
});
describe('Vertical slider', () => {
let component;
let container;
beforeEach(() => {
component = getSlider({ label: 'Slider Label', vertical: true });
container = findRenderedDOMComponentWithClass(component, 'slds-slider');
});
afterEach(() => {
removeSlider();
});
it('slider has class "slds-slider_vertical"', () => {
expect(container.className).to.include('slds-slider_vertical');
});
});
});