From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser_tab_visibility_and_play_time.js | 216 +++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 dom/media/test/browser/browser_tab_visibility_and_play_time.js (limited to 'dom/media/test/browser/browser_tab_visibility_and_play_time.js') diff --git a/dom/media/test/browser/browser_tab_visibility_and_play_time.js b/dom/media/test/browser/browser_tab_visibility_and_play_time.js new file mode 100644 index 0000000000..66fae40889 --- /dev/null +++ b/dom/media/test/browser/browser_tab_visibility_and_play_time.js @@ -0,0 +1,216 @@ +/** + * This test is used to ensure that invisible play time would be accumulated + * when tab is in background. It also checks the HDR video accumulation time. + * However, this test won't directly check the reported telemetry result, + * because we can't check the snapshot histogram in the content process. + * The actual probe checking happens in `test_accumulated_play_time.html`. + */ +"use strict"; + +const PAGE_URL = + "https://example.com/browser/dom/media/test/browser/file_media.html"; + +// This HDR tests will only pass on platforms that accurately report color +// depth in their VideoInfo structures. Presently, that is only true for +// macOS. + +const reportsColorDepthFromVideoData = AppConstants.platform == "macosx"; + +add_task(async function testChangingTabVisibilityAffectsInvisiblePlayTime() { + const originalTab = gBrowser.selectedTab; + const mediaTab = await openMediaTab(PAGE_URL); + + info(`measuring play time when tab is in foreground`); + await startMedia({ + mediaTab, + shouldAccumulateTime: true, + shouldAccumulateInvisibleTime: false, + shouldAccumulateHDRTime: reportsColorDepthFromVideoData, + }); + await pauseMedia(mediaTab); + + info(`measuring play time when tab is in background`); + await BrowserTestUtils.switchTab(window.gBrowser, originalTab); + await startMedia({ + mediaTab, + shouldAccumulateTime: true, + shouldAccumulateInvisibleTime: true, + shouldAccumulateHDRTime: reportsColorDepthFromVideoData, + }); + await pauseMedia(mediaTab); + + BrowserTestUtils.removeTab(mediaTab); +}); + +/** + * Following are helper functions. + */ +async function openMediaTab(url) { + info(`open tab for media playback`); + const tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser, url); + info(`add content helper functions and variables`); + await SpecialPowers.spawn(tab.linkedBrowser, [], _ => { + content.waitForOnTimeUpdate = element => { + return new Promise(resolve => { + element.addEventListener( + "timeupdate", + e => { + resolve(); + }, + { once: true } + ); + }); + }; + + content.sleep = ms => { + return new Promise(resolve => content.setTimeout(resolve, ms)); + }; + + content.assertAttributeDefined = (videoChrome, checkType) => { + ok(videoChrome[checkType] != undefined, `${checkType} exists`); + }; + content.assertValueEqualTo = (videoChrome, checkType, expectedValue) => { + content.assertAttributeDefined(videoChrome, checkType); + is( + videoChrome[checkType], + expectedValue, + `${checkType} equals to ${expectedValue}` + ); + }; + content.assertValueConstantlyIncreases = async (videoChrome, checkType) => { + content.assertAttributeDefined(videoChrome, checkType); + const valueSnapshot = videoChrome[checkType]; + await content.waitForOnTimeUpdate(videoChrome); + ok( + videoChrome[checkType] > valueSnapshot, + `${checkType} keeps increasing` + ); + }; + content.assertValueKeptUnchanged = async (videoChrome, checkType) => { + content.assertAttributeDefined(videoChrome, checkType); + const valueSnapshot = videoChrome[checkType]; + await content.sleep(1000); + ok( + videoChrome[checkType] == valueSnapshot, + `${checkType} keeps unchanged` + ); + }; + }); + return tab; +} + +function startMedia({ + mediaTab, + shouldAccumulateTime, + shouldAccumulateInvisibleTime, + shouldAccumulateHDRTime, +}) { + return SpecialPowers.spawn( + mediaTab.linkedBrowser, + [ + shouldAccumulateTime, + shouldAccumulateInvisibleTime, + shouldAccumulateHDRTime, + ], + async (accumulateTime, accumulateInvisibleTime, accumulateHDRTime) => { + const video = content.document.getElementById("video"); + ok( + await video.play().then( + () => true, + () => false + ), + "video started playing" + ); + const videoChrome = SpecialPowers.wrap(video); + if (accumulateTime) { + await content.assertValueConstantlyIncreases( + videoChrome, + "totalVideoPlayTime" + ); + } else { + await content.assertValueKeptUnchanged( + videoChrome, + "totalVideoPlayTime" + ); + } + if (accumulateInvisibleTime) { + await content.assertValueConstantlyIncreases( + videoChrome, + "invisiblePlayTime" + ); + } else { + await content.assertValueKeptUnchanged( + videoChrome, + "invisiblePlayTime" + ); + } + + const videoHDR = content.document.getElementById("videoHDR"); + + // HDR test video might not decode on all platforms, so catch + // the play() command and exit early in such a case. Failure to + // decode might manifest as a timeout, so add a rejection race + // to catch that. + let didDecode = true; + const playPromise = videoHDR.play().then( + () => true, + () => false + ); + /* eslint-disable mozilla/no-arbitrary-setTimeout */ + const tooSlowPromise = new Promise(resolve => + setTimeout(() => { + info("videoHDR timed out."); + didDecode = false; + resolve(false); + }, 1000) + ); + /* eslint-enable mozilla/no-arbitrary-setTimeout */ + + let didPlay = await Promise.race(playPromise, tooSlowPromise).catch( + err => { + info("videoHDR failed to decode with error: " + err.message); + didDecode = false; + return false; + } + ); + + if (!didDecode) { + return; + } + + ok(didPlay, "videoHDR started playing"); + const videoHDRChrome = SpecialPowers.wrap(videoHDR); + if (accumulateHDRTime) { + await content.assertValueConstantlyIncreases( + videoHDRChrome, + "totalVideoHDRPlayTime" + ); + } else { + await content.assertValueKeptUnchanged( + videoHDRChrome, + "totalVideoHDRPlayTime" + ); + } + } + ); +} + +function pauseMedia(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { + const video = content.document.getElementById("video"); + video.pause(); + ok(true, "video paused"); + const videoChrome = SpecialPowers.wrap(video); + await content.assertValueKeptUnchanged(videoChrome, "totalVideoPlayTime"); + await content.assertValueKeptUnchanged(videoChrome, "invisiblePlayTime"); + + const videoHDR = content.document.getElementById("videoHDR"); + videoHDR.pause(); + ok(true, "videoHDR paused"); + const videoHDRChrome = SpecialPowers.wrap(videoHDR); + await content.assertValueKeptUnchanged( + videoHDRChrome, + "totalVideoHDRPlayTime" + ); + }); +} -- cgit v1.2.3