test-ui-sidebar.js 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487
  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. module.metadata = {
  6. 'engines': {
  7. 'Firefox': '*'
  8. }
  9. };
  10. const { Cu } = require('chrome');
  11. const { Loader } = require('sdk/test/loader');
  12. const { show, hide } = require('sdk/ui/sidebar/actions');
  13. const { isShowing } = require('sdk/ui/sidebar/utils');
  14. const { getMostRecentBrowserWindow } = require('sdk/window/utils');
  15. const { open, close, focus, promise: windowPromise } = require('sdk/window/helpers');
  16. const { setTimeout, setImmediate } = require('sdk/timers');
  17. const { isPrivate } = require('sdk/private-browsing');
  18. const data = require('./fixtures');
  19. const { URL } = require('sdk/url');
  20. const { once, off, emit } = require('sdk/event/core');
  21. const { defer, all } = require('sdk/core/promise');
  22. const { BUILTIN_SIDEBAR_MENUITEMS, isSidebarShowing,
  23. getSidebarMenuitems, getExtraSidebarMenuitems, makeID, simulateCommand,
  24. simulateClick, isChecked } = require('./sidebar/utils');
  25. exports.testSidebarBasicLifeCycle = function(assert, done) {
  26. const { Sidebar } = require('sdk/ui/sidebar');
  27. let testName = 'testSidebarBasicLifeCycle';
  28. let window = getMostRecentBrowserWindow();
  29. assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
  30. let sidebarXUL = window.document.getElementById('sidebar');
  31. assert.ok(sidebarXUL, 'sidebar xul element does exist');
  32. assert.ok(!getExtraSidebarMenuitems().length, 'there are no extra sidebar menuitems');
  33. assert.equal(isSidebarShowing(window), false, 'sidebar is not showing 1');
  34. let sidebarDetails = {
  35. id: testName,
  36. title: 'test',
  37. url: 'data:text/html;charset=utf-8,'+testName
  38. };
  39. let sidebar = Sidebar(sidebarDetails);
  40. // test the sidebar attributes
  41. for (let key of Object.keys(sidebarDetails)) {
  42. assert.equal(sidebarDetails[key], sidebar[key], 'the attributes match the input');
  43. }
  44. assert.pass('The Sidebar constructor worked');
  45. let extraMenuitems = getExtraSidebarMenuitems();
  46. assert.equal(extraMenuitems.length, 1, 'there is one extra sidebar menuitems');
  47. let ele = window.document.getElementById(makeID(testName));
  48. assert.equal(ele, extraMenuitems[0], 'the only extra menuitem is the one for our sidebar.')
  49. assert.ok(ele, 'sidebar element was added');
  50. assert.ok(!isChecked(ele), 'the sidebar is not displayed');
  51. assert.equal(ele.getAttribute('label'), sidebar.title, 'the sidebar title is the menuitem label')
  52. assert.equal(isSidebarShowing(window), false, 'sidebar is not showing 2');
  53. sidebar.on('show', function() {
  54. assert.pass('the show event was fired');
  55. assert.equal(isSidebarShowing(window), true, 'sidebar is not showing 3');
  56. assert.equal(isShowing(sidebar), true, 'the sidebar is showing');
  57. assert.ok(isChecked(ele), 'the sidebar is displayed');
  58. sidebar.once('hide', function() {
  59. assert.pass('the hide event was fired');
  60. assert.ok(!isChecked(ele), 'the sidebar menuitem is not checked');
  61. assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
  62. assert.equal(isSidebarShowing(window), false, 'the sidebar elemnt is hidden');
  63. sidebar.once('detach', function() {
  64. // calling destroy twice should not matter
  65. sidebar.destroy();
  66. sidebar.destroy();
  67. let sidebarMI = getSidebarMenuitems();
  68. for (let mi of sidebarMI) {
  69. assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar')
  70. assert.ok(!isChecked(mi), 'no sidebar menuitem is checked');
  71. }
  72. assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
  73. assert.pass('calling destroy worked without error');
  74. done();
  75. });
  76. });
  77. sidebar.hide();
  78. assert.pass('hiding sidebar..');
  79. });
  80. sidebar.show();
  81. assert.pass('showing sidebar..');
  82. }
  83. exports.testSideBarIsInNewWindows = function(assert, done) {
  84. const { Sidebar } = require('sdk/ui/sidebar');
  85. let testName = 'testSideBarIsInNewWindows';
  86. let sidebar = Sidebar({
  87. id: testName,
  88. title: testName,
  89. url: 'data:text/html;charset=utf-8,'+testName
  90. });
  91. let startWindow = getMostRecentBrowserWindow();
  92. let ele = startWindow.document.getElementById(makeID(testName));
  93. assert.ok(ele, 'sidebar element was added');
  94. open().then(function(window) {
  95. let ele = window.document.getElementById(makeID(testName));
  96. assert.ok(ele, 'sidebar element was added');
  97. // calling destroy twice should not matter
  98. sidebar.destroy();
  99. sidebar.destroy();
  100. assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
  101. assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE');
  102. close(window).then(done, assert.fail);
  103. })
  104. }
  105. exports.testSideBarIsShowingInNewWindows = function(assert, done) {
  106. const { Sidebar } = require('sdk/ui/sidebar');
  107. let testName = 'testSideBarIsShowingInNewWindows';
  108. let sidebar = Sidebar({
  109. id: testName,
  110. title: testName,
  111. url: URL('data:text/html;charset=utf-8,'+testName)
  112. });
  113. let startWindow = getMostRecentBrowserWindow();
  114. let ele = startWindow.document.getElementById(makeID(testName));
  115. assert.ok(ele, 'sidebar element was added');
  116. let oldEle = ele;
  117. sidebar.once('attach', function() {
  118. assert.pass('attach event fired');
  119. sidebar.once('show', function() {
  120. assert.pass('show event fired');
  121. sidebar.once('show', function() {
  122. let window = getMostRecentBrowserWindow();
  123. assert.notEqual(startWindow, window, 'window is new');
  124. let sb = window.document.getElementById('sidebar');
  125. if (sb && sb.docShell && sb.contentDocument && sb.contentDocument.getElementById('web-panels-browser')) {
  126. end();
  127. }
  128. else {
  129. sb.addEventListener('DOMWindowCreated', end, false);
  130. }
  131. function end() {
  132. sb.removeEventListener('DOMWindowCreated', end, false);
  133. let webPanelBrowser = sb.contentDocument.getElementById('web-panels-browser');
  134. let ele = window.document.getElementById(makeID(testName));
  135. assert.ok(ele, 'sidebar element was added 2');
  136. assert.ok(isChecked(ele), 'the sidebar is checked');
  137. assert.notEqual(ele, oldEle, 'there are two different sidebars');
  138. assert.equal(isShowing(sidebar), true, 'the sidebar is showing in new window');
  139. sidebar.destroy();
  140. assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
  141. assert.ok(!isSidebarShowing(window), 'sidebar in most recent window is not showing');
  142. assert.ok(!isSidebarShowing(startWindow), 'sidebar in most start window is not showing');
  143. assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
  144. assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE');
  145. setTimeout(function() {
  146. close(window).then(done, assert.fail);
  147. });
  148. }
  149. });
  150. startWindow.OpenBrowserWindow();
  151. });
  152. });
  153. show(sidebar);
  154. assert.pass('showing the sidebar');
  155. }
  156. // TODO: determine if this is acceptable..
  157. /*
  158. exports.testAddonGlobalSimple = function(assert, done) {
  159. const { Sidebar } = require('sdk/ui/sidebar');
  160. let testName = 'testAddonGlobalSimple';
  161. let sidebar = Sidebar({
  162. id: testName,
  163. title: testName,
  164. url: data.url('test-sidebar-addon-global.html')
  165. });
  166. sidebar.on('show', function({worker}) {
  167. assert.pass('sidebar was attached');
  168. assert.ok(!!worker, 'attach event has worker');
  169. worker.port.on('X', function(msg) {
  170. assert.equal(msg, '23', 'the final message is correct');
  171. sidebar.destroy();
  172. done();
  173. });
  174. worker.port.emit('X', '2');
  175. });
  176. show(sidebar);
  177. }
  178. */
  179. exports.testAddonGlobalComplex = function(assert, done) {
  180. const { Sidebar } = require('sdk/ui/sidebar');
  181. let testName = 'testAddonGlobalComplex';
  182. let sidebar = Sidebar({
  183. id: testName,
  184. title: testName,
  185. url: data.url('test-sidebar-addon-global.html')
  186. });
  187. sidebar.on('attach', function(worker) {
  188. assert.pass('sidebar was attached');
  189. assert.ok(!!worker, 'attach event has worker');
  190. worker.port.once('Y', function(msg) {
  191. assert.equal(msg, '1', 'got event from worker');
  192. worker.port.on('X', function(msg) {
  193. assert.equal(msg, '123', 'the final message is correct');
  194. sidebar.destroy();
  195. done();
  196. });
  197. worker.port.emit('X', msg + '2');
  198. })
  199. });
  200. show(sidebar);
  201. }
  202. exports.testAddonReady = function(assert, done) {
  203. const { Sidebar } = require('sdk/ui/sidebar');
  204. let testName = 'testAddonReady';
  205. let sidebar = Sidebar({
  206. id: testName,
  207. title: testName,
  208. url: data.url('test-sidebar-addon-global.html'),
  209. onReady: function(worker) {
  210. assert.pass('sidebar was attached');
  211. assert.ok(!!worker, 'attach event has worker');
  212. worker.port.on('X', function(msg) {
  213. assert.equal(msg, '123', 'the final message is correct');
  214. sidebar.destroy();
  215. done();
  216. });
  217. worker.port.emit('X', '12');
  218. }
  219. });
  220. show(sidebar);
  221. }
  222. exports.testShowingOneSidebarAfterAnother = function(assert, done) {
  223. const { Sidebar } = require('sdk/ui/sidebar');
  224. let testName = 'testShowingOneSidebarAfterAnother';
  225. let sidebar1 = Sidebar({
  226. id: testName + '1',
  227. title: testName + '1',
  228. url: 'data:text/html;charset=utf-8,'+ testName + 1
  229. });
  230. let sidebar2 = Sidebar({
  231. id: testName + '2',
  232. title: testName + '2',
  233. url: 'data:text/html;charset=utf-8,'+ testName + 2
  234. });
  235. let window = getMostRecentBrowserWindow();
  236. let IDs = [ sidebar1.id, sidebar2.id ];
  237. let extraMenuitems = getExtraSidebarMenuitems(window);
  238. assert.equal(extraMenuitems.length, 2, 'there are two extra sidebar menuitems');
  239. function testShowing(sb1, sb2, sbEle) {
  240. assert.equal(isShowing(sidebar1), sb1);
  241. assert.equal(isShowing(sidebar2), sb2);
  242. assert.equal(isSidebarShowing(window), sbEle);
  243. }
  244. testShowing(false, false, false);
  245. sidebar1.once('show', function() {
  246. testShowing(true, false, true);
  247. for (let mi of getExtraSidebarMenuitems(window)) {
  248. let menuitemID = mi.getAttribute('id').replace(/^jetpack-sidebar-/, '');
  249. assert.ok(IDs.indexOf(menuitemID) >= 0, 'the extra menuitem is for one of our test sidebars');
  250. assert.equal(isChecked(mi), menuitemID == sidebar1.id, 'the test sidebar menuitem has the correct checked value');
  251. }
  252. sidebar2.once('show', function() {
  253. testShowing(false, true, true);
  254. for (let mi of getExtraSidebarMenuitems(window)) {
  255. let menuitemID = mi.getAttribute('id').replace(/^jetpack-sidebar-/, '');
  256. assert.ok(IDs.indexOf(menuitemID) >= 0, 'the extra menuitem is for one of our test sidebars');
  257. assert.equal(isChecked(mi), menuitemID == sidebar2.id, 'the test sidebar menuitem has the correct checked value');
  258. }
  259. sidebar1.destroy();
  260. sidebar2.destroy();
  261. testShowing(false, false, false);
  262. done();
  263. });
  264. show(sidebar2);
  265. assert.pass('showing sidebar 2');
  266. })
  267. show(sidebar1);
  268. assert.pass('showing sidebar 1');
  269. }
  270. exports.testSidebarUnload = function(assert, done) {
  271. const { Sidebar } = require('sdk/ui/sidebar');
  272. let testName = 'testSidebarUnload';
  273. let loader = Loader(module);
  274. let window = getMostRecentBrowserWindow();
  275. assert.equal(isPrivate(window), false, 'the current window is not private');
  276. let sidebar = loader.require('sdk/ui/sidebar').Sidebar({
  277. id: testName,
  278. title: testName,
  279. url: 'data:text/html;charset=utf-8,'+ testName,
  280. onShow: function() {
  281. assert.pass('onShow works for Sidebar');
  282. loader.unload();
  283. let sidebarMI = getSidebarMenuitems();
  284. for (let mi of sidebarMI) {
  285. assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar')
  286. assert.ok(!isChecked(mi), 'no sidebar menuitem is checked');
  287. }
  288. assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
  289. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
  290. done();
  291. }
  292. })
  293. sidebar.show();
  294. assert.pass('showing the sidebar');
  295. }
  296. exports.testRemoteContent = function(assert) {
  297. const { Sidebar } = require('sdk/ui/sidebar');
  298. let testName = 'testRemoteContent';
  299. try {
  300. let sidebar = Sidebar({
  301. id: testName,
  302. title: testName,
  303. url: 'http://dne.xyz.mozilla.org'
  304. });
  305. assert.fail('a bad sidebar was created..');
  306. sidebar.destroy();
  307. }
  308. catch(e) {
  309. assert.ok(/The option "url" must be a valid local URI\./.test(e), 'remote content is not acceptable');
  310. }
  311. }
  312. exports.testInvalidURL = function(assert) {
  313. const { Sidebar } = require('sdk/ui/sidebar');
  314. let testName = 'testInvalidURL';
  315. try {
  316. let sidebar = Sidebar({
  317. id: testName,
  318. title: testName,
  319. url: 'http:mozilla.org'
  320. });
  321. assert.fail('a bad sidebar was created..');
  322. sidebar.destroy();
  323. }
  324. catch(e) {
  325. assert.ok(/The option "url" must be a valid local URI\./.test(e), 'invalid URIs are not acceptable');
  326. }
  327. }
  328. exports.testInvalidURLType = function(assert) {
  329. const { Sidebar } = require('sdk/ui/sidebar');
  330. let testName = 'testInvalidURLType';
  331. try {
  332. let sidebar = Sidebar({
  333. id: testName,
  334. title: testName
  335. });
  336. assert.fail('a bad sidebar was created..');
  337. sidebar.destroy();
  338. }
  339. catch(e) {
  340. assert.ok(/The option "url" must be a valid local URI\./.test(e), 'invalid URIs are not acceptable');
  341. }
  342. }
  343. exports.testInvalidTitle = function(assert) {
  344. const { Sidebar } = require('sdk/ui/sidebar');
  345. let testName = 'testInvalidTitle';
  346. try {
  347. let sidebar = Sidebar({
  348. id: testName,
  349. title: '',
  350. url: 'data:text/html;charset=utf-8,'+testName
  351. });
  352. assert.fail('a bad sidebar was created..');
  353. sidebar.destroy();
  354. }
  355. catch(e) {
  356. assert.equal('The option "title" must be one of the following types: string', e.message, 'invalid titles are not acceptable');
  357. }
  358. }
  359. exports.testInvalidID = function(assert) {
  360. const { Sidebar } = require('sdk/ui/sidebar');
  361. let testName = 'testInvalidID';
  362. try {
  363. let sidebar = Sidebar({
  364. id: '!',
  365. title: testName,
  366. url: 'data:text/html;charset=utf-8,'+testName
  367. });
  368. assert.fail('a bad sidebar was created..');
  369. sidebar.destroy();
  370. }
  371. catch(e) {
  372. assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
  373. }
  374. }
  375. exports.testInvalidBlankID = function(assert) {
  376. const { Sidebar } = require('sdk/ui/sidebar');
  377. let testName = 'testInvalidBlankID';
  378. try {
  379. let sidebar = Sidebar({
  380. id: '',
  381. title: testName,
  382. url: 'data:text/html;charset=utf-8,'+testName
  383. });
  384. assert.fail('a bad sidebar was created..');
  385. sidebar.destroy();
  386. }
  387. catch(e) {
  388. assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
  389. }
  390. }
  391. exports.testInvalidNullID = function(assert) {
  392. const { Sidebar } = require('sdk/ui/sidebar');
  393. let testName = 'testInvalidNullID';
  394. try {
  395. let sidebar = Sidebar({
  396. id: null,
  397. title: testName,
  398. url: 'data:text/html;charset=utf-8,'+testName
  399. });
  400. assert.fail('a bad sidebar was created..');
  401. sidebar.destroy();
  402. }
  403. catch(e) {
  404. assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
  405. }
  406. }
  407. exports.testUndefinedID = function(assert) {
  408. const { Sidebar } = require('sdk/ui/sidebar');
  409. let testName = 'testInvalidUndefinedID';
  410. try {
  411. let sidebar = Sidebar({
  412. title: testName,
  413. url: 'data:text/html;charset=utf-8,' + testName
  414. });
  415. assert.ok(sidebar.id, 'an undefined id was accepted, id was creawted: ' + sidebar.id);
  416. assert.ok(getMostRecentBrowserWindow().document.getElementById(makeID(sidebar.id)), 'the sidebar element was found');
  417. sidebar.destroy();
  418. }
  419. catch(e) {
  420. assert.fail('undefined ids are acceptable');
  421. assert.fail(e.message);
  422. }
  423. }
  424. // TEST: edge case where web panel is destroyed while loading
  425. exports.testDestroyEdgeCaseBug = function(assert, done) {
  426. const { Sidebar } = require('sdk/ui/sidebar');
  427. let testName = 'testDestroyEdgeCaseBug';
  428. let window = getMostRecentBrowserWindow();
  429. let sidebar = Sidebar({
  430. id: testName,
  431. title: testName,
  432. url: 'data:text/html;charset=utf-8,'+testName
  433. });
  434. // NOTE: purposely not listening to show event b/c the event happens
  435. // between now and then.
  436. sidebar.show();
  437. assert.equal(isPrivate(window), false, 'the new window is not private');
  438. assert.equal(isSidebarShowing(window), true, 'the sidebar is showing');
  439. //assert.equal(isShowing(sidebar), true, 'the sidebar is showing');
  440. open().then(focus).then(function(window2) {
  441. assert.equal(isPrivate(window2), false, 'the new window is not private');
  442. assert.equal(isSidebarShowing(window2), false, 'the sidebar is not showing');
  443. assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
  444. sidebar.destroy();
  445. assert.pass('destroying the sidebar');
  446. close(window2).then(function() {
  447. let loader = Loader(module);
  448. assert.equal(isPrivate(window), false, 'the current window is not private');
  449. let sidebar = loader.require('sdk/ui/sidebar').Sidebar({
  450. id: testName,
  451. title: testName,
  452. url: 'data:text/html;charset=utf-8,'+ testName,
  453. onShow: function() {
  454. assert.pass('onShow works for Sidebar');
  455. loader.unload();
  456. let sidebarMI = getSidebarMenuitems();
  457. for (let mi of sidebarMI) {
  458. assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar')
  459. assert.ok(!isChecked(mi), 'no sidebar menuitem is checked');
  460. }
  461. assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
  462. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
  463. done();
  464. }
  465. })
  466. sidebar.show();
  467. assert.pass('showing the sidebar');
  468. });
  469. });
  470. }
  471. exports.testClickingACheckedMenuitem = function(assert, done) {
  472. const { Sidebar } = require('sdk/ui/sidebar');
  473. let testName = 'testClickingACheckedMenuitem';
  474. let window = getMostRecentBrowserWindow();
  475. let sidebar = Sidebar({
  476. id: testName,
  477. title: testName,
  478. url: 'data:text/html;charset=utf-8,'+testName,
  479. });
  480. sidebar.show().then(function() {
  481. assert.pass('the show callback works');
  482. sidebar.once('hide', function() {
  483. assert.pass('clicking the menuitem after the sidebar has shown hides it.');
  484. sidebar.destroy();
  485. done();
  486. });
  487. let menuitem = window.document.getElementById(makeID(sidebar.id));
  488. simulateCommand(menuitem);
  489. });
  490. };
  491. exports.testTitleSetter = function(assert, done) {
  492. const { Sidebar } = require('sdk/ui/sidebar');
  493. let testName = 'testTitleSetter';
  494. let { document } = getMostRecentBrowserWindow();
  495. let sidebar1 = Sidebar({
  496. id: testName,
  497. title: testName,
  498. url: 'data:text/html;charset=utf-8,'+testName,
  499. });
  500. assert.equal(sidebar1.title, testName, 'title getter works');
  501. sidebar1.show().then(function() {
  502. assert.equal(document.getElementById(makeID(sidebar1.id)).getAttribute('label'),
  503. testName,
  504. 'the menuitem label is correct');
  505. assert.equal(document.getElementById('sidebar-title').value, testName, 'the menuitem label is correct');
  506. sidebar1.title = 'foo';
  507. assert.equal(sidebar1.title, 'foo', 'title getter works');
  508. assert.equal(document.getElementById(makeID(sidebar1.id)).getAttribute('label'),
  509. 'foo',
  510. 'the menuitem label was updated');
  511. assert.equal(document.getElementById('sidebar-title').value, 'foo', 'the sidebar title was updated');
  512. sidebar1.destroy();
  513. done();
  514. }, assert.fail);
  515. }
  516. exports.testURLSetter = function(assert, done) {
  517. const { Sidebar } = require('sdk/ui/sidebar');
  518. let testName = 'testURLSetter';
  519. let window = getMostRecentBrowserWindow();
  520. let { document } = window;
  521. let url = 'data:text/html;charset=utf-8,'+testName;
  522. let sidebar1 = Sidebar({
  523. id: testName,
  524. title: testName,
  525. url: url
  526. });
  527. assert.equal(sidebar1.url, url, 'url getter works');
  528. assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
  529. assert.ok(!isChecked(document.getElementById(makeID(sidebar1.id))),
  530. 'the menuitem is not checked');
  531. assert.equal(isSidebarShowing(window), false, 'the new window sidebar is not showing');
  532. windowPromise(window.OpenBrowserWindow(), 'load').then(function(window) {
  533. let { document } = window;
  534. assert.pass('new window was opened');
  535. sidebar1.show().then(function() {
  536. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  537. assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
  538. 'the menuitem is checked');
  539. assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
  540. sidebar1.once('show', function() {
  541. assert.pass('setting the sidebar.url causes a show event');
  542. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  543. assert.ok(isSidebarShowing(window), 'the new window sidebar is still showing');
  544. assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
  545. 'the menuitem is still checked');
  546. sidebar1.destroy();
  547. close(window).then(done);
  548. });
  549. sidebar1.url = (url + '1');
  550. assert.equal(sidebar1.url, (url + '1'), 'url getter works');
  551. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  552. assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
  553. }, assert.fail);
  554. }, assert.fail);
  555. }
  556. exports.testDuplicateID = function(assert) {
  557. const { Sidebar } = require('sdk/ui/sidebar');
  558. let testName = 'testDuplicateID';
  559. let window = getMostRecentBrowserWindow();
  560. let { document } = window;
  561. let url = 'data:text/html;charset=utf-8,'+testName;
  562. let sidebar1 = Sidebar({
  563. id: testName,
  564. title: testName,
  565. url: url
  566. });
  567. assert.throws(function() {
  568. Sidebar({
  569. id: testName,
  570. title: testName + 1,
  571. url: url + 2
  572. }).destroy();
  573. }, /The ID .+ seems already used\./i, 'duplicate IDs will throw errors');
  574. sidebar1.destroy();
  575. }
  576. exports.testURLSetterToSameValueReloadsSidebar = function(assert, done) {
  577. const { Sidebar } = require('sdk/ui/sidebar');
  578. let testName = 'testURLSetterToSameValueReloadsSidebar';
  579. let window = getMostRecentBrowserWindow();
  580. let { document } = window;
  581. let url = 'data:text/html;charset=utf-8,'+testName;
  582. let sidebar1 = Sidebar({
  583. id: testName,
  584. title: testName,
  585. url: url
  586. });
  587. assert.equal(sidebar1.url, url, 'url getter works');
  588. assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
  589. assert.ok(!isChecked(document.getElementById(makeID(sidebar1.id))),
  590. 'the menuitem is not checked');
  591. assert.equal(isSidebarShowing(window), false, 'the new window sidebar is not showing');
  592. windowPromise(window.OpenBrowserWindow(), 'load').then(function(window) {
  593. let { document } = window;
  594. assert.pass('new window was opened');
  595. sidebar1.show().then(function() {
  596. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  597. assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
  598. 'the menuitem is checked');
  599. assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
  600. sidebar1.once('show', function() {
  601. assert.pass('setting the sidebar.url causes a show event');
  602. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  603. assert.ok(isSidebarShowing(window), 'the new window sidebar is still showing');
  604. assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
  605. 'the menuitem is still checked');
  606. sidebar1.destroy();
  607. close(window).then(done);
  608. });
  609. sidebar1.url = url;
  610. assert.equal(sidebar1.url, url, 'url getter works');
  611. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  612. assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
  613. }, assert.fail);
  614. }, assert.fail);
  615. }
  616. exports.testShowingInOneWindowDoesNotAffectOtherWindows = function(assert, done) {
  617. const { Sidebar } = require('sdk/ui/sidebar');
  618. let testName = 'testShowingInOneWindowDoesNotAffectOtherWindows';
  619. let window1 = getMostRecentBrowserWindow();
  620. let url = 'data:text/html;charset=utf-8,'+testName;
  621. let sidebar1 = Sidebar({
  622. id: testName,
  623. title: testName,
  624. url: url
  625. });
  626. assert.equal(sidebar1.url, url, 'url getter works');
  627. assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
  628. let checkCount = 1;
  629. function checkSidebarShowing(window, expected) {
  630. assert.pass('check count ' + checkCount++);
  631. let mi = window.document.getElementById(makeID(sidebar1.id));
  632. if (mi) {
  633. assert.equal(isChecked(mi), expected,
  634. 'the menuitem is not checked');
  635. }
  636. assert.equal(isSidebarShowing(window), expected || false, 'the new window sidebar is not showing');
  637. }
  638. checkSidebarShowing(window1, false);
  639. windowPromise(window1.OpenBrowserWindow(), 'load').then(function(window) {
  640. let { document } = window;
  641. assert.pass('new window was opened!');
  642. // waiting for show
  643. sidebar1.once('show', function() {
  644. // check state of the new window
  645. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  646. checkSidebarShowing(window, true);
  647. // check state of old window
  648. checkSidebarShowing(window1, false);
  649. // waiting for show using url setter
  650. sidebar1.once('show', function() {
  651. assert.pass('setting the sidebar.url causes a new show event');
  652. // check state of the new window
  653. assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
  654. checkSidebarShowing(window, true);
  655. // check state of old window
  656. checkSidebarShowing(window1, false);
  657. // calling destroy() twice should not matter
  658. sidebar1.destroy();
  659. sidebar1.destroy();
  660. // check state of the new window
  661. assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
  662. checkSidebarShowing(window, undefined);
  663. // check state of old window
  664. checkSidebarShowing(window1, undefined);
  665. close(window).then(done);
  666. });
  667. assert.pass('setting sidebar1.url');
  668. sidebar1.url += '1';
  669. assert.pass('set sidebar1.url');
  670. });
  671. sidebar1.show();
  672. }, assert.fail);
  673. }
  674. exports.testHidingAHiddenSidebarRejects = function(assert) {
  675. const { Sidebar } = require('sdk/ui/sidebar');
  676. let testName = 'testHidingAHiddenSidebarRejects';
  677. let url = 'data:text/html;charset=utf-8,'+testName;
  678. let sidebar = Sidebar({
  679. id: testName,
  680. title: testName,
  681. url: url
  682. });
  683. sidebar.hide().then(assert.fail, assert.pass).then(function() {
  684. sidebar.destroy();
  685. done();
  686. }, assert.fail);
  687. }
  688. exports.testGCdSidebarsOnUnload = function(assert, done) {
  689. const loader = Loader(module);
  690. const { Sidebar } = loader.require('sdk/ui/sidebar');
  691. const window = getMostRecentBrowserWindow();
  692. let testName = 'testGCdSidebarsOnUnload';
  693. let url = 'data:text/html;charset=utf-8,'+testName;
  694. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
  695. // IMPORTANT: make no reference to the sidebar instance, so it is GC'd
  696. let sidebar = Sidebar({
  697. id: testName,
  698. title: testName,
  699. url: url
  700. });
  701. sidebar.show().then(function() {
  702. sidebar = null;
  703. assert.equal(isSidebarShowing(window), true, 'the sidebar is showing');
  704. let menuitemID = makeID(testName);
  705. assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found');
  706. Cu.schedulePreciseGC(function() {
  707. loader.unload();
  708. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing after unload');
  709. assert.ok(!window.document.getElementById(menuitemID), 'the menuitem was removed');
  710. done();
  711. })
  712. }, assert.fail).then(null, assert.fail);
  713. }
  714. exports.testGCdShowingSidebarsOnUnload = function(assert, done) {
  715. const loader = Loader(module);
  716. const { Sidebar } = loader.require('sdk/ui/sidebar');
  717. const window = getMostRecentBrowserWindow();
  718. let testName = 'testGCdShowingSidebarsOnUnload';
  719. let url = 'data:text/html;charset=utf-8,'+testName;
  720. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
  721. let sidebar = Sidebar({
  722. id: testName,
  723. title: testName,
  724. url: url
  725. });
  726. sidebar.on('show', function() {
  727. sidebar = null;
  728. assert.equal(isSidebarShowing(window), true, 'the sidebar is showing');
  729. let menuitemID = makeID(testName);
  730. assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found');
  731. Cu.schedulePreciseGC(function() {
  732. assert.equal(isSidebarShowing(window), true, 'the sidebar is still showing after gc');
  733. assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found after gc');
  734. loader.unload();
  735. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing after unload');
  736. assert.ok(!window.document.getElementById(menuitemID), 'the menuitem was removed');
  737. done();
  738. })
  739. });
  740. sidebar.show();
  741. }
  742. exports.testDetachEventOnWindowClose = function(assert, done) {
  743. const loader = Loader(module);
  744. const { Sidebar } = loader.require('sdk/ui/sidebar');
  745. const window = getMostRecentBrowserWindow();
  746. let testName = 'testDetachEventOnWindowClose';
  747. let url = 'data:text/html;charset=utf-8,' + testName;
  748. windowPromise(window.OpenBrowserWindow(), 'load').then(focus).then(function(window) {
  749. let sidebar = Sidebar({
  750. id: testName,
  751. title: testName,
  752. url: url,
  753. onAttach: function() {
  754. assert.pass('the attach event is fired');
  755. window.close();
  756. },
  757. onDetach: function() {
  758. assert.pass('the detach event is fired when the window showing it closes');
  759. loader.unload();
  760. done();
  761. }
  762. });
  763. sidebar.show();
  764. }).then(null, assert.fail);
  765. }
  766. exports.testHideEventOnWindowClose = function(assert, done) {
  767. const loader = Loader(module);
  768. const { Sidebar } = loader.require('sdk/ui/sidebar');
  769. const window = getMostRecentBrowserWindow();
  770. let testName = 'testDetachEventOnWindowClose';
  771. let url = 'data:text/html;charset=utf-8,' + testName;
  772. windowPromise(window.OpenBrowserWindow(), 'load').then(focus).then(function(window) {
  773. let sidebar = Sidebar({
  774. id: testName,
  775. title: testName,
  776. url: url,
  777. onAttach: function() {
  778. assert.pass('the attach event is fired');
  779. window.close();
  780. },
  781. onHide: function() {
  782. assert.pass('the hide event is fired when the window showing it closes');
  783. loader.unload();
  784. done();
  785. }
  786. });
  787. sidebar.show();
  788. }).then(null, assert.fail);
  789. }
  790. exports.testGCdHiddenSidebarsOnUnload = function(assert, done) {
  791. const loader = Loader(module);
  792. const { Sidebar } = loader.require('sdk/ui/sidebar');
  793. const window = getMostRecentBrowserWindow();
  794. let testName = 'testGCdHiddenSidebarsOnUnload';
  795. let url = 'data:text/html;charset=utf-8,'+testName;
  796. assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
  797. // IMPORTANT: make no reference to the sidebar instance, so it is GC'd
  798. Sidebar({
  799. id: testName,
  800. title: testName,
  801. url: url
  802. });
  803. let menuitemID = makeID(testName);
  804. assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found');
  805. Cu.schedulePreciseGC(function() {
  806. assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found after gc');
  807. loader.unload();
  808. assert.ok(!window.document.getElementById(menuitemID), 'the menuitem was removed');
  809. done();
  810. });
  811. }
  812. exports.testSidebarGettersAndSettersAfterDestroy = function(assert) {
  813. const { Sidebar } = require('sdk/ui/sidebar');
  814. let testName = 'testSidebarGettersAndSettersAfterDestroy';
  815. let url = 'data:text/html;charset=utf-8,'+testName;
  816. let sidebar = Sidebar({
  817. id: testName,
  818. title: testName,
  819. url: url
  820. });
  821. sidebar.destroy();
  822. assert.equal(sidebar.id, undefined, 'sidebar after destroy has no id');
  823. assert.throws(() => sidebar.id = 'foo-tang',
  824. /^setting a property that has only a getter/,
  825. 'id cannot be set at runtime');
  826. assert.equal(sidebar.id, undefined, 'sidebar after destroy has no id');
  827. assert.equal(sidebar.title, undefined, 'sidebar after destroy has no title');
  828. sidebar.title = 'boo-tang';
  829. assert.equal(sidebar.title, undefined, 'sidebar after destroy has no title');
  830. assert.equal(sidebar.url, undefined, 'sidebar after destroy has no url');
  831. sidebar.url = url + 'barz';
  832. assert.equal(sidebar.url, undefined, 'sidebar after destroy has no url');
  833. }
  834. exports.testSidebarLeakCheckDestroyAfterAttach = function(assert, done) {
  835. const { Sidebar } = require('sdk/ui/sidebar');
  836. let testName = 'testSidebarLeakCheckDestroyAfterAttach';
  837. let window = getMostRecentBrowserWindow();
  838. let sidebar = Sidebar({
  839. id: testName,
  840. title: testName,
  841. url: 'data:text/html;charset=utf-8,'+testName
  842. });
  843. sidebar.on('attach', function() {
  844. assert.pass('the sidebar was shown');
  845. sidebar.on('show', function() {
  846. assert.fail('the sidebar show listener should have been removed');
  847. });
  848. assert.pass('added a sidebar show listener');
  849. sidebar.on('hide', function() {
  850. assert.fail('the sidebar hide listener should have been removed');
  851. });
  852. assert.pass('added a sidebar hide listener');
  853. let panelBrowser = window.document.getElementById('sidebar').contentDocument.getElementById('web-panels-browser');
  854. panelBrowser.contentWindow.addEventListener('unload', function onUnload() {
  855. panelBrowser.contentWindow.removeEventListener('unload', onUnload, false);
  856. // wait a tick..
  857. setTimeout(function() {
  858. assert.pass('the sidebar web panel was unloaded properly');
  859. done();
  860. })
  861. }, false);
  862. sidebar.destroy();
  863. });
  864. assert.pass('showing the sidebar');
  865. sidebar.show();
  866. }
  867. exports.testSidebarLeakCheckUnloadAfterAttach = function(assert, done) {
  868. const loader = Loader(module);
  869. const { Sidebar } = loader.require('sdk/ui/sidebar');
  870. let testName = 'testSidebarLeakCheckUnloadAfterAttach';
  871. let window = getMostRecentBrowserWindow();
  872. let sidebar = Sidebar({
  873. id: testName,
  874. title: testName,
  875. url: 'data:text/html;charset=utf-8,'+testName
  876. });
  877. sidebar.on('attach', function() {
  878. assert.pass('the sidebar was shown');
  879. sidebar.on('show', function() {
  880. assert.fail('the sidebar show listener should have been removed');
  881. });
  882. assert.pass('added a sidebar show listener');
  883. sidebar.on('hide', function() {
  884. assert.fail('the sidebar hide listener should have been removed');
  885. });
  886. assert.pass('added a sidebar hide listener');
  887. let panelBrowser = window.document.getElementById('sidebar').contentDocument.getElementById('web-panels-browser');
  888. panelBrowser.contentWindow.addEventListener('unload', function onUnload() {
  889. panelBrowser.contentWindow.removeEventListener('unload', onUnload, false);
  890. // wait a tick..
  891. setTimeout(function() {
  892. assert.pass('the sidebar web panel was unloaded properly');
  893. done();
  894. })
  895. }, false);
  896. loader.unload();
  897. });
  898. assert.pass('showing the sidebar');
  899. sidebar.show();
  900. }
  901. exports.testTwoSidebarsWithSameTitleAndURL = function(assert) {
  902. const { Sidebar } = require('sdk/ui/sidebar');
  903. let testName = 'testTwoSidebarsWithSameTitleAndURL';
  904. let title = testName;
  905. let url = 'data:text/html;charset=utf-8,' + testName;
  906. let sidebar1 = Sidebar({
  907. id: testName + 1,
  908. title: title,
  909. url: url
  910. });
  911. assert.throws(function() {
  912. Sidebar({
  913. id: testName + 2,
  914. title: title,
  915. url: url
  916. }).destroy();
  917. }, /title.+url.+invalid/i, 'Creating two sidebars with the same title + url is not allowed');
  918. let sidebar2 = Sidebar({
  919. id: testName + 2,
  920. title: title,
  921. url: 'data:text/html;charset=utf-8,X'
  922. });
  923. assert.throws(function() {
  924. sidebar2.url = url;
  925. }, /title.+url.+invalid/i, 'Creating two sidebars with the same title + url is not allowed');
  926. sidebar2.title = 'foo';
  927. sidebar2.url = url;
  928. assert.throws(function() {
  929. sidebar2.title = title;
  930. }, /title.+url.+invalid/i, 'Creating two sidebars with the same title + url is not allowed');
  931. sidebar1.destroy();
  932. sidebar2.destroy();
  933. }
  934. exports.testChangingURLBackToOriginalValue = function(assert) {
  935. const { Sidebar } = require('sdk/ui/sidebar');
  936. let testName = 'testChangingURLBackToOriginalValue';
  937. let title = testName;
  938. let url = 'data:text/html;charset=utf-8,' + testName;
  939. let count = 0;
  940. let sidebar = Sidebar({
  941. id: testName,
  942. title: title,
  943. url: url
  944. });
  945. sidebar.url = url + 2;
  946. assert.equal(sidebar.url, url + 2, 'the sidebar.url is correct');
  947. sidebar.url = url;
  948. assert.equal(sidebar.url, url, 'the sidebar.url is correct');
  949. sidebar.title = 'foo';
  950. assert.equal(sidebar.title, 'foo', 'the sidebar.title is correct');
  951. sidebar.title = title;
  952. assert.equal(sidebar.title, title, 'the sidebar.title is correct');
  953. sidebar.destroy();
  954. assert.pass('Changing values back to originals works');
  955. }
  956. exports.testShowToOpenXToClose = function(assert, done) {
  957. const { Sidebar } = require('sdk/ui/sidebar');
  958. let testName = 'testShowToOpenXToClose';
  959. let title = testName;
  960. let url = 'data:text/html;charset=utf-8,' + testName;
  961. let window = getMostRecentBrowserWindow();
  962. let sidebar = Sidebar({
  963. id: testName,
  964. title: testName,
  965. url: url,
  966. onShow: function() {
  967. assert.ok(isChecked(menuitem), 'menuitem is checked');
  968. let closeButton = window.document.querySelector('#sidebar-header > toolbarbutton.tabs-closebutton');
  969. simulateCommand(closeButton);
  970. },
  971. onHide: function() {
  972. assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  973. sidebar.destroy();
  974. done();
  975. }
  976. });
  977. let menuitem = window.document.getElementById(makeID(sidebar.id));
  978. assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  979. sidebar.show();
  980. }
  981. exports.testShowToOpenMenuitemToClose = function(assert, done) {
  982. const { Sidebar } = require('sdk/ui/sidebar');
  983. let testName = 'testShowToOpenMenuitemToClose';
  984. let title = testName;
  985. let url = 'data:text/html;charset=utf-8,' + testName;
  986. let window = getMostRecentBrowserWindow();
  987. let sidebar = Sidebar({
  988. id: testName,
  989. title: testName,
  990. url: url,
  991. onShow: function() {
  992. assert.ok(isChecked(menuitem), 'menuitem is checked');
  993. simulateCommand(menuitem);
  994. },
  995. onHide: function() {
  996. assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  997. sidebar.destroy();
  998. done();
  999. }
  1000. });
  1001. let menuitem = window.document.getElementById(makeID(sidebar.id));
  1002. assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  1003. sidebar.show();
  1004. }
  1005. exports.testDestroyWhileNonBrowserWindowIsOpen = function(assert, done) {
  1006. const { Sidebar } = require('sdk/ui/sidebar');
  1007. let testName = 'testDestroyWhileNonBrowserWindowIsOpen';
  1008. let url = 'data:text/html;charset=utf-8,' + testName;
  1009. let sidebar = Sidebar({
  1010. id: testName,
  1011. title: testName,
  1012. url: url
  1013. });
  1014. open('chrome://browser/content/preferences/preferences.xul').then(function(window) {
  1015. try {
  1016. sidebar.show();
  1017. assert.equal(isSidebarShowing(getMostRecentBrowserWindow()), true, 'the sidebar is showing');
  1018. sidebar.destroy();
  1019. assert.pass('sidebar was destroyed while a non browser window was open');
  1020. }
  1021. catch(e) {
  1022. assert.fail(e);
  1023. }
  1024. return window;
  1025. }).then(close).then(function() {
  1026. assert.equal(isSidebarShowing(getMostRecentBrowserWindow()), false, 'the sidebar is not showing');
  1027. }).then(done, assert.fail);
  1028. }
  1029. exports.testEventListeners = function(assert, done) {
  1030. const { Sidebar } = require('sdk/ui/sidebar');
  1031. let testName = 'testWhatThisIsInSidebarEventListeners';
  1032. let eventListenerOrder = [];
  1033. let constructorOnShow = defer();
  1034. let constructorOnHide = defer();
  1035. let constructorOnAttach = defer();
  1036. let constructorOnReady = defer();
  1037. let onShow = defer();
  1038. let onHide = defer();
  1039. let onAttach = defer();
  1040. let onReady = defer();
  1041. let onceShow = defer();
  1042. let onceHide = defer();
  1043. let onceAttach = defer();
  1044. let onceReady = defer();
  1045. function testThis() {
  1046. assert(this, sidebar, '`this` is correct');
  1047. }
  1048. let sidebar = Sidebar({
  1049. id: testName,
  1050. title: testName,
  1051. url: 'data:text/html;charset=utf-8,' + testName,
  1052. onShow: function() {
  1053. assert.equal(this, sidebar, '`this` is correct in onShow');
  1054. eventListenerOrder.push('onShow');
  1055. constructorOnShow.resolve();
  1056. },
  1057. onAttach: function() {
  1058. assert.equal(this, sidebar, '`this` is correct in onAttach');
  1059. eventListenerOrder.push('onAttach');
  1060. constructorOnAttach.resolve();
  1061. },
  1062. onReady: function() {
  1063. assert.equal(this, sidebar, '`this` is correct in onReady');
  1064. eventListenerOrder.push('onReady');
  1065. constructorOnReady.resolve();
  1066. },
  1067. onHide: function() {
  1068. assert.equal(this, sidebar, '`this` is correct in onHide');
  1069. eventListenerOrder.push('onHide');
  1070. constructorOnHide.resolve();
  1071. }
  1072. });
  1073. sidebar.once('show', function() {
  1074. assert.equal(this, sidebar, '`this` is correct in once show');
  1075. eventListenerOrder.push('once show');
  1076. onceShow.resolve();
  1077. });
  1078. sidebar.once('attach', function() {
  1079. assert.equal(this, sidebar, '`this` is correct in once attach');
  1080. eventListenerOrder.push('once attach');
  1081. onceAttach.resolve();
  1082. });
  1083. sidebar.once('ready', function() {
  1084. assert.equal(this, sidebar, '`this` is correct in once ready');
  1085. eventListenerOrder.push('once ready');
  1086. onceReady.resolve();
  1087. });
  1088. sidebar.once('hide', function() {
  1089. assert.equal(this, sidebar, '`this` is correct in once hide');
  1090. eventListenerOrder.push('once hide');
  1091. onceHide.resolve();
  1092. });
  1093. sidebar.on('show', function() {
  1094. assert.equal(this, sidebar, '`this` is correct in on show');
  1095. eventListenerOrder.push('on show');
  1096. onShow.resolve();
  1097. sidebar.hide();
  1098. });
  1099. sidebar.on('attach', function() {
  1100. assert.equal(this, sidebar, '`this` is correct in on attach');
  1101. eventListenerOrder.push('on attach');
  1102. onAttach.resolve();
  1103. });
  1104. sidebar.on('ready', function() {
  1105. assert.equal(this, sidebar, '`this` is correct in on ready');
  1106. eventListenerOrder.push('on ready');
  1107. onReady.resolve();
  1108. });
  1109. sidebar.on('hide', function() {
  1110. assert.equal(this, sidebar, '`this` is correct in on hide');
  1111. eventListenerOrder.push('on hide');
  1112. onHide.resolve();
  1113. });
  1114. all(constructorOnShow.promise,
  1115. constructorOnAttach.promise,
  1116. constructorOnReady.promise,
  1117. constructorOnHide.promise,
  1118. onceShow.promise,
  1119. onceAttach.promise,
  1120. onceReady.promise,
  1121. onceHide.promise,
  1122. onShow.promise,
  1123. onAttach.promise,
  1124. onReady.promise,
  1125. onHide.promise).then(function() {
  1126. assert.equal(eventListenerOrder.join(), [
  1127. 'onAttach',
  1128. 'once attach',
  1129. 'on attach',
  1130. 'onReady',
  1131. 'once ready',
  1132. 'on ready',
  1133. 'onShow',
  1134. 'once show',
  1135. 'on show',
  1136. 'onHide',
  1137. 'once hide',
  1138. 'on hide'
  1139. ].join(), 'the event order was correct');
  1140. sidebar.destroy();
  1141. }).then(done, assert.fail);
  1142. sidebar.show();
  1143. }
  1144. // For more information see Bug 920780
  1145. exports.testAttachDoesNotEmitWhenShown = function(assert, done) {
  1146. const { Sidebar } = require('sdk/ui/sidebar');
  1147. let testName = 'testSidebarLeakCheckUnloadAfterAttach';
  1148. let count = 0;
  1149. let sidebar = Sidebar({
  1150. id: testName,
  1151. title: testName,
  1152. url: 'data:text/html;charset=utf-8,'+testName,
  1153. onAttach: function() {
  1154. if (count > 2) {
  1155. assert.fail('sidebar was attached again..');
  1156. }
  1157. else {
  1158. assert.pass('sidebar was attached ' + count + ' time(s)');
  1159. }
  1160. if (++count == 1) {
  1161. setTimeout(function() {
  1162. let shown = false;
  1163. let endShownTest = false;
  1164. sidebar.once('show', function() {
  1165. assert.pass('shown was emitted');
  1166. shown = !endShownTest && true;
  1167. });
  1168. sidebar.show().then(function() {
  1169. assert.pass('calling hide');
  1170. sidebar.hide();
  1171. }).then(function() {
  1172. endShownTest = true;
  1173. setTimeout(function() {
  1174. sidebar.show().then(function() {
  1175. assert.ok(!shown, 'show did not emit');
  1176. sidebar.hide().then(function() {
  1177. sidebar.destroy();
  1178. done();
  1179. }).then(null, assert.fail);
  1180. })
  1181. })
  1182. }).then(null, assert.fail);
  1183. });
  1184. }
  1185. }
  1186. });
  1187. sidebar.show();
  1188. }
  1189. // If the module doesn't support the app we're being run in, require() will
  1190. // throw. In that case, remove all tests above from exports, and add one dummy
  1191. // test that passes.
  1192. try {
  1193. require('sdk/ui/sidebar');
  1194. }
  1195. catch (err) {
  1196. if (!/^Unsupported Application/.test(err.message))
  1197. throw err;
  1198. module.exports = {
  1199. 'test Unsupported Application': assert => assert.pass(err.message)
  1200. }
  1201. }
  1202. require('sdk/test').run(exports);