browser_media_control_seek.js (4437B)
1 const PAGE_URL = 2 "https://example.com/browser/dom/media/mediacontrol/tests/browser/file_non_autoplay.html"; 3 4 const testVideoId = "video"; 5 6 add_task(async function setupTestingPref() { 7 await SpecialPowers.pushPrefEnv({ 8 set: [["media.mediacontrol.testingevents.enabled", true]], 9 }); 10 }); 11 12 /** 13 * This test is used to check if the `seekto` action can be sent when calling 14 * media controller's `seekTo()`. In addition, the seeking related properties 15 * which would be sent to the action handler should also be correct as what we 16 * set in `seekTo()`. 17 */ 18 add_task(async function testSetPositionState() { 19 info(`open media page`); 20 const tab = await createLoadedTabWrapper(PAGE_URL); 21 22 info(`start media`); 23 await playMedia(tab, testVideoId); 24 25 const seektime = 0; 26 info(`seek to ${seektime} seconds.`); 27 await PerformSeekTo(tab, { 28 seekTime: seektime, 29 }); 30 31 info(`seek to ${seektime} seconds and set fastseek to true`); 32 await PerformSeekTo(tab, { 33 seekTime: seektime, 34 fastSeek: true, 35 }); 36 37 info(`seek to ${seektime} seconds and set fastseek to false`); 38 await PerformSeekTo(tab, { 39 seekTime: seektime, 40 fastSeek: false, 41 }); 42 43 info(`remove tab`); 44 await tab.close(); 45 }); 46 47 add_task(async function testSeekRelative() { 48 info(`open media page`); 49 const tab = await createLoadedTabWrapper(PAGE_URL); 50 51 info(`start media`); 52 await playMedia(tab, testVideoId); 53 54 let seekoffset = 5; 55 info(`seek forward ${seekoffset} seconds`); 56 await PerformSeekRelative(tab, "seekforward", { 57 seekOffset: seekoffset, 58 }); 59 60 seekoffset = 4; 61 info(`seek backward ${seekoffset} seconds`); 62 await PerformSeekRelative(tab, "seekbackward", { 63 seekOffset: seekoffset, 64 }); 65 66 info(`remove tab`); 67 await tab.close(); 68 }); 69 70 /** 71 * The following is helper function. 72 */ 73 async function PerformSeekTo(tab, seekDetails) { 74 await SpecialPowers.spawn( 75 tab.linkedBrowser, 76 [seekDetails, testVideoId], 77 (seekDetails, Id) => { 78 const { seekTime, fastSeek } = seekDetails; 79 content.navigator.mediaSession.setActionHandler("seekto", details => { 80 Assert.notEqual( 81 details.seekTime, 82 undefined, 83 "Seektime must be presented" 84 ); 85 is(seekTime, details.seekTime, "Get correct seektime"); 86 if (fastSeek) { 87 is(fastSeek, details.fastSeek, "Get correct fastSeek"); 88 } else { 89 Assert.strictEqual( 90 details.fastSeek, 91 undefined, 92 "Details should not contain fastSeek" 93 ); 94 } 95 // We use `onseek` as a hint to know if the `seekto` has been received 96 // or not. The reason we don't return a resolved promise instead is 97 // because if we do so, it can't guarantees that the `seekto` action 98 // handler has been set before calling `mediaController.seekTo`. 99 content.document.getElementById(Id).currentTime = seekTime; 100 }); 101 } 102 ); 103 const seekPromise = SpecialPowers.spawn( 104 tab.linkedBrowser, 105 [testVideoId], 106 Id => { 107 const video = content.document.getElementById(Id); 108 return new Promise(r => (video.onseeked = () => r())); 109 } 110 ); 111 const { seekTime, fastSeek } = seekDetails; 112 tab.linkedBrowser.browsingContext.mediaController.seekTo(seekTime, fastSeek); 113 await seekPromise; 114 } 115 116 async function PerformSeekRelative(tab, mode, seekDetails) { 117 await SpecialPowers.spawn( 118 tab.linkedBrowser, 119 [seekDetails, mode, testVideoId], 120 (seekDetails, mode, Id) => { 121 const { seekOffset } = seekDetails; 122 content.navigator.mediaSession.setActionHandler(mode, details => { 123 Assert.notEqual( 124 details.seekOffset, 125 undefined, 126 "Seekoffset must be presented" 127 ); 128 is(seekOffset, details.seekOffset, "Get correct seekoffset"); 129 130 content.document.getElementById(Id).currentTime += 131 mode == "seekforward" ? seekOffset : -seekOffset; 132 }); 133 } 134 ); 135 const seekPromise = SpecialPowers.spawn( 136 tab.linkedBrowser, 137 [testVideoId], 138 Id => { 139 const video = content.document.getElementById(Id); 140 return new Promise(r => (video.onseeked = () => r())); 141 } 142 ); 143 const { seekOffset } = seekDetails; 144 if (mode === "seekforward") { 145 tab.linkedBrowser.browsingContext.mediaController.seekForward(seekOffset); 146 } else { 147 tab.linkedBrowser.browsingContext.mediaController.seekBackward(seekOffset); 148 } 149 await seekPromise; 150 }