Bug 844183: Uplift Add-on SDK changeset 2bee189e1cb87f5fbe38ce862c8ff35ee0978480

bf2c2f609b...2bee189e1c
This commit is contained in:
Dave Townsend
2013-02-22 10:22:25 -08:00
parent 84b52575a8
commit d3d3a8b3b2
27 changed files with 891 additions and 494 deletions

View File

@@ -1,30 +1,30 @@
The files which make up the SDK are developed by Mozilla and licensed
under the MPL 2.0 (http://mozilla.org/MPL/2.0/), with the exception of the
components listed below, which are made available by their authors under
the licenses listed alongside.
syntaxhighlighter
------------------
doc/static-files/syntaxhighlighter
Made available under the MIT license.
jQuery
------
examples/reddit-panel/data/jquery-1.4.4.min.js
examples/annotator/data/jquery-1.4.2.min.js
Made available under the MIT license.
simplejson
----------
python-lib/simplejson
Made available under the MIT license.
Python Markdown
---------------
python-lib/markdown
Made available under the BSD license.
LibraryDetector
---------------
examples/library-detector/data/library-detector.js
Made available under the MIT license.
The files which make up the SDK are developed by Mozilla and licensed
under the MPL 2.0 (http://mozilla.org/MPL/2.0/), with the exception of the
components listed below, which are made available by their authors under
the licenses listed alongside.
syntaxhighlighter
------------------
doc/static-files/syntaxhighlighter
Made available under the MIT license.
jQuery
------
examples/reddit-panel/data/jquery-1.4.4.min.js
examples/annotator/data/jquery-1.4.2.min.js
Made available under the MIT license.
simplejson
----------
python-lib/simplejson
Made available under the MIT license.
Python Markdown
---------------
python-lib/markdown
Made available under the BSD license.
LibraryDetector
---------------
examples/library-detector/data/library-detector.js
Made available under the MIT license.

View File

@@ -1,45 +1,45 @@
Add-on SDK README
==================
Before proceeding, please make sure you've installed Python 2.5,
2.6, or 2.7 (if it's not already on your system):
http://python.org/download/
Note that Python 3.0 and 3.1 are not supported in this release.
For Windows users, MozillaBuild (https://wiki.mozilla.org/MozillaBuild)
will install the correct version of Python and the MSYS package, which
will make it easier to work with the SDK.
To get started, first enter the same directory that this README file
is in (the SDK's root directory) using a shell program. On Unix systems
or on Windows with MSYS, you can execute the following command:
source bin/activate
Windows users using cmd.exe should instead run:
bin\activate.bat
Then run:
cfx docs
This should start a documentation server and open a web browser
with further instructions.
If you get an error when running cfx or have any other problems getting
started, see the "Troubleshooting" guide at:
https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/troubleshooting.html
Bugs
-------
* file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
Style Guidelines
--------------------
Add-on SDK README
==================
Before proceeding, please make sure you've installed Python 2.5,
2.6, or 2.7 (if it's not already on your system):
http://python.org/download/
Note that Python 3.0 and 3.1 are not supported in this release.
For Windows users, MozillaBuild (https://wiki.mozilla.org/MozillaBuild)
will install the correct version of Python and the MSYS package, which
will make it easier to work with the SDK.
To get started, first enter the same directory that this README file
is in (the SDK's root directory) using a shell program. On Unix systems
or on Windows with MSYS, you can execute the following command:
source bin/activate
Windows users using cmd.exe should instead run:
bin\activate.bat
Then run:
cfx docs
This should start a documentation server and open a web browser
with further instructions.
If you get an error when running cfx or have any other problems getting
started, see the "Troubleshooting" guide at:
https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/troubleshooting.html
Bugs
-------
* file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
Style Guidelines
--------------------
* https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide

View File

@@ -19,6 +19,13 @@ const resourceHandler = ioService.getProtocolHandler('resource').
const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
getService(Ci.mozIJSSubScriptLoader);
const prefService = Cc['@mozilla.org/preferences-service;1'].
getService(Ci.nsIPrefService);
const appInfo = Cc["@mozilla.org/xre/app-info;1"].
getService(Ci.nsIXULAppInfo);
const vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
getService(Ci.nsIVersionComparator);
const REASON = [ 'unknown', 'startup', 'shutdown', 'enable', 'disable',
'install', 'uninstall', 'upgrade', 'downgrade' ];
@@ -120,19 +127,54 @@ function startup(data, reasonCode) {
if (name == 'addon-sdk')
paths['tests/'] = prefixURI + name + '/tests/';
// Maps sdk module folders to their resource folder
paths['sdk/'] = prefixURI + 'addon-sdk/lib/sdk/';
paths['toolkit/'] = prefixURI + 'addon-sdk/lib/toolkit/';
// test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
// so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
// until we no longer support SDK modules in XPI:
paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
// Starting with Firefox 21.0a1, we start using modules shipped into firefox
// Still allow using modules from the xpi if the manifest tell us to do so.
// And only try to look for sdk modules in xpi if the xpi actually ship them
if (options['is-sdk-bundled'] &&
(vc.compare(appInfo.version, '21.0a1') < 0 ||
options['force-use-bundled-sdk'])) {
// Maps sdk module folders to their resource folder
paths[''] = prefixURI + 'addon-sdk/lib/';
// test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
// so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
// until we no longer support SDK modules in XPI:
paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
}
// Retrieve list of module folder overloads based on preferences in order to
// eventually used a local modules instead of files shipped into Firefox.
let branch = prefService.getBranch('extensions.modules.' + id + '.path');
paths = branch.getChildList('', {}).reduce(function (result, name) {
// Allows overloading of any sub folder by replacing . by / in pref name
let path = name.substr(1).split('.').join('/');
// Only accept overloading folder by ensuring always ending with `/`
if (path) path += '/';
let fileURI = branch.getCharPref(name);
// Maps the given file:// URI to a resource:// in order to avoid various
// failure that happens with file:// URI and be close to production env
let resourcesURI = ioService.newURI(fileURI, null, null);
let resName = 'extensions.modules.' + domain + '.commonjs.path' + name;
resourceHandler.setSubstitution(resName, resourcesURI);
result[path] = 'resource://' + resName + '/';
return result;
}, paths);
// Make version 2 of the manifest
let manifest = options.manifest;
// Import `cuddlefish.js` module using a Sandbox and bootstrap loader.
let cuddlefishURI = prefixURI + options.loader;
let cuddlefishPath = 'loader/cuddlefish.js';
let cuddlefishURI = 'resource://gre/modules/commonjs/sdk/' + cuddlefishPath;
if (paths['sdk/']) { // sdk folder has been overloaded
// (from pref, or cuddlefish is still in the xpi)
cuddlefishURI = paths['sdk/'] + cuddlefishPath;
}
else if (paths['']) { // root modules folder has been overloaded
cuddlefishURI = paths[''] + 'sdk/' + cuddlefishPath;
}
cuddlefishSandbox = loadSandbox(cuddlefishURI);
let cuddlefish = cuddlefishSandbox.exports;

View File

@@ -1,364 +1,364 @@
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import signal
import threading
import urllib2, urllib
import zipfile
import tarfile
import subprocess
import optparse
import sys, re
#import win32api
class SDK:
def __init__(self):
try:
# Take the current working directory
self.default_path = os.getcwd()
if sys.platform == "win32":
self.mswindows = True
else:
self.mswindows = False
# Take the default home path of the user.
home = os.path.expanduser('~')
# The following are the parameters that can be used to pass a dynamic URL, a specific path or a binry. The binary is not used yet. It will be used in version 2.0
# If a dynamic path is to be mentioned, it should start with a '/'. For eg. "/Desktop"
parser = optparse.OptionParser()
parser.add_option('-u', '--url', dest = 'url', default = 'https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/addon-sdk-latest.zip')
parser.add_option('-p', '--path', dest = 'path', default = self.default_path)
parser.add_option('-b', '--binary', dest = 'binary')#, default='/Applications/Firefox.app')
(options, args) = parser.parse_args()
# Get the URL from the parameter
self.link = options.url
# Set the base path for the user. If the user supplies the path, use the home variable as well. Else, take the default path of this script as the installation directory.
if options.path!=self.default_path:
if self.mswindows:
self.base_path = home + str(options.path).strip() + '\\'
else:
self.base_path = home + str(options.path).strip() + '/'
else:
if self.mswindows:
self.base_path = str(options.path).strip() + '\\'
else:
self.base_path = str(options.path).strip() + '/'
assert ' ' not in self.base_path, "You cannot have a space in your home path. Please remove the space before you continue."
print('Your Base path is =' + self.base_path)
# This assignment is not used in this program. It will be used in version 2 of this script.
self.bin = options.binary
# if app or bin is empty, dont pass anything
# Search for the .zip file or tarball file in the URL.
i = self.link.rfind('/')
self.fname = self.link[i+1:]
z = re.search('zip',self.fname,re.I)
g = re.search('gz',self.fname,re.I)
if z:
print 'zip file present in the URL.'
self.zip = True
self.gz = False
elif g:
print 'gz file present in the URL'
self.gz = True
self.zip = False
else:
print 'zip/gz file not present. Check the URL.'
return
print("File name is =" + self.fname)
# Join the base path and the zip/tar file name to crate a complete Local file path.
self.fpath = self.base_path + self.fname
print('Your local file path will be=' + self.fpath)
except AssertionError, e:
print e.args[0]
sys.exit(1)
# Download function - to download the SDK from the URL to the local machine.
def download(self,url,fpath,fname):
try:
# Start the download
print("Downloading...Please be patient!")
urllib.urlretrieve(url,filename = fname)
print('Download was successful.')
except ValueError: # Handles broken URL errors.
print 'The URL is ether broken or the file does not exist. Please enter the correct URL.'
raise
except urllib2.URLError: # Handles URL errors
print '\nURL not correct. Check again!'
raise
# Function to extract the downloaded zipfile.
def extract(self, zipfilepath, extfile):
try:
# Timeout is set to 30 seconds.
timeout = 30
# Change the directory to the location of the zip file.
try:
os.chdir(zipfilepath)
except OSError:
# Will reach here if zip file doesnt exist
print 'O/S Error:' + zipfilepath + 'does not exist'
raise
# Get the folder name of Jetpack to get the exact version number.
if self.zip:
try:
f = zipfile.ZipFile(extfile, "r")
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.namelist()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
elif self.gz:
try:
f = tarfile.open(extfile,'r')
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.getnames()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
print ('Starting to Extract...')
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
if self.zip:
# Call the command to unzip the file.
if self.mswindows:
zipfile.ZipFile.extractall(f)
else:
p = subprocess.Popen('unzip '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
elif self.gz:
# Call the command to untar the file.
if self.mswindows:
tarfile.TarFile.extractall(f)
else:
p = subprocess.Popen('tar -xf '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
#No need to handle for windows because windows automatically replaces old files with new files. It does not ask the user(as it does in Mac/Unix)
if self.mswindows==False:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows ))
watch.start()
(stdout, stderr) = p.communicate()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
# Abort process if process fails.
if not success:
raise RuntimeError
kill_check.clear()
print('Extraction Successful.')
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during file extraction: ", sys.exc_info()[0]
raise
# Function to run the cfx testall comands and to make sure the SDK is not broken.
def run_testall(self, home_path, folder_name):
try:
timeout = 500
self.new_dir = home_path + folder_name
try:
os.chdir(self.new_dir)
except OSError:
# Will reach here if the jetpack 0.X directory doesnt exist
print 'O/S Error: Jetpack directory does not exist at ' + self.new_dir
raise
print '\nStarting tests...'
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
# Set the path for the logs. They will be in the parent directory of the Jetpack SDK.
log_path = home_path + 'tests.log'
# Subprocess call to set up the jetpack environment and to start the tests. Also sends the output to a log file.
if self.bin != None:
if self.mswindows:
p = subprocess.Popen("bin\\activate && cfx testall -a firefox -b \"" + self.bin + "\"" , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
elif self.bin == None:
if self.mswindows:
p=subprocess.Popen('bin\\activate && cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
#Write the output to log file
f=open(log_path,"w")
f.write(stdout+stderr)
f.close()
#Watchdog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode!=0:
print('\nAll tests were not successful. Check the test-logs in the jetpack directory.')
result_sdk(home_path)
#sys.exit(1)
raise RuntimeError
else:
ret_code=result_sdk(home_path)
if ret_code==0:
print('\nAll tests were successful. Yay \o/ . Running a sample package test now...')
else:
print ('\nThere were errors during the tests.Take a look at logs')
raise RuntimeError
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during the testall command execution:", sys.exc_info()[0]
raise
def package(self, example_dir):
try:
timeout = 30
print '\nNow Running packaging tests...'
kill_check = threading.Event()
# Set the path for the example logs. They will be in the parent directory of the Jetpack SDK.
exlog_path = example_dir + 'test-example.log'
# Subprocess call to test the sample example for packaging.
if self.bin!=None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}" -b \"" + self.bin + "\"' , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
elif self.bin==None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' ', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
#Write the output to log file
f=open(exlog_path,"w")
f.write(stdout+stderr)
f.close()
#Watch dog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode != 0:
print('\nSample tests were not executed correctly. Check the test-example log in jetpack diretory.')
result_example(example_dir)
raise RuntimeError
else:
ret_code=result_example(example_dir)
if ret_code==0:
print('\nAll tests pass. The SDK is working! Yay \o/')
else:
print ('\nTests passed with warning.Take a look at logs')
sys.exit(1)
except RuntimeError:
print "Ending program"
sys.exit(1)
except:
print "Error during running sample tests:", sys.exc_info()[0]
raise
def result_sdk(sdk_dir):
log_path = sdk_dir + 'tests.log'
print 'Results are logged at:' + log_path
try:
f = open(log_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open test log at ' + log_path
raise
for line in reversed(open(log_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result - FAIL. Look at the test log at '+log_path)
return 1
return 0
def result_example(sdk_dir):
exlog_path = sdk_dir + 'test-example.log'
print 'Sample test results are logged at:' + exlog_path
try:
f = open(exlog_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open sample test log at ' + exlog_path
raise
#Read the file in reverse and check for the keyword 'FAIL'.
for line in reversed(open(exlog_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result for Sample tests - FAIL. Look at the test log at '+exlog_path)
return 1
return 0
def kill_process(process, kill_check, mswindows):
print '\nProcess Timedout. Killing the process. Please Rerun this script.'
if mswindows:
win32api.TerminateProcess(process, -1)
else:
os.kill(process, signal.SIGKILL)
kill_check.set()# tell the main routine to kill. Used SIGKILL to hard kill the process.
return
if __name__ == "__main__":
obj = SDK()
obj.download(obj.link,obj.fpath,obj.fname)
obj.extract(obj.base_path,obj.fname)
obj.run_testall(obj.base_path,obj.folder_name)
obj.package(obj.base_path)
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import signal
import threading
import urllib2, urllib
import zipfile
import tarfile
import subprocess
import optparse
import sys, re
#import win32api
class SDK:
def __init__(self):
try:
# Take the current working directory
self.default_path = os.getcwd()
if sys.platform == "win32":
self.mswindows = True
else:
self.mswindows = False
# Take the default home path of the user.
home = os.path.expanduser('~')
# The following are the parameters that can be used to pass a dynamic URL, a specific path or a binry. The binary is not used yet. It will be used in version 2.0
# If a dynamic path is to be mentioned, it should start with a '/'. For eg. "/Desktop"
parser = optparse.OptionParser()
parser.add_option('-u', '--url', dest = 'url', default = 'https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/addon-sdk-latest.zip')
parser.add_option('-p', '--path', dest = 'path', default = self.default_path)
parser.add_option('-b', '--binary', dest = 'binary')#, default='/Applications/Firefox.app')
(options, args) = parser.parse_args()
# Get the URL from the parameter
self.link = options.url
# Set the base path for the user. If the user supplies the path, use the home variable as well. Else, take the default path of this script as the installation directory.
if options.path!=self.default_path:
if self.mswindows:
self.base_path = home + str(options.path).strip() + '\\'
else:
self.base_path = home + str(options.path).strip() + '/'
else:
if self.mswindows:
self.base_path = str(options.path).strip() + '\\'
else:
self.base_path = str(options.path).strip() + '/'
assert ' ' not in self.base_path, "You cannot have a space in your home path. Please remove the space before you continue."
print('Your Base path is =' + self.base_path)
# This assignment is not used in this program. It will be used in version 2 of this script.
self.bin = options.binary
# if app or bin is empty, dont pass anything
# Search for the .zip file or tarball file in the URL.
i = self.link.rfind('/')
self.fname = self.link[i+1:]
z = re.search('zip',self.fname,re.I)
g = re.search('gz',self.fname,re.I)
if z:
print 'zip file present in the URL.'
self.zip = True
self.gz = False
elif g:
print 'gz file present in the URL'
self.gz = True
self.zip = False
else:
print 'zip/gz file not present. Check the URL.'
return
print("File name is =" + self.fname)
# Join the base path and the zip/tar file name to crate a complete Local file path.
self.fpath = self.base_path + self.fname
print('Your local file path will be=' + self.fpath)
except AssertionError, e:
print e.args[0]
sys.exit(1)
# Download function - to download the SDK from the URL to the local machine.
def download(self,url,fpath,fname):
try:
# Start the download
print("Downloading...Please be patient!")
urllib.urlretrieve(url,filename = fname)
print('Download was successful.')
except ValueError: # Handles broken URL errors.
print 'The URL is ether broken or the file does not exist. Please enter the correct URL.'
raise
except urllib2.URLError: # Handles URL errors
print '\nURL not correct. Check again!'
raise
# Function to extract the downloaded zipfile.
def extract(self, zipfilepath, extfile):
try:
# Timeout is set to 30 seconds.
timeout = 30
# Change the directory to the location of the zip file.
try:
os.chdir(zipfilepath)
except OSError:
# Will reach here if zip file doesnt exist
print 'O/S Error:' + zipfilepath + 'does not exist'
raise
# Get the folder name of Jetpack to get the exact version number.
if self.zip:
try:
f = zipfile.ZipFile(extfile, "r")
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.namelist()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
elif self.gz:
try:
f = tarfile.open(extfile,'r')
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.getnames()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
print ('Starting to Extract...')
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
if self.zip:
# Call the command to unzip the file.
if self.mswindows:
zipfile.ZipFile.extractall(f)
else:
p = subprocess.Popen('unzip '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
elif self.gz:
# Call the command to untar the file.
if self.mswindows:
tarfile.TarFile.extractall(f)
else:
p = subprocess.Popen('tar -xf '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
#No need to handle for windows because windows automatically replaces old files with new files. It does not ask the user(as it does in Mac/Unix)
if self.mswindows==False:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows ))
watch.start()
(stdout, stderr) = p.communicate()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
# Abort process if process fails.
if not success:
raise RuntimeError
kill_check.clear()
print('Extraction Successful.')
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during file extraction: ", sys.exc_info()[0]
raise
# Function to run the cfx testall comands and to make sure the SDK is not broken.
def run_testall(self, home_path, folder_name):
try:
timeout = 500
self.new_dir = home_path + folder_name
try:
os.chdir(self.new_dir)
except OSError:
# Will reach here if the jetpack 0.X directory doesnt exist
print 'O/S Error: Jetpack directory does not exist at ' + self.new_dir
raise
print '\nStarting tests...'
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
# Set the path for the logs. They will be in the parent directory of the Jetpack SDK.
log_path = home_path + 'tests.log'
# Subprocess call to set up the jetpack environment and to start the tests. Also sends the output to a log file.
if self.bin != None:
if self.mswindows:
p = subprocess.Popen("bin\\activate && cfx testall -a firefox -b \"" + self.bin + "\"" , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
elif self.bin == None:
if self.mswindows:
p=subprocess.Popen('bin\\activate && cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
#Write the output to log file
f=open(log_path,"w")
f.write(stdout+stderr)
f.close()
#Watchdog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode!=0:
print('\nAll tests were not successful. Check the test-logs in the jetpack directory.')
result_sdk(home_path)
#sys.exit(1)
raise RuntimeError
else:
ret_code=result_sdk(home_path)
if ret_code==0:
print('\nAll tests were successful. Yay \o/ . Running a sample package test now...')
else:
print ('\nThere were errors during the tests.Take a look at logs')
raise RuntimeError
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during the testall command execution:", sys.exc_info()[0]
raise
def package(self, example_dir):
try:
timeout = 30
print '\nNow Running packaging tests...'
kill_check = threading.Event()
# Set the path for the example logs. They will be in the parent directory of the Jetpack SDK.
exlog_path = example_dir + 'test-example.log'
# Subprocess call to test the sample example for packaging.
if self.bin!=None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}" -b \"" + self.bin + "\"' , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
elif self.bin==None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' ', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
#Write the output to log file
f=open(exlog_path,"w")
f.write(stdout+stderr)
f.close()
#Watch dog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode != 0:
print('\nSample tests were not executed correctly. Check the test-example log in jetpack diretory.')
result_example(example_dir)
raise RuntimeError
else:
ret_code=result_example(example_dir)
if ret_code==0:
print('\nAll tests pass. The SDK is working! Yay \o/')
else:
print ('\nTests passed with warning.Take a look at logs')
sys.exit(1)
except RuntimeError:
print "Ending program"
sys.exit(1)
except:
print "Error during running sample tests:", sys.exc_info()[0]
raise
def result_sdk(sdk_dir):
log_path = sdk_dir + 'tests.log'
print 'Results are logged at:' + log_path
try:
f = open(log_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open test log at ' + log_path
raise
for line in reversed(open(log_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result - FAIL. Look at the test log at '+log_path)
return 1
return 0
def result_example(sdk_dir):
exlog_path = sdk_dir + 'test-example.log'
print 'Sample test results are logged at:' + exlog_path
try:
f = open(exlog_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open sample test log at ' + exlog_path
raise
#Read the file in reverse and check for the keyword 'FAIL'.
for line in reversed(open(exlog_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result for Sample tests - FAIL. Look at the test log at '+exlog_path)
return 1
return 0
def kill_process(process, kill_check, mswindows):
print '\nProcess Timedout. Killing the process. Please Rerun this script.'
if mswindows:
win32api.TerminateProcess(process, -1)
else:
os.kill(process, signal.SIGKILL)
kill_check.set()# tell the main routine to kill. Used SIGKILL to hard kill the process.
return
if __name__ == "__main__":
obj = SDK()
obj.download(obj.link,obj.fpath,obj.fname)
obj.extract(obj.base_path,obj.fname)
obj.run_testall(obj.base_path,obj.folder_name)
obj.package(obj.base_path)

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.1" id="svg2997" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" viewBox="-0.5 -0.5 200 200" overflow="visible" enable-background="new -0.5 -0.5 200 200" xml:space="preserve">
<path id="path85" fill="#FFFFFF" d="M-2559.936,6359.65c19.127,26.489,46.371,47.744,80.988,44.707 C-2479.339,6371.648-2523.898,6352.641-2559.936,6359.65z"/>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -139,6 +139,11 @@ opened in the first tab in that window. This is an optional property.
If present and true, the new tab will be opened to the right of the active tab
and will not be active. This is an optional property.
@prop isPrivate {boolean}
Boolean which will determine if a private tab should be opened.
Private browsing mode must be supported in order to do this.
See the [private-browsing](modules/sdk/private-browsing.html) documentation for more information.
@prop [isPinned] {boolean}
If present and true, then the new tab will be pinned as an
[app tab](http://support.mozilla.com/en-US/kb/what-are-app-tabs).

View File

@@ -118,6 +118,11 @@ If the only option being used is `url`, then a bare string URL can be passed to
String URL to be opened in the new window.
This is a required property.
@prop isPrivate {boolean}
Boolean which will determine if a private window should be opened.
Private browsing mode must be supported in order to do this.
See the [private-browsing](modules/sdk/private-browsing.html) documentation for more information.
@prop [onOpen] {function}
A callback function that is called when the window has opened. This does not
mean that the URL content has loaded, only that the window itself is fully

View File

@@ -13,6 +13,7 @@ function Options(options) {
url: { is: ["string"] },
inBackground: { is: ["undefined", "boolean"] },
isPinned: { is: ["undefined", "boolean"] },
isPrivate: { is: ["undefined", "boolean"] },
onOpen: { is: ["undefined", "function"] },
onClose: { is: ["undefined", "function"] },
onReady: { is: ["undefined", "function"] },

View File

@@ -4,19 +4,61 @@
'use strict';
// TODO: BUG 792670 - remove dependency below
const { browserWindows } = require('../windows');
const { browserWindows: windows } = require('../windows');
const { tabs } = require('../windows/tabs-firefox');
const { isPrivate } = require('../private-browsing');
const { isWindowPBSupported } = require('../private-browsing/utils')
const { isPrivateBrowsingSupported } = require('sdk/self');
const supportPrivateTabs = isPrivateBrowsingSupported && isWindowPBSupported;
Object.defineProperties(tabs, {
open: { value: function open(options) {
if (options.inNewWindow)
if (options.inNewWindow) {
// `tabs` option is under review and may be removed.
return browserWindows.open({ tabs: [ options ] });
// Open in active window if new window was not required.
return browserWindows.activeWindow.tabs.open(options);
windows.open({
tabs: [ options ],
isPrivate: options.isPrivate
});
return undefined;
}
// Open in active window if new window was not required..
let activeWindow = windows.activeWindow;
let privateState = !!options.isPrivate;
// if the active window is in the state that we need then use it
if (!supportPrivateTabs || privateState === isPrivate(activeWindow)) {
activeWindow.tabs.open(options);
}
else {
// find a window in the state that we need
let window = getWindow(privateState);
if (window) {
window.tabs.open(options);
}
// open a window in the state that we need
else {
windows.open({
tabs: [ options ],
isPrivate: options.isPrivate
});
}
}
return undefined;
}}
});
function getWindow(privateState) {
for each (let window in windows) {
if (privateState === isPrivate(window)) {
return window;
}
}
return null;
}
// Workaround for bug 674195. Freezing objects from other compartments fail,
// so we use `Object.freeze` from the same component as objects
// `hasOwnProperty`. Since `hasOwnProperty` here will be from other component

View File

@@ -102,10 +102,13 @@ function openTab(window, url, options) {
return window.BrowserApp.addTab(url, {
selected: options.inBackground ? false : true,
pinned: options.isPinned || false,
isPrivate: options.private || false
isPrivate: options.isPrivate || false
});
}
return window.gBrowser.addTab(url);
let tab = window.gBrowser.addTab(url);
if (!options.inBackground)
activateTab(tab);
return tab;
};
exports.openTab = openTab;

View File

@@ -19,7 +19,8 @@ const { Cc, Ci, Cr } = require('chrome'),
{ ns } = require('../core/namespace'),
{ observer: windowObserver } = require('./observer'),
{ getOwnerWindow } = require('../private-browsing/window/utils'),
viewNS = require('sdk/core/namespace').ns();
viewNS = require('../core/namespace').ns(),
{ isPrivateBrowsingSupported } = require('../self');
/**
* Window trait composes safe wrappers for browser window that are E10S
@@ -68,7 +69,7 @@ const BrowserWindowTrait = Trait.compose(
this._tabOptions = [ Options(options.url) ];
}
this._private = !!options.private;
this._isPrivate = isPrivateBrowsingSupported && !!options.isPrivate;
this._load();
@@ -209,9 +210,13 @@ const browserWindows = Trait.resolve({ toString: null }).compose(
return window ? BrowserWindow({window: window}) : null;
},
open: function open(options) {
if (typeof options === "string")
if (typeof options === "string") {
// `tabs` option is under review and may be removed.
options = { tabs: [Options(options)] };
options = {
tabs: [Options(options)],
isPrivate: isPrivateBrowsingSupported && options.isPrivate
};
}
return BrowserWindow(options);
},

View File

@@ -41,7 +41,7 @@ const WindowLoader = Trait.compose({
_load: function _load() {
if (this.__window) return;
this._window = openDialog({
private: this._private,
private: this._isPrivate,
args: this._tabOptions.map(function(options) options.url).join("|")
});
},

View File

@@ -17,11 +17,15 @@ const { EventTarget } = require('../event/target');
const { when: unload } = require('../system/unload');
const { windowIterator } = require('../deprecated/window-utils');
const { List, addListItem, removeListItem } = require('../util/list');
const { isPrivateBrowsingSupported } = require('sdk/self');
const { isTabPBSupported } = require('sdk/private-browsing/utils');
const mainWindow = windowNS(browserWindows.activeWindow).window;
const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
const supportPrivateTabs = isPrivateBrowsingSupported && isTabPBSupported;
const Tabs = Class({
implements: [ List ],
extends: EventTarget,
@@ -53,7 +57,8 @@ const Tabs = Class({
}
let rawTab = openTab(windowNS(activeWin).window, options.url, {
inBackground: options.inBackground
inBackground: options.inBackground,
isPrivate: supportPrivateTabs && options.isPrivate
});
// by now the tab has been created

View File

@@ -13,9 +13,10 @@ const { Tab } = require("../tabs/tab");
const { EventEmitter } = require("../deprecated/events");
const { EVENTS } = require("../tabs/events");
const { getOwnerWindow, getActiveTab, getTabs,
openTab, activateTab } = require("../tabs/utils");
openTab } = require("../tabs/utils");
const { Options } = require("../tabs/common");
const { observer: tabsObserver } = require("../tabs/observer");
const { isWindowPrivate } = require("../private-browsing/utils");
const TAB_BROWSER = "tabbrowser";
@@ -152,11 +153,14 @@ const TabList = List.resolve({ constructor: "_init" }).compose(
_activeTab: null,
open: function open(options) {
let window = this._window;
let chromeWindow = window._window;
options = Options(options);
this._window._tabOptions.push(options);
let tab = openTab(this._window._window, options.url);
if (!options.inBackground)
activateTab(tab);
// save the tab options
window._tabOptions.push(options);
// open the tab
let tab = openTab(chromeWindow, options.url, options);
}
// This is ugly, but necessary. Will be removed by #596248
}).resolve({ toString: null })

View File

@@ -161,6 +161,28 @@ parser_groups = (
default="firefox",
cmds=['test', 'run', 'testex', 'testpkgs',
'testall'])),
(("-o", "--overload-modules",), dict(dest="overload_modules",
help=("Overload JS modules integrated into"
" Firefox with the one from your SDK"
" repository"),
action="store_true",
default=False,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall'])),
(("", "--strip-sdk",), dict(dest="bundle_sdk",
help=("Do not ship SDK modules in the xpi"),
action="store_false",
default=True,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall', 'xpi'])),
(("", "--force-use-bundled-sdk",), dict(dest="force_use_bundled_sdk",
help=("When --strip-sdk isn't passed, "
"force using sdk modules shipped in "
"the xpi instead of firefox ones"),
action="store_true",
default=False,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall', 'xpi'])),
(("", "--no-run",), dict(dest="no_run",
help=("Instead of launching the "
"application, just show the command "
@@ -764,6 +786,14 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
harness_options.update(build)
# When cfx is run from sdk root directory, we will strip sdk modules and
# override them with local modules.
# So that integration tools will continue to work and use local modules
if os.getcwd() == env_root:
options.bundle_sdk = True
options.force_use_bundled_sdk = False
options.overload_modules = True
extra_environment = {}
if command == "test":
# This should be contained in the test runner package.
@@ -792,14 +822,32 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
mydir = os.path.dirname(os.path.abspath(__file__))
app_extension_dir = os.path.join(mydir, "../../app-extension")
if target_cfg.get('preferences'):
harness_options['preferences'] = target_cfg.get('preferences')
harness_options['manifest'] = manifest.get_harness_options_manifest()
harness_options['allTestModules'] = manifest.get_all_test_modules()
if len(harness_options['allTestModules']) == 0 and command == "test":
sys.exit(0)
harness_options['manifest'] = \
manifest.get_harness_options_manifest(options.bundle_sdk)
# Gives an hint to tell if sdk modules are bundled or not
harness_options['is-sdk-bundled'] = options.bundle_sdk
if options.force_use_bundled_sdk:
if not options.bundle_sdk:
print >>sys.stderr, ("--force-use-bundled-sdk and --strip-sdk "
"can't be used at the same time.")
sys.exit(1)
if options.overload_modules:
print >>sys.stderr, ("--force-use-bundled-sdk and --overload-modules "
"can't be used at the same time.")
sys.exit(1)
# Pass a flag in order to force using sdk modules shipped in the xpi
harness_options['force-use-bundled-sdk'] = True
# Pass the list of absolute path for all test modules
if command == "test":
harness_options['allTestModules'] = manifest.get_all_test_modules()
if len(harness_options['allTestModules']) == 0:
sys.exit(0)
from cuddlefish.rdf import gen_manifest, RDFUpdate
@@ -825,7 +873,7 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
# build_manifest earlier
used_files = None
if command == "xpi":
used_files = set(manifest.get_used_files())
used_files = set(manifest.get_used_files(options.bundle_sdk))
if options.no_strip_xpi:
used_files = None # disables the filter, includes all files
@@ -872,7 +920,11 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
norun=options.no_run,
used_files=used_files,
enable_mobile=options.enable_mobile,
mobile_app_name=options.mobile_app_name)
mobile_app_name=options.mobile_app_name,
env_root=env_root,
is_running_tests=(command == "test"),
overload_modules=options.overload_modules,
bundle_sdk=options.bundle_sdk)
except ValueError, e:
print ""
print "A given cfx option has an inappropriate value:"

View File

@@ -260,7 +260,7 @@ class ManifestBuilder:
used.add(package)
return sorted(used)
def get_used_files(self):
def get_used_files(self, bundle_sdk_modules):
# returns all .js files that we reference, plus data/ files. You will
# need to add the loader, off-manifest files that it needs, and
# generated metadata.
@@ -269,16 +269,22 @@ class ManifestBuilder:
yield absname
for me in self.get_module_entries():
yield me.js_filename
# Do not add manifest entries for system modules,
# so that we won't ship SDK files.
if me.packageName != "addon-sdk" or bundle_sdk_modules:
yield me.js_filename
def get_all_test_modules(self):
return self.test_modules
def get_harness_options_manifest(self):
def get_harness_options_manifest(self, bundle_sdk_modules):
manifest = {}
for me in self.get_module_entries():
path = me.get_path()
manifest[path] = me.get_entry_for_manifest()
# Do not add manifest entries for system modules,
# so that we won't ship SDK files.
if me.packageName != "addon-sdk" or bundle_sdk_modules:
manifest[path] = me.get_entry_for_manifest()
return manifest
def get_manifest_entry(self, package, section, module):

View File

@@ -380,7 +380,11 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
logfile=None, addons=None, args=None, extra_environment={},
norun=None,
used_files=None, enable_mobile=False,
mobile_app_name=None):
mobile_app_name=None,
env_root=None,
is_running_tests=False,
overload_modules=False,
bundle_sdk=True):
if binary:
binary = os.path.expanduser(binary)
@@ -392,6 +396,22 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
cmdargs = []
preferences = dict(DEFAULT_COMMON_PREFS)
# Overload global commonjs path with lib/ folders
file_scheme = "file://"
# win32 file scheme needs 3 slashes
if not env_root.startswith("/"):
file_scheme = file_scheme + "/"
addon_id = harness_options["jetpackID"]
pref_prefix = "extensions.modules." + addon_id + ".path"
if overload_modules:
preferences[pref_prefix] = file_scheme + \
os.path.join(env_root, "lib").replace("\\", "/") + "/"
# Overload tests/ mapping with test/ folder, only when running test
if is_running_tests:
preferences[pref_prefix + ".tests"] = file_scheme + \
os.path.join(env_root, "test").replace("\\", "/") + "/"
# For now, only allow running on Mobile with --force-mobile argument
if app_type in ["fennec", "fennec-on-device"] and not enable_mobile:
print """
@@ -483,7 +503,8 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
manifest=manifest_rdf,
xpi_path=xpi_path,
harness_options=harness_options,
limit_to=used_files)
limit_to=used_files,
bundle_sdk=bundle_sdk)
addons.append(xpi_path)
starttime = last_output_time = time.time()

View File

@@ -43,7 +43,7 @@ class Basic(unittest.TestCase):
# target_cfg.dependencies is not provided, so we'll search through
# all known packages (everything in 'deps').
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
m = m.get_harness_options_manifest()
m = m.get_harness_options_manifest(False)
def assertReqIs(modname, reqname, path):
reqs = m["one/%s" % modname]["requirements"]
@@ -72,7 +72,7 @@ class Basic(unittest.TestCase):
[target_cfg.name, "addon-sdk"])
self.failUnlessEqual(deps, ["addon-sdk", "three"])
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
m = m.get_harness_options_manifest()
m = m.get_harness_options_manifest(False)
def assertReqIs(modname, reqname, path):
reqs = m["three/%s" % modname]["requirements"]
self.failUnlessEqual(reqs[reqname], path)
@@ -90,7 +90,7 @@ class Basic(unittest.TestCase):
self.failUnlessEqual(deps, ["addon-sdk", "five"])
# all we care about is that this next call doesn't raise an exception
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
m = m.get_harness_options_manifest()
m = m.get_harness_options_manifest(False)
reqs = m["five/main"]["requirements"]
self.failUnlessEqual(reqs, {});

View File

@@ -202,7 +202,7 @@ class SmallXPI(unittest.TestCase):
[target_cfg.name, "addon-sdk"])
addon_sdk_dir = pkg_cfg.packages["addon-sdk"].lib[0]
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
used_files = list(m.get_used_files())
used_files = list(m.get_used_files(True))
here = up(os.path.abspath(__file__))
def absify(*parts):
fn = os.path.join(here, "linker-files", *parts)

View File

@@ -22,7 +22,8 @@ def mkzipdir(zf, path):
zf.writestr(dirinfo, "")
def build_xpi(template_root_dir, manifest, xpi_path,
harness_options, limit_to=None, extra_harness_options={}):
harness_options, limit_to=None, extra_harness_options={},
bundle_sdk=True):
zf = zipfile.ZipFile(xpi_path, "w", zipfile.ZIP_DEFLATED)
open('.install.rdf', 'w').write(str(manifest))
@@ -84,6 +85,10 @@ def build_xpi(template_root_dir, manifest, xpi_path,
# of all packages sections directories
for packageName in harness_options['packages']:
base_arcpath = ZIPSEP.join(['resources', packageName])
# Eventually strip sdk files. We need to do that in addition to the
# whilelist as the whitelist is only used for `cfx xpi`:
if not bundle_sdk and packageName == 'addon-sdk':
continue
# Always write the top directory, even if it contains no files, since
# the harness will try to access it.
dirs_to_create.add(base_arcpath)

View File

@@ -3,11 +3,164 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const { Ci } = require('chrome');
const { isPrivateBrowsingSupported } = require('sdk/self');
const tabs = require('sdk/tabs');
const { browserWindows: windows } = require('sdk/windows');
const { isPrivate } = require('sdk/private-browsing');
const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
const { is } = require('sdk/system/xul-app');
const { isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
const TAB_URL = 'data:text/html;charset=utf-8,TEST-TAB';
exports.testIsPrivateBrowsingTrue = function(assert) {
assert.ok(isPrivateBrowsingSupported,
'isPrivateBrowsingSupported property is true');
};
// test tab.open with isPrivate: true
// test isPrivate on a tab
// test getOwnerWindow on windows and tabs
exports.testGetOwnerWindow = function(assert, done) {
let window = windows.activeWindow;
let chromeWindow = getOwnerWindow(window);
assert.ok(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
tabs.open({
url: 'about:blank',
isPrivate: true,
onOpen: function(tab) {
// test that getOwnerWindow works as expected
if (is('Fennec')) {
assert.notStrictEqual(chromeWindow, getOwnerWindow(tab));
assert.ok(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow);
}
else {
if (isWindowPBSupported) {
assert.notStrictEqual(chromeWindow,
getOwnerWindow(tab),
'associated window is not the same for window and window\'s tab');
}
else {
assert.strictEqual(chromeWindow,
getOwnerWindow(tab),
'associated window is the same for window and window\'s tab');
}
}
let pbSupported = isTabPBSupported || isWindowPBSupported;
// test that the tab is private if it should be
assert.equal(isPrivate(tab), pbSupported);
assert.equal(isPrivate(getOwnerWindow(tab)), pbSupported);
tab.close(function() done());
}
});
};
// test that it is possible to open a private tab
exports.testTabOpenPrivate = function(assert, done) {
tabs.open({
url: TAB_URL,
isPrivate: true,
onReady: function(tab) {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), (isWindowPBSupported || isTabPBSupported));
tab.close(function() {
done();
});
}
});
}
// test that it is possible to open a non private tab
exports.testTabOpenPrivateDefault = function(assert, done) {
tabs.open({
url: TAB_URL,
onReady: function(tab) {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), false);
tab.close(function() {
done();
});
}
});
}
// test that it is possible to open a non private tab in explicit case
exports.testTabOpenPrivateOffExplicit = function(assert, done) {
tabs.open({
url: TAB_URL,
isPrivate: false,
onReady: function(tab) {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), false);
tab.close(function() {
done();
});
}
});
}
// test windows.open with isPrivate: true
// test isPrivate on a window
if (!is('Fennec')) {
// test that it is possible to open a private window
exports.testWindowOpenPrivate = function(assert, done) {
windows.open({
url: TAB_URL,
isPrivate: true,
onOpen: function(window) {
let tab = window.tabs[0];
tab.once('ready', function() {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), isWindowPBSupported, 'tab is private');
window.close(function() {
done();
});
});
}
});
};
exports.testIsPrivateOnWindowOn = function(assert, done) {
windows.open({
isPrivate: true,
onOpen: function(window) {
assert.equal(isPrivate(window), isWindowPBSupported, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), isWindowPBSupported, 'isPrivate for a tab is false when it should be');
window.close(done);
}
});
};
exports.testIsPrivateOnWindowOffImplicit = function(assert, done) {
windows.open({
onOpen: function(window) {
assert.equal(isPrivate(window), false, 'isPrivate for a window is false when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
})
}
exports.testIsPrivateOnWindowOffExplicit = function(assert, done) {
windows.open({
isPrivate: false,
onOpen: function(window) {
assert.equal(isPrivate(window), false, 'isPrivate for a window is false when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
})
}
}
require('sdk/test/runner').runTestsFromModule(module);

View File

@@ -12,7 +12,7 @@ exports.testIsPrivateOnTab = function(test) {
test.assert(!pb.isPrivate(chromeWindow), 'the top level window is not private');
let rawTab = openTab(chromeWindow, 'data:text/html,<h1>Hi!</h1>', {
private: true
isPrivate: true
});
// test that the tab is private

View File

@@ -32,10 +32,10 @@ exports.testPerWindowPrivateBrowsingGetter = function(assert, done) {
exports.testIsPrivateOnWindowOn = function(assert, done) {
windows.open({
private: true,
isPrivate: true,
onOpen: function(window) {
assert.equal(isPrivate(window), true, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), true, 'isPrivate for a tab is false when it should be');
assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
});

View File

@@ -93,7 +93,7 @@ exports.testDeprecateEvent = function(assert, done) {
emit(testObj, 'water');
});
assert.equal(errors.length, 1, "only one error is dispatched");
let msg = errors[0];console.log(msg);
let msg = errors[0];
assert.ok(msg.indexOf("BAD") !== -1, "message contains the given message");
assert.ok(msg.indexOf("deprecateEvent") !== -1,
"message contains name of the caller function");

View File

@@ -7,6 +7,7 @@ const { Ci } = require('chrome');
const { pb, pbUtils, getOwnerWindow } = require('./private-browsing/helper');
const { merge } = require('sdk/util/object');
const windows = require('sdk/windows').browserWindows;
const tabs = require('sdk/tabs');
const winUtils = require('sdk/window/utils');
const { isPrivateBrowsingSupported } = require('sdk/self');
const { is } = require('sdk/system/xul-app');
@@ -70,9 +71,9 @@ exports.testGetOwnerWindow = function(test) {
let chromeWindow = getOwnerWindow(window);
test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
window.tabs.open({
tabs.open({
url: 'about:blank',
private: true, // should be ignored in this case
isPrivate: true,
onOpen: function(tab) {
// test that getOwnerWindow works as expected
if (is('Fennec')) {
@@ -86,6 +87,7 @@ exports.testGetOwnerWindow = function(test) {
// test that the tab is not private
// private flag should be ignored by default
test.assert(!isPrivate(tab));
test.assert(!isPrivate(getOwnerWindow(tab)));
tab.close(function() test.done());
}

View File

@@ -6,6 +6,8 @@
const { Loader } = require('sdk/test/loader');
const { browserWindows } = require('sdk/windows');
const tabs = require('sdk/tabs');
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>';
@@ -289,8 +291,29 @@ exports.testTabContentTypeAndReload = function(test) {
}
else {
test.assertEqual(tab.contentType, "text/xml");
tab.close(function() test.done());
tab.close(function() {
test.done();
});
}
}
});
};
// test that it is possible to open a private tab
exports.testTabOpenPrivate = function(test) {
test.waitUntilDone();
let url = 'about:blank';
tabs.open({
url: url,
isPrivate: true,
onReady: function(tab) {
test.assertEqual(tab.url, url, 'opened correct tab');
test.assertEqual(isPrivate(tab), false, 'private tabs arenot supported by default');
tab.close(function() {
test.done();
});
}
});
}

View File

@@ -12,6 +12,8 @@ const wm = Cc['@mozilla.org/appshell/window-mediator;1'].
const { browserWindows } = require("sdk/windows");
const tabs = require("sdk/tabs");
const { WindowTracker } = require("sdk/deprecated/window-utils");
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported } = require('sdk/private-browsing/utils');
// TEST: open & close window
exports.testOpenAndCloseWindow = function(test) {
@@ -101,7 +103,7 @@ exports.testWindowTabsObject = function(test) {
}
browserWindows.open({
url: "data:text/html;charset=utf-8,<title>tab 1</title>",
onActivate: function onOpen(win) {
onActivate: function onActivate(win) {
window = win;
runTest();
},
@@ -370,3 +372,24 @@ exports.testTrackWindows = function(test) {
openWindow();
}
// test that it is not possible to open a private window by default
exports.testWindowOpenPrivateDefault = function(test) {
test.waitUntilDone();
browserWindows.open({
url: 'about:mozilla',
isPrivate: true,
onOpen: function(window) {
let tab = window.tabs[0];
tab.once('ready', function() {
test.assertEqual(tab.url, 'about:mozilla', 'opened correct tab');
test.assertEqual(isPrivate(tab), false, 'tab is not private');
window.close(function() {
test.done();
});
});
}
});
}