summaryrefslogtreecommitdiffstats
path: root/dom/media/mediacontrol/tests/browser/browser_media_control_metadata.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/mediacontrol/tests/browser/browser_media_control_metadata.js')
-rw-r--r--dom/media/mediacontrol/tests/browser/browser_media_control_metadata.js416
1 files changed, 416 insertions, 0 deletions
diff --git a/dom/media/mediacontrol/tests/browser/browser_media_control_metadata.js b/dom/media/mediacontrol/tests/browser/browser_media_control_metadata.js
new file mode 100644
index 0000000000..75a0d80ac9
--- /dev/null
+++ b/dom/media/mediacontrol/tests/browser/browser_media_control_metadata.js
@@ -0,0 +1,416 @@
+const PAGE_NON_AUTOPLAY =
+ "https://example.com/browser/dom/media/mediacontrol/tests/browser/file_non_autoplay.html";
+const PAGE_EMPTY_TITLE_URL =
+ "https://example.com/browser/dom/media/mediacontrol/tests/browser/file_empty_title.html";
+
+const testVideoId = "video";
+const defaultFaviconName = "defaultFavicon.svg";
+
+add_task(async function setupTestingPref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["media.mediacontrol.testingevents.enabled", true],
+ ["dom.media.mediasession.enabled", true],
+ ],
+ });
+});
+
+/**
+ * This test includes many different test cases of checking the current media
+ * metadata from the tab which is being controlled by the media control. Each
+ * `add_task(..)` is a different testing scenario.
+ *
+ * Media metadata is the information that can tell user about what title, artist,
+ * album and even art work the tab is currently playing to. The metadta is
+ * usually set from MediaSession API, but if the site doesn't use that API, we
+ * would also generate a default metadata instead.
+ *
+ * The current metadata would only be available after the page starts playing
+ * media at least once, if the page hasn't started any media before, then the
+ * current metadata is always empty.
+ *
+ * For following situations, we would create a default metadata which title is
+ * website's title and artwork is from our default favicon icon.
+ * (1) the page doesn't use MediaSession API
+ * (2) media session doesn't has metadata
+ * (3) media session has an empty metadata
+ *
+ * Otherwise, the current metadata would be media session's metadata from the
+ * tab which is currently controlled by the media control.
+ */
+add_task(async function testDefaultMetadataForPageWithoutMediaSession() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`should use default metadata because of lacking of media session`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(
+ async function testDefaultMetadataForEmptyTitlePageWithoutMediaSession() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_EMPTY_TITLE_URL);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`should use default metadata because of lacking of media session`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`remove tab`);
+ await tab.close();
+ }
+);
+
+add_task(async function testDefaultMetadataForPageUsingEmptyMetadata() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`create empty media metadata`);
+ await setMediaMetadata(tab, {
+ title: "",
+ artist: "",
+ album: "",
+ artwork: [],
+ });
+
+ info(`should use default metadata because of empty media metadata`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testDefaultMetadataForPageUsingNullMetadata() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`create empty media metadata`);
+ await setNullMediaMetadata(tab);
+
+ info(`should use default metadata because of lacking of media metadata`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testMetadataWithEmptyTitleAndArtwork() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`create media metadata with empty title and artwork`);
+ await setMediaMetadata(tab, {
+ title: "",
+ artist: "foo",
+ album: "bar",
+ artwork: [],
+ });
+
+ info(`should use default metadata because of empty title and artwork`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testMetadataWithoutTitleAndArtwork() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`create media metadata with empty title and artwork`);
+ await setMediaMetadata(tab, {
+ artist: "foo",
+ album: "bar",
+ });
+
+ info(`should use default metadata because of lacking of title and artwork`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testMetadataInPrivateBrowsing() {
+ info(`create a private window`);
+ const inputWindow = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY, { inputWindow });
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`set metadata`);
+ let metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata);
+
+ info(`should use default metadata because of in private browsing mode`);
+ await isGivenTabUsingDefaultMetadata(tab, { isPrivateBrowsing: true });
+
+ info(`remove tab`);
+ await tab.close();
+
+ info(`close private window`);
+ await BrowserTestUtils.closeWindow(inputWindow);
+});
+
+add_task(async function testSetMetadataFromMediaSessionAPI() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`set metadata`);
+ let metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata);
+
+ info(`check if current active metadata is equal to what we've set before`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`set metadata again to see if current metadata would change`);
+ metadata = {
+ title: "foo2",
+ artist: "bar2",
+ album: "foo2",
+ artwork: [{ src: "bar2.jpg", sizes: "129x129", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata);
+
+ info(`check if current active metadata is equal to what we've set before`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testSetMetadataBeforeMediaStarts() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY, {
+ needCheck: false,
+ });
+
+ info(`set metadata`);
+ let metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata, { notExpectChange: true });
+
+ info(`current media metadata should be empty before media starts`);
+ isCurrentMetadataEmpty();
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testSetMetadataAfterMediaPaused() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media in order to let this tab be controlled`);
+ await playMedia(tab, testVideoId);
+
+ info(`pause media`);
+ await pauseMedia(tab, testVideoId);
+
+ info(`set metadata after media is paused`);
+ let metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata);
+
+ info(`check if current active metadata is equal to what we've set before`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testSetMetadataAmongMultipleTabs() {
+ info(`open media page in tab1`);
+ const tab1 = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media in tab1`);
+ await playMedia(tab1, testVideoId);
+
+ info(`set metadata for tab1`);
+ let metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab1, metadata);
+
+ info(`check if current active metadata is equal to what we've set before`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`open another page in tab2`);
+ const tab2 = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media in tab2`);
+ await playMedia(tab2, testVideoId);
+
+ info(`set metadata for tab2`);
+ metadata = {
+ title: "foo2",
+ artist: "bar2",
+ album: "foo2",
+ artwork: [{ src: "bar2.jpg", sizes: "129x129", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab2, metadata);
+
+ info(`current active metadata should become metadata from tab2`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(
+ `update metadata for tab1, which should not affect current metadata ` +
+ `because media session in tab2 is the one we're controlling right now`
+ );
+ await setMediaMetadata(tab1, {
+ title: "foo3",
+ artist: "bar3",
+ album: "foo3",
+ artwork: [{ src: "bar3.jpg", sizes: "130x130", type: "image/jpeg" }],
+ });
+
+ info(`current active metadata should still be metadata from tab2`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`remove tabs`);
+ await Promise.all([tab1.close(), tab2.close()]);
+});
+
+add_task(async function testMetadataAfterTabNavigation() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`set metadata`);
+ let metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata);
+
+ info(`check if current active metadata is equal to what we've set before`);
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`navigate tab to blank page`);
+ await Promise.all([
+ new Promise(r => (tab.controller.ondeactivated = r)),
+ BrowserTestUtils.loadURIString(tab.linkedBrowser, "about:blank"),
+ ]);
+
+ info(`current media metadata should be reset`);
+ isCurrentMetadataEmpty();
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+add_task(async function testUpdateDefaultMetadataWhenPageTitleChanges() {
+ info(`open media page`);
+ const tab = await createLoadedTabWrapper(PAGE_NON_AUTOPLAY);
+
+ info(`start media`);
+ await playMedia(tab, testVideoId);
+
+ info(`should use default metadata because of lacking of media session`);
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`default metadata should be updated after page title changes`);
+ await changePageTitle(tab, { shouldAffectMetadata: true });
+ await isGivenTabUsingDefaultMetadata(tab);
+
+ info(`after setting metadata, title change won't affect current metadata`);
+ const metadata = {
+ title: "foo",
+ artist: "bar",
+ album: "foo",
+ artwork: [{ src: "bar.jpg", sizes: "128x128", type: "image/jpeg" }],
+ };
+ await setMediaMetadata(tab, metadata);
+ await changePageTitle(tab, { shouldAffectMetadata: false });
+ await isCurrentMetadataEqualTo(metadata);
+
+ info(`remove tab`);
+ await tab.close();
+});
+
+/**
+ * The following are helper functions.
+ */
+function setMediaMetadata(tab, metadata, { notExpectChange } = {}) {
+ const controller = tab.linkedBrowser.browsingContext.mediaController;
+ const metadatachangePromise = notExpectChange
+ ? Promise.resolve()
+ : new Promise(r => (controller.onmetadatachange = r));
+ return Promise.all([
+ metadatachangePromise,
+ SpecialPowers.spawn(tab.linkedBrowser, [metadata], data => {
+ content.navigator.mediaSession.metadata = new content.MediaMetadata(data);
+ }),
+ ]);
+}
+
+function setNullMediaMetadata(tab) {
+ const promise = SpecialPowers.spawn(tab.linkedBrowser, [], () => {
+ content.navigator.mediaSession.metadata = null;
+ });
+ return Promise.all([promise, waitUntilControllerMetadataChanged()]);
+}
+
+async function changePageTitle(tab, { shouldAffectMetadata } = {}) {
+ const controller = tab.linkedBrowser.browsingContext.mediaController;
+ const shouldWaitMetadataChangePromise = shouldAffectMetadata
+ ? new Promise(r => (controller.onmetadatachange = r))
+ : Promise.resolve();
+ await Promise.all([
+ shouldWaitMetadataChangePromise,
+ SpecialPowers.spawn(tab.linkedBrowser, [], _ => {
+ content.document.title = "new title";
+ }),
+ ]);
+}