summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/webextensions/test/browser/browser_openDialog.js
blob: f95365a4c0b9fdbb98c0a1490320a0cfee56c79e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

// Tests the dialog open by the Options button for addons that provide a
// custom chrome-like protocol for optionsURL.

var CustomChromeProtocol = {
  scheme: "khrome",
  defaultPort: -1,
  protocolFlags: Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
                 Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
                 Ci.nsIProtocolHandler.URI_NORELATIVE |
                 Ci.nsIProtocolHandler.URI_NOAUTH,

  newURI: function CCP_newURI(aSpec, aOriginCharset, aBaseUri) {
    let uri = Cc["@mozilla.org/network/simple-uri;1"].
              createInstance(Ci.nsIURI);
    uri.spec = aSpec;
    return uri;
  },

  newChannel2: function CCP_newChannel2(aURI, aLoadInfo) {
    let url = Services.io.newURI("chrome:" + aURI.path, null, null);
    let ch = Services.io.newChannelFromURIWithLoadInfo(url, aLoadInfo);
    ch.originalURI = aURI;
    return ch;
  },

  newChannel: function CCP_newChannel(aURI) {
    return this.newChannel2(aURI, null);
  },

  allowPort: function CCP_allowPort(aPort, aScheme) {
    return false;
  },

  QueryInterface: XPCOMUtils.generateQI([
    Ci.nsIProtocolHandler
  ]),

  classID: Components.ID("{399cb2d1-05dd-4363-896f-63b78e008cf8}"),

  factory: {
    registrar: Components.manager.QueryInterface(Ci.nsIComponentRegistrar),

    register: function CCP_register() {
      this.registrar.registerFactory(
        CustomChromeProtocol.classID,
        "CustomChromeProtocol",
        "@mozilla.org/network/protocol;1?name=khrome",
        this
      );
    },

    unregister: function CCP_register() {
      this.registrar.unregisterFactory(CustomChromeProtocol.classID, this);
    },

    // nsIFactory
    createInstance: function BNPH_createInstance(aOuter, aIID) {
      if (aOuter) {
        throw Components.Exception("Class does not allow aggregation",
                                   Components.results.NS_ERROR_NO_AGGREGATION);
      }
      return CustomChromeProtocol.QueryInterface(aIID);
    },

    lockFactory: function BNPH_lockFactory(aLock) {
      throw Components.Exception("Function lockFactory is not implemented",
                                 Components.results.NS_ERROR_NOT_IMPLEMENTED);
    },

    QueryInterface: XPCOMUtils.generateQI([
      Ci.nsIFactory
    ])
  }
}

function test() {
  waitForExplicitFinish();
  requestLongerTimeout(2);

  info("Registering custom chrome-like protocol.");
  CustomChromeProtocol.factory.register();
  registerCleanupFunction(() => CustomChromeProtocol.factory.unregister());

  const ADDONS_LIST = [
    { id: "test1@tests.mozilla.org",
      name: "Test add-on 1",
      optionsURL: CHROMEROOT + "addon_prefs.xul" },
    { id: "test2@tests.mozilla.org",
      name: "Test add-on 2",
      optionsURL: (CHROMEROOT + "addon_prefs.xul").replace("chrome:", "khrome:") },
  ];

  var gProvider = new MockProvider();
  gProvider.createAddons(ADDONS_LIST);

  open_manager("addons://list/extension", function(aManager) {
    let addonList = aManager.document.getElementById("addon-list");
    let currentAddon;
    let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply");

    function getAddonByName(aName) {
      for (let addonItem of addonList.childNodes) {
        if (addonItem.hasAttribute("name") &&
            addonItem.getAttribute("name") == aName)
          return addonItem;
      }
      return null;
    }

    function observer(aSubject, aTopic, aData) {
      switch (aTopic) {
        case "domwindowclosed":
          // Give the preference window a chance to finish closing before
          // closing the add-ons manager.
          waitForFocus(function () {
            test_next_addon();
          });
          break;
        case "domwindowopened":
          let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
          waitForFocus(function () {
            // If the openDialog privileges are wrong a new browser window
            // will open, let the test proceed (and fail) rather than timeout.
            if (win.location != currentAddon.optionsURL &&
                win.location != "chrome://browser/content/browser.xul")
              return;

            is(win.location, currentAddon.optionsURL,
               "The correct addon pref window should have opened");

            let chromeFlags = win.QueryInterface(Ci.nsIInterfaceRequestor).
                                  getInterface(Ci.nsIWebNavigation).
                                  QueryInterface(Ci.nsIDocShellTreeItem).treeOwner.
                                  QueryInterface(Ci.nsIInterfaceRequestor).
                                  getInterface(Ci.nsIXULWindow).chromeFlags;
            ok(chromeFlags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME &&
               (instantApply || chromeFlags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG),
               "Window was open as a chrome dialog.");

            win.close();
          }, win);
          break;
      }
    }

    function test_next_addon() {
      currentAddon = ADDONS_LIST.shift();
      if (!currentAddon) {
        Services.ww.unregisterNotification(observer);
        close_manager(aManager, finish);
        return;
      }

      info("Testing " + currentAddon.name);
      let addonItem = getAddonByName(currentAddon.name, addonList);
      let optionsBtn =
        aManager.document.getAnonymousElementByAttribute(addonItem, "anonid",
                                                         "preferences-btn");
      is(optionsBtn.hidden, false, "Prefs button should be visible.")

      addonList.ensureElementIsVisible(addonItem);
      EventUtils.synthesizeMouseAtCenter(optionsBtn, { }, aManager);
    }

    Services.ww.registerNotification(observer);
    test_next_addon();
  });

}