Bug 1316851 - Testcases should directly inherit from MarionetteTestCase and PuppeteerMixin. draft
authorHenrik Skupin <mail@hskupin.info>
Fri, 11 Nov 2016 14:37:01 +0100
changeset 437719 bc1313a366f2bdd9b6d488756914aabe155a1f0b
parent 437704 721cc1b4ff1c9d40c4e222f5d47190a6a9726312
child 536715 5642f56d2b51e41efb2ea067d3562c13799dc75a
push id35499
push userbmo:hskupin@gmail.com
push dateFri, 11 Nov 2016 14:25:53 +0000
bugs1316851
milestone52.0a1
Bug 1316851 - Testcases should directly inherit from MarionetteTestCase and PuppeteerMixin. MozReview-Commit-ID: 2wu70A51NQw
testing/firefox-ui/harness/firefox_ui_harness/runners/base.py
testing/firefox-ui/harness/firefox_ui_harness/testcases.py
testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py
testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py
testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py
testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py
testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py
testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py
testing/firefox-ui/tests/functional/security/test_dv_certificate.py
testing/firefox-ui/tests/functional/security/test_enable_privilege.py
testing/firefox-ui/tests/functional/security/test_ev_certificate.py
testing/firefox-ui/tests/functional/security/test_mixed_content_page.py
testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py
testing/firefox-ui/tests/functional/security/test_no_certificate.py
testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py
testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py
testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py
testing/firefox-ui/tests/functional/security/test_security_notification.py
testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py
testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py
testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py
testing/firefox-ui/tests/functional/security/test_unknown_issuer.py
testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py
testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py
testing/firefox-ui/tests/puppeteer/test_about_window.py
testing/firefox-ui/tests/puppeteer/test_appinfo.py
testing/firefox-ui/tests/puppeteer/test_l10n.py
testing/firefox-ui/tests/puppeteer/test_menubar.py
testing/firefox-ui/tests/puppeteer/test_notifications.py
testing/firefox-ui/tests/puppeteer/test_page_info_window.py
testing/firefox-ui/tests/puppeteer/test_places.py
testing/firefox-ui/tests/puppeteer/test_prefs.py
testing/firefox-ui/tests/puppeteer/test_security.py
testing/firefox-ui/tests/puppeteer/test_software_update.py
testing/firefox-ui/tests/puppeteer/test_tabbar.py
testing/firefox-ui/tests/puppeteer/test_toolbars.py
testing/firefox-ui/tests/puppeteer/test_update_wizard.py
testing/firefox-ui/tests/puppeteer/test_utils.py
testing/firefox-ui/tests/puppeteer/test_windows.py
--- a/testing/firefox-ui/harness/firefox_ui_harness/runners/base.py
+++ b/testing/firefox-ui/harness/firefox_ui_harness/runners/base.py
@@ -3,30 +3,29 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 import shutil
 import tempfile
 
 import mozfile
 import mozinfo
-from marionette import BaseMarionetteTestRunner
 
-from firefox_ui_harness.testcases import FirefoxTestCase
+from marionette import BaseMarionetteTestRunner, MarionetteTestCase
 
 
 class FirefoxUITestRunner(BaseMarionetteTestRunner):
 
     def __init__(self, **kwargs):
         super(FirefoxUITestRunner, self).__init__(**kwargs)
 
         # select the appropriate GeckoInstance
         self.app = 'fxdesktop'
 
-        self.test_handlers = [FirefoxTestCase]
+        self.test_handlers = [MarionetteTestCase]
 
     def duplicate_application(self, application_folder):
         """Creates a copy of the specified binary."""
 
         if self.workspace:
             target_folder = os.path.join(self.workspace_path, 'application.copy')
         else:
             target_folder = tempfile.mkdtemp('.application.copy')
--- a/testing/firefox-ui/harness/firefox_ui_harness/testcases.py
+++ b/testing/firefox-ui/harness/firefox_ui_harness/testcases.py
@@ -3,41 +3,27 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 import pprint
 from datetime import datetime
 
 import mozfile
 
-from marionette import MarionetteTestCase
-from marionette_driver import Wait
-from marionette_driver.errors import NoSuchWindowException
-
 from firefox_puppeteer import PuppeteerMixin
 from firefox_puppeteer.api.prefs import Preferences
 from firefox_puppeteer.api.software_update import SoftwareUpdate
 from firefox_puppeteer.ui.update_wizard import UpdateWizardDialog
 
-
-class FirefoxTestCase(PuppeteerMixin, MarionetteTestCase):
-    """Base TestCase class for Firefox Desktop tests.
-
-    This class enhances the MarionetteTestCase class with PuppeteerMixin on top
-    of MarionetteTestCase by reordering the MRO.
-
-    If you're extending the inheritance tree further to make specialized
-    TestCases, favour the use of super() as opposed to explicit calls to a
-    parent class.
-
-    """
-    pass
+from marionette import MarionetteTestCase
+from marionette_driver import Wait
+from marionette_driver.errors import NoSuchWindowException
 
 
-class UpdateTestCase(FirefoxTestCase):
+class UpdateTestCase(PuppeteerMixin, MarionetteTestCase):
 
     TIMEOUT_UPDATE_APPLY = 300
     TIMEOUT_UPDATE_CHECK = 30
     TIMEOUT_UPDATE_DOWNLOAD = 360
 
     # For the old update wizard, the errors are displayed inside the dialog. For the
     # handling of updates in the about window the errors are displayed in new dialogs.
     # When the old wizard is open we have to set the preference, so the errors will be
--- a/testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py
+++ b/testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestBrowserWindowShortcuts(FirefoxTestCase):
+class TestBrowserWindowShortcuts(PuppeteerMixin, MarionetteTestCase):
 
     def test_addons_manager(self):
         # If an about:xyz page is visible, no new tab will be opened
         with self.marionette.using_context('content'):
             self.marionette.navigate('about:')
 
         # TODO: To be moved to the upcoming add-ons library
         def opener(tab):
--- a/testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py
+++ b/testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestAccessLocationBar(FirefoxTestCase):
+class TestAccessLocationBar(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestAccessLocationBar, self).setUp()
 
         # Clear complete history so there's no interference from previous entries.
         self.puppeteer.places.remove_all_history()
 
         self.test_urls = [
--- a/testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py
+++ b/testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestEscapeAutocomplete(FirefoxTestCase):
+class TestEscapeAutocomplete(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestEscapeAutocomplete, self).setUp()
 
         # Clear complete history so there's no interference from previous entries.
         self.puppeteer.places.remove_all_history()
 
         self.test_urls = [
--- a/testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py
+++ b/testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestFaviconInAutocomplete(FirefoxTestCase):
+class TestFaviconInAutocomplete(PuppeteerMixin, MarionetteTestCase):
 
     PREF_SUGGEST_SEARCHES = 'browser.urlbar.suggest.searches'
     PREF_SUGGEST_BOOKMARK = 'browser.urlbar.suggest.bookmark'
 
     def setUp(self):
         super(TestFaviconInAutocomplete, self).setUp()
 
         # Disable suggestions for searches and bookmarks to get results only for history
--- a/testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py
+++ b/testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestStarInAutocomplete(FirefoxTestCase):
+class TestStarInAutocomplete(PuppeteerMixin, MarionetteTestCase):
     """ This replaces
     http://hg.mozilla.org/qa/mozmill-tests/file/default/firefox/tests/functional/testAwesomeBar/testSuggestBookmarks.js
     Check a star appears in autocomplete list for a bookmarked page.
     """
 
     PREF_SUGGEST_SEARCHES = 'browser.urlbar.suggest.searches'
 
     def setUp(self):
--- a/testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py
+++ b/testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py
@@ -1,20 +1,19 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from firefox_puppeteer.ui.browser.window import BrowserWindow
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-from firefox_puppeteer.ui.browser.window import BrowserWindow
-
-
-class TestAboutPrivateBrowsing(FirefoxTestCase):
+class TestAboutPrivateBrowsing(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestAboutPrivateBrowsing, self).setUp()
 
         # Use a fake local support URL
         support_url = 'about:blank?'
         self.puppeteer.prefs.set_pref('app.support.baseURL', support_url)
 
--- a/testing/firefox-ui/tests/functional/security/test_dv_certificate.py
+++ b/testing/firefox-ui/tests/functional/security/test_dv_certificate.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestDVCertificate(FirefoxTestCase):
+class TestDVCertificate(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestDVCertificate, self).setUp()
 
         self.locationbar = self.browser.navbar.locationbar
         self.identity_popup = self.browser.navbar.locationbar.identity_popup
 
         self.url = 'https://ssl-dv.mozqa.com'
--- a/testing/firefox-ui/tests/functional/security/test_enable_privilege.py
+++ b/testing/firefox-ui/tests/functional/security/test_enable_privilege.py
@@ -1,18 +1,17 @@
 # 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 import MarionetteTestCase
 from marionette_driver import By
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestEnablePrivilege(FirefoxTestCase):
+class TestEnablePrivilege(MarionetteTestCase):
 
     def test_enable_privilege(self):
         with self.marionette.using_context('content'):
             url = self.marionette.absolute_url('security/enable_privilege.html')
             self.marionette.navigate(url)
 
             result = self.marionette.find_element(By.ID, 'result')
             self.assertEqual(result.get_property('textContent'), 'PASS')
--- a/testing/firefox-ui/tests/functional/security/test_ev_certificate.py
+++ b/testing/firefox-ui/tests/functional/security/test_ev_certificate.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestEVCertificate(FirefoxTestCase):
+class TestEVCertificate(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestEVCertificate, self).setUp()
 
         self.locationbar = self.browser.navbar.locationbar
         self.identity_popup = self.locationbar.identity_popup
 
         self.url = 'https://ssl-ev.mozqa.com/'
--- a/testing/firefox-ui/tests/functional/security/test_mixed_content_page.py
+++ b/testing/firefox-ui/tests/functional/security/test_mixed_content_page.py
@@ -1,16 +1,17 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class TestMixedContentPage(FirefoxTestCase):
+class TestMixedContentPage(PuppeteerMixin, MarionetteTestCase):
     def setUp(self):
         super(TestMixedContentPage, self).setUp()
 
         self.locationbar = self.browser.navbar.locationbar
         self.identity_popup = self.locationbar.identity_popup
 
         self.url = 'https://mozqa.com/data/firefox/security/mixedcontent.html'
 
--- a/testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py
+++ b/testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestMixedScriptContentBlocking(FirefoxTestCase):
+class TestMixedScriptContentBlocking(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestMixedScriptContentBlocking, self).setUp()
 
         self.url = 'https://mozqa.com/data/firefox/security/mixed_content_blocked/index.html'
 
         self.test_elements = [
             ('result1', 'Insecure script one'),
--- a/testing/firefox-ui/tests/functional/security/test_no_certificate.py
+++ b/testing/firefox-ui/tests/functional/security/test_no_certificate.py
@@ -1,20 +1,20 @@
 # 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 urlparse import urlparse
 
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import expected, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestNoCertificate(FirefoxTestCase):
+class TestNoCertificate(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestNoCertificate, self).setUp()
 
         self.locationbar = self.browser.navbar.locationbar
         self.identity_popup = self.locationbar.identity_popup
 
         self.url = self.marionette.absolute_url('layout/mozilla.html')
--- a/testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py
+++ b/testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py
@@ -1,19 +1,20 @@
 # 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
 
-from firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import Wait
 
 
-class TestSafeBrowsingInitialDownload(FirefoxTestCase):
+class TestSafeBrowsingInitialDownload(PuppeteerMixin, MarionetteTestCase):
 
     file_extensions = [
         'pset',
         'sbstore',
     ]
 
     prefs_download_lists = [
         'urlclassifier.blockedTable',
--- a/testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py
+++ b/testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py
@@ -1,20 +1,20 @@
 # 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 time
 
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, expected, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestSafeBrowsingNotificationBar(FirefoxTestCase):
+class TestSafeBrowsingNotificationBar(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSafeBrowsingNotificationBar, self).setUp()
 
         self.test_data = [
             # Unwanted software URL
             {
                 # First two properties are not needed,
--- a/testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py
+++ b/testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py
@@ -1,20 +1,20 @@
 # 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 time
 
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, expected, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestSafeBrowsingWarningPages(FirefoxTestCase):
+class TestSafeBrowsingWarningPages(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSafeBrowsingWarningPages, self).setUp()
 
         self.urls = [
             # Unwanted software URL
             'https://www.itisatrap.org/firefox/unwanted.html',
             # Phishing URL
--- a/testing/firefox-ui/tests/functional/security/test_security_notification.py
+++ b/testing/firefox-ui/tests/functional/security/test_security_notification.py
@@ -1,21 +1,21 @@
 # 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 time
 
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 from marionette_driver.errors import MarionetteException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestSecurityNotification(FirefoxTestCase):
+class TestSecurityNotification(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSecurityNotification, self).setUp()
 
         self.urls = [
             # Invalid cert page
             'https://ssl-expired.mozqa.com',
             # Secure page
--- a/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py
+++ b/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py
@@ -1,21 +1,21 @@
 # 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 time
 
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, expected, Wait
 from marionette_driver.errors import MarionetteException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestSSLDisabledErrorPage(FirefoxTestCase):
+class TestSSLDisabledErrorPage(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSSLDisabledErrorPage, self).setUp()
 
         self.url = 'https://tlsv1-0.mozqa.com'
 
         self.puppeteer.utils.sanitize({"sessions": True})
 
--- a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py
+++ b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py
@@ -1,19 +1,19 @@
 # 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 import Wait
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette.marionette_test import skip_if_e10s
-
-from firefox_ui_harness.testcases import FirefoxTestCase
+from marionette_driver import Wait
 
 
-class TestSSLStatusAfterRestart(FirefoxTestCase):
+class TestSSLStatusAfterRestart(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSSLStatusAfterRestart, self).setUp()
 
         self.test_data = (
             {
                 'url': 'https://ssl-dv.mozqa.com',
                 'identity': '',
--- a/testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py
+++ b/testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py
@@ -1,21 +1,20 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, expected, Wait
-
 from marionette_driver.errors import NoAlertPresentException
 from marionette_driver.marionette import Alert
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestSubmitUnencryptedInfoWarning(FirefoxTestCase):
+class TestSubmitUnencryptedInfoWarning(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSubmitUnencryptedInfoWarning, self).setUp()
 
         self.url = 'https://ssl-dv.mozqa.com/data/firefox/security/unencryptedsearch.html'
         self.test_string = 'mozilla'
 
         self.puppeteer.prefs.set_pref('security.warn_submit_insecure', True)
--- a/testing/firefox-ui/tests/functional/security/test_unknown_issuer.py
+++ b/testing/firefox-ui/tests/functional/security/test_unknown_issuer.py
@@ -1,21 +1,20 @@
 # 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 time
 
+from marionette import MarionetteTestCase
 from marionette_driver import By
 from marionette_driver.errors import MarionetteException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestUnknownIssuer(FirefoxTestCase):
+class TestUnknownIssuer(MarionetteTestCase):
 
     def setUp(self):
         super(TestUnknownIssuer, self).setUp()
 
         self.url = 'https://ssl-unknownissuer.mozqa.com'
 
     def test_unknown_issuer(self):
         with self.marionette.using_context('content'):
--- a/testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py
+++ b/testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py
@@ -1,21 +1,21 @@
 # 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 time
 
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 from marionette_driver.errors import MarionetteException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestUntrustedConnectionErrorPage(FirefoxTestCase):
+class TestUntrustedConnectionErrorPage(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestUntrustedConnectionErrorPage, self).setUp()
 
         self.url = 'https://ssl-selfsigned.mozqa.com'
 
     def test_untrusted_connection_error_page(self):
         self.marionette.set_context('content')
--- a/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py
+++ b/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py
@@ -1,16 +1,17 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class TestRestoreWindowsAfterRestart(FirefoxTestCase):
+class TestRestoreWindowsAfterRestart(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestRestoreWindowsAfterRestart, self).setUp()
 
         # Each list element represents a window of tabs loaded at
         # some testing URL
         self.test_windows = set([
             # Window 1. Note the comma after the absolute_url call -
--- a/testing/firefox-ui/tests/puppeteer/test_about_window.py
+++ b/testing/firefox-ui/tests/puppeteer/test_about_window.py
@@ -1,16 +1,17 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class TestAboutWindow(FirefoxTestCase):
+class TestAboutWindow(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestAboutWindow, self).setUp()
 
         self.about_window = self.browser.open_about_window()
         self.deck = self.about_window.deck
 
     def tearDown(self):
--- a/testing/firefox-ui/tests/puppeteer/test_appinfo.py
+++ b/testing/firefox-ui/tests/puppeteer/test_appinfo.py
@@ -1,17 +1,19 @@
 # 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 mozversion
-from firefox_ui_harness.testcases import FirefoxTestCase
+
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class TestAppInfo(FirefoxTestCase):
+class TestAppInfo(PuppeteerMixin, MarionetteTestCase):
 
     def test_valid_properties(self):
         binary = self.marionette.bin
         version_info = mozversion.get_version(binary=binary)
 
         self.assertEqual(self.puppeteer.appinfo.ID, version_info['application_id'])
         self.assertEqual(self.puppeteer.appinfo.name, version_info['application_name'])
         self.assertEqual(self.puppeteer.appinfo.vendor, version_info['application_vendor'])
--- a/testing/firefox-ui/tests/puppeteer/test_l10n.py
+++ b/testing/firefox-ui/tests/puppeteer/test_l10n.py
@@ -1,20 +1,20 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from firefox_puppeteer.api.l10n import L10n
+from marionette import MarionetteTestCase
 from marionette_driver import By
 from marionette_driver.errors import MarionetteException
 
-from firefox_puppeteer.api.l10n import L10n
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestL10n(FirefoxTestCase):
+class TestL10n(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestL10n, self).setUp()
 
         self.l10n = L10n(self.marionette)
 
     def test_dtd_entity_chrome(self):
         dtds = ['chrome://global/locale/about.dtd',
--- a/testing/firefox-ui/tests/puppeteer/test_menubar.py
+++ b/testing/firefox-ui/tests/puppeteer/test_menubar.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver.errors import NoSuchElementException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestMenuBar(FirefoxTestCase):
+class TestMenuBar(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestMenuBar, self).setUp()
 
     def test_click_item_in_menubar(self):
         def opener(_):
             self.browser.menubar.select_by_id('file-menu',
                                               'menu_newNavigatorTab')
--- a/testing/firefox-ui/tests/puppeteer/test_notifications.py
+++ b/testing/firefox-ui/tests/puppeteer/test_notifications.py
@@ -1,23 +1,23 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from firefox_puppeteer.ui.browser.notifications import (
+    AddOnInstallFailedNotification,
+    AddOnInstallConfirmationNotification,
+)
+from marionette import MarionetteTestCase
 from marionette_driver import By
 from marionette_driver.errors import TimeoutException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
-from firefox_puppeteer.ui.browser.notifications import (
-    AddOnInstallFailedNotification,
-    AddOnInstallConfirmationNotification
-)
 
-
-class TestNotifications(FirefoxTestCase):
+class TestNotifications(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestNotifications, self).setUp()
 
         self.puppeteer.prefs.set_pref('extensions.install.requireSecureOrigin', False)
 
         self.addons_url = self.marionette.absolute_url('addons/extensions/')
         self.puppeteer.utils.permissions.add(self.marionette.baseurl, 'install')
--- a/testing/firefox-ui/tests/puppeteer/test_page_info_window.py
+++ b/testing/firefox-ui/tests/puppeteer/test_page_info_window.py
@@ -1,16 +1,17 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class TestPageInfoWindow(FirefoxTestCase):
+class TestPageInfoWindow(PuppeteerMixin, MarionetteTestCase):
 
     def tearDown(self):
         try:
             self.puppeteer.windows.close_all([self.browser])
         finally:
             super(TestPageInfoWindow, self).tearDown()
 
     def test_elements(self):
--- a/testing/firefox-ui/tests/puppeteer/test_places.py
+++ b/testing/firefox-ui/tests/puppeteer/test_places.py
@@ -1,18 +1,18 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestPlaces(FirefoxTestCase):
+class TestPlaces(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestPlaces, self).setUp()
 
         self.urls = [self.marionette.absolute_url('layout/mozilla_governance.html'),
                      self.marionette.absolute_url('layout/mozilla_grants.html'),
                      ]
 
--- a/testing/firefox-ui/tests/puppeteer/test_prefs.py
+++ b/testing/firefox-ui/tests/puppeteer/test_prefs.py
@@ -1,16 +1,17 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class testPreferences(FirefoxTestCase):
+class testPreferences(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(testPreferences, self).setUp()
 
         self.new_pref = 'marionette.unittest.set_pref'
         self.unknown_pref = 'marionette.unittest.unknown'
 
         self.bool_pref = 'browser.tabs.loadBookmarksInBackground'
--- a/testing/firefox-ui/tests/puppeteer/test_security.py
+++ b/testing/firefox-ui/tests/puppeteer/test_security.py
@@ -1,18 +1,18 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
-
+from firefox_puppeteer import PuppeteerMixin
 from firefox_puppeteer.errors import NoCertificateError
+from marionette import MarionetteTestCase
 
 
-class TestSecurity(FirefoxTestCase):
+class TestSecurity(PuppeteerMixin, MarionetteTestCase):
 
     def test_get_address_from_certificate(self):
         url = 'https://ssl-ev.mozqa.com'
 
         with self.marionette.using_context(self.marionette.CONTEXT_CONTENT):
             self.marionette.navigate(url)
 
         cert = self.browser.tabbar.tabs[0].certificate
--- a/testing/firefox-ui/tests/puppeteer/test_software_update.py
+++ b/testing/firefox-ui/tests/puppeteer/test_software_update.py
@@ -1,20 +1,20 @@
 # 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
 
-from firefox_ui_harness.testcases import FirefoxTestCase
-
+from firefox_puppeteer import PuppeteerMixin
 from firefox_puppeteer.api.software_update import SoftwareUpdate
+from marionette import MarionetteTestCase
 
 
-class TestSoftwareUpdate(FirefoxTestCase):
+class TestSoftwareUpdate(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSoftwareUpdate, self).setUp()
 
         self.software_update = SoftwareUpdate(self.marionette)
 
         self.saved_mar_channels = self.software_update.mar_channels.channels
         self.software_update.mar_channels.channels = set(['expected', 'channels'])
@@ -64,17 +64,17 @@ class TestSoftwareUpdate(FirefoxTestCase
 
     def test_os_version(self):
         self.assertTrue(self.software_update.os_version)
 
     def test_staging_directory(self):
         self.assertTrue(self.software_update.staging_directory)
 
 
-class TestUpdateChannel(FirefoxTestCase):
+class TestUpdateChannel(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestUpdateChannel, self).setUp()
 
         self.software_update = SoftwareUpdate(self.marionette)
 
         self.saved_channel = self.software_update.update_channel.default_channel
         self.software_update.update_channel.default_channel = 'expected_channel'
@@ -91,17 +91,17 @@ class TestUpdateChannel(FirefoxTestCase)
     def test_update_channel_default_channel(self):
         self.assertEqual(self.software_update.update_channel.default_channel, 'expected_channel')
 
     def test_update_channel_set_default_channel(self):
         self.software_update.update_channel.default_channel = 'new_channel'
         self.assertEqual(self.software_update.update_channel.default_channel, 'new_channel')
 
 
-class TestMARChannels(FirefoxTestCase):
+class TestMARChannels(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestMARChannels, self).setUp()
 
         self.software_update = SoftwareUpdate(self.marionette)
 
         self.saved_mar_channels = self.software_update.mar_channels.channels
         self.software_update.mar_channels.channels = set(['expected', 'channels'])
--- a/testing/firefox-ui/tests/puppeteer/test_tabbar.py
+++ b/testing/firefox-ui/tests/puppeteer/test_tabbar.py
@@ -1,18 +1,18 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
-
+from firefox_puppeteer import PuppeteerMixin
 from firefox_puppeteer.errors import NoCertificateError
+from marionette import MarionetteTestCase
 
 
-class TestTabBar(FirefoxTestCase):
+class TestTabBar(PuppeteerMixin, MarionetteTestCase):
 
     def tearDown(self):
         try:
             self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]])
         finally:
             super(TestTabBar, self).tearDown()
 
     def test_basics(self):
@@ -109,17 +109,17 @@ class TestTabBar(FirefoxTestCase):
 
         # Switch by callback
         tabbar.switch_to(lambda tab: tab.window.tabbar.selected_tab != tab)
         self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle)
 
         tabbar.close_tab(tabbar.tabs[1])
 
 
-class TestTab(FirefoxTestCase):
+class TestTab(PuppeteerMixin, MarionetteTestCase):
 
     def tearDown(self):
         try:
             self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]])
         finally:
             super(TestTab, self).tearDown()
 
     def test_basic(self):
--- a/testing/firefox-ui/tests/puppeteer/test_toolbars.py
+++ b/testing/firefox-ui/tests/puppeteer/test_toolbars.py
@@ -1,19 +1,19 @@
 # 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 firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 from marionette_driver import expected, By, Wait
 from marionette_driver.errors import NoSuchElementException
 
-from firefox_ui_harness.testcases import FirefoxTestCase
 
-
-class TestNavBar(FirefoxTestCase):
+class TestNavBar(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestNavBar, self).setUp()
 
         self.navbar = self.browser.navbar
         self.url = self.marionette.absolute_url('layout/mozilla.html')
 
         with self.marionette.using_context('content'):
@@ -72,17 +72,17 @@ class TestNavBar(FirefoxTestCase):
             # Navigate forward
             self.navbar.forward_button.click()
 
         Wait(self.marionette).until(expected.element_not_present(lambda m:
                                     m.find_element(By.ID, 'mozilla_logo')))
         self.assertEqual(self.marionette.get_url(), self.browser.default_homepage)
 
 
-class TestLocationBar(FirefoxTestCase):
+class TestLocationBar(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestLocationBar, self).setUp()
 
         self.locationbar = self.browser.navbar.locationbar
 
     def test_elements(self):
         self.assertEqual(self.locationbar.urlbar.get_attribute('localName'), 'textbox')
@@ -128,17 +128,17 @@ class TestLocationBar(FirefoxTestCase):
     def test_load_url(self):
         data_uri = 'data:text/html,<title>Title</title>'
         self.locationbar.load_url(data_uri)
 
         with self.marionette.using_context('content'):
             Wait(self.marionette).until(lambda mn: mn.get_url() == data_uri)
 
 
-class TestAutoCompleteResults(FirefoxTestCase):
+class TestAutoCompleteResults(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestAutoCompleteResults, self).setUp()
 
         self.browser.navbar.locationbar.clear()
 
         self.autocomplete_results = self.browser.navbar.locationbar.autocomplete_results
 
@@ -198,17 +198,17 @@ class TestAutoCompleteResults(FirefoxTes
                 all_matches = title_matches + url_matches
                 self.assertTrue(len(all_matches) > 0)
                 for match_fragment in all_matches:
                     self.assertIn(match_fragment.lower(), input_text)
 
             self.autocomplete_results.close()
 
 
-class TestIdentityPopup(FirefoxTestCase):
+class TestIdentityPopup(PuppeteerMixin, MarionetteTestCase):
     def setUp(self):
         super(TestIdentityPopup, self).setUp()
 
         self.locationbar = self.browser.navbar.locationbar
         self.identity_popup = self.locationbar.identity_popup
 
         self.url = 'https://ssl-ev.mozqa.com'
 
--- a/testing/firefox-ui/tests/puppeteer/test_update_wizard.py
+++ b/testing/firefox-ui/tests/puppeteer/test_update_wizard.py
@@ -1,17 +1,18 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
 from firefox_puppeteer.ui.update_wizard import UpdateWizardDialog
+from marionette import MarionetteTestCase
 
 
-class TestUpdateWizard(FirefoxTestCase):
+class TestUpdateWizard(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestUpdateWizard, self).setUp()
 
         def opener(win):
             self.marionette.execute_script("""
               let updatePrompt = Components.classes["@mozilla.org/updates/update-prompt;1"]
                                  .createInstance(Components.interfaces.nsIUpdatePrompt);
--- a/testing/firefox-ui/tests/puppeteer/test_utils.py
+++ b/testing/firefox-ui/tests/puppeteer/test_utils.py
@@ -1,16 +1,17 @@
 # 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 firefox_ui_harness.testcases import FirefoxTestCase
+from firefox_puppeteer import PuppeteerMixin
+from marionette import MarionetteTestCase
 
 
-class TestSanitize(FirefoxTestCase):
+class TestSanitize(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         super(TestSanitize, self).setUp()
 
         # Clear all previous history and cookies.
         self.puppeteer.places.remove_all_history()
         self.marionette.delete_all_cookies()
 
--- a/testing/firefox-ui/tests/puppeteer/test_windows.py
+++ b/testing/firefox-ui/tests/puppeteer/test_windows.py
@@ -1,22 +1,22 @@
 # 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 firefox_puppeteer.errors as errors
+
+from firefox_puppeteer import PuppeteerMixin
+from firefox_puppeteer.ui.windows import BaseWindow
+from marionette import MarionetteTestCase
 from marionette_driver import By, Wait
 from marionette_driver.errors import NoSuchWindowException
 
-import firefox_puppeteer.errors as errors
 
-from firefox_puppeteer.ui.windows import BaseWindow
-from firefox_ui_harness.testcases import FirefoxTestCase
-
-
-class BaseWindowTestCase(FirefoxTestCase):
+class BaseWindowTestCase(PuppeteerMixin, MarionetteTestCase):
 
     def setUp(self):
         """
         These tests open and close windows pretty rapidly, which
         (since bug 1261842) can cause content processes to be
         spawned and discarded in large numbers. By default, Firefox
         has a 5 second timeout for shutting down content processes,
         but we can get into cases where the content process just