summaryrefslogtreecommitdiffstats
path: root/addon-sdk/source/test/test-tab.js
blob: 1bf4ef20fea23dea948646d1af6841b509d8d9fc (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";

const tabs = require("sdk/tabs");
const windowUtils = require("sdk/deprecated/window-utils");
const windows = require("sdk/windows").browserWindows;
const app = require("sdk/system/xul-app");
const { viewFor } = require("sdk/view/core");
const { modelFor } = require("sdk/model/core");
const { getBrowserForTab, getTabId, isTab } = require("sdk/tabs/utils");
const { defer } = require("sdk/lang/functional");

function tabExistenceInTabs(assert, found, tab, tabs) {
  let tabFound = false;

  for (let t of tabs) {
    assert.notEqual(t.title, undefined, 'tab title is not undefined');
    assert.notEqual(t.url, undefined, 'tab url is not undefined');
    assert.notEqual(t.index, undefined, 'tab index is not undefined');

    if (t === tab) {
      tabFound = true;
      break;
    }
  }

  // check for the tab's existence
  if (found)
    assert.ok(tabFound, 'the tab was found as expected');
  else
    assert.ok(!tabFound, 'the tab was not found as expected');
}

exports.testBehaviorOnCloseAfterReady = function(assert, done) {
  tabs.open({
    url: "about:mozilla",
    onReady: function(tab) {
      assert.equal(tab.url, "about:mozilla", "Tab has the expected url");
      // if another test ends before closing a tab then index != 1 here
      assert.ok(tab.index >= 1, "Tab has the expected index, a value greater than 0");

      let testTabFound = tabExistenceInTabs.bind(null, assert, true, tab);
      let testTabNotFound = tabExistenceInTabs.bind(null, assert, false, tab);

      // tab in require("sdk/tabs") ?
      testTabFound(tabs);
      // tab was found in require("sdk/windows").windows.activeWindow.tabs ?
      let activeWindowTabs = windows.activeWindow.tabs;
      testTabFound(activeWindowTabs);

      tab.close(function () {
        assert.equal(tab.url, undefined,
                     "After being closed, tab attributes are undefined (url)");
        assert.equal(tab.index, undefined,
                     "After being closed, tab attributes are undefined (index)");

        tab.destroy();

        testTabNotFound(tabs);
        testTabNotFound(windows.activeWindow.tabs);
        testTabNotFound(activeWindowTabs);

        // Ensure that we can call destroy multiple times without throwing
        tab.destroy();

        testTabNotFound(tabs);
        testTabNotFound(windows.activeWindow.tabs);
        testTabNotFound(activeWindowTabs);

        done();
      });
    }
  });
};

exports.testBug844492 = function(assert, done) {
  const activeWindowTabs = windows.activeWindow.tabs;
  let openedTabs = 0;

  tabs.on('open', function onOpenTab(tab) {
    openedTabs++;

    let testTabFound = tabExistenceInTabs.bind(null, assert, true, tab);
    let testTabNotFound = tabExistenceInTabs.bind(null, assert, false, tab);

    testTabFound(tabs);
    testTabFound(windows.activeWindow.tabs);
    testTabFound(activeWindowTabs);

    tab.close();

    testTabNotFound(tabs);
    testTabNotFound(windows.activeWindow.tabs);
    testTabNotFound(activeWindowTabs);

    if (openedTabs >= 2) {
      tabs.removeListener('open', onOpenTab);
      done();
    }
  });

  tabs.open({ url: 'about:mozilla' });
  tabs.open({ url: 'about:mozilla' });
};

exports.testBehaviorOnCloseAfterOpen = function(assert, done) {
  tabs.open({
    url: "about:mozilla",
    onOpen: function(tab) {
      assert.notEqual(tab.url, undefined, "Tab has a url");
      assert.ok(tab.index >= 1, "Tab has the expected index");

      let testTabFound = tabExistenceInTabs.bind(null, assert, true, tab);
      let testTabNotFound = tabExistenceInTabs.bind(null, assert, false, tab);

      // tab in require("sdk/tabs") ?
      testTabFound(tabs);
      // tab was found in require("sdk/windows").windows.activeWindow.tabs ?
      let activeWindowTabs = windows.activeWindow.tabs;
      testTabFound(activeWindowTabs);

      tab.close(function () {
        assert.equal(tab.url, undefined,
                     "After being closed, tab attributes are undefined (url)");
        assert.equal(tab.index, undefined,
                     "After being closed, tab attributes are undefined (index)");

        tab.destroy();

        if (app.is("Firefox")) {
          // Ensure that we can call destroy multiple times without throwing;
          // Fennec doesn't use this internal utility
          tab.destroy();
          tab.destroy();
        }

        testTabNotFound(tabs);
        testTabNotFound(windows.activeWindow.tabs);
        testTabNotFound(activeWindowTabs);

        // Ensure that we can call destroy multiple times without throwing
        tab.destroy();

        testTabNotFound(tabs);
        testTabNotFound(windows.activeWindow.tabs);
        testTabNotFound(activeWindowTabs);

        done();
      });
    }
  });
};

exports["test viewFor(tab)"] = (assert, done) => {
  // Note we defer handlers as length collection is updated after
  // handler is invoked, so if test is finished before counnts are
  // updated wrong length will show up in followup tests.
  tabs.once("open", defer(tab => {
    const view = viewFor(tab);
    assert.ok(view, "view is returned");
    assert.equal(getTabId(view), tab.id, "tab has a same id");

    tab.close(defer(done));
  }));

  tabs.open({ url: "about:mozilla" });
};


exports["test modelFor(xulTab)"] = (assert, done) => {
  tabs.open({
    url: "about:mozilla",
    onReady: tab => {
      const view = viewFor(tab);
      assert.ok(view, "view is returned");
      assert.ok(isTab(view), "view is underlaying tab");
      assert.equal(getTabId(view), tab.id, "tab has a same id");
      assert.equal(modelFor(view), tab, "modelFor(view) is SDK tab");

      tab.close(defer(done));
    }
  });
};

exports["test tab.readyState"] = (assert, done) => {
  tabs.open({
    url: "data:text/html;charset=utf-8,test_readyState",
    onOpen: (tab) => {
      assert.notEqual(["uninitialized", "loading"].indexOf(tab.readyState), -1,
        "tab is either uninitialized or loading when onOpen");
    },
    onReady: (tab) => {
      assert.notEqual(["interactive", "complete"].indexOf(tab.readyState), -1,
        "tab is either interactive or complete when onReady");
    },
    onLoad: (tab) => {
      assert.equal(tab.readyState, "complete", "tab is complete onLoad");
      tab.close(defer(done));
    }
  });
}

exports["test tab.readyState for existent tabs"] = function* (assert) {
  assert.equal(tabs.length, 1, "tabs contains an existent tab");

  function frameScript() {
    sendAsyncMessage("test:contentDocument.readyState", content.document.readyState);
  }

  for (let tab of tabs) {
    let browserForTab = getBrowserForTab(viewFor(tab));
    let mm = browserForTab.messageManager;

    yield new Promise((resolve) => {
      mm.addMessageListener("test:contentDocument.readyState", function listener(evt) {
        mm.removeMessageListener("test:contentDocument.readyState", listener);
        assert.equal(evt.data, tab.readyState,
                     "tab.readyState has the same value of the associated contentDocument.readyState CPOW");
        resolve();
      });
      mm.loadFrameScript(`data:,new ${frameScript};`, false);
    });
  }
}

require("sdk/test").run(module.exports);