browser_tab_visibility_and_play_time.js (5798B)
1 /** 2 * This test is used to ensure that invisible play time would be accumulated 3 * when tab is in background. It also checks the HDR video accumulation time. 4 * However, this test won't directly check the reported telemetry result, 5 * because we can't check the snapshot histogram in the content process. 6 * The actual probe checking happens in `test_accumulated_play_time.html`. 7 */ 8 "use strict"; 9 10 const PAGE_URL = 11 "https://example.com/browser/dom/media/test/browser/file_media.html"; 12 13 add_task(async function testChangingTabVisibilityAffectsInvisiblePlayTime() { 14 const originalTab = gBrowser.selectedTab; 15 const mediaTab = await openMediaTab(PAGE_URL); 16 17 info(`measuring play time when tab is in foreground`); 18 await startMedia({ 19 mediaTab, 20 shouldAccumulateTime: true, 21 shouldAccumulateInvisibleTime: false, 22 shouldAccumulateHDRTime: true, 23 }); 24 await pauseMedia(mediaTab); 25 26 info(`measuring play time when tab is in background`); 27 await BrowserTestUtils.switchTab(window.gBrowser, originalTab); 28 await startMedia({ 29 mediaTab, 30 shouldAccumulateTime: true, 31 shouldAccumulateInvisibleTime: true, 32 shouldAccumulateHDRTime: true, 33 }); 34 await pauseMedia(mediaTab); 35 36 BrowserTestUtils.removeTab(mediaTab); 37 }); 38 39 /** 40 * Following are helper functions. 41 */ 42 async function openMediaTab(url) { 43 info(`open tab for media playback`); 44 const tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser, url); 45 info(`add content helper functions and variables`); 46 await SpecialPowers.spawn(tab.linkedBrowser, [], _ => { 47 content.waitForOnTimeUpdate = element => { 48 return new Promise(resolve => { 49 // Wait longer to ensure the system clock has actually moved forward, 50 // preventing intermittent failures. 51 let count = 0; 52 const listener = () => { 53 if (++count > 2) { 54 element.removeEventListener("timeupdate", listener); 55 resolve(); 56 } 57 }; 58 element.addEventListener("timeupdate", listener); 59 }); 60 }; 61 62 content.sleep = ms => { 63 return new Promise(resolve => content.setTimeout(resolve, ms)); 64 }; 65 66 content.assertAttributeDefined = (videoChrome, checkType) => { 67 Assert.notEqual(videoChrome[checkType], undefined, `${checkType} exists`); 68 }; 69 content.assertValueEqualTo = (videoChrome, checkType, expectedValue) => { 70 content.assertAttributeDefined(videoChrome, checkType); 71 is( 72 videoChrome[checkType], 73 expectedValue, 74 `${checkType} equals to ${expectedValue}` 75 ); 76 }; 77 content.assertValueConstantlyIncreases = async (videoChrome, checkType) => { 78 content.assertAttributeDefined(videoChrome, checkType); 79 const valueSnapshot = videoChrome[checkType]; 80 await content.waitForOnTimeUpdate(videoChrome); 81 Assert.greater( 82 videoChrome[checkType], 83 valueSnapshot, 84 `${checkType} keeps increasing` 85 ); 86 }; 87 content.assertValueKeptUnchanged = async (videoChrome, checkType) => { 88 content.assertAttributeDefined(videoChrome, checkType); 89 const valueSnapshot = videoChrome[checkType]; 90 await content.sleep(1000); 91 Assert.equal( 92 videoChrome[checkType], 93 valueSnapshot, 94 `${checkType} keeps unchanged` 95 ); 96 }; 97 }); 98 return tab; 99 } 100 101 function startMedia({ 102 mediaTab, 103 shouldAccumulateTime, 104 shouldAccumulateInvisibleTime, 105 shouldAccumulateHDRTime, 106 }) { 107 return SpecialPowers.spawn( 108 mediaTab.linkedBrowser, 109 [ 110 shouldAccumulateTime, 111 shouldAccumulateInvisibleTime, 112 shouldAccumulateHDRTime, 113 ], 114 async (accumulateTime, accumulateInvisibleTime, accumulateHDRTime) => { 115 const video = content.document.getElementById("video"); 116 ok( 117 await video.play().then( 118 () => true, 119 () => false 120 ), 121 "video started playing" 122 ); 123 const videoChrome = SpecialPowers.wrap(video); 124 if (accumulateTime) { 125 await content.assertValueConstantlyIncreases( 126 videoChrome, 127 "totalVideoPlayTime" 128 ); 129 } else { 130 await content.assertValueKeptUnchanged( 131 videoChrome, 132 "totalVideoPlayTime" 133 ); 134 } 135 if (accumulateInvisibleTime) { 136 await content.assertValueConstantlyIncreases( 137 videoChrome, 138 "invisiblePlayTime" 139 ); 140 } else { 141 await content.assertValueKeptUnchanged( 142 videoChrome, 143 "invisiblePlayTime" 144 ); 145 } 146 147 const videoHDR = content.document.getElementById("videoHDR"); 148 ok( 149 videoHDR.play().then( 150 () => true, 151 () => false 152 ), 153 "videoHDR started playing" 154 ); 155 const videoHDRChrome = SpecialPowers.wrap(videoHDR); 156 if (accumulateHDRTime) { 157 await content.assertValueConstantlyIncreases( 158 videoHDRChrome, 159 "totalVideoHDRPlayTime" 160 ); 161 } else { 162 await content.assertValueKeptUnchanged( 163 videoHDRChrome, 164 "totalVideoHDRPlayTime" 165 ); 166 } 167 } 168 ); 169 } 170 171 function pauseMedia(tab) { 172 return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { 173 const video = content.document.getElementById("video"); 174 video.pause(); 175 ok(true, "video paused"); 176 const videoChrome = SpecialPowers.wrap(video); 177 await content.assertValueKeptUnchanged(videoChrome, "totalVideoPlayTime"); 178 await content.assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); 179 180 const videoHDR = content.document.getElementById("videoHDR"); 181 videoHDR.pause(); 182 ok(true, "videoHDR paused"); 183 const videoHDRChrome = SpecialPowers.wrap(videoHDR); 184 await content.assertValueKeptUnchanged( 185 videoHDRChrome, 186 "totalVideoHDRPlayTime" 187 ); 188 }); 189 }