test-tab-events.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const { Loader } = require("sdk/test/loader");
  6. const utils = require("sdk/tabs/utils");
  7. const { open, close } = require("sdk/window/helpers");
  8. const { getMostRecentBrowserWindow } = require("sdk/window/utils");
  9. const { events } = require("sdk/tab/events");
  10. const { on, off } = require("sdk/event/core");
  11. const { resolve, defer } = require("sdk/core/promise");
  12. let isFennec = require("sdk/system/xul-app").is("Fennec");
  13. function test(options) {
  14. return function(assert, done) {
  15. let tabEvents = [];
  16. let tabs = [];
  17. let { promise, resolve: resolveP } = defer();
  18. let win = isFennec ? resolve(getMostRecentBrowserWindow()) :
  19. open(null, {
  20. features: { private: true, toolbar:true, chrome: true }
  21. });
  22. let window = null;
  23. // Firefox events are fired sync; Fennec events async
  24. // this normalizes the tests
  25. function handler (event) {
  26. tabEvents.push(event);
  27. runIfReady();
  28. }
  29. function runIfReady () {
  30. let releventEvents = getRelatedEvents(tabEvents, tabs);
  31. if (options.readyWhen(releventEvents))
  32. options.end({
  33. tabs: tabs,
  34. events: releventEvents,
  35. assert: assert,
  36. done: resolveP
  37. });
  38. }
  39. win.then(function(w) {
  40. window = w;
  41. on(events, "data", handler);
  42. options.start({ tabs: tabs, window: window });
  43. // Execute here for synchronous FF events, as the handlers
  44. // were called before tabs were pushed to `tabs`
  45. runIfReady();
  46. return promise;
  47. }).then(function() {
  48. off(events, "data", handler);
  49. return isFennec ? null : close(window);
  50. }).then(done, assert.fail);
  51. };
  52. }
  53. // Just making sure that tab events work for already opened tabs not only
  54. // for new windows.
  55. exports["test current window"] = test({
  56. readyWhen: events => events.length === 3,
  57. start: ({ tabs, window }) => {
  58. let tab = utils.openTab(window, 'data:text/plain,open');
  59. tabs.push(tab);
  60. utils.closeTab(tab);
  61. },
  62. end: ({ tabs, events, assert, done }) => {
  63. let [open, select, close] = events;
  64. let tab = tabs[0];
  65. assert.equal(open.type, "TabOpen");
  66. assert.equal(open.target, tab);
  67. assert.equal(select.type, "TabSelect");
  68. assert.equal(select.target, tab);
  69. assert.equal(close.type, "TabClose");
  70. assert.equal(close.target, tab);
  71. done();
  72. }
  73. });
  74. exports["test open"] = test({
  75. readyWhen: events => events.length === 2,
  76. start: ({ tabs, window }) => {
  77. tabs.push(utils.openTab(window, 'data:text/plain,open'));
  78. },
  79. end: ({ tabs, events, assert, done }) => {
  80. let [open, select] = events;
  81. let tab = tabs[0];
  82. assert.equal(open.type, "TabOpen");
  83. assert.equal(open.target, tab);
  84. assert.equal(select.type, "TabSelect");
  85. assert.equal(select.target, tab);
  86. done();
  87. }
  88. });
  89. exports["test open -> close"] = test({
  90. readyWhen: events => events.length === 3,
  91. start: ({ tabs, window }) => {
  92. // First tab is useless we just open it so that closing second tab won't
  93. // close window on some platforms.
  94. utils.openTab(window, 'data:text/plain,ignore');
  95. let tab = utils.openTab(window, 'data:text/plain,open-close');
  96. tabs.push(tab);
  97. utils.closeTab(tab);
  98. },
  99. end: ({ tabs, events, assert, done }) => {
  100. let [open, select, close] = events;
  101. let tab = tabs[0];
  102. assert.equal(open.type, "TabOpen");
  103. assert.equal(open.target, tab);
  104. assert.equal(select.type, "TabSelect");
  105. assert.equal(select.target, tab);
  106. assert.equal(close.type, "TabClose");
  107. assert.equal(close.target, tab);
  108. done();
  109. }
  110. });
  111. exports["test open -> open -> select"] = test({
  112. readyWhen: events => events.length === 5,
  113. start: ({tabs, window}) => {
  114. tabs.push(utils.openTab(window, 'data:text/plain,Tab-1'));
  115. tabs.push(utils.openTab(window, 'data:text/plain,Tab-2'));
  116. utils.activateTab(tabs[0], window);
  117. },
  118. end: ({ tabs, events, assert, done }) => {
  119. let [ tab1, tab2 ] = tabs;
  120. let tab1Events = 0;
  121. getRelatedEvents(events, tab1).map(event => {
  122. tab1Events++;
  123. if (tab1Events === 1)
  124. assert.equal(event.type, "TabOpen", "first tab opened");
  125. else
  126. assert.equal(event.type, "TabSelect", "first tab selected");
  127. assert.equal(event.target, tab1);
  128. });
  129. assert.equal(tab1Events, 3, "first tab has 3 events");
  130. let tab2Opened;
  131. getRelatedEvents(events, tab2).map(event => {
  132. if (!tab2Opened)
  133. assert.equal(event.type, "TabOpen", "second tab opened");
  134. else
  135. assert.equal(event.type, "TabSelect", "second tab selected");
  136. tab2Opened = true;
  137. assert.equal(event.target, tab2);
  138. });
  139. done();
  140. }
  141. });
  142. exports["test open -> pin -> unpin"] = test({
  143. readyWhen: events => events.length === (isFennec ? 2 : 5),
  144. start: ({ tabs, window }) => {
  145. tabs.push(utils.openTab(window, 'data:text/plain,pin-unpin'));
  146. utils.pin(tabs[0]);
  147. utils.unpin(tabs[0]);
  148. },
  149. end: ({ tabs, events, assert, done }) => {
  150. let [open, select, move, pin, unpin] = events;
  151. let tab = tabs[0];
  152. assert.equal(open.type, "TabOpen");
  153. assert.equal(open.target, tab);
  154. assert.equal(select.type, "TabSelect");
  155. assert.equal(select.target, tab);
  156. if (isFennec) {
  157. assert.pass("Tab pin / unpin is not supported by Fennec");
  158. }
  159. else {
  160. assert.equal(move.type, "TabMove");
  161. assert.equal(move.target, tab);
  162. assert.equal(pin.type, "TabPinned");
  163. assert.equal(pin.target, tab);
  164. assert.equal(unpin.type, "TabUnpinned");
  165. assert.equal(unpin.target, tab);
  166. }
  167. done();
  168. }
  169. });
  170. exports["test open -> open -> move "] = test({
  171. readyWhen: events => events.length === (isFennec ? 4 : 5),
  172. start: ({tabs, window}) => {
  173. tabs.push(utils.openTab(window, 'data:text/plain,Tab-1'));
  174. tabs.push(utils.openTab(window, 'data:text/plain,Tab-2'));
  175. utils.move(tabs[0], 2);
  176. },
  177. end: ({ tabs, events, assert, done }) => {
  178. let [ tab1, tab2 ] = tabs;
  179. let tab1Events = 0;
  180. getRelatedEvents(events, tab1).map(event => {
  181. tab1Events++;
  182. if (tab1Events === 1)
  183. assert.equal(event.type, "TabOpen", "first tab opened");
  184. else if (tab1Events === 2)
  185. assert.equal(event.type, "TabSelect", "first tab selected");
  186. else if (tab1Events === 3 && isFennec)
  187. assert.equal(event.type, "TabMove", "first tab moved");
  188. assert.equal(event.target, tab1);
  189. });
  190. assert.equal(tab1Events, isFennec ? 2 : 3,
  191. "correct number of events for first tab");
  192. let tab2Events = 0;
  193. getRelatedEvents(events, tab2).map(event => {
  194. tab2Events++;
  195. if (tab2Events === 1)
  196. assert.equal(event.type, "TabOpen", "second tab opened");
  197. else
  198. assert.equal(event.type, "TabSelect", "second tab selected");
  199. assert.equal(event.target, tab2);
  200. });
  201. done();
  202. }
  203. });
  204. function getRelatedEvents (events, tabs) {
  205. return events.filter(({target}) => ~([].concat(tabs)).indexOf(target));
  206. }
  207. require("sdk/test").run(exports);