I'm building a test using Mocha
and Chai
for my ReactJS
components. Basically I have this structure for my components:
- ScheduleApp
- ScheduleForm
Under my ScheduleForm
I'm using this jQuery
plugin bootstrap-timepicker. I'm using another plugin called bootstrap-datepicker
and it is running just fine notice the componentDidMount
on my ScheduleForm
.
// ScheduleForm.jsx Component
import React, {PropTypes} from 'react';
import jQuery from 'jquery';
import datepicker from 'bootstrap-datepicker';
import timepicker from 'bootstrap-timepicker';
export default class ScheduleForm extends React.Component {
handleChange() {
// Some code to handle the onChange event
}
componentDidMount() {
jQuery(this.refs.startDate).datepicker({
autoclose: true,
format: 'yyyy-mm-dd'
}).on("changeDate", function(e) {
this.onStartDateChange(e);
}.bind(this));
jQuery(this.refs.startTime).timepicker({
defaultTime: '8:00 AM',
snapToStep: false
}).on('changeTime.timepicker', function(e) {
this.onStartTimeChange(e);
}.bind(this));
jQuery(this.refs.endTime).timepicker({
defaultTime: '2:00 PM',
snapToStep: false
}).on('changeTime.timepicker', function(e) {
this.onEndTimeChange(e);
}.bind(this));
}
render() {
<div>
<div className="form-group">
<label>Start Date</label>
<input className="form-control" type="text" onChange={this.handleChange} ref="startDate" />
</div>
<div className="form-group">
<label>Start Time</label>
<input className="form-control" type="text" onChange={this.handleChange} ref="startTime" />
</div>
<div className="form-group">
<label>End Time</label>
<input className="form-control" type="text" onChange={this.handleChange} ref="endTime" />
</div>
</div>
}
}
Here's my parent component:
// ScheduleApp.jsx Component
import React from 'react';
import ScheduleForm from './schedule-form.jsx';
export default class ScheduleApp extends React.Component {
constructor() {
super();
this.state = {
startTime: '8:00 AM',
endTime: '2:00 PM'
}
}
handleStartTimeChange(startTime) {
this.setState({
startTime: startTime
});
}
handleEndTimeChange(endTime) {
this.setState({
endTime: endTime
});
}
render() {
return <div>
<ScheduleForm
handleStartTimeChange={this.handleStartTimeChange.bind(this)}
handleEndTimeChange={this.handleEndTimeChange.bind(this)}
startTime={this.state.startTime}
endTime={this.state.endTime} />
</div>
}
}
Now here is my test spec for this component:
// test.spec.js
import React from 'react';
import { mount, shallow } from 'enzyme';
import {expect} from 'chai';
import ScheduleApp from '../src/components/schedule-app.jsx';
import ScheduleForm from '../src/components/schedule-form.jsx';
describe('<ScheduleApp/>', function() {
it('contains 1 <ScheduleForm/> component', function() {
const wrapper = mount(<ScheduleApp />);
expect(wrapper.find(ScheduleForm)).to.have.length(1);
});
});
Here is my jsdom
file:
if (!global.document) {
try {
const jsdom = require('jsdom').jsdom; // could throw
const exposedProperties = ['window', 'navigator', 'document'];
global.document = jsdom('');
global.window = document.defaultView;
Object.keys(document.defaultView).forEach((property) => {
if (typeof global[property] === 'undefined') {
exposedProperties.push(property);
global[property] = document.defaultView[property];
}
});
global.navigator = {
userAgent: 'node.js',
};
} catch (e) {
// jsdom is not supported...
}
}
After running my test I get this error TypeError: (0 , _jquery2.default)(...).timepicker is not a function
. I can load this field fine without problem on my browser but with my test spec it throws out an error for the timepicker
plugin and it's running ok with the datepicker
.
Also if it's worth noting, bootstrap-datepicker
and bootstrap-timepicker
use the same jQuery and only bootstrap-timepicker
requires window
and document
in its function parameter, like so:
(function($, window, document) {
}())
Also, is there a way to find out where the jQuery
plugin is failing? This would have been really easy if I it shows it on the logs.
Any help would be much appreciated.