Skip to content

Commit a1287bc

Browse files
Add cross browser testing via SauceLabs (#298)
* Add sauce labs testing info to karma This also removes Node versions 4, 5, 6 from Travis. The node version only matters for development not for use. I don't think it's a problem officially supporting only the latest node for development. * Make specs work under IE 11
1 parent ad9e115 commit a1287bc

File tree

6 files changed

+348
-96
lines changed

6 files changed

+348
-96
lines changed

.travis.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
language: node_js
22
node_js:
33
- "7"
4-
- "6"
5-
- "5"
6-
- "4"
74
before_script:
85
- export DISPLAY=:99.0
96
- sh -e /etc/init.d/xvfb start

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Accessible modal dialog component for React.JS
55
[![Code Climate](https://codeclimate.com/github/reactjs/react-modal/badges/gpa.svg)](https://codeclimate.com/github/reactjs/react-modal)
66
[![Coverage Status](https://coveralls.io/repos/github/reactjs/react-modal/badge.svg?branch=master)](https://coveralls.io/github/reactjs/react-modal?branch=master)
77

8+
[![Build Status](https://saucelabs.com/browser-matrix/cd-reactmodal.svg)](https://saucelabs.com/beta/builds/ad582339a83145e1a4d3e8b8a1809b6c)
9+
810
## Active Development
911
The modal is currently undergoing significant development for a v2 release. The `master` branch contains that development work.
1012
If you'd like to see the latest stable version please use the release tags (https://github.com/reactjs/react-modal/releases)

karma.conf.js

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,66 @@
1-
module.exports = function(config) {
1+
const webpackTestConfig = require('./webpack.test.config');
2+
3+
module.exports = function karmaConfig (config) {
4+
let browsers = [];
5+
const customLaunchers = {};
6+
7+
function createCustomLauncher (browser, version, platform) {
8+
return {
9+
base: 'SauceLabs',
10+
browserName: browser,
11+
version,
12+
platform
13+
};
14+
}
15+
16+
if (process.env.SAUCE_USERNAME || process.env.SAUCE_ACCESS_KEY) {
17+
const OPTIONS = [
18+
'SAUCE_CHROME',
19+
'SAUCE_FIREFOX',
20+
'SAUCE_SAFARI',
21+
'SAUCE_IE',
22+
'SAUCE_EDGE',
23+
];
24+
25+
let runAll = true;
26+
27+
OPTIONS.forEach((opt) => {
28+
if (process.env[opt]) {
29+
runAll = false;
30+
}
31+
});
32+
33+
// Chrome
34+
if (runAll || process.env.SAUCE_CHROME) {
35+
customLaunchers.SL_Chrome = createCustomLauncher('chrome');
36+
}
37+
38+
// Firefox
39+
if (runAll || process.env.SAUCE_FIREFOX) {
40+
customLaunchers.SL_Firefox = createCustomLauncher('firefox');
41+
}
42+
43+
// Safari
44+
if (runAll || process.env.SAUCE_SAFARI) {
45+
customLaunchers.SL_Safari10 = createCustomLauncher('safari', 10);
46+
customLaunchers.SL_Safari9 = createCustomLauncher('safari', 9);
47+
}
48+
49+
// IE
50+
if (runAll || process.env.SAUCE_IE) {
51+
customLaunchers.SL_IE11 = createCustomLauncher('internet explorer', 11, 'Windows 10');
52+
}
53+
54+
// Edge
55+
if (runAll || process.env.SAUCE_EDGE) {
56+
customLaunchers.SL_Edge = createCustomLauncher('microsoftedge', null, 'Windows 10');
57+
}
58+
59+
browsers = Object.keys(customLaunchers);
60+
} else {
61+
browsers = [(process.env.CONTINUOUS_INTEGRATION) ? 'Firefox' : 'Chrome'];
62+
}
63+
264
config.set({
365

466
basePath: '',
@@ -10,10 +72,10 @@ module.exports = function(config) {
1072
],
1173

1274
preprocessors: {
13-
'specs/spec_index.js': [ 'webpack', 'sourcemap' ]
75+
'specs/spec_index.js': ['webpack', 'sourcemap']
1476
},
1577

16-
webpack: require('./webpack.test.config'),
78+
webpack: webpackTestConfig,
1779

1880
webpackMiddleware: {
1981
stats: 'errors-only'
@@ -39,10 +101,25 @@ module.exports = function(config) {
39101

40102
autoWatch: true,
41103

42-
browsers: [ (process.env.CONTINUOUS_INTEGRATION) ? 'Firefox' : 'Chrome' ],
43-
44-
captureTimeout: 60000,
45-
46-
singleRun: (process.env.CONTINUOUS_INTEGRATION)
104+
browsers,
105+
customLaunchers,
106+
107+
// Increase timeouts to prevent the issue with disconnected tests (https://goo.gl/nstA69)
108+
captureTimeout: 4 * 60 * 1000,
109+
browserDisconnectTimeout: 10000,
110+
browserDisconnectTolerance: 1,
111+
browserNoActivityTimeout: 4 * 60 * 1000,
112+
113+
singleRun: (process.env.CONTINUOUS_INTEGRATION),
114+
115+
// SauceLabs config
116+
sauceLabs: {
117+
recordScreenshots: false,
118+
connectOptions: {
119+
port: 5757,
120+
logfile: 'sauce_connect.log'
121+
},
122+
public: 'public'
123+
}
47124
});
48125
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"karma-firefox-launcher": "1.0.0",
5656
"karma-mocha": "^1.3.0",
5757
"karma-mocha-reporter": "^2.2.1",
58+
"karma-sauce-launcher": "^1.1.0",
5859
"karma-sourcemap-loader": "^0.3.7",
5960
"karma-webpack": "^1.8.1",
6061
"mocha": "3.2.0",

specs/Modal.spec.js

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,30 @@ describe('Modal', () => {
270270
unmountModal();
271271
});
272272

273+
it('should close on Esc key event', () => {
274+
const requestCloseCallback = sinon.spy();
275+
const modal = renderModal({
276+
isOpen: true,
277+
shouldCloseOnOverlayClick: true,
278+
onRequestClose: requestCloseCallback
279+
});
280+
expect(modal.props.isOpen).toEqual(true);
281+
expect(() => {
282+
Simulate.keyDown(modal.portal.content, {
283+
// The keyCode is all that matters, so this works
284+
key: 'FakeKeyToTestLater',
285+
keyCode: 27,
286+
which: 27
287+
});
288+
}).toNotThrow();
289+
expect(requestCloseCallback.called).toBeTruthy();
290+
// Check if event is passed to onRequestClose callback.
291+
const event = requestCloseCallback.getCall(0).args[0];
292+
expect(event).toBeTruthy();
293+
expect(event.constructor).toBeTruthy();
294+
expect(event.key).toEqual('FakeKeyToTestLater');
295+
});
296+
273297
describe('should close on overlay click', () => {
274298
afterEach('Unmount modal', () => {
275299
unmountModal();
@@ -365,7 +389,15 @@ describe('Modal', () => {
365389
});
366390
const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
367391
window.addEventListener('click', () => { hasPropagated = true; });
368-
overlay[0].dispatchEvent(new MouseEvent('click', { bubbles: true }));
392+
// Work around for running the spec in IE 11
393+
let mouseEvent = null;
394+
try {
395+
mouseEvent = new MouseEvent('click', { bubbles: true });
396+
} catch (err) {
397+
mouseEvent = document.createEvent('MouseEvent');
398+
mouseEvent.initEvent('click', true, false);
399+
}
400+
overlay[0].dispatchEvent(mouseEvent);
369401
expect(hasPropagated).toBeTruthy();
370402
});
371403
});
@@ -380,34 +412,19 @@ describe('Modal', () => {
380412
expect(modal.props.isOpen).toEqual(true);
381413
const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
382414
expect(overlay.length).toEqual(1);
383-
Simulate.mouseDown(overlay[0]); // click the overlay
384-
Simulate.mouseUp(overlay[0]);
415+
// click the overlay
416+
Simulate.mouseDown(overlay[0]);
417+
Simulate.mouseUp(overlay[0], {
418+
// Used to test that this was the event received
419+
fakeData: 'ABC'
420+
});
385421
expect(requestCloseCallback.called).toBeTruthy();
386422
// Check if event is passed to onRequestClose callback.
387423
const event = requestCloseCallback.getCall(0).args[0];
388424
expect(event).toBeTruthy();
389425
expect(event.constructor).toBeTruthy();
390-
expect(event.constructor.name).toEqual('SyntheticEvent');
391-
});
392-
});
393-
394-
it('should close on Esc key event', () => {
395-
const requestCloseCallback = sinon.spy();
396-
const modal = renderModal({
397-
isOpen: true,
398-
shouldCloseOnOverlayClick: true,
399-
onRequestClose: requestCloseCallback
426+
expect(event.fakeData).toEqual('ABC');
400427
});
401-
expect(modal.props.isOpen).toEqual(true);
402-
expect(() => {
403-
Simulate.keyDown(modal.portal.content, { key: 'Esc', keyCode: 27, which: 27 });
404-
}).toNotThrow();
405-
expect(requestCloseCallback.called).toBeTruthy();
406-
// Check if event is passed to onRequestClose callback.
407-
const event = requestCloseCallback.getCall(0).args[0];
408-
expect(event).toBeTruthy();
409-
expect(event.constructor).toBeTruthy();
410-
expect(event.constructor.name).toEqual('SyntheticEvent');
411428
});
412429

413430
// it('adds --before-close for animations', function() {

0 commit comments

Comments
 (0)