| <!DOCTYPE html> |
| <title>Media Controls: overflow menu keyboard navigation</title> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../media-controls.js"></script> |
| <body> |
| </body> |
| <script> |
| |
| function testNavigation(root, elements, next, previous) { |
| // Internal copy of the array. They are otherwise passed by reference. |
| const list = elements.slice(0); |
| |
| assert_equals(root.activeElement, list[0]); |
| |
| list.forEach(element => { |
| if (element == list[0]) |
| return; |
| |
| next(); |
| |
| assert_equals(root.activeElement, element); |
| assert_equals( |
| window.getComputedStyle(element).getPropertyValue('background-color'), |
| 'rgb(224, 224, 224)'); |
| }); |
| |
| // Next action after reaching the end is a no-op. |
| next(); |
| assert_equals(root.activeElement, list.pop()); |
| // pop() will remove the last element which will allow the next iteration to |
| // start from n-1. |
| |
| list.reverse().forEach(element => { |
| previous(); |
| |
| assert_equals(root.activeElement, element); |
| assert_equals( |
| window.getComputedStyle(element).getPropertyValue('background-color'), |
| 'rgb(224, 224, 224)'); |
| }); |
| |
| // Previous element after reaching the beginning is a no-op. |
| previous(); |
| assert_equals(root.activeElement, list[list.length - 1]); |
| } |
| |
| async_test(t => { |
| assert_true('internals' in window); |
| assert_true('eventSender' in window); |
| |
| const video = document.createElement('video'); |
| video.controls = true; |
| video.src = '../content/test.ogv'; |
| internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true); |
| |
| [ '../track/captions-webvtt/captions-fast.vtt', |
| '../track/captions-webvtt/captions-rtl.vtt' ].forEach(source => { |
| const track = document.createElement('track'); |
| track.src = source; |
| track.kind = 'captions'; |
| video.appendChild(track); |
| }); |
| |
| assert_equals(video.textTracks.length, 2); |
| |
| document.body.appendChild(video); |
| |
| video.addEventListener('loadedmetadata', t.step_func(() => { |
| assert_true(isVisible(overflowButton(video))); |
| singleTapOnControl(overflowButton(video), t.step_func_done(() => { |
| const menu = overflowMenu(video); |
| assert_true(isVisible(menu)); |
| assert_equals(internals.shadowRoot(video).activeElement, |
| menu.lastElementChild); |
| |
| const elements = [ menu.lastElementChild, |
| menu.lastElementChild.previousSibling ]; |
| |
| if (document.pictureInPictureEnabled) |
| elements.push(menu.lastElementChild.previousSibling.previousSibling); |
| |
| testNavigation(internals.shadowRoot(video), elements, |
| () => { eventSender.keyDown('ArrowUp'); }, |
| () => { eventSender.keyDown('ArrowDown'); }); |
| |
| testNavigation(internals.shadowRoot(video), elements, |
| () => { eventSender.keyDown('Tab', [ 'shiftKey' ]); }, |
| () => { eventSender.keyDown('Tab'); }); |
| |
| // Navigating with Shift + Arrow Keys should also work. |
| testNavigation(internals.shadowRoot(video), elements, |
| () => { eventSender.keyDown('ArrowUp', [ 'shiftKey' ]); }, |
| () => { eventSender.keyDown('ArrowDown', [ 'shiftKey' ]); }); |
| |
| // Closing. |
| eventSender.keyDown('Escape'); |
| assert_false(isVisible(menu)); |
| assert_equals(internals.shadowRoot(video).activeElement, |
| overflowButton(video)); |
| })); |
| }), { once: true }); |
| }); |
| </script> |