diff --git a/tests/compat/test_gecko42.py b/tests/compat/test_gecko42.py new file mode 100644 index 000000000..ec030d1a6 --- /dev/null +++ b/tests/compat/test_gecko42.py @@ -0,0 +1,86 @@ +from helper import CompatTestCase +from validator.chromemanifest import ChromeManifest +from validator.compat import FX42_DEFINITION +from validator.errorbundler import ErrorBundle +from validator.testcases import content + + +class TestFX42Compat(CompatTestCase): + """Test that compatibility tests for Gecko 42 are properly executed.""" + + VERSION = FX42_DEFINITION + + def test_parseContentType(self): + self.run_script_for_compat(""" + var netutil = Components + .classes["@mozilla.org/network/util;1"] + .getService(Components.interfaces.nsINetUtil); + netutil.parseContentType('text/html', 'utf-8', {}); + """) + self.assert_compat_error() + + def test_newTab_xul(self): + """Tests that the newTab.xul overlay is not in the chrome.manifest.""" + + err = ErrorBundle() + assert content.test_newTab_xul(err, None) is None + + err.save_resource('chrome.manifest', + ChromeManifest('foo bar', 'chrome.manifest')) + content.test_newTab_xul(err, None) + assert not err.failed() + + err.save_resource( + 'chrome.manifest', + ChromeManifest( + ('overlay chrome://browser/content/newtab/newTab.xul ' + 'chrome://ch/content/newtab/index.xul'), + 'chrome.manifest')) + content.test_newTab_xul(err, None) + assert err.failed() + + def test_mozRequestAnimationFrame(self): + self.run_script_for_compat(""" + // Don't flag comments: window.mozRequestAnimationFrame() + window.requestAnimationFrame(); + """) + assert not self.compat_err.errors + assert not self.compat_err.warnings + + self.run_script_for_compat(""" + window.mozRequestAnimationFrame(); + """) + self.assert_compat_error() + + def _test_nsIPermissionManager(self, method): + self.run_script_for_compat(""" + var perms = Cc["@mozilla.org/permissionmanager;1"] + .getService(Ci.nsIPermissionManager); + %s + """ % method) + self.assert_compat_error() + + def _test_ServicesPerms(self, method): + self.run_script_for_compat(""" + Components.utils.import("resource://gre/modules/Services.jsm"); + var perms = Services.perms; + %s + """ % method) + self.assert_compat_error() + + def test_nsIPermissionManagerMethods(self): + methods = ("perms.add(url, 'cookie', 1);", + "perms.addFromPrincipal(url, 'cookie', 1);", + "perms.remove('yahoo.com', 'cookie');", + "perms.removeFromPrincipal('yahoo.com', 'cookie');", + "perms.removeAll();", + "perms.testExactPermission(url, cookie);" + "perms.testExactPermissionFromPrincipal(url, cookie);", + "perms.testPermission(url, cookie);", + "perms.testPermissionFromPrincipal(url, cookie);") + + for method in methods: + yield self._test_nsIPermissionManager, method + + for method in methods: + yield self._test_ServicesPerms, method diff --git a/validator/compat.py b/validator/compat.py index 86e92e22f..eb82574ff 100644 --- a/validator/compat.py +++ b/validator/compat.py @@ -27,6 +27,7 @@ def _build_definition(maj_version_num, firefox=True, fennec=True, FX39_DEFINITION = _build_definition(39) FX40_DEFINITION = _build_definition(40) FX41_DEFINITION = _build_definition(41) +FX42_DEFINITION = _build_definition(42) _tb_definition = (lambda ver: _build_definition(ver, firefox=False, fennec=False, android=False)) diff --git a/validator/testcases/content.py b/validator/testcases/content.py index f5b80f423..9ac4c3246 100644 --- a/validator/testcases/content.py +++ b/validator/testcases/content.py @@ -14,8 +14,8 @@ import validator.testcases.scripting as testendpoint_js import validator.testcases.langpack as testendpoint_langpack from validator.xpi import XPIManager -from validator.constants import (PACKAGE_LANGPACK, PACKAGE_SUBPACKAGE, - PACKAGE_THEME) +from validator.constants import (BUGZILLA_BUG, PACKAGE_LANGPACK, + PACKAGE_SUBPACKAGE, PACKAGE_THEME) FLAGGED_FILES = set(['.DS_Store', 'Thumbs.db']) @@ -52,6 +52,30 @@ def test_xpcnativewrappers(err, xpi_package=None): context=triple['context']) +@decorator.register_test(tier=1) +def test_newTab_xul(err, xpi_package=None): + """Tests the chrome.manifest file to ensure that it doesn't contain the + deprecated chrome://browser/content/newtab/newTab.xul overlay.""" + + # Don't even both with the test(s) if there's no chrome.manifest. + chrome = err.get_resource('chrome.manifest') + if not chrome: + return None + + for triple in chrome.triples: + # Test to make sure that the triple's subject is valid + if triple['predicate'] == 'chrome://browser/content/newtab/newTab.xul': + err.warning( + ('testcases_content', 'test_newTab_xul', + 'found_in_chrome_manifest'), + 'newTab.xul is now newTab.xhtml.', + 'newTab.xul is now newTab.xhtml. ' + 'See %s for more information.' % BUGZILLA_BUG % 1167601, + filename=triple['filename'], + line=triple['line'], + context=triple['context']) + + @decorator.register_test(tier=2) def test_packed_packages(err, xpi_package=None): 'Tests XPI and JAR files for naughty content.' diff --git a/validator/testcases/javascript/actions.py b/validator/testcases/javascript/actions.py index 840c8b28a..d9c93c413 100644 --- a/validator/testcases/javascript/actions.py +++ b/validator/testcases/javascript/actions.py @@ -6,7 +6,7 @@ # Global import of predefinedentities will cause an import loop import instanceactions from validator.constants import (BUGZILLA_BUG, DESCRIPTION_TYPES, FENNEC_GUID, - FIREFOX_GUID, MAX_STR_SIZE) + FIREFOX_GUID, MAX_STR_SIZE, MDN_DOC) from validator.decorator import version_range from jstypes import JSArray, JSContext, JSLiteral, JSObject, JSWrapper @@ -614,6 +614,19 @@ def _readonly_top(traverser, right, node_right): tier=5) +def _renamed_mozRequestAnimationFrame(traverser): + """Handle the deprecation of mozRequestAnimationFrame.""" + traverser.err.warning( + err_id=('testcases_javascript_actions', + '_renamed_mozRequestAnimationFrame'), + warning='window.mozRequestionAnimationFrame has been unprefixed', + description='mozRequestAnimationFrame is no longer supported in ' + 'prefixed form, please use requestAnimationFrame instead. ' + 'See %s for more information.' % + MDN_DOC % 'Web/API/window/requestAnimationFrame', + compatibility_type='error') + + def _expression(traverser, node): """ This is a helper method that allows node definitions to point at diff --git a/validator/testcases/javascript/entity_values.py b/validator/testcases/javascript/entity_values.py index b7c3c16b3..3b87e7fec 100644 --- a/validator/testcases/javascript/entity_values.py +++ b/validator/testcases/javascript/entity_values.py @@ -171,6 +171,33 @@ def on_override(wrapper, arguments, traverser): return {'return': on_override} +@register_entity('nsIPermissionManager.add') +@register_entity('nsIPermissionManager.addFromPrincipal') +@register_entity('nsIPermissionManager.remove') +@register_entity('nsIPermissionManager.removeFromPrincipal') +@register_entity('nsIPermissionManager.removeAll') +@register_entity('nsIPermissionManager.testExactPermission') +@register_entity('nsIPermissionManager.testExactPermissionFromPrincipal') +@register_entity('nsIPermissionManager.testPermission') +@register_entity('nsIPermissionManager.testPermissionFromPrincipal') +def nsIPermissionManager(traverser): + traverser.err.warning( + err_id=('testcases_javascript_entity_values', + 'nsIPermissionManager'), + warning='The Permission Manager now uses origins instead of hosts.', + description=( + 'The Permission Manager now uses origins instead of hosts, ' + 'meaning that http://mozilla.com and https://mozilla.com now ' + 'have different permissions. Some methods in the component now ' + 'take nsIURI instead of strings. ' + 'See %s for more information.' % BUGZILLA_BUG % 1165263), + filename=traverser.filename, + line=traverser.line, + column=traverser.position, + compatibility_type='error', + context=traverser.context) + + # Thunderbird 29 JS changes TB29_JS_ENTITIES = [ {'name':'DisablePhishingWarning', diff --git a/validator/testcases/javascript/instanceactions.py b/validator/testcases/javascript/instanceactions.py index 908770056..1bcb9b473 100644 --- a/validator/testcases/javascript/instanceactions.py +++ b/validator/testcases/javascript/instanceactions.py @@ -12,6 +12,7 @@ import actions from instanceproperties import _set_HTML_property +from validator.constants import BUGZILLA_BUG def addEventListener(args, traverser, node, wrapper): @@ -334,6 +335,24 @@ def set_preference(wrapper, arguments, traverser): from validator.testcases.regex import validate_pref validate_pref(pref, traverser, kw, wrapper=arg) + +def parseContentType(args, traverser, node, wrapper): + traverser.err.warning( + err_id=('testcases_javascript_entity_values', + 'nsINetUtilParseContentType'), + warning='`nsINetUtil.parseContentType()` method has been renamed to ' + '`nsINetUtil.parseResponseContentType`.', + description='The `nsINetUtil.parseContentType()` method has been ' + 'renamed to `nsINetUtil.parseResponseContentType()`. Its ' + 'behavior should remain the same.' + 'See %s for more information.' % BUGZILLA_BUG % 1214929, + filename=traverser.filename, + line=traverser.line, + column=traverser.position, + compatibility_type='error', + context=traverser.context) + + INSTANCE_DEFINITIONS = { 'addEventListener': addEventListener, 'bind': bind, @@ -350,4 +369,5 @@ def set_preference(wrapper, arguments, traverser): 'openDialog': openDialog, 'QueryInterface': QueryInterface, 'setAttribute': setAttribute, + 'parseContentType': parseContentType, } diff --git a/validator/testcases/javascript/predefinedentities.py b/validator/testcases/javascript/predefinedentities.py index f67423f72..ffafa956b 100644 --- a/validator/testcases/javascript/predefinedentities.py +++ b/validator/testcases/javascript/predefinedentities.py @@ -479,7 +479,17 @@ def registry_key(write=False): u'writeIntValue': REGISTRY_WRITE, u'writeStringValue': REGISTRY_WRITE, }}, - } + 'nsIPermissionManager': {'value': { + 'add': entity('nsIPermissionManager.add'), + 'addFromPrincipal': entity('nsIPermissionManager.addFromPrincipal'), + 'remove': entity('nsIPermissionManager.remove'), + 'removeFromPrincipal': entity('nsIPermissionManager.removeFromPrincipal'), + 'removeAll': entity('nsIPermissionManager.removeAll'), + 'testExactPermission': entity('nsIPermissionManager.testExactPermission'), + 'testExactPermissionFromPrincipal': entity('nsIPermissionManager.testExactPermissionFromPrincipal'), + 'testPermission': entity('nsIPermissionManager.testPermission'), + 'testPermissionFromPrincipal': entity('nsIPermissionManager.testPermissionFromPrincipal')}}, +} INTERFACE_ENTITIES = {u'nsIXMLHttpRequest': {'xpcom_map': @@ -947,6 +957,8 @@ def interface_obj(iface): u'width': {'readonly': False}, u'height': {'readonly': False}, u'top': {'readonly': actions._readonly_top}, + u'mozRequestAnimationFrame': { + 'value': actions._renamed_mozRequestAnimationFrame}, u'content': {'context': 'content',