summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/fullscreen/head.js
blob: b6aade2e03db4ea091743516b3ded3b1541c4be8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const { ContentTaskUtils } = ChromeUtils.import(
  "resource://testing-common/ContentTaskUtils.jsm"
);
function waitForFullScreenState(browser, state) {
  return new Promise(resolve => {
    let eventReceived = false;

    let observe = (subject, topic, data) => {
      if (!eventReceived) {
        return;
      }
      Services.obs.removeObserver(observe, "fullscreen-painted");
      resolve();
    };
    Services.obs.addObserver(observe, "fullscreen-painted");

    browser.ownerGlobal.addEventListener(
      `MozDOMFullscreen:${state ? "Entered" : "Exited"}`,
      () => {
        eventReceived = true;
      },
      { once: true }
    );
  });
}

/**
 * Spawns content task in browser to enter / leave fullscreen
 * @param browser - Browser to use for JS fullscreen requests
 * @param {Boolean} fullscreenState - true to enter fullscreen, false to leave
 * @returns {Promise} - Resolves once fullscreen change is applied
 */
async function changeFullscreen(browser, fullScreenState) {
  await new Promise(resolve =>
    SimpleTest.waitForFocus(resolve, browser.ownerGlobal)
  );
  let fullScreenChange = waitForFullScreenState(browser, fullScreenState);
  SpecialPowers.spawn(browser, [fullScreenState], async state => {
    // Wait for document focus before requesting full-screen
    await ContentTaskUtils.waitForCondition(
      () => content.browsingContext.isActive && content.document.hasFocus(),
      "Waiting for document focus"
    );
    if (state) {
      content.document.body.requestFullscreen();
    } else {
      content.document.exitFullscreen();
    }
  });
  return fullScreenChange;
}

async function testExpectFullScreenExit(browser, leaveFS, action) {
  let fsPromise = waitForFullScreenState(browser, !leaveFS);
  if (leaveFS) {
    if (action) {
      await action();
    }
    await fsPromise;
    ok(true, "Should leave full-screen");
  } else {
    if (action) {
      await action();
    }
    let result = await Promise.race([
      fsPromise,
      new Promise(resolve => {
        SimpleTest.requestFlakyTimeout("Wait for failure condition");
        // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
        setTimeout(() => resolve(true), 2500);
      }),
    ]);
    ok(result, "Should not leave full-screen");
  }
}

function jsWindowFocus(browser, iframeId) {
  return ContentTask.spawn(browser, { iframeId }, async args => {
    let destWin = content;
    if (args.iframeId) {
      let iframe = content.document.getElementById(args.iframeId);
      if (!iframe) {
        throw new Error("iframe not set");
      }
      destWin = iframe.contentWindow;
    }
    await content.wrappedJSObject.sendMessage(destWin, "focus");
  });
}

async function jsWindowOpen(browser, iframeId) {
  let windowOpened = BrowserTestUtils.waitForNewWindow();
  ContentTask.spawn(browser, { iframeId }, async args => {
    let destWin = content;
    if (args.iframeId) {
      // Create a cross origin iframe
      destWin = (
        await content.wrappedJSObject.createIframe(args.iframeId, true)
      ).contentWindow;
    }
    // Send message to either the iframe or the current page to open a popup
    await content.wrappedJSObject.sendMessage(destWin, "open");
  });
  return windowOpened;
}

function waitForFocus(...args) {
  return new Promise(resolve => SimpleTest.waitForFocus(resolve, ...args));
}

function waitForBrowserWindowActive(win) {
  return new Promise(resolve => {
    if (Services.focus.activeWindow == win) {
      resolve();
    } else {
      win.addEventListener(
        "activate",
        () => {
          resolve();
        },
        { once: true }
      );
    }
  });
}