[Pkg-mozext-commits] [requestpolicy] 127/257: [tst][ref] Add-On Library: Replace UI lib by API lib
David Prévot
taffit at moszumanska.debian.org
Thu Jan 28 03:20:05 UTC 2016
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository requestpolicy.
commit e2b116acdb56cff727239baeb5e29e27e9d25e7e
Author: Martin Kimmerle <dev at 256k.de>
Date: Wed Nov 4 18:27:19 2015 +0100
[tst][ref] Add-On Library: Replace UI lib by API lib
Replace the Puppeteer library "ui/addons.py" by "api/addon.py".
The old library used the UI of the "about:addons` page, whereas
the new library uses directly the `AddonManager` API inside
Firefox. This is a much cleaner way of doing install, uninstall,
enable and disable actions to Add-Ons, and therefore the library
is also easier to maintain.
---
tests/marionette/rp_puppeteer/__init__.py | 4 +
tests/marionette/rp_puppeteer/api/addon.py | 257 ++++++++++++++++
tests/marionette/rp_puppeteer/tests/manifest.ini | 2 +-
tests/marionette/rp_puppeteer/tests/test_addon.py | 68 +++++
tests/marionette/rp_puppeteer/tests/test_addons.py | 172 -----------
tests/marionette/rp_puppeteer/ui/addons.py | 339 ---------------------
.../test_multiple_installations.py | 214 +++++++------
.../test_restartlessness.py | 74 +++--
tests/marionette/tests/test_setup_page.py | 30 +-
9 files changed, 516 insertions(+), 644 deletions(-)
diff --git a/tests/marionette/rp_puppeteer/__init__.py b/tests/marionette/rp_puppeteer/__init__.py
index c770a28..5b778f8 100644
--- a/tests/marionette/rp_puppeteer/__init__.py
+++ b/tests/marionette/rp_puppeteer/__init__.py
@@ -28,6 +28,10 @@ class RequestPolicyPuppeteer(object):
def requests(self):
pass
+ @use_class_as_property('api.addon.RequestPolicy')
+ def rp_addon(self):
+ pass
+
@use_class_as_property('api.rules.Rules')
def rules(self):
pass
diff --git a/tests/marionette/rp_puppeteer/api/addon.py b/tests/marionette/rp_puppeteer/api/addon.py
new file mode 100644
index 0000000..797b5a4
--- /dev/null
+++ b/tests/marionette/rp_puppeteer/api/addon.py
@@ -0,0 +1,257 @@
+# 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/.
+
+from marionette_driver.wait import Wait
+from firefox_puppeteer.base import BaseLib
+from rp_puppeteer.api.error_detection import (LoggingErrorDetection,
+ ConsoleErrorDetection)
+from contextlib import contextmanager
+
+
+class Addon(BaseLib):
+ """Class to install/uninstall/enable/disable an Add-On."""
+
+ sandbox = "rp-puppeteer-addons"
+
+ def __init__(self, marionette_getter, addon_id, install_url):
+ super(Addon, self).__init__(marionette_getter)
+ self.addon_id = addon_id
+ self.install_url = install_url
+
+ #################################
+ # Public Properties and Methods #
+ #################################
+
+ def install(self):
+ with self._addon_install():
+ # Start installing.
+ self.marionette.execute_script("""
+ var globalScope = this;
+ globalScope.addonInstall.install();
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ def is_installation_finished(_):
+ return self.marionette.execute_script("""
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
+ var globalScope = this;
+ var state = globalScope.addonInstall.state;
+ return state === AddonManager.STATE_INSTALLED;
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ # Wait until installed.
+ Wait(self.marionette).until(is_installation_finished)
+
+ def uninstall(self):
+ with self._addon():
+ return self.marionette.execute_script("""
+ var globalScope = this;
+ var addon = globalScope.addon;
+
+ if (addon !== null) {
+ addon.uninstall();
+ }
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ Wait(self.marionette).until(lambda _: not self.is_installed)
+
+ def enable(self):
+ self._set_user_disabled(False)
+ Wait(self.marionette).until(lambda _: self.is_active)
+
+ def disable(self):
+ self._set_user_disabled(True)
+ Wait(self.marionette).until(lambda _: not self.is_active)
+
+ @property
+ def is_installed(self):
+ with self._addon():
+ return self.marionette.execute_script("""
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
+ var globalScope = this;
+ var addon = globalScope.addon;
+
+ if (addon !== null) {
+ return true;
+ }
+ return false;
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ @property
+ def is_active(self):
+ with self._addon():
+ return self.marionette.execute_script("""
+ var globalScope = this;
+ var addon = globalScope.addon;
+
+ if (addon !== null) {
+ return addon.isActive;
+ }
+ return false;
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ ##################################
+ # Private Properties and Methods #
+ ##################################
+
+ @contextmanager
+ def _addon(self):
+ """Provide an `Addon` object in the sandbox."""
+
+ self.marionette.execute_script("""
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
+ var addonID = arguments[0];
+
+ var globalScope = this;
+ globalScope.addon = null;
+ globalScope.addonCallbackCalled = false;
+
+ var addonCallback = function (addon) {
+ globalScope.addon = addon;
+ globalScope.addonCallbackCalled = true;
+ };
+
+ AddonManager.getAddonByID(addonID, addonCallback);
+ """, sandbox=self.sandbox, new_sandbox=False, script_args=[self.addon_id])
+
+ self._wait_until_true("addonCallbackCalled")
+
+ try:
+ yield
+ finally:
+ # Cleanup
+ self.marionette.execute_script("""
+ var globalScope = this;
+ delete globalScope.addon;
+ delete globalScope.addonCallbackCalled;
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ @contextmanager
+ def _addon_install(self):
+ """Provide an `AddonInstall` object in the sandbox."""
+
+ self.marionette.execute_script("""
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
+ var installUrl = arguments[0];
+
+ var globalScope = this;
+ globalScope.addonInstall = null;
+ globalScope.installCallbackCalled = false;
+
+ var installCallback = function (addonInstall) {
+ globalScope.addonInstall = addonInstall;
+ globalScope.installCallbackCalled = true;
+ };
+
+ AddonManager.getInstallForURL(installUrl, installCallback,
+ "application/x-xpinstall");
+ """, sandbox=self.sandbox, new_sandbox=False, script_args=[self.install_url])
+
+ self._wait_until_true("installCallbackCalled")
+
+ try:
+ yield
+ finally:
+ # Cleanup
+ self.marionette.execute_script("""
+ var globalScope = this;
+ delete globalScope.addonInstall;
+ delete globalScope.installCallbackCalled;
+ """, sandbox=self.sandbox, new_sandbox=False)
+
+ def _wait_until_true(self, variable_name):
+ def is_true(_):
+ return self.marionette.execute_script(
+ """
+ var globalScope = this;
+ return globalScope[arguments[0]] === true;
+ """, sandbox=self.sandbox, new_sandbox=False,
+ script_args=[variable_name])
+
+ Wait(self.marionette).until(is_true)
+
+ def _set_user_disabled(self, value):
+ assert isinstance(value, bool)
+ with self._addon():
+ return self.marionette.execute_script("""
+ var globalScope = this;
+ var addon = globalScope.addon;
+
+ if (addon !== null) {
+ addon.userDisabled = arguments[0];
+ }
+ """, sandbox=self.sandbox, new_sandbox=False, script_args=[value])
+
+
+class RequestPolicy(Addon):
+ """Class to install/uninstall/enable/disable RequestPolicy."""
+
+ ignore_errors = False
+
+ def __init__(self, marionette_getter):
+ Addon.__init__(self, marionette_getter,
+ addon_id="rpcontinued at non-amo.requestpolicy.org",
+ install_url=("http://localhost/.dist/"
+ "requestpolicy-unit-testing.xpi"))
+
+ self.pref_welcome_win = "extensions.requestpolicy.welcomeWindowShown"
+
+ self.logging_error_detect = LoggingErrorDetection(marionette_getter)
+ self.console_error_detect = ConsoleErrorDetection(marionette_getter)
+
+ #################################
+ # Public Properties and Methods #
+ #################################
+
+ def install(self, ignore_errors=False):
+ with self._ensure_no_errors():
+ super(RequestPolicy, self).install()
+
+ def uninstall(self, ignore_errors=False):
+ with self._ensure_no_errors():
+ super(RequestPolicy, self).uninstall()
+
+ def enable(self, ignore_errors=False):
+ with self._ensure_no_errors():
+ super(RequestPolicy, self).enable()
+
+ def disable(self, ignore_errors=False):
+ with self._ensure_no_errors():
+ super(RequestPolicy, self).disable()
+
+ ##################################
+ # Private Properties and Methods #
+ ##################################
+
+ @contextmanager
+ def _ensure_no_errors(self):
+ if self.ignore_errors:
+ yield
+ return
+
+ logging_errors_before = self.logging_error_detect.n_errors
+ console_errors_before = self.console_error_detect.n_errors
+ yield
+ logging_error_count = (self.logging_error_detect.n_errors -
+ logging_errors_before)
+ console_error_count = (self.console_error_detect.n_errors -
+ console_errors_before)
+ console_error_messages = self.console_error_detect.messages
+
+ if logging_error_count > 0 and console_error_count > 0:
+ raise Exception("There have been {} Logging errors and "
+ "{} Console errors! "
+ "Console error messages were: {}"
+ .format(logging_error_count, console_error_count,
+ console_error_messages))
+ elif logging_error_count > 0:
+ raise Exception("There have been {} Logging "
+ "errors!".format(logging_error_count))
+ elif console_error_count > 0:
+ raise Exception("There have been {} Console errors! "
+ "Messages were: {}".format(console_error_count,
+ console_error_messages))
diff --git a/tests/marionette/rp_puppeteer/tests/manifest.ini b/tests/marionette/rp_puppeteer/tests/manifest.ini
index ffd1e0f..bf2d45a 100644
--- a/tests/marionette/rp_puppeteer/tests/manifest.ini
+++ b/tests/marionette/rp_puppeteer/tests/manifest.ini
@@ -1,4 +1,4 @@
-[test_addons.py]
+[test_addon.py]
[test_context_menu.py]
[test_error_detection.py]
[test_l10n.py]
diff --git a/tests/marionette/rp_puppeteer/tests/test_addon.py b/tests/marionette/rp_puppeteer/tests/test_addon.py
new file mode 100644
index 0000000..49df254
--- /dev/null
+++ b/tests/marionette/rp_puppeteer/tests/test_addon.py
@@ -0,0 +1,68 @@
+# 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/.
+
+from rp_ui_harness import RequestPolicyTestCase
+from rp_puppeteer.api.addon import Addon
+
+
+class TestAddons(RequestPolicyTestCase):
+
+ def setUp(self):
+ super(TestAddons, self).setUp()
+ self.addon = Addon(lambda: self.marionette,
+ addon_id="dummy-ext at requestpolicy.org",
+ install_url="http://localhost/.dist/dummy-ext.xpi")
+ self.addon.install()
+
+ def tearDown(self):
+ try:
+ self.addon.uninstall()
+ finally:
+ super(TestAddons, self).tearDown()
+
+ def test_uninstall_install(self):
+ self.assertTrue(self.addon.is_installed)
+ self.addon.uninstall()
+ self.assertFalse(self.addon.is_installed)
+ self.addon.install()
+ self.assertTrue(self.addon.is_installed)
+
+ def test_multiple_uninstall_install(self):
+ self.addon.uninstall()
+ self.addon.uninstall()
+ self.addon.install()
+ self.addon.install()
+
+ def test_disable_enable(self):
+ self.assertTrue(self.addon.is_active)
+ self.addon.disable()
+ self.assertFalse(self.addon.is_active)
+ self.addon.enable()
+ self.assertTrue(self.addon.is_active)
+
+ def test_multiple_disable_enable(self):
+ self.addon.disable()
+ self.addon.disable()
+ self.addon.enable()
+ self.addon.enable()
+
+ def test_is_installed(self):
+ self.assertTrue(self.addon.is_installed)
+ self.addon.disable()
+ self.assertTrue(self.addon.is_installed)
+ self.addon.uninstall()
+ self.assertFalse(self.addon.is_installed)
+ self.addon.install()
+ self.assertTrue(self.addon.is_installed)
+ self.addon.enable()
+
+ def test_is_active(self):
+ self.assertTrue(self.addon.is_active)
+ self.addon.disable()
+ self.assertFalse(self.addon.is_active)
+ self.addon.uninstall()
+ self.assertFalse(self.addon.is_active)
+ self.addon.install()
+ self.addon.enable()
+ self.assertTrue(self.addon.is_active)
diff --git a/tests/marionette/rp_puppeteer/tests/test_addons.py b/tests/marionette/rp_puppeteer/tests/test_addons.py
deleted file mode 100644
index e28fba3..0000000
--- a/tests/marionette/rp_puppeteer/tests/test_addons.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# 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/.
-
-from rp_ui_harness import RequestPolicyTestCase
-
-from rp_puppeteer.ui.addons import Addons, AboutAddonsTab
-
-
-ADDON_ID = "dummy-ext at requestpolicy.org"
-INSTALL_URL = "http://localhost/link.html?.dist/dummy-ext.xpi"
-
-
-class AddonsTestCase(RequestPolicyTestCase):
- def selected_tab_is_about_addons(self):
- location = self.browser.tabbar.selected_tab.location
- return location == "about:addons"
-
- def extension_category_is_selected(self):
- if not self.selected_tab_is_about_addons():
- return False
- with self.marionette.using_context("content"):
-
- # Using `get_attribute` does not work here. It raises
- # an exception: "Element is not selectable".
- rv = self.marionette.execute_script(
- """
- let category = document.getElementById("category-extension");
- return category.getAttribute("selected");
- """);
- return rv == "true"
-
- def count_tabs(self):
- return len(self.browser.tabbar.tabs)
-
-
-class TestAddons(AddonsTestCase):
- def setUp(self):
- AddonsTestCase.setUp(self)
- self.addons = Addons(lambda: self.marionette)
- self.addons.install_addon(INSTALL_URL)
-
- def tearDown(self):
- try:
- self.addons.remove_addon_by_id(ADDON_ID)
- finally:
- AddonsTestCase.tearDown(self)
-
- def test_using_addon_list(self):
- num_tabs = self.count_tabs()
- self.assertFalse(self.selected_tab_is_about_addons())
- with self.addons.using_addon_list() as about_addons:
- self.assertIsInstance(about_addons, AboutAddonsTab)
- self.assertTrue(self.selected_tab_is_about_addons())
- self.assertTrue(self.extension_category_is_selected())
- self.assertEqual(self.count_tabs(), num_tabs + 1,
- msg="The number of tabs has increased by one.")
- self.assertFalse(self.selected_tab_is_about_addons())
- self.assertEqual(self.count_tabs(), num_tabs,
- msg="The number of tabs is like in the beginning.")
-
- def test_install_in_two_steps(self):
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
- self.addons.remove_addon_by_id(ADDON_ID)
- self.assertFalse(self.addons.is_addon_installed(ADDON_ID))
-
- tab = None
- with self.addons.install_addon_in_two_steps(INSTALL_URL):
- # when a tab is opened and selected, there shouldn't be an exception
- tab = self.browser.tabbar.open_tab()
- tab.select()
- tab.close()
-
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
-
- def test_uninstall_install(self):
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
- self.addons.remove_addon_by_id(ADDON_ID)
- self.assertFalse(self.addons.is_addon_installed(ADDON_ID))
- self.addons.install_addon(INSTALL_URL)
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
-
- def test_multiple_uninstall_install(self):
- self.addons.remove_addon_by_id(ADDON_ID)
- self.addons.remove_addon_by_id(ADDON_ID)
- self.addons.install_addon(INSTALL_URL)
- self.addons.install_addon(INSTALL_URL)
-
- def test_disable_enable(self):
- self.assertTrue(self.addons.is_addon_enabled(ADDON_ID))
- self.addons.disable_addon_by_id(ADDON_ID)
- self.assertFalse(self.addons.is_addon_enabled(ADDON_ID))
- self.addons.enable_addon_by_id(ADDON_ID)
- self.assertTrue(self.addons.is_addon_enabled(ADDON_ID))
-
- def test_multiple_disable_enable(self):
- self.addons.disable_addon_by_id(ADDON_ID)
- self.addons.disable_addon_by_id(ADDON_ID)
- self.addons.enable_addon_by_id(ADDON_ID)
- self.addons.enable_addon_by_id(ADDON_ID)
-
- def test_is_installed(self):
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
- self.addons.disable_addon_by_id(ADDON_ID)
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
- self.addons.remove_addon_by_id(ADDON_ID)
- self.assertFalse(self.addons.is_addon_installed(ADDON_ID))
- self.addons.install_addon(INSTALL_URL)
- self.assertTrue(self.addons.is_addon_installed(ADDON_ID))
- self.addons.enable_addon_by_id(ADDON_ID)
-
- def test_is_enabled(self):
- self.assertTrue(self.addons.is_addon_enabled(ADDON_ID))
- self.addons.disable_addon_by_id(ADDON_ID)
- self.assertFalse(self.addons.is_addon_enabled(ADDON_ID))
- self.addons.remove_addon_by_id(ADDON_ID)
- self.assertFalse(self.addons.is_addon_enabled(ADDON_ID))
- self.addons.install_addon(INSTALL_URL)
- self.addons.enable_addon_by_id(ADDON_ID)
- self.assertTrue(self.addons.is_addon_enabled(ADDON_ID))
-
-
-class TestAboutAddons(AddonsTestCase):
- def setUp(self):
- RequestPolicyTestCase.setUp(self)
-
- Addons(lambda: self.marionette).install_addon(INSTALL_URL)
-
- self.about_addons = AboutAddonsTab(lambda: self.marionette)
- self.about_addons.open_tab()
- self.about_addons.set_category_by_id("extension")
-
- def tearDown(self):
- try:
- if self.about_addons.is_addon_installed(ADDON_ID):
- self.about_addons.remove_addon(self.addon)
- self.about_addons.close_tab()
- finally:
- RequestPolicyTestCase.tearDown(self)
-
- @property
- def addon(self):
- return self.about_addons.get_addon_by_id(ADDON_ID)
-
- def test_close_tab_open_tab(self):
- self.assertTrue(self.selected_tab_is_about_addons())
- self.about_addons.close_tab()
- self.assertFalse(self.selected_tab_is_about_addons())
- self.about_addons.open_tab()
- self.assertTrue(self.selected_tab_is_about_addons())
-
- def test_disable_enable(self):
- """Test the methods `disable`, `enable` and `is_enabled`.
- """
- self.assertTrue(self.addon.is_enabled(), msg="The addon is enabled.")
- self.about_addons.disable_addon(self.addon)
- self.assertFalse(self.addon.is_enabled(),
- msg="The addon has been disabled.")
- self.about_addons.enable_addon(self.addon)
- self.assertTrue(self.addon.is_enabled(),
- msg="The addon is enabled again.")
-
- def test_uninstall(self):
- def is_installed():
- return self.about_addons.is_addon_installed(ADDON_ID)
-
- self.assertTrue(is_installed(), msg="The addon is installed.")
- self.about_addons.remove_addon(self.addon)
-
- # The addon should be already uninstalled when `remove`
- # returns. Therefore there is no "wait until".
- self.assertFalse(is_installed(), msg="The addon has been removed.")
diff --git a/tests/marionette/rp_puppeteer/ui/addons.py b/tests/marionette/rp_puppeteer/ui/addons.py
deleted file mode 100644
index 838493f..0000000
--- a/tests/marionette/rp_puppeteer/ui/addons.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# 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/.
-
-from marionette_driver.errors import NoSuchElementException
-from marionette_driver.wait import Wait
-from firefox_puppeteer.base import BaseLib
-from firefox_puppeteer.ui.windows import Windows
-from rp_puppeteer.api.error_detection import (LoggingErrorDetection,
- ConsoleErrorDetection)
-from contextlib import contextmanager
-
-
-class _InstallNotifications(object):
- """This class provides methods for managing the install notificaitons.
- """
-
- def __init__(self, marionette):
- self.marionette = marionette
- self.wait = Wait(self.marionette)
-
- def is_hidden(self, notification_id):
- with self.marionette.using_context("chrome"):
- try:
- hidden_attr = (
- self.marionette
- .find_element("id", notification_id)
- .get_attribute("hidden")
- )
- return hidden_attr == "true"
- except NoSuchElementException:
- return True
-
- def wait_until_not_hidden(self, notification_id):
- self.wait.until(
- lambda m: not self.is_hidden(notification_id),
- message=("Notification with ID {} is shown."
- .format(notification_id)))
-
- def wait_until_hidden(self, notification_id):
- self.wait.until(
- lambda m: self.is_hidden(notification_id),
- message=("Notification with ID {} is hidden."
- .format(notification_id)))
-
- @contextmanager
- def wrap_lifetime(self, notification_id):
- """Yields as soon as the notification is shown, and
- finally returns as soon as the notification is hidden."""
-
- self.wait_until_not_hidden(notification_id)
- try:
- yield
- finally:
- self.wait_until_hidden(notification_id)
-
-
-class RequestPolicy(BaseLib):
- """With this class, RequestPolicy can be installed, enabled, disabled
- or removed.
- """
-
- def __init__(self, marionette_getter):
- BaseLib.__init__(self, marionette_getter)
-
- self.pref_welcome_win = "extensions.requestpolicy.welcomeWindowShown"
- self.addon_id = "rpcontinued at non-amo.requestpolicy.org"
- self.install_url = ("http://localhost/link.html?"
- ".dist/requestpolicy-unit-testing.xpi")
-
- self.addons = Addons(marionette_getter)
-
- self.logging_error_detect = LoggingErrorDetection(marionette_getter)
- self.console_error_detect = ConsoleErrorDetection(marionette_getter)
-
- @contextmanager
- def _ensure_no_errors(self):
- logging_errors_before = self.logging_error_detect.n_errors
- console_errors_before = self.console_error_detect.n_errors
- yield
- logging_error_count = (self.logging_error_detect.n_errors -
- logging_errors_before)
- console_error_count = (self.console_error_detect.n_errors -
- console_errors_before)
- console_error_messages = self.console_error_detect.messages
-
- if logging_error_count > 0 and console_error_count > 0:
- raise Exception("There have been {} Logging errors and "
- "{} Console errors! "
- "Console error messages were: {}"
- .format(logging_error_count, console_error_count,
- console_error_messages))
- elif logging_error_count > 0:
- raise Exception("There have been {} Logging "
- "errors!".format(logging_error_count))
- elif console_error_count > 0:
- raise Exception("There have been {} Console errors! "
- "Messages were: {}".format(console_error_count,
- console_error_messages))
-
- @contextmanager
- def install_in_two_steps(self):
- with self._ensure_no_errors():
- with self.addons.install_addon_in_two_steps(self.install_url):
- yield
-
- def install(self):
- with self._ensure_no_errors():
- self.addons.install_addon(self.install_url)
-
- def remove(self):
- with self._ensure_no_errors():
- self.addons.remove_addon_by_id(self.addon_id)
-
- def enable(self):
- with self._ensure_no_errors():
- self.addons.enable_addon_by_id(self.addon_id)
-
- def disable(self):
- with self._ensure_no_errors():
- self.addons.disable_addon_by_id(self.addon_id)
-
- def is_installed(self):
- return self.addons.is_addon_installed(self.addon_id)
-
- def is_enabled(self):
- return self.addons.is_addon_enabled(self.addon_id)
-
-
-class Addons(BaseLib):
- """With this class, an addon can be installed, enabled, disabled
- or removed. All actions required, such as opening `about:addons`,
- is done automatically.
- """
-
- def __init__(self, marionette_getter):
- BaseLib.__init__(self, marionette_getter)
-
- @contextmanager
- def using_addon_list(self):
- about_addons = AboutAddonsTab(lambda: self.marionette)
- about_addons.open_tab()
- about_addons.set_category_by_id("extension")
- try:
- yield about_addons
- finally:
- about_addons.close_tab()
-
- @contextmanager
- def install_addon_in_two_steps(self, install_url):
- # open a new tab where the install URL will be opened
- install_tab = Windows(lambda: self.marionette).current.tabbar.open_tab()
-
- with self.marionette.using_context("content"):
- # open the install URL
- self.marionette.navigate(install_url)
- # open the first link
- self.marionette.find_element("tag name", "a").click()
-
- with self.marionette.using_context("chrome"):
- notif = _InstallNotifications(self.marionette)
-
- with notif.wrap_lifetime("addon-install-blocked-notification"):
- # Allow the XPI to be downloaded. ("allow" button)
- (
- self.marionette
- .find_element("id", "addon-install-blocked-notification")
- .find_element("anon attribute", {"anonid": "button"})
- .click()
- )
-
- with notif.wrap_lifetime("addon-install-confirmation-notification"):
- # Confirm installation.
- (
- self.marionette
- .find_element("id", "addon-install-confirmation-accept")
- .click()
- )
-
- if install_tab.selected:
- # If the installation tab is still selected, the
- # "install complete" notification is shown.
- # If the selected tab has changed, there is no such
- # notification.
-
- with notif.wrap_lifetime("addon-install-complete-notification"):
- # Close the "install complete" notification.
- (
- self.marionette
- .find_element("id",
- "addon-install-complete-notification")
- .find_element("anon attribute",
- {"anonid": "closebutton"})
- .click()
- )
-
- try:
- yield
- finally:
- install_tab.close()
-
- def install_addon(self, install_url):
- with self.install_addon_in_two_steps(install_url):
- pass
-
- def remove_addon_by_id(self, addon_id):
- with self.using_addon_list() as about_addons:
- addon = about_addons.get_addon_by_id(addon_id)
- about_addons.remove_addon(addon)
-
- def enable_addon_by_id(self, addon_id):
- with self.using_addon_list() as about_addons:
- addon = about_addons.get_addon_by_id(addon_id)
- about_addons.enable_addon(addon)
-
- def disable_addon_by_id(self, addon_id):
- with self.using_addon_list() as about_addons:
- addon = about_addons.get_addon_by_id(addon_id)
- about_addons.disable_addon(addon)
-
- def is_addon_installed(self, addon_id):
- with self.using_addon_list() as about_addons:
- addon = about_addons.get_addon_by_id(addon_id)
- return addon != None
-
- def is_addon_enabled(self, addon_id):
- with self.using_addon_list() as about_addons:
- addon = about_addons.get_addon_by_id(addon_id)
- if addon == None:
- return False
- return addon.is_enabled()
-
-
-class AboutAddonsTab(BaseLib):
- """This class helps handling an `about:addons` tab.
- """
-
- def open_tab(self):
- self._tab = Windows(lambda: self.marionette).current.tabbar.open_tab()
- with self.marionette.using_context("content"):
- self.marionette.navigate("about:addons")
-
- def close_tab(self):
- with self.marionette.using_context("chrome"):
- if self._tab != None:
- self._tab.close()
- self._tab = None
-
- def set_category_by_id(self, category_id):
- with self.marionette.using_context("content"):
- (
- self.marionette
- .find_element("id", "category-" + category_id)
- .click()
- )
-
- def get_addon_by_id(self, addon_id):
- with self.marionette.using_context("content"):
- try:
- handle = (
- self.marionette
- .find_element("id", "list-view")
- .find_element("css selector",
- ".addon[value='{}']".format(addon_id))
- )
- return Addon(lambda: self.marionette, handle)
- except NoSuchElementException:
- return None
-
- def is_addon_installed(self, addon_id):
- # Switch categories to dispose of the undo link
- # which is displayed after clicking the "remove" button.
- self.set_category_by_id("theme")
- self.set_category_by_id("extension")
-
- return self.get_addon_by_id(addon_id) != None
-
- def enable_addon(self, addon):
- addon.click_enable()
- (
- Wait(self.marionette)
- .until(lambda m: addon.is_enabled(),
- message="The addon has been enabled.")
- )
-
- def disable_addon(self, addon):
- addon.click_disable()
- (
- Wait(self.marionette)
- .until(lambda m: not addon.is_enabled(),
- message="The addon has been disabled.")
- )
-
- def remove_addon(self, addon):
- if addon == None:
- # the addon does not exist
- return
- addon_id = addon.addon_id
- addon.click_remove()
- (
- Wait(self.marionette)
- .until(lambda m: not self.is_addon_installed(addon_id),
- message="The addon has been uninstalled.")
- )
-
-
-class Addon(BaseLib):
- def __init__(self, marionette_getter, addon_handle):
- BaseLib.__init__(self, marionette_getter)
- self._handle = addon_handle
-
- @property
- def addon_id(self):
- with self.marionette.using_context("content"):
- return self._handle.get_attribute("value")
-
- def is_enabled(self):
- with self.marionette.using_context("content"):
- return self._handle.get_attribute("active") == "true"
-
- def _click_on_button(self, button_name):
- with self.marionette.using_context("content"):
- (
- self._handle
- .find_element("anon attribute",
- {"anonid": button_name + "-btn"})
- .click()
- )
-
- def click_enable(self):
- if not self.is_enabled():
- self._click_on_button("enable")
-
- def click_disable(self):
- if self.is_enabled():
- self._click_on_button("disable")
-
- def click_remove(self):
- self._click_on_button("remove")
diff --git a/tests/marionette/tests/addon_install_and_upgrade/test_multiple_installations.py b/tests/marionette/tests/addon_install_and_upgrade/test_multiple_installations.py
index 9c29487..9699c0e 100644
--- a/tests/marionette/tests/addon_install_and_upgrade/test_multiple_installations.py
+++ b/tests/marionette/tests/addon_install_and_upgrade/test_multiple_installations.py
@@ -3,36 +3,54 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from rp_ui_harness import RequestPolicyTestCase
-from rp_puppeteer.ui.addons import RequestPolicy, Addons
+from rp_puppeteer.api.addon import Addon
+from marionette_driver.errors import NoSuchElementException
-OLD_VERSION__ADDON_ID = "requestpolicy at requestpolicy.com"
-AMO_VERSION__ADDON_ID = "rpcontinued at requestpolicy.org"
-
-def _install_url(filename):
- return "http://localhost/link.html?.dist/" + filename
-
-OLD_VERSION__INSTALL_URL = _install_url("requestpolicy-v1.0.beta9.3"
- "__preprocess.py.xpi")
-AMO_VERSION__INSTALL_URL = _install_url("requestpolicy-amo.xpi")
-
+# v1.0.beta9.3
+RP_BETA_9 = {"id": "requestpolicy at requestpolicy.com",
+ "xpi": "requestpolicy-v1.0.beta9.3__preprocess.py.xpi"}
+# AMO version
+RP_AMO = {"id": "rpcontinued at requestpolicy.org",
+ "xpi": "requestpolicy-amo.xpi"}
NOTICE_URL = "chrome://rpcontinued/content/multiple-installations.html"
class MultipleInstallationsTestCase(RequestPolicyTestCase):
+ OTHER_ADDON = None
+
def setUp(self):
- RequestPolicyTestCase.setUp(self)
- self.rp = RequestPolicy(lambda: self.marionette)
- self.addons = Addons(lambda: self.marionette)
+ super(MultipleInstallationsTestCase, self).setUp()
+
+ self.rp_addon.ignore_errors = True
+
+ assert self.OTHER_ADDON is not None
+ self.other_rp = Addon(lambda: self.marionette,
+ addon_id=self.OTHER_ADDON["id"],
+ install_url=("http://localhost/.dist/" +
+ self.OTHER_ADDON["xpi"]))
def tearDown(self):
- self._close_notice_tabs()
- # Restart the browser. (It's a method of FirefoxTestCase.)
- # It's necessary to restart because multiple installed versions
- # might have broken RequestPolicy's functionality.
- self.restart()
- RequestPolicyTestCase.tearDown(self)
+ try:
+ self._close_notice_tabs()
+
+ self.other_rp.uninstall()
+ self.rp_addon.install()
+
+ self.rp_addon.ignore_errors = False
+
+ # Restart the browser. (It's a method of FirefoxTestCase.)
+ # It's necessary to restart because multiple installed versions
+ # might have broken RequestPolicy's functionality.
+ self.restart()
+ finally:
+ # It's highly probable that errors occur. However, the tests
+ # in this file don't intend to avoid these errors.
+ self.logging_error_detect.reset()
+ self.console_error_detect.reset()
+
+ super(MultipleInstallationsTestCase, self).tearDown()
def _get_notice_tabs(self):
tabs = self.browser.tabbar.tabs
@@ -65,10 +83,11 @@ class MultipleInstallationsTestCase(RequestPolicyTestCase):
tab.select()
with self.marionette.using_context("content"):
- # check if the word "Notice" is on the page
- notice = self.marionette.find_element(
- "xpath",
- "//*[contains(text(),'Notice')]")
+ try:
+ self.marionette.find_element("xpath",
+ "//*[contains(text(),'Notice')]")
+ except NoSuchElementException:
+ self.fail("The Notice Tab should contain the word 'Notice'.")
def _close_notice_tabs(self):
tabs = self._get_notice_tabs()
@@ -76,90 +95,105 @@ class MultipleInstallationsTestCase(RequestPolicyTestCase):
tab.close()
-class OldVersionTestCase(MultipleInstallationsTestCase):
- INSTALL_URL = OLD_VERSION__INSTALL_URL
- ADDON_ID = OLD_VERSION__ADDON_ID
- def tearDown(self):
- self.addons.remove_addon_by_id(self.ADDON_ID)
- MultipleInstallationsTestCase.tearDown(self)
+class CommonTests:
+ """Common tests for all so-called "other" versions.
+ Idea from
+ https://stackoverflow.com/questions/1323455/python-unit-test-with-base-and-sub-class/25695512#25695512
+ """
-class TestOldVersionActive_ThenInstallCurrentVersion(OldVersionTestCase):
- def setUp(self):
- OldVersionTestCase.setUp(self)
- self.rp.remove()
- self.addons.install_addon(self.INSTALL_URL)
+ class OtherVersionActive_ThenInstallCurrentVersion(MultipleInstallationsTestCase):
+ def setUp(self):
+ MultipleInstallationsTestCase.setUp(self)
+ self.rp_addon.uninstall()
+ self.other_rp.install()
- def test_notice_is_shown(self):
- with self.rp.install_in_two_steps():
+ def test_notice_is_shown(self):
+ self.rp_addon.install()
self._assert_notice_tab()
-class TestOldVersionActive_ThenEnableCurrentVersion(OldVersionTestCase):
- def setUp(self):
- OldVersionTestCase.setUp(self)
- self.rp.disable()
- self.addons.install_addon(self.INSTALL_URL)
+ class OtherVersionActive_ThenEnableCurrentVersion(MultipleInstallationsTestCase):
+ def setUp(self):
+ MultipleInstallationsTestCase.setUp(self)
+ self.rp_addon.disable()
+ self.other_rp.install()
- def test_notice_is_shown(self):
- self.rp.enable()
- self._assert_notice_tab()
+ def test_notice_is_shown(self):
+ self.rp_addon.enable()
+ self._assert_notice_tab()
-class TestOldVersionNotActive_ThenInstall(OldVersionTestCase):
- def test_notice_is_shown(self):
- with self.addons.install_addon_in_two_steps(self.INSTALL_URL):
+ class OtherVersionNotActive_ThenInstall(MultipleInstallationsTestCase):
+ def test_notice_is_shown(self):
+ self.other_rp.install()
self._assert_notice_tab()
-class TestOldVersionNotActive_ThenEnable(OldVersionTestCase):
- def setUp(self):
- OldVersionTestCase.setUp(self)
- # After this preparation, both the current and the old version
- # will be installed, but the old version will be disabled.
- self.rp.disable()
- self.addons.install_addon(self.INSTALL_URL)
- self.addons.disable_addon_by_id(self.ADDON_ID)
- self.rp.enable()
- self.assertIsNone(self._notice_tab,
- msg=("No 'notice' tab has been opened during "
- "preparation"))
-
- def test_notice_is_shown(self):
- self.addons.enable_addon_by_id(self.ADDON_ID)
- self._assert_notice_tab()
-
-class TestOldAndCurrentVersionActiveAfterRestart(OldVersionTestCase):
- def setUp(self):
- OldVersionTestCase.setUp(self)
- self.addons.install_addon(self.INSTALL_URL)
- self._close_notice_tabs()
+ class OtherVersionNotActive_ThenEnable(MultipleInstallationsTestCase):
+ def setUp(self):
+ MultipleInstallationsTestCase.setUp(self)
+ # After this preparation, both the current and the old version
+ # will be installed, but the old version will be disabled.
+ self.rp_addon.disable()
+ self.other_rp.install()
+ self.other_rp.disable()
+ self.rp_addon.enable()
+ self.assertIsNone(self._notice_tab,
+ msg=("No 'notice' tab has been opened during "
+ "preparation"))
+
+ def test_notice_is_shown(self):
+ self.other_rp.enable()
+ self._assert_notice_tab()
+
+ class OtherAndCurrentVersionActiveAfterRestart(MultipleInstallationsTestCase):
+ def setUp(self):
+ MultipleInstallationsTestCase.setUp(self)
+ self.other_rp.install()
+ self._close_notice_tabs()
- def test_notice_is_shown(self):
- self.restart()
- # Don't require the tab to be selected. It somehow doesn't get
- # selected in the unit test, but it works when done manually.
- self._assert_notice_tab(selected_required=False)
+ def test_notice_is_shown(self):
+ self.restart()
+ # Don't require the tab to be selected. It somehow doesn't get
+ # selected in the unit test, but it works when done manually.
+ self._assert_notice_tab(selected_required=False)
class TestAMOVersionActive_ThenInstallCurrentVersion(\
- TestOldVersionActive_ThenInstallCurrentVersion):
- INSTALL_URL = AMO_VERSION__INSTALL_URL
- ADDON_ID = AMO_VERSION__ADDON_ID
+ CommonTests.OtherVersionActive_ThenInstallCurrentVersion):
+ OTHER_ADDON = RP_AMO
class TestAMOVersionActive_ThenEnableCurrentVersion(\
- TestOldVersionActive_ThenEnableCurrentVersion):
- INSTALL_URL = AMO_VERSION__INSTALL_URL
- ADDON_ID = AMO_VERSION__ADDON_ID
+ CommonTests.OtherVersionActive_ThenEnableCurrentVersion):
+ OTHER_ADDON = RP_AMO
class TestAMOVersionNotActive_ThenInstall(\
- TestOldVersionNotActive_ThenInstall):
- INSTALL_URL = AMO_VERSION__INSTALL_URL
- ADDON_ID = AMO_VERSION__ADDON_ID
+ CommonTests.OtherVersionNotActive_ThenInstall):
+ OTHER_ADDON = RP_AMO
class TestAMOVersionNotActive_ThenEnable(\
- TestOldVersionNotActive_ThenEnable):
- INSTALL_URL = AMO_VERSION__INSTALL_URL
- ADDON_ID = AMO_VERSION__ADDON_ID
+ CommonTests.OtherVersionNotActive_ThenEnable):
+ OTHER_ADDON = RP_AMO
class TestAMOAndNonAMOVersionActiveAfterRestart(\
- TestOldAndCurrentVersionActiveAfterRestart):
- INSTALL_URL = AMO_VERSION__INSTALL_URL
- ADDON_ID = AMO_VERSION__ADDON_ID
+ CommonTests.OtherAndCurrentVersionActiveAfterRestart):
+ OTHER_ADDON = RP_AMO
+
+
+class TestOldVersionActive_ThenInstallCurrentVersion(\
+ CommonTests.OtherVersionActive_ThenInstallCurrentVersion):
+ OTHER_ADDON = RP_BETA_9
+
+class TestOldVersionActive_ThenEnableCurrentVersion(\
+ CommonTests.OtherVersionActive_ThenEnableCurrentVersion):
+ OTHER_ADDON = RP_BETA_9
+
+class TestOldVersionNotActive_ThenInstall(\
+ CommonTests.OtherVersionNotActive_ThenInstall):
+ OTHER_ADDON = RP_BETA_9
+
+class TestOldVersionNotActive_ThenEnable(\
+ CommonTests.OtherVersionNotActive_ThenEnable):
+ OTHER_ADDON = RP_BETA_9
+
+class TestOldAndCurrentVersionActiveAfterRestart(\
+ CommonTests.OtherAndCurrentVersionActiveAfterRestart):
+ OTHER_ADDON = RP_BETA_9
diff --git a/tests/marionette/tests/addon_install_and_upgrade/test_restartlessness.py b/tests/marionette/tests/addon_install_and_upgrade/test_restartlessness.py
index c60be8e..e878f2f 100644
--- a/tests/marionette/tests/addon_install_and_upgrade/test_restartlessness.py
+++ b/tests/marionette/tests/addon_install_and_upgrade/test_restartlessness.py
@@ -3,38 +3,54 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from rp_ui_harness import RequestPolicyTestCase
-from rp_puppeteer.ui.addons import RequestPolicy
+from marionette.marionette_test import SkipTest
+import time
PREF_WELCOME_WIN_SHOWN = "extensions.requestpolicy.welcomeWindowShown"
-class TestRequestPolicyRestartlessness(RequestPolicyTestCase):
- """These tests ensure that RequestPolicy can be uninstalled/installed and
- disabled/enabled restartless.
- """
+class CommonTests:
+ class TestRequestPolicyRestartlessness(RequestPolicyTestCase):
+ """These tests ensure that RequestPolicy can be uninstalled/installed and
+ disabled/enabled restartless.
+ """
+
+ def test_disable_enable(self):
+ self.assertTrue(self.rp_addon.is_active, msg="The addon is enabled.")
+ self.rp_addon.disable()
+ self.assertFalse(self.rp_addon.is_active,
+ msg="The addon has been disabled.")
+ self.rp_addon.enable()
+ self.assertTrue(self.rp_addon.is_active,
+ msg="The addon has been re-enabled.")
+
+ def test_uninstall_install(self):
+ # remove:
+ self.assertTrue(self.rp_addon.is_installed,
+ msg="The addon is installed.")
+ self.rp_addon.uninstall()
+ self.assertFalse(self.rp_addon.is_installed,
+ msg="The addon has been removed.")
+
+ # re-install:
+ self.prefs.set_pref(PREF_WELCOME_WIN_SHOWN, True)
+ self.rp_addon.install()
+ self.assertTrue(self.rp_addon.is_installed,
+ msg="The addon has been re-installed.")
+
+
+class TestNormal(CommonTests.TestRequestPolicyRestartlessness):
+ def setUp(self):
+ super(TestNormal, self).setUp()
+ # Wait some time in order to ensure the browser is in idle.
+ time.sleep(0.2)
+
+class TestAfterNavigate(CommonTests.TestRequestPolicyRestartlessness):
def setUp(self):
- RequestPolicyTestCase.setUp(self)
- self.rp = RequestPolicy(lambda: self.marionette)
-
- def test_disable_enable(self):
- self.assertTrue(self.rp.is_enabled(), msg="The addon is enabled.")
- self.rp.disable()
- self.assertFalse(self.rp.is_enabled(),
- msg="The addon has been disabled.")
- self.rp.enable()
- self.assertTrue(self.rp.is_enabled(),
- msg="The addon has been re-enabled.")
-
- def test_uninstall_install(self):
- # remove:
- self.assertTrue(self.rp.is_installed(), msg="The addon is installed.")
- self.rp.remove()
- self.assertFalse(self.rp.is_installed(),
- msg="The addon has been removed.")
-
- # re-install:
- self.prefs.set_pref(PREF_WELCOME_WIN_SHOWN, True)
- self.rp.install()
- self.assertTrue(self.rp.is_installed(),
- msg="The addon has been re-installed.")
+ super(TestAfterNavigate, self).setUp()
+
+ raise SkipTest("Skipping due to issue #728.")
+
+ with self.marionette.using_context("content"):
+ self.marionette.navigate("http://localhost/")
diff --git a/tests/marionette/tests/test_setup_page.py b/tests/marionette/tests/test_setup_page.py
index b7480fd..a5711ec 100644
--- a/tests/marionette/tests/test_setup_page.py
+++ b/tests/marionette/tests/test_setup_page.py
@@ -4,7 +4,7 @@
from rp_ui_harness import RequestPolicyTestCase
from marionette_driver.wait import Wait
-from rp_puppeteer.ui.addons import RequestPolicy
+import time
PREF_WELCOME_WIN_SHOWN = "extensions.requestpolicy.welcomeWindowShown"
@@ -23,18 +23,22 @@ class TestSetupPageShowingUp(RequestPolicyTestCase):
def test_on_install(self):
- rp = RequestPolicy(lambda: self.marionette)
- rp.remove()
+ # FIXME: Issue #728; [Restartlessness] RP should not cause
+ # JavaScript errors on shutdown while requests are being called.
+ time.sleep(0.2)
+
+ self.rp_addon.uninstall()
self.prefs.set_pref(PREF_WELCOME_WIN_SHOWN, False)
- with rp.install_in_two_steps():
- setup_tab = Wait(self.marionette).until(
- lambda m: self._get_setup_tab(),
- message="RequestPolicy has opened its Setup page.")
- self.assertTrue(self.prefs.get_pref(PREF_WELCOME_WIN_SHOWN),
- msg=("The 'welcome window shown' pref has "
- "been set to `true`."))
- self.assertTrue(setup_tab.selected,
- msg="The setup tab is selected.")
- setup_tab.close()
+ self.rp_addon.install()
+
+ setup_tab = Wait(self.marionette).until(
+ lambda m: self._get_setup_tab(),
+ message="RequestPolicy has opened its Setup page.")
+ self.assertTrue(self.prefs.get_pref(PREF_WELCOME_WIN_SHOWN),
+ msg=("The 'welcome window shown' pref has "
+ "been set to `true`."))
+ self.assertTrue(setup_tab.selected,
+ msg="The setup tab is selected.")
+ setup_tab.close()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/requestpolicy.git
More information about the Pkg-mozext-commits
mailing list