summaryrefslogtreecommitdiffstats
path: root/dom/xul/test/file_bug1069772.xul
blob: b909852469f020a90f46765cc92845bb35d134d8 (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                 type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1069772
-->
<window title="Mozilla Bug 1069772"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="run();">

  <!-- test code goes here -->
  <script type="application/javascript">
  <![CDATA[

  const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
  Cu.import("resource://testing-common/ContentTask.jsm");
  Cu.import("resource://testing-common/BrowserTestUtils.jsm");
  Cu.import("resource://gre/modules/Services.jsm");
  ContentTask.setTestScope(window.opener.wrappedJSObject);

  let imports = ['SimpleTest', 'ok', 'is'];
  for (let name of imports) {
    window[name] = window.opener.wrappedJSObject[name];
  }

  /** Test for Bug 1069772 **/
  function run() {
    // test the transition:
    // prerender => visible => hidden => visible
    // on a non-remote browser
    createPrerenderedBrowser(false)
    .then(browser => verifyBrowser(browser, true, false))
    .then(browser => verifyVisibility(browser, 'prerender'))
    .then(browser => makePrerenderedBrowserActive(browser))
    .then(browser => verifyBrowser(browser, false, false))
    .then(browser => verifyVisibility(browser, 'visible'))
    .then(browser => hideBrowser(browser))
    .then(browser => verifyBrowser(browser, false, false))
    .then(browser => verifyVisibility(browser, 'hidden'))
    .then(browser => showBrowser(browser))
    .then(browser => verifyBrowser(browser, false, false))
    .then(browser => verifyVisibility(browser, 'visible'))

    // test the transition:
    // prerender => visible => hidden => visible
    // on a remote browser
    .then(() => createPrerenderedBrowser(true))
    .then(browser => verifyBrowser(browser, true, true))
    .then(browser => verifyVisibility(browser, 'prerender'))
    .then(browser => makePrerenderedBrowserActive(browser))
    .then(browser => verifyBrowser(browser, false, true))
    .then(browser => verifyVisibility(browser, 'visible'))
    .then(browser => hideBrowser(browser))
    .then(browser => verifyBrowser(browser, false, true))
    .then(browser => verifyVisibility(browser, 'hidden'))
    .then(browser => showBrowser(browser))
    .then(browser => verifyBrowser(browser, false, true))
    .then(browser => verifyVisibility(browser, 'visible'))

    // finish test
    .then(() => {
      window.close();
      SimpleTest.finish();
    });
  }

  function createPrerenderedBrowser(remote) {
    let browser = document.createElement('browser');
    browser.setAttribute('type', 'content');
    browser.setAttribute('prerendered', true);
    browser.setAttribute('remote', remote);
    browser.setAttribute('src', 'data:text/html;charset=UTF-8,<html><body>' +
     '<iframe id="iframe" src="data:text/html;charset=UTF-8,Hello Frame!">' +
     '</iframe></body></html>');

    // wait for 'load' and 'pageshow'
    let promises = [];
    promises.push(BrowserTestUtils.browserLoaded(browser));
    promises.push(new Promise(resolve =>
      Services.mm.addMessageListener('test:pageshow', resolve)));
    Services.mm.loadFrameScript('data:,' +
      'addEventListener("pageshow", ' +
      '() => sendAsyncMessage("test:pageshow", null), false);',
      true);

    document.getElementById('stack').appendChild(browser);
    return Promise.all(promises).then(() => browser);
  }

  function verifyBrowser(browser, prerendered, remote) {
    let docShellOrTabParent = remote ?
      browser.frameLoader.tabParent : browser.frameLoader.docShell;
    ok(docShellOrTabParent, 'docShellOrTabParent should not be null');
    is(docShellOrTabParent.isPrerendered, prerendered,
      'isPrerendered should be ' + prerendered);
    return browser;
  }

  function verifyVisibility(browser, visibility) {
    return ContentTask.spawn(browser, visibility, (v) => {
      let iframe = content.document.getElementById('iframe');
      is(content.document.visibilityState, v, 'check doc.visibilityState');
      is(content.document.hidden, v != 'visible', 'check doc.hidden');
      is(iframe.contentDocument.visibilityState, v, 'check iframe doc.visibilityState');
      is(iframe.contentDocument.hidden, v != 'visible', 'check iframe doc.hidden');
    }).then(() => browser);
  }

  function makePrerenderedBrowserActive(browser) {
    let promise = waitForVisibilityChange(browser);
    browser.setAttribute('prerendered', false);
    browser.makePrerenderedBrowserActive();
    return promise.then(() => browser);
  }

  function hideBrowser(browser) {
    let promise = waitForVisibilityChange(browser);
    browser.docShellIsActive = false;
    return promise.then(() => browser);
  }

  function showBrowser(browser) {
    let promise = waitForVisibilityChange(browser);
    browser.docShellIsActive = true;
    return promise.then(() => browser);
  }

  function waitForVisibilityChange(browser) {
    return ContentTask.spawn(browser, null, () => {
      return new Promise(resolve => {
        let iframe = content.document.getElementById('iframe');
        iframe.contentDocument.addEventListener('visibilitychange', function listener() {
          iframe.contentDocument.removeEventListener('visibilitychange', listener);
          resolve();
        });
      });
    });
  }

  ]]>
  </script>
  <stack id="stack" flex="1" />
</window>