From 39284b8448efb8abe44d8dfb44e351d364889cf7 Mon Sep 17 00:00:00 2001 From: jquense Date: Thu, 14 Jan 2016 10:05:09 -0500 Subject: [PATCH] [fixed] preventDefault for Enter keys --- karma.conf.js | 23 ++++++- package.json | 2 +- src/Combobox.jsx | 14 ++-- src/DropdownList.jsx | 6 ++ src/localizers/simple-number.js | 4 +- test/combobox.browser.jsx | 109 +++++++++++++++++++++++--------- test/index.js | 1 + 7 files changed, 116 insertions(+), 43 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index ccc6bb7fe..8a473c86e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,5 +1,13 @@ 'use strict'; + + +if (process.env.TRAVIS) { + configuration.browsers = ['Chrome_travis_ci']; +} + +config.set(configuration); + module.exports = function (config) { config.set({ @@ -17,12 +25,14 @@ module.exports = function (config) { port: 9876, colors: true, - autoWatch: process.env.TRAVIS_CI ? false : true, - singleRun: process.env.TRAVIS_CI ? true : false, + autoWatch: process.env.TRAVIS ? false : true, + singleRun: process.env.TRAVIS ? true : false, logLevel: config.LOG_INFO, - browsers: ['Chrome'], + browsers: process.env.TRAVIS + ? ['ChromeTravis'] + : ['Chrome'], preprocessors: { 'test/index.js': ['webpack', 'sourcemap'] @@ -31,6 +41,13 @@ module.exports = function (config) { webpack: require('./build/test.config'), webpackServer: { noInfo: true + }, + + customLaunchers: { + ChromeTravis: { + base: 'Chrome', + flags: ['--no-sandbox'] + } } }); }; diff --git a/package.json b/package.json index 01b4d81f0..4af690f65 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "scriptjs": "^2.5.8", "sinon": "^1.17.2", "style-loader": "^0.12.3", - "teaspoon": "^5.0.1", + "teaspoon": "^6.0.0", "url-loader": "^0.5.5", "webpack": "^1.10.5", "webpack-dev-server": "^1.10.1", diff --git a/src/Combobox.jsx b/src/Combobox.jsx index 55abbc2a6..6b3fe9007 100644 --- a/src/Combobox.jsx +++ b/src/Combobox.jsx @@ -318,22 +318,22 @@ var ComboBox = React.createClass({ if (e.defaultPrevented) return - if ( key === 'End' ) + if (key === 'End') if ( isOpen ) this.setState({ focusedItem: list.last() }) else select(list.last(), true) - else if ( key === 'Home' ) - if ( isOpen ) this.setState({ focusedItem: list.first() }) + else if (key === 'Home') + if (isOpen) this.setState({ focusedItem: list.first() }) else select(list.first(), true) - else if ( key === 'Escape' && isOpen ) + else if (key === 'Escape' && isOpen) this.close() - else if ( key === 'Enter' && isOpen ) { + else if (key === 'Enter' && isOpen) { + e.preventDefault(); select(this.state.focusedItem, true) } - - else if ( key === 'ArrowDown' ) { + else if (key === 'ArrowDown') { if ( alt ) this.open() else { diff --git a/src/DropdownList.jsx b/src/DropdownList.jsx index 8795b7379..2c7217357 100644 --- a/src/DropdownList.jsx +++ b/src/DropdownList.jsx @@ -292,11 +292,17 @@ var DropdownList = React.createClass({ e.preventDefault() } else if (key === 'Escape' && isOpen) { + e.preventDefault(); closeWithFocus() } else if ((key === 'Enter' || (key === ' ' && !filtering)) && isOpen ) { + e.preventDefault(); change(this.state.focusedItem, true) } + else if (key === ' ' && !filtering && !isOpen) { + e.preventDefault(); + this.open() + } else if (key === 'ArrowDown') { if (alt) this.open() else if (isOpen) this.setState({ focusedItem: list.next(focusedItem) }) diff --git a/src/localizers/simple-number.js b/src/localizers/simple-number.js index ea82afe1a..1ad69021d 100644 --- a/src/localizers/simple-number.js +++ b/src/localizers/simple-number.js @@ -12,9 +12,9 @@ export default function simpleNumber(options) { let localizer = { formats: { - default: `-#${grouping}##0${decimal}`, + default: `-#${grouping}##0${decimal}` }, - + // TODO major bump consistent ordering parse(value, culture, format) { if (format) { diff --git a/test/combobox.browser.jsx b/test/combobox.browser.jsx index 6efe886eb..95853b4f2 100644 --- a/test/combobox.browser.jsx +++ b/test/combobox.browser.jsx @@ -6,14 +6,16 @@ import { findDOMNode } from 'react-dom'; var React = require('react/addons'); var ComboBox = require('../src/Combobox.jsx'); +var Popup = require('../src/Popup.jsx') +var $ = require('teaspoon'); var TestUtils = React.addons.TestUtils , render = TestUtils.renderIntoDocument , findTag = TestUtils.findRenderedDOMComponentWithTag , findClass = TestUtils.findRenderedDOMComponentWithClass - , findType = TestUtils.findRenderedComponentWithType , trigger = TestUtils.Simulate; + describe('ComboBox', function(){ var dataList = [ { label: 'jimmy', id: 0 }, @@ -22,56 +24,89 @@ describe('ComboBox', function(){ ]; it('should set initial values', function(){ - var dropdown = render( - {}} />); - - expect( findClass(dropdown, 'rw-input').value).to.be('hello'); + $({}} />) + .render() + .find('input.rw-input') + .tap(c => + expect(c.dom().value).to.be('hello')); }) it('should respect textField and valueFields', function(){ - var comboBox = render( i.label } valueField='id' />); - - expect(findClass(comboBox, 'rw-input').value) - .to.be('jimmy'); + $( + i.label } + valueField='id' + /> + ).render() + .find('input.rw-input') + .tap(c => + expect(c.dom().value).to.be('jimmy')); }) it('should pass NAME down', function(){ - var comboBox = render() - , input = findClass(comboBox, 'rw-input'); - - expect(input.hasAttribute('name')).to.be(true) + $( + + ).render() + .find(':dom.rw-input') + .tap(c => + expect(c.dom().hasAttribute('name')).to.be(true)); }) it('should start closed', function(done){ - var comboBox = render() - , input = findClass(comboBox, 'rw-input') - , popup = findType(comboBox, require('../src/Popup.jsx')); + var inst = $( + + ).render() - expect(comboBox._values.open).to.not.be(true) + let input = inst.find('.rw-input:dom').dom() + , popup = inst.find(Popup).dom(); - expect(findDOMNode(comboBox).className).to.not.match(/\brw-open\b/) + expect(inst.unwrap()._values.open).to.not.be(true) + + expect(inst.dom().className).to.not.match(/\brw-open\b/) expect(input.getAttribute('aria-expanded')).to.be('false') setTimeout(function(){ - expect(findDOMNode(popup).style.display).to.be('none') + expect(popup.style.display).to.be('none') done() }, 0) }) it('should open when clicked', function(done){ - var comboBox = render() - , input = findClass(comboBox, 'rw-input') - , popup = findType(comboBox, require('../src/Popup.jsx')) + var inst = $( + + ).render() - trigger.click(findClass(comboBox, 'rw-select')) + let input = inst.find('.rw-input:dom').dom() + , popup = inst.find(Popup).unwrap(); + + expect(inst.unwrap()._values.open).to.not.be(true) + expect(inst.dom().className).to.not.match(/\brw-open\b/) + + inst.single('.rw-select:dom') + .trigger('click') + + expect(input.getAttribute('aria-expanded')).to.be('true') + expect(popup.props.open).to.be(true) + done() - setTimeout(function() { - expect(comboBox._values.open).to.be(true) - expect(findDOMNode(comboBox).className).to.match(/\brw-open\b/) - expect(input.getAttribute('aria-expanded')).to.be('true') - expect(popup.props.open).to.be(true) - done() - }, 10) }) it('should trigger focus/blur events', function(done){ @@ -137,6 +172,20 @@ describe('ComboBox', function(){ }, 0) }) + it('should not trigger form submission', function(){ + let spy; + let select = $( +
{ throw new Error('should not submit!') }}> + {}} onKeyDown={spy = sinon.spy()}/> + + ).render(); + + select.find('input') + .trigger('keyDown', { key: 'Enter' }) + + expect(spy.calledOnce).to.equal(true); + }) + it('should set id on list', function(){ var comboBox = render() , list = findTag(comboBox, 'ul'); diff --git a/test/index.js b/test/index.js index c16528b76..c6ac0c4e9 100644 --- a/test/index.js +++ b/test/index.js @@ -8,6 +8,7 @@ require('../src/localizers/globalize')(globalize) //disable this particular optimization sinon.stub(widgetHelpers, 'isFirstFocusedRender', ()=> true) + var testsContext = require.context('../test', true, /\.browser\.(js$|jsx$)/); if ( typeof __REACT_VERSION__ !== 'undefined' ) {