This article needs a technical review. How you can help.
SpecialPowers is a set of APIs available to Mochitest tests. Mochitests are intended to be written like regular web pages. However, sometimes tests need to do things that regular web pages are not permitted to do for security reasons. In these cases, the SpecialPowers APIs can be used to perform specific actions outside of the reach of normal web pages.
Method overview
Preference APIs
Promise pushPrefEnv(inPrefs, [callback]); |
Promise popPrefEnv([callback]); |
Promise flushPrefEnv([callback]); |
bool getBoolPref(aPrefName); |
int getIntPref(aPrefName); |
string getCharPref(aPrefName); |
any getComplexValue(aPrefName); |
void setBoolPref(aPrefName, aValue); |
void setIntPref(aPrefName, aValue); |
void setCharPref(aPrefName, aValue); |
void setComplexValue(aPrefName, aValue); |
void clearUserPref(aPrefName); |
Permission APIs
void pushPermissions(inPermissions, callback); |
void popPermissions(callback); |
void flushPermissions(callback); |
void addPermission(type, allow, arg); |
void removePermission(type, arg); |
bool hasPermission(type, arg); |
bool testPermission(type, value, arg); |
void setFullscreenAllowed(document); |
void removeFullscreenAllowed(document); |
Event Listener / Observer APIs
TBD
Garbage Collection APIs
TBD
Privilege Wrapper APIs
Object wrap(Object); |
XPCOM Components APIs
Cc |
Ci |
Cr |
Cu |
Log APIs
TBD
Environment APIs
bool isMainProcess(); |
string getMozFullPath(file); |
bool isWindowPrivate(aWindow); |
bool isBackButtonEnabled(aWindow); |
int assertionCount(); |
void removeExpectedCrashDumpFiles(aExpectingProcessCrash); |
string[] findUnexpectedCrashDumpFiles(); |
Focus Management APIs
TBD
Mock APIs
TBD
Form History APIs
TBD
Snapshot APIs
TBD
Clipboard APIs
TBD
Console APIs
TBD
Layout APIs
TBD
Frame Message APIs
TBD
Apps APIs
TBD
Other APIs
XMLHttpRequest createSystemXHR(); |
void quit(); |
DOMWindowUtils getDOMWindowUtils(window); |
void executeSoon(aFun, aWindow); |
object getDOMRequestService(); |
void openDialog(aWindow, aArg); |
string sanityCheck(); |
Attributes
Attribute | Type | Description |
---|---|---|
DOMWindowUtils |
||
Services |
Methods
Preference APIs
See nsIPrefBranch
for documentation on the APIs that these methods use internally.
getBoolPref(aPrefName)
Gets the value of the preference aPrefName
as a boolean.
getIntPref(aPrefName)
Gets the value of the preference aPrefName
as an integer.
getCharPref(aPrefName)
Gets the value of the preference aPrefName
as a string.
getComplexValue(aPrefName)
Gets the value of the preference aPrefName
as an XPCOM object.
setBoolPref(aPrefName, aValue)
Sets the value of the preference aPrefName
to the boolean value aValue
.
setIntPref(aPrefName, aValue)
Sets the value of the preference aPrefName
to the integer value aValue
.
setCharPref(aPrefName, aValue)
Sets the value of the preference aPrefName
to the string value aValue
.
setComplexValue(aPrefName, aValue)
Sets the value of the preference aPrefName
to the XPCOM object aValue
.
clearUserPref(aPrefName)
Resets the preference aPrefName
to its default value.
Permission APIs
TBD
Event Listener / Observer APIs
addChromeEventListener(type, listener, capture, allowUntrusted)
Adds an event listener to the TabChildGlobal object.
removeChromeEventListener(type, listener, capture)
Removes an event listener from the TabChildGlobal object.
Garbage Collection APIs
gc()
Forces a round of garbage collection to be performed.
Privilege Wrapper APIs
Object wrap(Object)
Wraps a chrome object so that it can be accessed. Needed for accessing the return values of methods returned by XPCOM components (for example).
XPCOM Components APIs
Cc
The value of Components.classes
, as available to chrome code.
Ci
The value of Components.interfaces
, as available to chrome code.
Cr
The value of Components.results
, as available to chrome code.
Cu
The value of Components.utils
, as available to chrome code.
Log APIs
TBD
Environment APIs
TBD
Focus Management APIs
TBD
Mock APIs
MockFilePicker
This replaces the standard File Picker with one that can be controlled via script, for testing load and save code. To use it, add the following lines of code to your test:
var MockFilePicker = SpecialPowers.MockFilePicker; MockFilePicker.reset(); // You must call reset before each test
This patch has examples of how to use the MockFilePicker, and also how to use it for XPCShell tests. The code in testing/mochitest/MockFilePicker.jsm
might also be helpful.
Form History APIs
TBD
Snapshot APIs
TBD
Clipboard APIs
TBD
Console APIs
TBD
Layout APIs
TBD
Frame Message APIs
loadChromeScript()
TBD
Apps APIs
TBD
Other APIs
createSystemXHR()
Creates and returns an XMLHttpRequest instance which has full "system privileges". In other words, it can:
- Make cross-site requests without any restrictions, i.e. the target server does not need to support CORS.
- Set any header using xhr.setRequestHeader.
- Read any response using xhr.getResponseHeader and xhr.getAllResponseHeaders.
- Load and parse XUL contents using the xhr.responseXML property.
- Make requests without a
referer
(sic) header. If you want areferer
header set, you have to do so manually using xhr.setRequestHeader.
However, any document parsed by the xhr object and accessed through xhr.responseXML is created using a null principal, which limits what the document can do.
sanityCheck()
Returns the string "foo"
.
Adding new APIs
If your test requires privileged functionality that's not currently present, you can add new APIs to the SpecialPowers object.
Because of the support for out-of-process content, the SpecialPowers implementation is split into two separate files:
- SpecialPowersObserver.jsm, which is always run in the parent process.
- specialpowers.js, which is a content script, and may be run in the content process.
Both files execute with chrome privileges, but certain XPCOM APIs are not available in content processes. Consult with an Electrolysis or Mobile peer if you are unsure if you can use a specific API there. You may also want to read the Message Manager documentation for more detailed information on how cross-process messaging works.
A simple example
Let's say you wanted to expose the numberOfScreens
attribute from the nsIScreenManager
interface. Let's also suppose that this interface is not available in the content process, just to make our example more complete. To start, first you would need to define the new API on the SpecialPowers
object that is exposed to content. This object is defined in the content script.
SpecialPowers
is just a normal JavaScript object, you can add functions, attributes, getters, and setters to it like any other object. It does use the special __exposedProps__
property to hide any property beginning with an underscore ("_") from content scripts, so names starting with an underscore function like private members.Let's first add a numberOfScreens
getter to SpecialPowers
. It will simply send a blocking message to the chrome process, asking it to return the value in its response:
var SpecialPowers = {
// existing APIs
//...
// Provide nsIScreenManager.numberOfScreens
get numberOfScreens() {
// You could pass additional parameters in the second parameter, consult the message manager documentation for more details.
// Ideally this would be a memoizing getter, that's somewhat out of scope for this document.
return sendSyncMessage("SPNumberOfScreens", {})[0];
}
};
Now you need to provide a handler for this message in the chrome observer script. In the SpecialPowersObserver.observe
function, register your message underneath the existing messages:
// Register for any messages our API needs us to handle
messageManager.addMessageListener("SPPrefService", this);
messageManager.addMessageListener("SPNumberOfScreens", this);
Then, in the SpecialPowersObserver.receiveMessage
function, add a branch to handle your new message and return the result:
receiveMessage: function(aMessage) {
switch(aMessage.name) {
case "SPPrefService":
// existing code...
case "SPNumberOfScreens":
var screenManager = Components.classes["@mozilla.org/gfx/screenmanager;1"]
.getService(Components.interfaces.nsIScreenManager);}
return screenManager.numberOfScreens;
default:
That's it! You will need to rebuild in the testing/mochitest directory in your object directory for your changes to show up; then you should be able to use your new SpecialPowers.numberOfScreens
property in Mochitests.