addon-sdk/source/test/test-ui-action-button.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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';
     6 module.metadata = {
     7   'engines': {
     8     'Firefox': '> 28'
     9   }
    10 };
    12 const { Cu } = require('chrome');
    13 const { Loader } = require('sdk/test/loader');
    14 const { data } = require('sdk/self');
    15 const { open, focus, close } = require('sdk/window/helpers');
    16 const { setTimeout } = require('sdk/timers');
    17 const { getMostRecentBrowserWindow } = require('sdk/window/utils');
    18 const { partial } = require('sdk/lang/functional');
    20 const openBrowserWindow = partial(open, null, {features: {toolbar: true}});
    21 const openPrivateBrowserWindow = partial(open, null,
    22   {features: {toolbar: true, private: true}});
    24 function getWidget(buttonId, window = getMostRecentBrowserWindow()) {
    25   const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
    26   const { AREA_NAVBAR } = CustomizableUI;
    28   let widgets = CustomizableUI.getWidgetIdsInArea(AREA_NAVBAR).
    29     filter((id) => id.startsWith('action-button--') && id.endsWith(buttonId));
    31   if (widgets.length === 0)
    32     throw new Error('Widget with id `' + id +'` not found.');
    34   if (widgets.length > 1)
    35     throw new Error('Unexpected number of widgets: ' + widgets.length)
    37   return CustomizableUI.getWidget(widgets[0]).forWindow(window);
    38 };
    40 exports['test basic constructor validation'] = function(assert) {
    41   let loader = Loader(module);
    42   let { ActionButton } = loader.require('sdk/ui');
    44   assert.throws(
    45     () => ActionButton({}),
    46     /^The option/,
    47     'throws on no option given');
    49   // Test no label
    50   assert.throws(
    51     () => ActionButton({ id: 'my-button', icon: './icon.png'}),
    52     /^The option "label"/,
    53     'throws on no label given');
    55   // Test no id
    56   assert.throws(
    57     () => ActionButton({ label: 'my button', icon: './icon.png' }),
    58     /^The option "id"/,
    59     'throws on no id given');
    61   // Test no icon
    62   assert.throws(
    63     () => ActionButton({ id: 'my-button', label: 'my button' }),
    64     /^The option "icon"/,
    65     'throws on no icon given');
    68   // Test empty label
    69   assert.throws(
    70     () => ActionButton({ id: 'my-button', label: '', icon: './icon.png' }),
    71     /^The option "label"/,
    72     'throws on no valid label given');
    74   // Test invalid id
    75   assert.throws(
    76     () => ActionButton({ id: 'my button', label: 'my button', icon: './icon.png' }),
    77     /^The option "id"/,
    78     'throws on no valid id given');
    80   // Test empty id
    81   assert.throws(
    82     () => ActionButton({ id: '', label: 'my button', icon: './icon.png' }),
    83     /^The option "id"/,
    84     'throws on no valid id given');
    86   // Test remote icon
    87   assert.throws(
    88     () => ActionButton({ id: 'my-button', label: 'my button', icon: 'http://www.mozilla.org/favicon.ico'}),
    89     /^The option "icon"/,
    90     'throws on no valid icon given');
    92   // Test wrong icon: no absolute URI to local resource, neither relative './'
    93   assert.throws(
    94     () => ActionButton({ id: 'my-button', label: 'my button', icon: 'icon.png'}),
    95     /^The option "icon"/,
    96     'throws on no valid icon given');
    98   // Test wrong icon: no absolute URI to local resource, neither relative './'
    99   assert.throws(
   100     () => ActionButton({ id: 'my-button', label: 'my button', icon: 'foo and bar'}),
   101     /^The option "icon"/,
   102     'throws on no valid icon given');
   104   // Test wrong icon: '../' is not allowed
   105   assert.throws(
   106     () => ActionButton({ id: 'my-button', label: 'my button', icon: '../icon.png'}),
   107     /^The option "icon"/,
   108     'throws on no valid icon given');
   110   loader.unload();
   111 };
   113 exports['test button added'] = function(assert) {
   114   let loader = Loader(module);
   115   let { ActionButton } = loader.require('sdk/ui');
   117   let button = ActionButton({
   118     id: 'my-button-1',
   119     label: 'my button',
   120     icon: './icon.png'
   121   });
   123   // check defaults
   124   assert.equal(button.disabled, false,
   125     'disabled is set to default `false` value');
   127   let { node } = getWidget(button.id);
   129   assert.ok(!!node, 'The button is in the navbar');
   131   assert.equal(button.label, node.getAttribute('label'),
   132     'label is set');
   134   assert.equal(button.label, node.getAttribute('tooltiptext'),
   135     'tooltip is set');
   137   assert.equal(data.url(button.icon.substr(2)), node.getAttribute('image'),
   138     'icon is set');
   140   loader.unload();
   141 }
   143 exports['test button added with resource URI'] = function(assert) {
   144   let loader = Loader(module);
   145   let { ActionButton } = loader.require('sdk/ui');
   147   let button = ActionButton({
   148     id: 'my-button-1',
   149     label: 'my button',
   150     icon: data.url('icon.png')
   151   });
   153   assert.equal(button.icon, data.url('icon.png'),
   154     'icon is set');
   156   let { node } = getWidget(button.id);
   158   assert.equal(button.icon, node.getAttribute('image'),
   159     'icon on node is set');
   161   loader.unload();
   162 }
   164 exports['test button duplicate id'] = function(assert) {
   165   let loader = Loader(module);
   166   let { ActionButton } = loader.require('sdk/ui');
   168   let button = ActionButton({
   169     id: 'my-button-2',
   170     label: 'my button',
   171     icon: './icon.png'
   172   });
   174   assert.throws(() => {
   175     let doppelganger = ActionButton({
   176       id: 'my-button-2',
   177       label: 'my button',
   178       icon: './icon.png'
   179     });
   180   },
   181   /^The ID/,
   182   'No duplicates allowed');
   184   loader.unload();
   185 }
   187 exports['test button multiple destroy'] = function(assert) {
   188   let loader = Loader(module);
   189   let { ActionButton } = loader.require('sdk/ui');
   191   let button = ActionButton({
   192     id: 'my-button-2',
   193     label: 'my button',
   194     icon: './icon.png'
   195   });
   197   button.destroy();
   198   button.destroy();
   199   button.destroy();
   201   assert.pass('multiple destroy doesn\'t matter');
   203   loader.unload();
   204 }
   206 exports['test button removed on dispose'] = function(assert, done) {
   207   const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
   208   let loader = Loader(module);
   209   let { ActionButton } = loader.require('sdk/ui');
   211   let widgetId;
   213   CustomizableUI.addListener({
   214     onWidgetDestroyed: function(id) {
   215       if (id === widgetId) {
   216         CustomizableUI.removeListener(this);
   218         assert.pass('button properly removed');
   219         loader.unload();
   220         done();
   221       }
   222     }
   223   });
   225   let button = ActionButton({
   226     id: 'my-button-3',
   227     label: 'my button',
   228     icon: './icon.png'
   229   });
   231   // Tried to use `getWidgetIdsInArea` but seems undefined, not sure if it
   232   // was removed or it's not in the UX build yet
   233   widgetId = getWidget(button.id).id;
   235   button.destroy();
   236 };
   238 exports['test button global state updated'] = function(assert) {
   239   let loader = Loader(module);
   240   let { ActionButton } = loader.require('sdk/ui');
   242   let button = ActionButton({
   243     id: 'my-button-4',
   244     label: 'my button',
   245     icon: './icon.png'
   246   });
   248   // Tried to use `getWidgetIdsInArea` but seems undefined, not sure if it
   249   // was removed or it's not in the UX build yet
   251   let { node, id: widgetId } = getWidget(button.id);
   253   // check read-only properties
   255   assert.throws(() => button.id = 'another-id',
   256     /^setting a property that has only a getter/,
   257     'id cannot be set at runtime');
   259   assert.equal(button.id, 'my-button-4',
   260     'id is unchanged');
   261   assert.equal(node.id, widgetId,
   262     'node id is unchanged');
   264   // check writable properties
   266   button.label = 'New label';
   267   assert.equal(button.label, 'New label',
   268     'label is updated');
   269   assert.equal(node.getAttribute('label'), 'New label',
   270     'node label is updated');
   271   assert.equal(node.getAttribute('tooltiptext'), 'New label',
   272     'node tooltip is updated');
   274   button.icon = './new-icon.png';
   275   assert.equal(button.icon, './new-icon.png',
   276     'icon is updated');
   277   assert.equal(node.getAttribute('image'), data.url('new-icon.png'),
   278     'node image is updated');
   280   button.disabled = true;
   281   assert.equal(button.disabled, true,
   282     'disabled is updated');
   283   assert.equal(node.getAttribute('disabled'), 'true',
   284     'node disabled is updated');
   286   // TODO: test validation on update
   288   loader.unload();
   289 }
   291 exports['test button global state set and get with state method'] = function(assert) {
   292   let loader = Loader(module);
   293   let { ActionButton } = loader.require('sdk/ui');
   295   let button = ActionButton({
   296     id: 'my-button-16',
   297     label: 'my button',
   298     icon: './icon.png'
   299   });
   301   // read the button's state
   302   let state = button.state(button);
   304   assert.equal(state.label, 'my button',
   305     'label is correct');
   306   assert.equal(state.icon, './icon.png',
   307     'icon is correct');
   308   assert.equal(state.disabled, false,
   309     'disabled is correct');
   311   // set the new button's state
   312   button.state(button, {
   313     label: 'New label',
   314     icon: './new-icon.png',
   315     disabled: true
   316   });
   318   assert.equal(button.label, 'New label',
   319     'label is updated');
   320   assert.equal(button.icon, './new-icon.png',
   321     'icon is updated');
   322   assert.equal(button.disabled, true,
   323     'disabled is updated');
   325   loader.unload();
   326 }
   328 exports['test button global state updated on multiple windows'] = function(assert, done) {
   329   let loader = Loader(module);
   330   let { ActionButton } = loader.require('sdk/ui');
   332   let button = ActionButton({
   333     id: 'my-button-5',
   334     label: 'my button',
   335     icon: './icon.png'
   336   });
   338   let nodes = [getWidget(button.id).node];
   340   openBrowserWindow().then(window => {
   341     nodes.push(getWidget(button.id, window).node);
   343     button.label = 'New label';
   344     button.icon = './new-icon.png';
   345     button.disabled = true;
   347     for (let node of nodes) {
   348       assert.equal(node.getAttribute('label'), 'New label',
   349         'node label is updated');
   350       assert.equal(node.getAttribute('tooltiptext'), 'New label',
   351         'node tooltip is updated');
   353       assert.equal(button.icon, './new-icon.png',
   354         'icon is updated');
   355       assert.equal(node.getAttribute('image'), data.url('new-icon.png'),
   356         'node image is updated');
   358       assert.equal(button.disabled, true,
   359         'disabled is updated');
   360       assert.equal(node.getAttribute('disabled'), 'true',
   361         'node disabled is updated');
   362     };
   364     return window;
   365   }).
   366   then(close).
   367   then(loader.unload).
   368   then(done, assert.fail);
   369 };
   371 exports['test button window state'] = function(assert, done) {
   372   let loader = Loader(module);
   373   let { ActionButton } = loader.require('sdk/ui');
   374   let { browserWindows } = loader.require('sdk/windows');
   376   let button = ActionButton({
   377     id: 'my-button-6',
   378     label: 'my button',
   379     icon: './icon.png'
   380   });
   382   let mainWindow = browserWindows.activeWindow;
   383   let nodes = [getWidget(button.id).node];
   385   openBrowserWindow().then(focus).then(window => {
   386     nodes.push(getWidget(button.id, window).node);
   388     let { activeWindow } = browserWindows;
   390     button.state(activeWindow, {
   391       label: 'New label',
   392       icon: './new-icon.png',
   393       disabled: true
   394     });
   396     // check the states
   398     assert.equal(button.label, 'my button',
   399       'global label unchanged');
   400     assert.equal(button.icon, './icon.png',
   401       'global icon unchanged');
   402     assert.equal(button.disabled, false,
   403       'global disabled unchanged');
   405     let state = button.state(mainWindow);
   407     assert.equal(state.label, 'my button',
   408       'previous window label unchanged');
   409     assert.equal(state.icon, './icon.png',
   410       'previous window icon unchanged');
   411     assert.equal(state.disabled, false,
   412       'previous window disabled unchanged');
   414     let state = button.state(activeWindow);
   416     assert.equal(state.label, 'New label',
   417       'active window label updated');
   418     assert.equal(state.icon, './new-icon.png',
   419       'active window icon updated');
   420     assert.equal(state.disabled, true,
   421       'active disabled updated');
   423     // change the global state, only the windows without a state are affected
   425     button.label = 'A good label';
   427     assert.equal(button.label, 'A good label',
   428       'global label updated');
   429     assert.equal(button.state(mainWindow).label, 'A good label',
   430       'previous window label updated');
   431     assert.equal(button.state(activeWindow).label, 'New label',
   432       'active window label unchanged');
   434     // delete the window state will inherits the global state again
   436     button.state(activeWindow, null);
   438     assert.equal(button.state(activeWindow).label, 'A good label',
   439       'active window label inherited');
   441     // check the nodes properties
   442     let node = nodes[0];
   443     let state = button.state(mainWindow);
   445     assert.equal(node.getAttribute('label'), state.label,
   446       'node label is correct');
   447     assert.equal(node.getAttribute('tooltiptext'), state.label,
   448       'node tooltip is correct');
   450     assert.equal(node.getAttribute('image'), data.url(state.icon.substr(2)),
   451       'node image is correct');
   452     assert.equal(node.hasAttribute('disabled'), state.disabled,
   453       'disabled is correct');
   455     let node = nodes[1];
   456     let state = button.state(activeWindow);
   458     assert.equal(node.getAttribute('label'), state.label,
   459       'node label is correct');
   460     assert.equal(node.getAttribute('tooltiptext'), state.label,
   461       'node tooltip is correct');
   463     assert.equal(node.getAttribute('image'), data.url(state.icon.substr(2)),
   464       'node image is correct');
   465     assert.equal(node.hasAttribute('disabled'), state.disabled,
   466       'disabled is correct');
   468     return window;
   469   }).
   470   then(close).
   471   then(loader.unload).
   472   then(done, assert.fail);
   473 };
   476 exports['test button tab state'] = function(assert, done) {
   477   let loader = Loader(module);
   478   let { ActionButton } = loader.require('sdk/ui');
   479   let { browserWindows } = loader.require('sdk/windows');
   480   let tabs = loader.require('sdk/tabs');
   482   let button = ActionButton({
   483     id: 'my-button-7',
   484     label: 'my button',
   485     icon: './icon.png'
   486   });
   488   let mainTab = tabs.activeTab;
   489   let node = getWidget(button.id).node;
   491   tabs.open({
   492     url: 'about:blank',
   493     onActivate: function onActivate(tab) {
   494       tab.removeListener('activate', onActivate);
   496       let { activeWindow } = browserWindows;
   497       // set window state
   498       button.state(activeWindow, {
   499         label: 'Window label',
   500         icon: './window-icon.png'
   501       });
   503       // set previous active tab state
   504       button.state(mainTab, {
   505         label: 'Tab label',
   506         icon: './tab-icon.png',
   507       });
   509       // set current active tab state
   510       button.state(tab, {
   511         icon: './another-tab-icon.png',
   512         disabled: true
   513       });
   515       // check the states
   517       Cu.schedulePreciseGC(() => {
   518         assert.equal(button.label, 'my button',
   519           'global label unchanged');
   520         assert.equal(button.icon, './icon.png',
   521           'global icon unchanged');
   522         assert.equal(button.disabled, false,
   523           'global disabled unchanged');
   525         let state = button.state(mainTab);
   527         assert.equal(state.label, 'Tab label',
   528           'previous tab label updated');
   529         assert.equal(state.icon, './tab-icon.png',
   530           'previous tab icon updated');
   531         assert.equal(state.disabled, false,
   532           'previous tab disabled unchanged');
   534         let state = button.state(tab);
   536         assert.equal(state.label, 'Window label',
   537           'active tab inherited from window state');
   538         assert.equal(state.icon, './another-tab-icon.png',
   539           'active tab icon updated');
   540         assert.equal(state.disabled, true,
   541           'active disabled updated');
   543         // change the global state
   544         button.icon = './good-icon.png';
   546         // delete the tab state
   547         button.state(tab, null);
   549         assert.equal(button.icon, './good-icon.png',
   550           'global icon updated');
   551         assert.equal(button.state(mainTab).icon, './tab-icon.png',
   552           'previous tab icon unchanged');
   553         assert.equal(button.state(tab).icon, './window-icon.png',
   554           'tab icon inherited from window');
   556         // delete the window state
   557         button.state(activeWindow, null);
   559         assert.equal(button.state(tab).icon, './good-icon.png',
   560           'tab icon inherited from global');
   562         // check the node properties
   564         let state = button.state(tabs.activeTab);
   566         assert.equal(node.getAttribute('label'), state.label,
   567           'node label is correct');
   568         assert.equal(node.getAttribute('tooltiptext'), state.label,
   569           'node tooltip is correct');
   570         assert.equal(node.getAttribute('image'), data.url(state.icon.substr(2)),
   571           'node image is correct');
   572         assert.equal(node.hasAttribute('disabled'), state.disabled,
   573           'disabled is correct');
   575         tabs.once('activate', () => {
   576           // This is made in order to avoid to check the node before it
   577           // is updated, need a better check
   578           setTimeout(() => {
   579             let state = button.state(mainTab);
   581             assert.equal(node.getAttribute('label'), state.label,
   582               'node label is correct');
   583             assert.equal(node.getAttribute('tooltiptext'), state.label,
   584               'node tooltip is correct');
   585             assert.equal(node.getAttribute('image'), data.url(state.icon.substr(2)),
   586               'node image is correct');
   587             assert.equal(node.hasAttribute('disabled'), state.disabled,
   588               'disabled is correct');
   590             tab.close(() => {
   591               loader.unload();
   592               done();
   593             });
   594           }, 500);
   595         });
   597         mainTab.activate();
   598       });
   599     }
   600   });
   602 };
   604 exports['test button click'] = function(assert, done) {
   605   let loader = Loader(module);
   606   let { ActionButton } = loader.require('sdk/ui');
   607   let { browserWindows } = loader.require('sdk/windows');
   609   let labels = [];
   611   let button = ActionButton({
   612     id: 'my-button-8',
   613     label: 'my button',
   614     icon: './icon.png',
   615     onClick: ({label}) => labels.push(label)
   616   });
   618   let mainWindow = browserWindows.activeWindow;
   619   let chromeWindow = getMostRecentBrowserWindow();
   621   openBrowserWindow().then(focus).then(window => {
   622     button.state(mainWindow, { label: 'nothing' });
   623     button.state(mainWindow.tabs.activeTab, { label: 'foo'})
   624     button.state(browserWindows.activeWindow, { label: 'bar' });
   626     button.click();
   628     focus(chromeWindow).then(() => {
   629       button.click();
   631       assert.deepEqual(labels, ['bar', 'foo'],
   632         'button click works');
   634       close(window).
   635         then(loader.unload).
   636         then(done, assert.fail);
   637     });
   638   }).then(null, assert.fail);
   640 }
   642 exports['test button icon set'] = function(assert) {
   643   const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
   644   let loader = Loader(module);
   645   let { ActionButton } = loader.require('sdk/ui');
   647   // Test remote icon set
   648   assert.throws(
   649     () => ActionButton({
   650       id: 'my-button-10',
   651       label: 'my button',
   652       icon: {
   653         '16': 'http://www.mozilla.org/favicon.ico'
   654       }
   655     }),
   656     /^The option "icon"/,
   657     'throws on no valid icon given');
   659   let button = ActionButton({
   660     id: 'my-button-11',
   661     label: 'my button',
   662     icon: {
   663       '5': './icon5.png',
   664       '16': './icon16.png',
   665       '32': './icon32.png',
   666       '64': './icon64.png'
   667     }
   668   });
   670   let { node, id: widgetId } = getWidget(button.id);
   671   let { devicePixelRatio } = node.ownerDocument.defaultView;
   673   let size = 16 * devicePixelRatio;
   675   assert.equal(node.getAttribute('image'), data.url(button.icon[size].substr(2)),
   676     'the icon is set properly in navbar');
   678   let size = 32 * devicePixelRatio;
   680   CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_PANEL);
   682   assert.equal(node.getAttribute('image'), data.url(button.icon[size].substr(2)),
   683     'the icon is set properly in panel');
   685   // Using `loader.unload` without move back the button to the original area
   686   // raises an error in the CustomizableUI. This is doesn't happen if the
   687   // button is moved manually from navbar to panel. I believe it has to do
   688   // with `addWidgetToArea` method, because even with a `timeout` the issue
   689   // persist.
   690   CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_NAVBAR);
   692   loader.unload();
   693 }
   695 exports['test button icon se with only one option'] = function(assert) {
   696   const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
   697   let loader = Loader(module);
   698   let { ActionButton } = loader.require('sdk/ui');
   700   // Test remote icon set
   701   assert.throws(
   702     () => ActionButton({
   703       id: 'my-button-10',
   704       label: 'my button',
   705       icon: {
   706         '16': 'http://www.mozilla.org/favicon.ico'
   707       }
   708     }),
   709     /^The option "icon"/,
   710     'throws on no valid icon given');
   712   let button = ActionButton({
   713     id: 'my-button-11',
   714     label: 'my button',
   715     icon: {
   716       '5': './icon5.png'
   717     }
   718   });
   720   let { node, id: widgetId } = getWidget(button.id);
   722   assert.equal(node.getAttribute('image'), data.url(button.icon['5'].substr(2)),
   723     'the icon is set properly in navbar');
   725   CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_PANEL);
   727   assert.equal(node.getAttribute('image'), data.url(button.icon['5'].substr(2)),
   728     'the icon is set properly in panel');
   730   // Using `loader.unload` without move back the button to the original area
   731   // raises an error in the CustomizableUI. This is doesn't happen if the
   732   // button is moved manually from navbar to panel. I believe it has to do
   733   // with `addWidgetToArea` method, because even with a `timeout` the issue
   734   // persist.
   735   CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_NAVBAR);
   737   loader.unload();
   738 }
   740 exports['test button state validation'] = function(assert) {
   741   let loader = Loader(module);
   742   let { ActionButton } = loader.require('sdk/ui');
   743   let { browserWindows } = loader.require('sdk/windows');
   745   let button = ActionButton({
   746     id: 'my-button-12',
   747     label: 'my button',
   748     icon: './icon.png'
   749   })
   751   let state = button.state(button);
   753   assert.throws(
   754     () => button.state(button, { icon: 'http://www.mozilla.org/favicon.ico' }),
   755     /^The option "icon"/,
   756     'throws on remote icon given');
   758   loader.unload();
   759 };
   761 exports['test button are not in private windows'] = function(assert, done) {
   762   let loader = Loader(module);
   763   let { ActionButton } = loader.require('sdk/ui');
   764   let{ isPrivate } = loader.require('sdk/private-browsing');
   765   let { browserWindows } = loader.require('sdk/windows');
   767   let button = ActionButton({
   768     id: 'my-button-13',
   769     label: 'my button',
   770     icon: './icon.png'
   771   });
   773   openPrivateBrowserWindow().then(window => {
   774     assert.ok(isPrivate(window),
   775       'the new window is private');
   777     let { node } = getWidget(button.id, window);
   779     assert.ok(!node || node.style.display === 'none',
   780       'the button is not added / is not visible on private window');
   782     return window;
   783   }).
   784   then(close).
   785   then(loader.unload).
   786   then(done, assert.fail)
   787 }
   789 exports['test button state are snapshot'] = function(assert) {
   790   let loader = Loader(module);
   791   let { ActionButton } = loader.require('sdk/ui');
   792   let { browserWindows } = loader.require('sdk/windows');
   793   let tabs = loader.require('sdk/tabs');
   795   let button = ActionButton({
   796     id: 'my-button-14',
   797     label: 'my button',
   798     icon: './icon.png'
   799   });
   801   let state = button.state(button);
   802   let windowState = button.state(browserWindows.activeWindow);
   803   let tabState = button.state(tabs.activeTab);
   805   assert.deepEqual(windowState, state,
   806     'window state has the same properties of button state');
   808   assert.deepEqual(tabState, state,
   809     'tab state has the same properties of button state');
   811   assert.notEqual(windowState, state,
   812     'window state is not the same object of button state');
   814   assert.notEqual(tabState, state,
   815     'tab state is not the same object of button state');
   817   assert.deepEqual(button.state(button), state,
   818     'button state has the same content of previous button state');
   820   assert.deepEqual(button.state(browserWindows.activeWindow), windowState,
   821     'window state has the same content of previous window state');
   823   assert.deepEqual(button.state(tabs.activeTab), tabState,
   824     'tab state has the same content of previous tab state');
   826   assert.notEqual(button.state(button), state,
   827     'button state is not the same object of previous button state');
   829   assert.notEqual(button.state(browserWindows.activeWindow), windowState,
   830     'window state is not the same object of previous window state');
   832   assert.notEqual(button.state(tabs.activeTab), tabState,
   833     'tab state is not the same object of previous tab state');
   835   loader.unload();
   836 }
   838 exports['test button icon object is a snapshot'] = function(assert) {
   839   let loader = Loader(module);
   840   let { ActionButton } = loader.require('sdk/ui');
   842   let icon = {
   843     '16': './foo.png'
   844   };
   846   let button = ActionButton({
   847     id: 'my-button-17',
   848     label: 'my button',
   849     icon: icon
   850   });
   852   assert.deepEqual(button.icon, icon,
   853     'button.icon has the same properties of the object set in the constructor');
   855   assert.notEqual(button.icon, icon,
   856     'button.icon is not the same object of the object set in the constructor');
   858   assert.throws(
   859     () => button.icon[16] = './bar.png',
   860     /16 is read-only/,
   861     'properties of button.icon are ready-only'
   862   );
   864   let newIcon = {'16': './bar.png'};
   865   button.icon = newIcon;
   867   assert.deepEqual(button.icon, newIcon,
   868     'button.icon has the same properties of the object set');
   870   assert.notEqual(button.icon, newIcon,
   871     'button.icon is not the same object of the object set');
   873   loader.unload();
   874 }
   876 exports['test button after destroy'] = function(assert) {
   877   let loader = Loader(module);
   878   let { ActionButton } = loader.require('sdk/ui');
   879   let { browserWindows } = loader.require('sdk/windows');
   880   let { activeTab } = loader.require('sdk/tabs');
   882   let button = ActionButton({
   883     id: 'my-button-15',
   884     label: 'my button',
   885     icon: './icon.png',
   886     onClick: () => assert.fail('onClick should not be called')
   887   });
   889   button.destroy();
   891   assert.throws(
   892     () => button.click(),
   893     /^The state cannot be set or get/,
   894     'button.click() not executed');
   896   assert.throws(
   897     () => button.label,
   898     /^The state cannot be set or get/,
   899     'button.label cannot be get after destroy');
   901   assert.throws(
   902     () => button.label = 'my label',
   903     /^The state cannot be set or get/,
   904     'button.label cannot be set after destroy');
   906   assert.throws(
   907     () => {
   908       button.state(browserWindows.activeWindow, {
   909         label: 'window label'
   910       });
   911     },
   912     /^The state cannot be set or get/,
   913     'window state label cannot be set after destroy');
   915   assert.throws(
   916     () => button.state(browserWindows.activeWindow).label,
   917     /^The state cannot be set or get/,
   918     'window state label cannot be get after destroy');
   920   assert.throws(
   921     () => {
   922       button.state(activeTab, {
   923         label: 'tab label'
   924       });
   925     },
   926     /^The state cannot be set or get/,
   927     'tab state label cannot be set after destroy');
   929   assert.throws(
   930     () => button.state(activeTab).label,
   931     /^The state cannot be set or get/,
   932     'window state label cannot se get after destroy');
   934   loader.unload();
   935 };
   937 require('sdk/test').run(exports);

mercurial