| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../../resources/js-test.js"></script> |
| </head> |
| <body> |
| <p id="description"></p> |
| <p> |
| Please run this with DumpRenderTree. |
| </p> |
| Test following keys: |
| <ul> |
| <li>Digit keys</li> |
| <li>Left/Right - Move focus field inside element</li> |
| <li>Up/Down - Increment/decrement value of focus field</li> |
| <li>Tab - Move focus field</li> |
| <li>Backspace - Make value empty</li> |
| </ul> |
| <input id="before"> |
| <input id="input" type="time"> |
| <input id="another"> |
| <div id="console"></div> |
| <script> |
| description("Multiple fields UI of time input type with keyboard events"); |
| if (window.internals) |
| internals.settings.setLangAttributeAwareFormControlUIEnabled(true); |
| var input = document.getElementById("input"); |
| |
| function shadowPseudoIdOfFocusedSubField(host) |
| { |
| return internals.shadowPseudoId(internals.youngestShadowRoot(host).activeElement); |
| } |
| |
| function keyDown(key, modifiers) |
| { |
| if (!window.eventSender) |
| return; |
| eventSender.keyDown(key, modifiers); |
| } |
| |
| function beginTest(title, value) |
| { |
| debug("== " + title + " =="); |
| input.value = value; |
| input.blur(); |
| input.focus(); |
| } |
| |
| var eventsCounter = {}; |
| function countEvents(event) |
| { |
| if (eventsCounter[event.type] === undefined) |
| eventsCounter[event.type] = 0; |
| eventsCounter[event.type]++; |
| } |
| input.addEventListener('input', countEvents, false); |
| input.addEventListener('change', countEvents, false); |
| |
| beginTest('Digit keys'); |
| keyDown('7'); // -> 07:[--] -- |
| keyDown('5'); // -> 07:[05] -- |
| input.className = "CLASS"; |
| keyDown('6'); // -> 07:56 [--] |
| shouldBeUndefined('eventsCounter.input'); |
| shouldBeUndefined('eventsCounter.change'); |
| keyDown('A'); // -> 07:56 [AM] |
| shouldBeEqualToString('input.value', '07:56'); |
| shouldBe('eventsCounter.input', '1'); |
| shouldBe('eventsCounter.change', '1'); |
| |
| beginTest('Digit keys starting with zero'); |
| keyDown('0'); // -> [00]:-- -- |
| keyDown('2'); // -> 02:[--] -- |
| keyDown('0'); // -> 02:[00] -- |
| keyDown('3'); // -> 02:03 [--] |
| keyDown('P'); // -> 02:03 [PM] |
| shouldBeEqualToString('input.value', '14:03'); |
| |
| beginTest('Digit keys and backspace key','01:01'); |
| keyDown('0'); // -> [00]:-- -- |
| keyDown('Backspace'); // -> [--]:-- -- |
| keyDown('5'); // -> 05:[--] -- |
| keyDown('6'); // -> 05:06 [--] |
| keyDown('Backspace'); // -> 05:06 [--] |
| keyDown('P'); // -> 05:06 [PM] |
| shouldBeEqualToString('input.value', '17:06'); |
| |
| beginTest('Left/Right keys', '01:24'); |
| keyDown('ArrowRight'); |
| keyDown('5'); |
| keyDown('ArrowLeft'); |
| keyDown('6'); |
| shouldBeEqualToString('input.value', '06:05'); |
| keyDown('ArrowLeft'); |
| keyDown('ArrowLeft'); |
| keyDown('ArrowLeft'); |
| shouldBeEqualToString('document.activeElement.id', 'input'); |
| |
| beginTest('Up/Down keys', '04:56'); |
| keyDown('ArrowUp'); |
| shouldBeEqualToString('input.value', '05:56'); |
| keyDown('ArrowDown'); |
| keyDown('ArrowDown'); |
| shouldBeEqualToString('input.value', '03:56'); |
| |
| beginTest('Up/Down keys on empty value', ''); |
| eventsCounter = {}; |
| keyDown('ArrowUp'); // -> [01]:-- -- |
| keyDown('ArrowUp'); // -> [02]:-- -- |
| keyDown('ArrowRight'); // -> 02:[--] -- |
| keyDown('ArrowDown'); // -> 02:[59] -- |
| keyDown('ArrowDown'); // -> 02:[58] -- |
| keyDown('ArrowRight'); // -> 02:58 [--] |
| shouldBeUndefined('eventsCounter.input'); |
| shouldBeUndefined('eventsCounter.change'); |
| keyDown('ArrowDown'); // -> 02:58 [PM] |
| shouldBeEqualToString('input.value', '14:58'); |
| shouldBe('eventsCounter.input', '1'); |
| shouldBe('eventsCounter.change', '1'); |
| |
| beginTest('Tab key', '03:00'); |
| keyDown('\t'); |
| keyDown('5'); |
| shouldBeEqualToString('input.value', '03:05'); |
| keyDown('\t', ['shiftKey']); |
| keyDown('7'); |
| shouldBeEqualToString('input.value', '07:05'); |
| keyDown('\t'); |
| keyDown('\t'); |
| shouldBeEqualToString('document.activeElement.id', 'another'); |
| |
| beginTest('Tab navigation should skip disabled inputs', ''); |
| before.focus(); |
| input.disabled = true; |
| keyDown('\t'); |
| shouldBeEqualToString('document.activeElement.id', 'another'); |
| input.disabled = false; |
| |
| beginTest('Tab navigation should not skip readonly inputs, but editing operations should be ignored.', ''); |
| before.focus(); |
| input.value = '01:01'; |
| input.readOnly = true; |
| keyDown('\t'); |
| shouldBeEqualToString('document.activeElement.id', 'input'); |
| shouldBeEqualToString('shadowPseudoIdOfFocusedSubField(input)', '-webkit-datetime-edit-hour-field'); |
| shouldBeEqualToString('keyDown("ArrowUp"); input.value', '01:01'); |
| shouldBeEqualToString('keyDown("ArrowDown"); input.value', '01:01'); |
| keyDown('ArrowRight'); |
| shouldBeEqualToString('shadowPseudoIdOfFocusedSubField(input)', '-webkit-datetime-edit-minute-field'); |
| shouldBeEqualToString('keyDown("3"); input.value', '01:01'); |
| keyDown('\t'); |
| shouldBeEqualToString('shadowPseudoIdOfFocusedSubField(input)', '-webkit-datetime-edit-ampm-field'); |
| keyDown('ArrowLeft'); |
| shouldBeEqualToString('shadowPseudoIdOfFocusedSubField(input)', '-webkit-datetime-edit-minute-field'); |
| keyDown('\t'); |
| keyDown('\t'); |
| shouldBeEqualToString('document.activeElement.id', 'another'); |
| input.readOnly = false; |
| |
| beginTest('Shfit+Tab key', '03:00'); |
| another.focus(); |
| keyDown('\t', ['shiftKey']); |
| keyDown('P'); |
| shouldBeEqualToString('input.value', '15:00'); |
| keyDown('\t', ['shiftKey']); |
| keyDown('3'); |
| shouldBeEqualToString('input.value', '15:03'); |
| keyDown('\t', ['shiftKey']); |
| keyDown('\t', ['shiftKey']); |
| shouldBeEqualToString('document.activeElement.id', 'before'); |
| |
| beginTest('Up key on maximum value', '12:59:59.999'); |
| keyDown('ArrowUp'); |
| keyDown('\t'); |
| keyDown('ArrowUp'); |
| keyDown('\t'); |
| keyDown('ArrowUp'); |
| keyDown('\t'); |
| keyDown('ArrowUp'); |
| shouldBeEqualToString('input.value', '13:00'); |
| |
| beginTest('Down key on minimum value', '01:00'); |
| input.step = 0.001; |
| keyDown('ArrowDown'); |
| keyDown('\t'); |
| keyDown('ArrowDown'); |
| keyDown('\t'); |
| keyDown('ArrowDown'); |
| keyDown('\t'); |
| keyDown('ArrowDown'); |
| shouldBeEqualToString('input.value', '00:59:59.999'); |
| input.step = 60; |
| |
| beginTest('Backspace key', '12:34'); |
| keyDown("Backspace"); |
| shouldBeEqualToString('input.value', ''); |
| |
| beginTest('Delete key', '12:34'); |
| keyDown("Delete"); |
| shouldBeEqualToString('input.value', ''); |
| |
| beginTest('Typeahead', '12:34:56'); |
| keyDown('ArrowRight'); |
| keyDown('1'); |
| shouldBeEqualToString('input.value', '12:01:56'); |
| keyDown('ArrowRight'); |
| keyDown('ArrowLeft'); |
| keyDown('2'); |
| shouldBeEqualToString('input.value', '12:02:56'); |
| |
| input.setAttribute("lang", "he-il"); |
| beginTest('RTL focus navigation', '04:56'); |
| debug('The tests in this block fail on platforms without the lang-attribute-aware-form-control-UI feature.'); |
| keyDown('1'); // -> [01]:56 |
| shouldBeEqualToString('input.value', '01:56'); |
| keyDown('\t'); // -> 01:[56] |
| keyDown('2'); // -> 01:[02] |
| shouldBeEqualToString('input.value', '01:02'); |
| keyDown('\t', ['shiftKey']); // -> [01]:02 |
| keyDown('3'); // -> [03]:02 |
| shouldBeEqualToString('input.value', '03:02'); |
| input.removeAttribute("lang"); |
| </script> |
| </body> |
| </html> |