diff --git a/src/utils.js b/src/utils.js index feed7653..bd95227c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -28,3 +28,33 @@ export function getAlignPopupClassName(builtinPlacements, prefixCls, align, isAl export function saveRef(name, component) { this[name] = component; } + +// TestUtils.Simulate.keyDown doesn't work on PhantomJS +// https://github.com/ariya/phantomjs/issues/11289#issuecomment-278147426 +export function keyboardEvent(eventType, init) { + try { + return new KeyboardEvent(eventType, init); + } catch (error) { + const modKeys = [ + init.ctrlKey ? 'Control' : '', + init.shiftKey ? 'Shift' : '', + init.altKey ? 'Alt' : '', + init.altGrKey ? 'AltGr' : '', + init.metaKey ? 'Meta' : '', + ].join(' '); + const keyEvent = document.createEvent('KeyboardEvent'); + keyEvent.initKeyboardEvent( + eventType, // type + false, // canBubble + false, // cancelable + window, // view + init.char || '', // char + init.keyCode || 0, // key + 0, // location + modKeys, + init.repeat || false, + ); + keyEvent.key = init.key; + return keyEvent; + } +} diff --git a/tests/basic.spec.js b/tests/basic.spec.js index 955d9d65..fd60b336 100644 --- a/tests/basic.spec.js +++ b/tests/basic.spec.js @@ -11,7 +11,7 @@ import '../assets/index.less'; import Trigger from '../index'; import './basic.less'; import async from 'async'; -import { saveRef } from '../src/utils'; +import { saveRef, keyboardEvent } from '../src/utils'; const Simulate = TestUtils.Simulate; const scryRenderedDOMComponentsWithClass = TestUtils.scryRenderedDOMComponentsWithClass; @@ -895,4 +895,64 @@ describe('rc-trigger', function main() { expect(domNode.className).to.be('target className-in-trigger-1 className-in-trigger-2'); }); }); + + describe('keyboard', () => { + let visible; + const onChange = (value) => { + visible = value; + }; + + it('esc key works if keyboard=true ', () => { + const trigger = ReactDOM.render( + } + action={['click']} + popupAlign={placementAlignMap.right} + onPopupVisibleChange={onChange} + > +
click
+
, + div + ); + const domNode = ReactDOM.findDOMNode(trigger); + + // click trigger and show popup + Simulate.click(domNode); + expect(visible).to.be(true); + + // click escape + const event = keyboardEvent('keydown', { key: 'Escape', keyCode: 27 }); + document.dispatchEvent(event); + + // assert that popup hidden + expect(visible).to.be(false); + }); + + it('esc key doesn\'t work if keyboard=false ', () => { + const trigger = ReactDOM.render( + } + action={['click']} + popupAlign={placementAlignMap.right} + onPopupVisibleChange={onChange} + > +
click
+
, + div + ); + const domNode = ReactDOM.findDOMNode(trigger); + + // click trigger and show popup + Simulate.click(domNode); + expect(visible).to.be(true); + + // click escape + const event = keyboardEvent('keydown', { key: 'Escape', keyCode: 27 }); + document.dispatchEvent(event); + + // assert that popup still visible + expect(visible).to.be(true); + }); + }); });