accessibility-developer-tools
Version:
This is a library of accessibility-related testing and utility code.
614 lines (531 loc) • 20.5 kB
JavaScript
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.testing.eventsTest');
goog.setTestOnly('goog.testing.eventsTest');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.dom.InputType');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.events.KeyCodes');
goog.require('goog.math.Coordinate');
goog.require('goog.string');
goog.require('goog.style');
goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.events');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.recordFunction');
goog.require('goog.userAgent');
var firedEventTypes;
var firedEventCoordinates;
var firedScreenCoordinates;
var firedShiftKeys;
var firedKeyCodes;
var root;
var log;
var input;
var testButton;
var parentEl;
var childEl;
var coordinate = new goog.math.Coordinate(123, 456);
var stubs = new goog.testing.PropertyReplacer();
var eventCount;
function setUpPage() {
root = goog.dom.getElement('root');
log = goog.dom.getElement('log');
input = goog.dom.getElement('input');
testButton = goog.dom.getElement('testButton');
parentEl = goog.dom.getElement('parentEl');
childEl = goog.dom.getElement('childEl');
}
function setUp() {
stubs.reset();
goog.events.removeAll(root);
goog.events.removeAll(log);
goog.events.removeAll(input);
goog.events.removeAll(testButton);
goog.events.removeAll(parentEl);
goog.events.removeAll(childEl);
goog.dom.removeChildren(root);
firedEventTypes = [];
firedEventCoordinates = [];
firedScreenCoordinates = [];
firedShiftKeys = [];
firedKeyCodes = [];
for (var key in goog.events.EventType) {
goog.events.listen(root, goog.events.EventType[key], function(e) {
firedEventTypes.push(e.type);
var coord = new goog.math.Coordinate(e.clientX, e.clientY);
firedEventCoordinates.push(coord);
firedScreenCoordinates.push(
new goog.math.Coordinate(e.screenX, e.screenY));
firedShiftKeys.push(!!e.shiftKey);
firedKeyCodes.push(e.keyCode);
});
}
eventCount =
{parentBubble: 0, parentCapture: 0, childCapture: 0, childBubble: 0};
// Event listeners for the capture/bubble test.
goog.events.listen(parentEl, goog.events.EventType.CLICK, function(e) {
eventCount.parentCapture++;
assertEquals(parentEl, e.currentTarget);
assertEquals(childEl, e.target);
}, true);
goog.events.listen(childEl, goog.events.EventType.CLICK, function(e) {
eventCount.childCapture++;
assertEquals(childEl, e.currentTarget);
assertEquals(childEl, e.target);
}, true);
goog.events.listen(childEl, goog.events.EventType.CLICK, function(e) {
eventCount.childBubble++;
assertEquals(childEl, e.currentTarget);
assertEquals(childEl, e.target);
});
goog.events.listen(parentEl, goog.events.EventType.CLICK, function(e) {
eventCount.parentBubble++;
assertEquals(parentEl, e.currentTarget);
assertEquals(childEl, e.target);
});
}
function tearDownPage() {
for (var key in goog.events.EventType) {
var type = goog.events.EventType[key];
if (type == 'mousemove' || type == 'mouseout' || type == 'mouseover') {
continue;
}
goog.dom.appendChild(
input, goog.dom.createDom(
goog.dom.TagName.LABEL, null,
goog.dom.createDom(
goog.dom.TagName.INPUT,
{'id': type, 'type': goog.dom.InputType.CHECKBOX}),
type, goog.dom.createDom(goog.dom.TagName.BR)));
goog.events.listen(testButton, type, function(e) {
if (goog.dom.getElement(e.type).checked) {
e.preventDefault();
}
log.innerHTML +=
goog.string.subs('<br />%s (%s, %s)', e.type, e.clientX, e.clientY);
});
}
}
function testMouseEnter() {
goog.testing.events.fireMouseEnterEvent(root, null);
goog.testing.events.fireMouseEnterEvent(root, null, coordinate);
assertEventTypes(['mouseenter', 'mouseenter']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testMouseLeave() {
goog.testing.events.fireMouseLeaveEvent(root, null);
goog.testing.events.fireMouseLeaveEvent(root, null, coordinate);
assertEventTypes(['mouseleave', 'mouseleave']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testMouseOver() {
goog.testing.events.fireMouseOverEvent(root, null);
goog.testing.events.fireMouseOverEvent(root, null, coordinate);
assertEventTypes(['mouseover', 'mouseover']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testMouseOut() {
goog.testing.events.fireMouseOutEvent(root, null);
goog.testing.events.fireMouseOutEvent(root, null, coordinate);
assertEventTypes(['mouseout', 'mouseout']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testFocus() {
goog.testing.events.fireFocusEvent(root);
assertEventTypes(['focus']);
}
function testFocusIn() {
goog.testing.events.fireFocusInEvent(root);
assertEventTypes([goog.events.EventType.FOCUSIN]);
}
function testBlur() {
goog.testing.events.fireBlurEvent(root);
assertEventTypes(['blur']);
}
function testClickSequence() {
assertTrue(goog.testing.events.fireClickSequence(root));
assertEventTypes(['mousedown', 'mouseup', 'click']);
var rootPosition = goog.style.getClientPosition(root);
assertCoordinates([rootPosition, rootPosition, rootPosition]);
}
function testClickSequenceWithCoordinate() {
assertTrue(goog.testing.events.fireClickSequence(root, null, coordinate));
assertCoordinates([coordinate, coordinate, coordinate]);
assertArrayEquals([false, false, false], firedShiftKeys);
}
function testTouchStart() {
goog.testing.events.fireTouchStartEvent(root);
goog.testing.events.fireTouchStartEvent(root, coordinate);
assertEventTypes(['touchstart', 'touchstart']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testTouchMove() {
goog.testing.events.fireTouchMoveEvent(root);
goog.testing.events.fireTouchMoveEvent(root, coordinate, {touches: []});
assertEventTypes(['touchmove', 'touchmove']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testTouchEnd() {
goog.testing.events.fireTouchEndEvent(root);
goog.testing.events.fireTouchEndEvent(root, coordinate);
assertEventTypes(['touchend', 'touchend']);
assertCoordinates([goog.style.getClientPosition(root), coordinate]);
}
function testTouchSequence() {
assertTrue(goog.testing.events.fireTouchSequence(root));
assertEventTypes(['touchstart', 'touchend']);
var rootPosition = goog.style.getClientPosition(root);
assertCoordinates([rootPosition, rootPosition]);
}
function testTouchSequenceWithCoordinate() {
assertTrue(goog.testing.events.fireTouchSequence(root, coordinate));
assertCoordinates([coordinate, coordinate]);
}
function testClickSequenceWithEventProperty() {
assertTrue(
goog.testing.events.fireClickSequence(
root, null, undefined, {shiftKey: true}));
assertArrayEquals([true, true, true], firedShiftKeys);
}
function testClickSequenceCancellingMousedown() {
preventDefaultEventType('mousedown');
assertFalse(goog.testing.events.fireClickSequence(root));
assertEventTypes(['mousedown', 'mouseup', 'click']);
}
function testClickSequenceCancellingMousedownWithCoordinate() {
preventDefaultEventType('mousedown');
assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate));
assertCoordinates([coordinate, coordinate, coordinate]);
}
function testClickSequenceCancellingMouseup() {
preventDefaultEventType('mouseup');
assertFalse(goog.testing.events.fireClickSequence(root));
assertEventTypes(['mousedown', 'mouseup', 'click']);
}
function testClickSequenceCancellingMouseupWithCoordinate() {
preventDefaultEventType('mouseup');
assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate));
assertCoordinates([coordinate, coordinate, coordinate]);
}
function testClickSequenceCancellingClick() {
preventDefaultEventType('click');
assertFalse(goog.testing.events.fireClickSequence(root));
assertEventTypes(['mousedown', 'mouseup', 'click']);
}
function testClickSequenceCancellingClickWithCoordinate() {
preventDefaultEventType('click');
assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate));
assertCoordinates([coordinate, coordinate, coordinate]);
}
// For a double click, IE fires selectstart instead of the second mousedown,
// but we don't simulate selectstart. Also, IE doesn't fire the second click.
var DBLCLICK_SEQ =
(goog.userAgent.IE ?
['mousedown', 'mouseup', 'click', 'mouseup', 'dblclick'] :
[
'mousedown', 'mouseup', 'click', 'mousedown', 'mouseup', 'click',
'dblclick'
]);
var DBLCLICK_SEQ_COORDS = goog.array.repeat(coordinate, DBLCLICK_SEQ.length);
function testDoubleClickSequence() {
assertTrue(goog.testing.events.fireDoubleClickSequence(root));
assertEventTypes(DBLCLICK_SEQ);
}
function testDoubleClickSequenceWithCoordinate() {
assertTrue(goog.testing.events.fireDoubleClickSequence(root, coordinate));
assertCoordinates(DBLCLICK_SEQ_COORDS);
}
function testDoubleClickSequenceCancellingMousedown() {
preventDefaultEventType('mousedown');
assertFalse(goog.testing.events.fireDoubleClickSequence(root));
assertEventTypes(DBLCLICK_SEQ);
}
function testDoubleClickSequenceCancellingMousedownWithCoordinate() {
preventDefaultEventType('mousedown');
assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate));
assertCoordinates(DBLCLICK_SEQ_COORDS);
}
function testDoubleClickSequenceCancellingMouseup() {
preventDefaultEventType('mouseup');
assertFalse(goog.testing.events.fireDoubleClickSequence(root));
assertEventTypes(DBLCLICK_SEQ);
}
function testDoubleClickSequenceCancellingMouseupWithCoordinate() {
preventDefaultEventType('mouseup');
assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate));
assertCoordinates(DBLCLICK_SEQ_COORDS);
}
function testDoubleClickSequenceCancellingClick() {
preventDefaultEventType('click');
assertFalse(goog.testing.events.fireDoubleClickSequence(root));
assertEventTypes(DBLCLICK_SEQ);
}
function testDoubleClickSequenceCancellingClickWithCoordinate() {
preventDefaultEventType('click');
assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate));
assertCoordinates(DBLCLICK_SEQ_COORDS);
}
function testDoubleClickSequenceCancellingDoubleClick() {
preventDefaultEventType('dblclick');
assertFalse(goog.testing.events.fireDoubleClickSequence(root));
assertEventTypes(DBLCLICK_SEQ);
}
function testDoubleClickSequenceCancellingDoubleClickWithCoordinate() {
preventDefaultEventType('dblclick');
assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate));
assertCoordinates(DBLCLICK_SEQ_COORDS);
}
function testKeySequence() {
assertTrue(
goog.testing.events.fireKeySequence(root, goog.events.KeyCodes.ZERO));
assertEventTypes(['keydown', 'keypress', 'keyup']);
}
function testKeySequenceCancellingKeydown() {
preventDefaultEventType('keydown');
assertFalse(
goog.testing.events.fireKeySequence(root, goog.events.KeyCodes.ZERO));
assertEventTypes(['keydown', 'keyup']);
}
function testKeySequenceCancellingKeypress() {
preventDefaultEventType('keypress');
assertFalse(
goog.testing.events.fireKeySequence(root, goog.events.KeyCodes.ZERO));
assertEventTypes(['keydown', 'keypress', 'keyup']);
}
function testKeySequenceCancellingKeyup() {
preventDefaultEventType('keyup');
assertFalse(
goog.testing.events.fireKeySequence(root, goog.events.KeyCodes.ZERO));
assertEventTypes(['keydown', 'keypress', 'keyup']);
}
function testKeySequenceWithEscapeKey() {
assertTrue(
goog.testing.events.fireKeySequence(root, goog.events.KeyCodes.ESC));
if (goog.userAgent.EDGE ||
(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'))) {
assertEventTypes(['keydown', 'keyup']);
} else {
assertEventTypes(['keydown', 'keypress', 'keyup']);
}
}
function testKeySequenceForMacActionKeysNegative() {
stubs.set(goog.userAgent, 'GECKO', false);
goog.testing.events.fireKeySequence(
root, goog.events.KeyCodes.C, {'metaKey': true});
assertEventTypes(['keydown', 'keypress', 'keyup']);
}
function testKeySequenceForMacActionKeysPositive() {
stubs.set(goog.userAgent, 'GECKO', true);
stubs.set(goog.userAgent, 'MAC', true);
goog.testing.events.fireKeySequence(
root, goog.events.KeyCodes.C, {'metaKey': true});
assertEventTypes(['keypress', 'keyup']);
}
function testKeySequenceForOptionKeysOnMac() {
// Mac uses an option (or alt) key to type non-ASCII characters. This test
// verifies we can emulate key events sent when typing such non-ASCII
// characters.
stubs.set(goog.userAgent, 'WEBKIT', true);
stubs.set(goog.userAgent, 'MAC', true);
var optionKeyCodes = [
[ ], // option+'
[ ], // option+,
[ ], // option+-
[ ], // option+.
[ ], // option+/
[ ], // option+0
[ ], // option+1
[ ], // option+2
[ ], // option+3
[ ], // option+4
[ ], // option+5
[ ], // option+6
[ ], // option+7
[ ], // option+8
[ ], // option+9
[ ], // option+;
[ ], // option+=
[ ], // option+[
[
0xdc, 0x00ab
], // option+\
[ ], // option+]
[ ], // option+a
[ ], // option+b
[ ], // option+c
[ ], // option+d
[ ], // option+e
[ ], // option+f
[ ], // option+g
[ ], // option+h
[ ], // option+i
[ ], // option+j
[ ], // option+k
[ ], // option+l
[ ], // option+m
[ ], // option+n
[ ], // option+o
[ ], // option+p
[ ], // option+q
[ ], // option+r
[ ], // option+s
[ ], // option+t
[ ], // option+v
[ ], // option+w
[ ], // option+x
[ ], // option+y
[ ] // option+z
];
for (var i = 0; i < optionKeyCodes.length; ++i) {
firedEventTypes = [];
firedKeyCodes = [];
var keyCode = optionKeyCodes[i][0];
var keyPressKeyCode = optionKeyCodes[i][1];
goog.testing.events.fireNonAsciiKeySequence(
root, keyCode, keyPressKeyCode, {'altKey': true});
assertEventTypes(['keydown', 'keypress', 'keyup']);
assertArrayEquals([keyCode, keyPressKeyCode, keyCode], firedKeyCodes);
}
}
var CONTEXTMENU_SEQ = goog.userAgent.WINDOWS ?
['mousedown', 'mouseup', 'contextmenu'] :
goog.userAgent.GECKO ? ['mousedown', 'contextmenu', 'mouseup'] :
goog.userAgent.WEBKIT && goog.userAgent.MAC ?
['mousedown', 'contextmenu', 'mouseup', 'click'] :
['mousedown', 'contextmenu', 'mouseup'];
function testContextMenuSequence() {
assertTrue(goog.testing.events.fireContextMenuSequence(root));
assertEventTypes(CONTEXTMENU_SEQ);
}
function testContextMenuSequenceWithCoordinate() {
assertTrue(goog.testing.events.fireContextMenuSequence(root, coordinate));
assertEventTypes(CONTEXTMENU_SEQ);
assertCoordinates(goog.array.repeat(coordinate, CONTEXTMENU_SEQ.length));
}
function testContextMenuSequenceCancellingMousedown() {
preventDefaultEventType('mousedown');
assertFalse(goog.testing.events.fireContextMenuSequence(root));
assertEventTypes(CONTEXTMENU_SEQ);
}
function testContextMenuSequenceCancellingMouseup() {
preventDefaultEventType('mouseup');
assertFalse(goog.testing.events.fireContextMenuSequence(root));
assertEventTypes(CONTEXTMENU_SEQ);
}
function testContextMenuSequenceCancellingContextMenu() {
preventDefaultEventType('contextmenu');
assertFalse(goog.testing.events.fireContextMenuSequence(root));
assertEventTypes(CONTEXTMENU_SEQ);
}
function testContextMenuSequenceFakeMacWebkit() {
stubs.set(goog.userAgent, 'WINDOWS', false);
stubs.set(goog.userAgent, 'MAC', true);
stubs.set(goog.userAgent, 'WEBKIT', true);
assertTrue(goog.testing.events.fireContextMenuSequence(root));
assertEventTypes(['mousedown', 'contextmenu', 'mouseup', 'click']);
}
function testCaptureBubble_simple() {
assertTrue(goog.testing.events.fireClickEvent(childEl));
assertObjectEquals(
{parentCapture: 1, childCapture: 1, childBubble: 1, parentBubble: 1},
eventCount);
}
function testCaptureBubble_preventDefault() {
goog.events.listen(childEl, goog.events.EventType.CLICK, function(e) {
e.preventDefault();
});
assertFalse(goog.testing.events.fireClickEvent(childEl));
assertObjectEquals(
{parentCapture: 1, childCapture: 1, childBubble: 1, parentBubble: 1},
eventCount);
}
function testCaptureBubble_stopPropagationParentCapture() {
goog.events.listen(parentEl, goog.events.EventType.CLICK, function(e) {
e.stopPropagation();
}, true /* capture */);
assertTrue(goog.testing.events.fireClickEvent(childEl));
assertObjectEquals(
{parentCapture: 1, childCapture: 0, childBubble: 0, parentBubble: 0},
eventCount);
}
function testCaptureBubble_stopPropagationChildCapture() {
goog.events.listen(childEl, goog.events.EventType.CLICK, function(e) {
e.stopPropagation();
}, true /* capture */);
assertTrue(goog.testing.events.fireClickEvent(childEl));
assertObjectEquals(
{parentCapture: 1, childCapture: 1, childBubble: 0, parentBubble: 0},
eventCount);
}
function testCaptureBubble_stopPropagationChildBubble() {
goog.events.listen(childEl, goog.events.EventType.CLICK, function(e) {
e.stopPropagation();
});
assertTrue(goog.testing.events.fireClickEvent(childEl));
assertObjectEquals(
{parentCapture: 1, childCapture: 1, childBubble: 1, parentBubble: 0},
eventCount);
}
function testCaptureBubble_stopPropagationParentBubble() {
goog.events.listen(parentEl, goog.events.EventType.CLICK, function(e) {
e.stopPropagation();
});
assertTrue(goog.testing.events.fireClickEvent(childEl));
assertObjectEquals(
{parentCapture: 1, childCapture: 1, childBubble: 1, parentBubble: 1},
eventCount);
}
function testMixinListenable() {
var obj = {};
obj.doFoo = goog.testing.recordFunction();
goog.testing.events.mixinListenable(obj);
obj.doFoo();
assertEquals(1, obj.doFoo.getCallCount());
var handler = goog.testing.recordFunction();
goog.events.listen(obj, 'test', handler);
obj.dispatchEvent('test');
assertEquals(1, handler.getCallCount());
assertEquals(obj, handler.getLastCall().getArgument(0).target);
goog.events.unlisten(obj, 'test', handler);
obj.dispatchEvent('test');
assertEquals(1, handler.getCallCount());
goog.events.listen(obj, 'test', handler);
obj.dispose();
obj.dispatchEvent('test');
assertEquals(1, handler.getCallCount());
}
/**
* Assert that the list of events given was fired, in that order.
*/
function assertEventTypes(list) {
assertArrayEquals(list, firedEventTypes);
}
/**
* Assert that the list of event coordinates given was caught, in that order.
*/
function assertCoordinates(list) {
assertArrayEquals(list, firedEventCoordinates);
assertArrayEquals(list, firedScreenCoordinates);
}
/** Prevent default the event of the given type on the root element. */
function preventDefaultEventType(type) {
goog.events.listen(root, type, preventDefault);
}
function preventDefault(e) {
e.preventDefault();
}