Bug 1313312 - Separate out Puppeteer code into a core and mix-in class. r=maja_zf

MozReview-Commit-ID: IERAJWGQc3e

--HG--
rename : testing/puppeteer/firefox/firefox_puppeteer/testcases/base.py => testing/puppeteer/firefox/firefox_puppeteer/mixins.py
extra : rebase_source : f73d13fee2e8f45320e1905aaadf14da7b4e6892
This commit is contained in:
Henrik Skupin 2016-11-07 20:41:11 +01:00
parent d26e078627
commit 9ac27955ff
54 changed files with 327 additions and 335 deletions

View File

@ -11,7 +11,7 @@ from marionette_driver import Wait
from marionette_driver.errors import TimeoutException
from marionette.marionette_test import SkipTest
from firefox_puppeteer.testcases import BaseFirefoxTestCase
from firefox_puppeteer import PuppeteerMixin
from external_media_tests.utils import (timestamp_now, verbose_until)
from external_media_tests.media_utils.video_puppeteer import (
VideoException,
@ -19,7 +19,7 @@ from external_media_tests.media_utils.video_puppeteer import (
)
class MediaTestCase(BaseFirefoxTestCase, MarionetteTestCase):
class MediaTestCase(PuppeteerMixin, MarionetteTestCase):
"""
Necessary methods for MSE playback

View File

@ -17,4 +17,4 @@ mozversion==1.4
wptserve==1.3.0
marionette-client==3.1.0
marionette-driver==2.0.0
firefox-puppeteer >= 52.0.0, <53.0.0
firefox-puppeteer >= 52.1.0, <53.0.0

View File

@ -12,14 +12,23 @@ 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.testcases import BaseFirefoxTestCase
from firefox_puppeteer.ui.update_wizard import UpdateWizardDialog
class FirefoxTestCase(BaseFirefoxTestCase, MarionetteTestCase):
""" Integrate MarionetteTestCase with BaseFirefoxTestCase by reordering MRO """
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
@ -55,7 +64,7 @@ class UpdateTestCase(FirefoxTestCase):
def setUp(self, is_fallback=False):
super(UpdateTestCase, self).setUp()
self.software_update = SoftwareUpdate(lambda: self.marionette)
self.software_update = SoftwareUpdate(self.marionette)
self.download_duration = None
# Bug 604364 - Preparation to test multiple update steps
@ -222,7 +231,7 @@ class UpdateTestCase(FirefoxTestCase):
:param dialog: Instance of :class:`UpdateWizardDialog`.
"""
prefs = Preferences(lambda: self.marionette)
prefs = Preferences(self.marionette)
prefs.set_pref(self.PREF_APP_UPDATE_ALTWINDOWTYPE, dialog.window_type)
try:
@ -234,7 +243,8 @@ class UpdateTestCase(FirefoxTestCase):
# If incompatible add-on are installed, skip over the wizard page
# TODO: Remove once we no longer support version Firefox 45.0ESR
if self.utils.compare_version(self.appinfo.version, '49.0a1') == -1:
if self.puppeteer.utils.compare_version(self.puppeteer.appinfo.version,
'49.0a1') == -1:
if dialog.wizard.selected_panel == dialog.wizard.incompatible_list:
dialog.select_next_page()
@ -314,7 +324,7 @@ class UpdateTestCase(FirefoxTestCase):
def download_and_apply_forced_update(self):
# The update wizard dialog opens automatically after the restart but with a short delay
dialog = Wait(self.marionette, ignored_exceptions=[NoSuchWindowException]).until(
lambda _: self.windows.switch_to(lambda win: type(win) is UpdateWizardDialog)
lambda _: self.puppeteer.windows.switch_to(lambda win: type(win) is UpdateWizardDialog)
)
# In case of a broken complete update the about window has to be used

View File

@ -1,4 +1,4 @@
firefox-puppeteer >= 52.0.0, <53.0.0
firefox-puppeteer >= 52.1.0, <53.0.0
marionette-client >= 2.3.0
mozfile >= 1.2
mozinfo >= 0.8

View File

@ -37,7 +37,7 @@ class TestBrowserWindowShortcuts(FirefoxTestCase):
self.assertNotEqual(current_name, "input")
# TODO: To be moved to the upcoming search library
if self.platform == 'linux':
if self.puppeteer.platform == 'linux':
key = 'searchFocusUnix.commandkey'
else:
key = 'searchFocus.commandkey'

View File

@ -13,7 +13,7 @@ class TestAccessLocationBar(FirefoxTestCase):
FirefoxTestCase.setUp(self)
# Clear complete history so there's no interference from previous entries.
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
self.test_urls = [
'layout/mozilla_projects.html',
@ -34,7 +34,7 @@ class TestAccessLocationBar(FirefoxTestCase):
with self.marionette.using_context('content'):
for url in self.test_urls:
self.marionette.navigate(url)
self.places.wait_for_visited(self.test_urls, load_urls)
self.puppeteer.places.wait_for_visited(self.test_urls, load_urls)
with self.marionette.using_context('content'):
self.marionette.navigate('about:blank')
@ -44,17 +44,17 @@ class TestAccessLocationBar(FirefoxTestCase):
# Clear contents of url bar to focus, then arrow down for list of visited sites
# Verify that autocomplete is open and results are displayed
self.locationbar.clear()
self.urlbar.send_keys(self.keys.ARROW_DOWN)
self.urlbar.send_keys(self.puppeteer.keys.ARROW_DOWN)
Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open)
Wait(self.marionette).until(lambda _: len(self.autocomplete_results.visible_results) > 1)
# Arrow down again to select first item in list, appearing in reversed order, as loaded.
# Verify first item.
self.urlbar.send_keys(self.keys.ARROW_DOWN)
self.urlbar.send_keys(self.puppeteer.keys.ARROW_DOWN)
Wait(self.marionette).until(lambda _: self.autocomplete_results.selected_index == '0')
self.assertIn('mission', self.locationbar.value)
# Navigate to the currently selected url
# Verify it loads by comparing the page url to the test url
self.urlbar.send_keys(self.keys.ENTER)
self.urlbar.send_keys(self.puppeteer.keys.ENTER)
self.assertEqual(self.locationbar.value, self.test_urls[-1])

View File

@ -13,7 +13,7 @@ class TestEscapeAutocomplete(FirefoxTestCase):
FirefoxTestCase.setUp(self)
# Clear complete history so there's no interference from previous entries.
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
self.test_urls = [
'layout/mozilla.html',
@ -37,7 +37,7 @@ class TestEscapeAutocomplete(FirefoxTestCase):
with self.marionette.using_context('content'):
for url in self.test_urls:
self.marionette.navigate(url)
self.places.wait_for_visited(self.test_urls, load_urls)
self.puppeteer.places.wait_for_visited(self.test_urls, load_urls)
# Clear the location bar, type the test string, check that autocomplete list opens
self.locationbar.clear()
@ -46,10 +46,10 @@ class TestEscapeAutocomplete(FirefoxTestCase):
Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open)
# Press escape, check location bar value, check autocomplete list closed
self.locationbar.urlbar.send_keys(self.keys.ESCAPE)
self.locationbar.urlbar.send_keys(self.puppeteer.keys.ESCAPE)
self.assertEqual(self.locationbar.value, self.test_string)
Wait(self.marionette).until(lambda _: not self.autocomplete_results.is_open)
# Press escape again and check that locationbar returns to the page url
self.locationbar.urlbar.send_keys(self.keys.ESCAPE)
self.locationbar.urlbar.send_keys(self.puppeteer.keys.ESCAPE)
self.assertEqual(self.locationbar.value, self.test_urls[-1])

View File

@ -16,10 +16,10 @@ class TestFaviconInAutocomplete(FirefoxTestCase):
FirefoxTestCase.setUp(self)
# Disable suggestions for searches and bookmarks to get results only for history
self.prefs.set_pref(self.PREF_SUGGEST_SEARCHES, False)
self.prefs.set_pref(self.PREF_SUGGEST_BOOKMARK, False)
self.puppeteer.prefs.set_pref(self.PREF_SUGGEST_SEARCHES, False)
self.puppeteer.prefs.set_pref(self.PREF_SUGGEST_BOOKMARK, False)
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
self.test_urls = [self.marionette.absolute_url('layout/mozilla.html')]
@ -41,7 +41,7 @@ class TestFaviconInAutocomplete(FirefoxTestCase):
def load_urls():
with self.marionette.using_context('content'):
self.marionette.navigate(self.test_urls[0])
self.places.wait_for_visited(self.test_urls, load_urls)
self.puppeteer.places.wait_for_visited(self.test_urls, load_urls)
locationbar = self.browser.navbar.locationbar

View File

@ -22,12 +22,12 @@ class TestStarInAutocomplete(FirefoxTestCase):
self.test_urls = [self.marionette.absolute_url('layout/mozilla_grants.html')]
# Disable search suggestions to only get results for history and bookmarks
self.prefs.set_pref(self.PREF_SUGGEST_SEARCHES, False)
self.puppeteer.prefs.set_pref(self.PREF_SUGGEST_SEARCHES, False)
with self.marionette.using_context('content'):
self.marionette.navigate('about:blank')
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
def tearDown(self):
# Close the autocomplete results
@ -38,7 +38,7 @@ class TestStarInAutocomplete(FirefoxTestCase):
""", script_args=[self.bookmark_panel])
self.browser.navbar.locationbar.autocomplete_results.close()
self.places.restore_default_bookmarks()
self.puppeteer.places.restore_default_bookmarks()
self.marionette.clear_pref(self.PREF_SUGGEST_SEARCHES)
finally:
FirefoxTestCase.tearDown(self)
@ -53,7 +53,7 @@ class TestStarInAutocomplete(FirefoxTestCase):
# Navigate to all the urls specified in self.test_urls and wait for them to
# be registered as visited
self.places.wait_for_visited(self.test_urls, visit_urls)
self.puppeteer.places.wait_for_visited(self.test_urls, visit_urls)
# Bookmark the current page using the bookmark menu
self.browser.menubar.select_by_id('bookmarksMenu',
@ -71,7 +71,7 @@ class TestStarInAutocomplete(FirefoxTestCase):
with self.marionette.using_context('content'):
self.marionette.navigate('about:blank')
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
# Focus the locationbar, delete any contents there, and type the search string
locationbar = self.browser.navbar.locationbar

View File

@ -16,7 +16,7 @@ class TestAboutPrivateBrowsing(FirefoxTestCase):
# Use a fake local support URL
support_url = 'about:blank?'
self.prefs.set_pref('app.support.baseURL', support_url)
self.puppeteer.prefs.set_pref('app.support.baseURL', support_url)
self.pb_url = support_url + 'private-browsing'

View File

@ -21,7 +21,7 @@ class TestDVCertificate(FirefoxTestCase):
try:
self.browser.switch_to()
self.identity_popup.close(force=True)
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
FirefoxTestCase.tearDown(self)

View File

@ -21,7 +21,7 @@ class TestEVCertificate(FirefoxTestCase):
try:
self.browser.switch_to()
self.identity_popup.close(force=True)
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
FirefoxTestCase.tearDown(self)
@ -39,7 +39,7 @@ class TestEVCertificate(FirefoxTestCase):
# Get the information from the certificate
cert = self.browser.tabbar.selected_tab.certificate
address = self.security.get_address_from_certificate(cert)
address = self.puppeteer.security.get_address_from_certificate(cert)
# Check the identity popup label displays
self.assertEqual(self.locationbar.identity_organization_label.get_attribute('value'),

View File

@ -23,7 +23,7 @@ class TestNoCertificate(FirefoxTestCase):
try:
self.browser.switch_to()
self.identity_popup.close(force=True)
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
FirefoxTestCase.tearDown(self)

View File

@ -37,8 +37,8 @@ class TestSafeBrowsingNotificationBar(FirefoxTestCase):
}
]
self.prefs.set_pref('browser.safebrowsing.phishing.enabled', True)
self.prefs.set_pref('browser.safebrowsing.malware.enabled', True)
self.puppeteer.prefs.set_pref('browser.safebrowsing.phishing.enabled', True)
self.puppeteer.prefs.set_pref('browser.safebrowsing.malware.enabled', True)
# Give the browser a little time, because SafeBrowsing.jsm takes a while
# between start up and adding the example urls to the db.
@ -51,7 +51,7 @@ class TestSafeBrowsingNotificationBar(FirefoxTestCase):
def tearDown(self):
try:
self.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]])
self.marionette.clear_pref('browser.safebrowsing.phishing.enabled')
self.marionette.clear_pref('browser.safebrowsing.malware.enabled')
@ -101,7 +101,7 @@ class TestSafeBrowsingNotificationBar(FirefoxTestCase):
self.assertEquals(self.marionette.get_url(), self.browser.get_final_url(unsafe_page))
# Clean up here since the permission gets set in this function
self.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
# Check the not a forgery or attack button in the notification bar
def check_not_badware_button(self, button_property, report_page):

View File

@ -23,8 +23,8 @@ class TestSafeBrowsingWarningPages(FirefoxTestCase):
'https://www.itisatrap.org/firefox/its-an-attack.html'
]
self.prefs.set_pref('browser.safebrowsing.phishing.enabled', True)
self.prefs.set_pref('browser.safebrowsing.malware.enabled', True)
self.puppeteer.prefs.set_pref('browser.safebrowsing.phishing.enabled', True)
self.puppeteer.prefs.set_pref('browser.safebrowsing.malware.enabled', True)
# Give the browser a little time, because SafeBrowsing.jsm takes a
# while between start up and adding the example urls to the db.
@ -37,7 +37,7 @@ class TestSafeBrowsingWarningPages(FirefoxTestCase):
def tearDown(self):
try:
self.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]])
self.marionette.clear_pref('browser.safebrowsing.malware.enabled')
self.marionette.clear_pref('browser.safebrowsing.phishing.enabled')
@ -108,4 +108,4 @@ class TestSafeBrowsingWarningPages(FirefoxTestCase):
self.assertEquals(self.marionette.get_url(), self.browser.get_final_url(unsafe_page))
# Clean up by removing safe browsing permission for unsafe page
self.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')
self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing')

View File

@ -17,13 +17,13 @@ class TestSSLDisabledErrorPage(FirefoxTestCase):
self.url = 'https://tlsv1-0.mozqa.com'
self.utils.sanitize({"sessions": True})
self.puppeteer.utils.sanitize({"sessions": True})
# Disable SSL 3.0, TLS 1.0 and TLS 1.1 for secure connections
# by forcing the use of TLS 1.2
# see: http://kb.mozillazine.org/Security.tls.version.*#Possible_values_and_their_effects
self.prefs.set_pref('security.tls.version.min', 3)
self.prefs.set_pref('security.tls.version.max', 3)
self.puppeteer.prefs.set_pref('security.tls.version.min', 3)
self.puppeteer.prefs.set_pref('security.tls.version.max', 3)
def tearDown(self):
try:

View File

@ -32,14 +32,14 @@ class TestSSLStatusAfterRestart(FirefoxTestCase):
)
# Set browser to restore previous session
self.prefs.set_pref('browser.startup.page', 3)
self.puppeteer.prefs.set_pref('browser.startup.page', 3)
self.locationbar = self.browser.navbar.locationbar
self.identity_popup = self.locationbar.identity_popup
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]])
self.browser.switch_to()
self.identity_popup.close(force=True)
@ -101,7 +101,7 @@ class TestSSLStatusAfterRestart(FirefoxTestCase):
# Verify the domain listed on the security panel
# If this is a wildcard cert, check only the domain
if cert['commonName'].startswith('*'):
self.assertIn(self.security.get_domain_from_common_name(cert['commonName']),
self.assertIn(self.puppeteer.security.get_domain_from_common_name(cert['commonName']),
page_info.deck.security.domain.get_attribute('value'),
'Expected domain found in certificate for ' + url)
else:

View File

@ -18,7 +18,7 @@ class TestSubmitUnencryptedInfoWarning(FirefoxTestCase):
self.url = 'https://ssl-dv.mozqa.com/data/firefox/security/unencryptedsearch.html'
self.test_string = 'mozilla'
self.prefs.set_pref('security.warn_submit_insecure', True)
self.puppeteer.prefs.set_pref('security.warn_submit_insecure', True)
def tearDown(self):
try:

View File

@ -64,7 +64,7 @@ class TestRestoreWindowsAfterRestart(FirefoxTestCase):
self.restart()
windows = self.windows.all
windows = self.puppeteer.windows.all
# There's no guarantee that Marionette will return us an
# iterator for the opened windows that will match the

View File

@ -15,7 +15,7 @@ class TestAboutWindow(FirefoxTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
FirefoxTestCase.tearDown(self)
@ -64,5 +64,5 @@ class TestAboutWindow(FirefoxTestCase):
self.about_window.close()
for trigger in open_strategies:
about_window = self.browser.open_about_window(trigger=trigger)
self.assertEquals(about_window, self.windows.current)
self.assertEquals(about_window, self.puppeteer.windows.current)
about_window.close()

View File

@ -12,17 +12,18 @@ class TestAppInfo(FirefoxTestCase):
binary = self.marionette.bin
version_info = mozversion.get_version(binary=binary)
self.assertEqual(self.appinfo.ID, version_info['application_id'])
self.assertEqual(self.appinfo.name, version_info['application_name'])
self.assertEqual(self.appinfo.vendor, version_info['application_vendor'])
self.assertEqual(self.appinfo.version, version_info['application_version'])
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'])
self.assertEqual(self.puppeteer.appinfo.version, version_info['application_version'])
# Bug 1298328 - Platform buildid mismatch due to incremental builds
# self.assertEqual(self.appinfo.platformBuildID, version_info['platform_buildid'])
self.assertEqual(self.appinfo.platformVersion, version_info['platform_version'])
self.assertIsNotNone(self.appinfo.locale)
self.assertIsNotNone(self.appinfo.user_agent)
self.assertIsNotNone(self.appinfo.XPCOMABI)
# self.assertEqual(self.puppeteer.appinfo.platformBuildID,
# version_info['platform_buildid'])
self.assertEqual(self.puppeteer.appinfo.platformVersion, version_info['platform_version'])
self.assertIsNotNone(self.puppeteer.appinfo.locale)
self.assertIsNotNone(self.puppeteer.appinfo.user_agent)
self.assertIsNotNone(self.puppeteer.appinfo.XPCOMABI)
def test_invalid_properties(self):
with self.assertRaises(AttributeError):
self.appinfo.unknown
self.puppeteer.appinfo.unknown

View File

@ -13,7 +13,7 @@ class TestL10n(FirefoxTestCase):
def setUp(self):
FirefoxTestCase.setUp(self)
self.l10n = L10n(lambda: self.marionette)
self.l10n = L10n(self.marionette)
def tearDown(self):
FirefoxTestCase.tearDown(self)

View File

@ -17,17 +17,17 @@ class TestNotifications(FirefoxTestCase):
def setUp(self):
FirefoxTestCase.setUp(self)
self.prefs.set_pref('extensions.install.requireSecureOrigin', False)
self.puppeteer.prefs.set_pref('extensions.install.requireSecureOrigin', False)
self.addons_url = self.marionette.absolute_url('addons/extensions/')
self.utils.permissions.add(self.marionette.baseurl, 'install')
self.puppeteer.utils.permissions.add(self.marionette.baseurl, 'install')
def tearDown(self):
try:
self.marionette.clear_pref('extensions.install.requireSecureOrigin')
self.marionette.clear_pref('xpinstall.signatures.required')
self.utils.permissions.remove(self.addons_url, 'install')
self.puppeteer.utils.permissions.remove(self.addons_url, 'install')
if self.browser.notification:
self.browser.notification.close(force=True)
@ -69,7 +69,7 @@ class TestNotifications(FirefoxTestCase):
def test_addon_install_failed_notification(self):
"""Trigger add-on blocked notification using an unsigned add-on"""
# Ensure that installing unsigned extensions will fail
self.prefs.set_pref('xpinstall.signatures.required', True)
self.puppeteer.prefs.set_pref('xpinstall.signatures.required', True)
self.trigger_addon_notification(
'restartless_addon_unsigned.xpi',

View File

@ -9,7 +9,7 @@ class TestPageInfoWindow(FirefoxTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
FirefoxTestCase.tearDown(self)
@ -68,14 +68,14 @@ class TestPageInfoWindow(FirefoxTestCase):
)
for trigger in open_strategies:
if trigger == 'shortcut' and self.platform == 'windows_nt':
if trigger == 'shortcut' and self.puppeteer.platform == 'windows_nt':
# The shortcut for page info window does not exist on windows.
self.assertRaises(ValueError, self.browser.open_page_info_window,
trigger=trigger)
continue
page_info = self.browser.open_page_info_window(trigger=trigger)
self.assertEquals(page_info, self.windows.current)
self.assertEquals(page_info, self.puppeteer.windows.current)
page_info.close()
def test_close_window(self):
@ -90,7 +90,7 @@ class TestPageInfoWindow(FirefoxTestCase):
)
for trigger in close_strategies:
# menu only works on OS X
if trigger == 'menu' and self.platform != 'darwin':
if trigger == 'menu' and self.puppeteer.platform != 'darwin':
continue
page_info = self.browser.open_page_info_window()

View File

@ -18,8 +18,8 @@ class TestPlaces(FirefoxTestCase):
def tearDown(self):
try:
self.places.restore_default_bookmarks()
self.places.remove_all_history()
self.puppeteer.places.restore_default_bookmarks()
self.puppeteer.places.remove_all_history()
finally:
FirefoxTestCase.tearDown(self)
@ -44,7 +44,7 @@ class TestPlaces(FirefoxTestCase):
def test_plugins(self):
# TODO: Once we use a plugin, add a test case to verify that the data will be removed
self.places.clear_plugin_data()
self.puppeteer.places.clear_plugin_data()
def test_bookmarks(self):
star_button = self.marionette.find_element(By.ID, 'bookmarks-menu-button')
@ -54,18 +54,19 @@ class TestPlaces(FirefoxTestCase):
with self.marionette.using_context('content'):
self.marionette.navigate(url)
Wait(self.marionette).until(lambda _: self.places.is_bookmark_star_button_ready())
Wait(self.marionette).until(
lambda _: self.puppeteer.places.is_bookmark_star_button_ready())
star_button.click()
Wait(self.marionette).until(lambda _: self.places.is_bookmarked(url))
Wait(self.marionette).until(lambda _: self.puppeteer.places.is_bookmarked(url))
ids = self.places.get_folder_ids_for_url(url)
ids = self.puppeteer.places.get_folder_ids_for_url(url)
self.assertEqual(len(ids), 1)
self.assertEqual(ids[0], self.places.bookmark_folders.unfiled)
self.assertEqual(ids[0], self.puppeteer.places.bookmark_folders.unfiled)
# Restore default bookmarks, so the added URLs are gone
self.places.restore_default_bookmarks()
self.puppeteer.places.restore_default_bookmarks()
for url in self.urls:
self.assertFalse(self.places.is_bookmarked(url))
self.assertFalse(self.puppeteer.places.is_bookmarked(url))
def test_history(self):
self.assertEqual(len(self.get_all_urls_in_history()), 0)
@ -75,10 +76,10 @@ class TestPlaces(FirefoxTestCase):
with self.marionette.using_context('content'):
for url in self.urls:
self.marionette.navigate(url)
self.places.wait_for_visited(self.urls, load_urls)
self.puppeteer.places.wait_for_visited(self.urls, load_urls)
self.assertEqual(self.get_all_urls_in_history(), self.urls)
# Check that both pages are no longer in the remove_all_history
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
self.assertEqual(len(self.get_all_urls_in_history()), 0)

View File

@ -31,116 +31,116 @@ class testPreferences(FirefoxTestCase):
def test_get_pref(self):
# check correct types
self.assertTrue(isinstance(self.prefs.get_pref(self.bool_pref),
self.assertTrue(isinstance(self.puppeteer.prefs.get_pref(self.bool_pref),
bool))
self.assertTrue(isinstance(self.prefs.get_pref(self.int_pref),
self.assertTrue(isinstance(self.puppeteer.prefs.get_pref(self.int_pref),
int))
self.assertTrue(isinstance(self.prefs.get_pref(self.string_pref),
self.assertTrue(isinstance(self.puppeteer.prefs.get_pref(self.string_pref),
basestring))
# unknown
self.assertIsNone(self.prefs.get_pref(self.unknown_pref))
self.assertIsNone(self.puppeteer.prefs.get_pref(self.unknown_pref))
# default branch
orig_value = self.prefs.get_pref(self.int_pref)
self.prefs.set_pref(self.int_pref, 99999)
self.assertEqual(self.prefs.get_pref(self.int_pref), 99999)
self.assertEqual(self.prefs.get_pref(self.int_pref, True), orig_value)
orig_value = self.puppeteer.prefs.get_pref(self.int_pref)
self.puppeteer.prefs.set_pref(self.int_pref, 99999)
self.assertEqual(self.puppeteer.prefs.get_pref(self.int_pref), 99999)
self.assertEqual(self.puppeteer.prefs.get_pref(self.int_pref, True), orig_value)
# complex value
properties_file = 'chrome://branding/locale/browserconfig.properties'
self.assertEqual(self.prefs.get_pref('browser.startup.homepage'),
self.assertEqual(self.puppeteer.prefs.get_pref('browser.startup.homepage'),
properties_file)
value = self.prefs.get_pref('browser.startup.homepage',
interface='nsIPrefLocalizedString')
value = self.puppeteer.prefs.get_pref('browser.startup.homepage',
interface='nsIPrefLocalizedString')
self.assertNotEqual(value, properties_file)
def test_set_pref_casted_values(self):
# basestring as boolean
self.prefs.set_pref(self.bool_pref, '')
self.assertFalse(self.prefs.get_pref(self.bool_pref))
self.puppeteer.prefs.set_pref(self.bool_pref, '')
self.assertFalse(self.puppeteer.prefs.get_pref(self.bool_pref))
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.bool_pref)
self.prefs.set_pref(self.bool_pref, 'unittest')
self.assertTrue(self.prefs.get_pref(self.bool_pref))
self.puppeteer.prefs.set_pref(self.bool_pref, 'unittest')
self.assertTrue(self.puppeteer.prefs.get_pref(self.bool_pref))
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.bool_pref)
# int as boolean
self.prefs.set_pref(self.bool_pref, 0)
self.assertFalse(self.prefs.get_pref(self.bool_pref))
self.puppeteer.prefs.set_pref(self.bool_pref, 0)
self.assertFalse(self.puppeteer.prefs.get_pref(self.bool_pref))
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.bool_pref)
self.prefs.set_pref(self.bool_pref, 5)
self.assertTrue(self.prefs.get_pref(self.bool_pref))
self.puppeteer.prefs.set_pref(self.bool_pref, 5)
self.assertTrue(self.puppeteer.prefs.get_pref(self.bool_pref))
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.bool_pref)
# boolean as int
self.prefs.set_pref(self.int_pref, False)
self.assertEqual(self.prefs.get_pref(self.int_pref), 0)
self.puppeteer.prefs.set_pref(self.int_pref, False)
self.assertEqual(self.puppeteer.prefs.get_pref(self.int_pref), 0)
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.int_pref)
self.prefs.set_pref(self.int_pref, True)
self.assertEqual(self.prefs.get_pref(self.int_pref), 1)
self.puppeteer.prefs.set_pref(self.int_pref, True)
self.assertEqual(self.puppeteer.prefs.get_pref(self.int_pref), 1)
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.int_pref)
# int as string
self.prefs.set_pref(self.string_pref, 54)
self.assertEqual(self.prefs.get_pref(self.string_pref), '54')
self.puppeteer.prefs.set_pref(self.string_pref, 54)
self.assertEqual(self.puppeteer.prefs.get_pref(self.string_pref), '54')
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.string_pref)
def test_set_pref_invalid(self):
self.assertRaises(AssertionError,
self.prefs.set_pref, self.new_pref, None)
self.puppeteer.prefs.set_pref, self.new_pref, None)
def test_set_pref_new_preference(self):
self.prefs.set_pref(self.new_pref, True)
self.assertTrue(self.prefs.get_pref(self.new_pref))
self.puppeteer.prefs.set_pref(self.new_pref, True)
self.assertTrue(self.puppeteer.prefs.get_pref(self.new_pref))
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.new_pref)
self.prefs.set_pref(self.new_pref, 5)
self.assertEqual(self.prefs.get_pref(self.new_pref), 5)
self.puppeteer.prefs.set_pref(self.new_pref, 5)
self.assertEqual(self.puppeteer.prefs.get_pref(self.new_pref), 5)
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.new_pref)
self.prefs.set_pref(self.new_pref, 'test')
self.assertEqual(self.prefs.get_pref(self.new_pref), 'test')
self.puppeteer.prefs.set_pref(self.new_pref, 'test')
self.assertEqual(self.puppeteer.prefs.get_pref(self.new_pref), 'test')
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.new_pref)
def test_set_pref_new_values(self):
self.prefs.set_pref(self.bool_pref, True)
self.assertTrue(self.prefs.get_pref(self.bool_pref))
self.puppeteer.prefs.set_pref(self.bool_pref, True)
self.assertTrue(self.puppeteer.prefs.get_pref(self.bool_pref))
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.bool_pref)
self.prefs.set_pref(self.int_pref, 99999)
self.assertEqual(self.prefs.get_pref(self.int_pref), 99999)
self.puppeteer.prefs.set_pref(self.int_pref, 99999)
self.assertEqual(self.puppeteer.prefs.get_pref(self.int_pref), 99999)
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.int_pref)
self.prefs.set_pref(self.string_pref, 'test_string')
self.assertEqual(self.prefs.get_pref(self.string_pref), 'test_string')
self.puppeteer.prefs.set_pref(self.string_pref, 'test_string')
self.assertEqual(self.puppeteer.prefs.get_pref(self.string_pref), 'test_string')
# Remove when all self.marionette methods are implemented
# Please see Bug 1293588
self.marionette.clear_pref(self.string_pref)

View File

@ -20,7 +20,7 @@ class TestSecurity(FirefoxTestCase):
self.assertEqual(cert['organization'], 'Mozilla Corporation')
self.assertEqual(cert['issuerOrganization'], 'DigiCert Inc')
address = self.security.get_address_from_certificate(cert)
address = self.puppeteer.security.get_address_from_certificate(cert)
self.assertIsNotNone(address)
self.assertIsNotNone(address['city'])
self.assertIsNotNone(address['country'])

View File

@ -13,7 +13,7 @@ class TestSoftwareUpdate(FirefoxTestCase):
def setUp(self):
FirefoxTestCase.setUp(self)
self.software_update = SoftwareUpdate(lambda: self.marionette)
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'])
@ -72,7 +72,7 @@ class TestUpdateChannel(FirefoxTestCase):
def setUp(self):
FirefoxTestCase.setUp(self)
self.software_update = SoftwareUpdate(lambda: self.marionette)
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'
@ -98,7 +98,7 @@ class TestMARChannels(FirefoxTestCase):
def setUp(self):
FirefoxTestCase.setUp(self)
self.software_update = SoftwareUpdate(lambda: self.marionette)
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'])

View File

@ -19,7 +19,7 @@ class TestNavBar(FirefoxTestCase):
with self.marionette.using_context('content'):
self.marionette.navigate('about:blank')
# TODO: check why self.places.remove_all_history() does not work here
# TODO: check why self.puppeteer.places.remove_all_history() does not work here
self.marionette.execute_script("""
let count = gBrowser.sessionHistory.count;
gBrowser.sessionHistory.PurgeHistory(count);

View File

@ -24,7 +24,7 @@ class TestUpdateWizard(FirefoxTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
FirefoxTestCase.tearDown(self)

View File

@ -11,7 +11,7 @@ class TestSanitize(FirefoxTestCase):
FirefoxTestCase.setUp(self)
# Clear all previous history and cookies.
self.places.remove_all_history()
self.puppeteer.places.remove_all_history()
self.marionette.delete_all_cookies()
self.urls = [
@ -27,19 +27,19 @@ class TestSanitize(FirefoxTestCase):
with self.marionette.using_context('content'):
for url in self.urls:
self.marionette.navigate(url)
self.places.wait_for_visited(self.urls, load_urls)
self.puppeteer.places.wait_for_visited(self.urls, load_urls)
def tearDown(self):
FirefoxTestCase.tearDown(self)
def test_sanitize_history(self):
""" Clears history. """
self.assertEqual(self.places.get_all_urls_in_history(), self.urls)
self.utils.sanitize(data_type={"history": True})
self.assertEqual(self.places.get_all_urls_in_history(), [])
self.assertEqual(self.puppeteer.places.get_all_urls_in_history(), self.urls)
self.puppeteer.utils.sanitize(data_type={"history": True})
self.assertEqual(self.puppeteer.places.get_all_urls_in_history(), [])
def test_sanitize_cookies(self):
""" Clears cookies. """
self.assertIsNotNone(self.marionette.get_cookie('litmus_1'))
self.utils.sanitize(data_type={"cookies": True})
self.puppeteer.utils.sanitize(data_type={"cookies": True})
self.assertIsNone(self.marionette.get_cookie('litmus_1'))

View File

@ -27,7 +27,7 @@ class BaseWindowTestCase(FirefoxTestCase):
the shutdown timer.
"""
FirefoxTestCase.setUp(self)
self.prefs.set_pref('dom.ipc.tabs.shutdownTimeoutSecs', 0)
self.puppeteer.prefs.set_pref('dom.ipc.tabs.shutdownTimeoutSecs', 0)
def tearDown(self):
try:
@ -40,7 +40,7 @@ class TestWindows(BaseWindowTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
BaseWindowTestCase.tearDown(self)
@ -51,11 +51,11 @@ class TestWindows(BaseWindowTestCase):
for index in range(0, 2):
self.marionette.execute_script(""" window.open(); """)
windows = self.windows.all
windows = self.puppeteer.windows.all
self.assertEquals(len(windows), 3)
# Switch to the 2nd window
self.windows.switch_to(windows[1].handle)
self.puppeteer.windows.switch_to(windows[1].handle)
self.assertEquals(windows[1].handle, self.marionette.current_chrome_window_handle)
# TODO: Needs updated tabs module for improved navigation
@ -63,7 +63,7 @@ class TestWindows(BaseWindowTestCase):
self.marionette.navigate(url)
# Switch to the last window and find 2nd window by URL
self.windows.switch_to(windows[2].handle)
self.puppeteer.windows.switch_to(windows[2].handle)
# TODO: A window can have multiple tabs, so this may need an update
# when the tabs module gets implemented
@ -71,21 +71,21 @@ class TestWindows(BaseWindowTestCase):
with win.marionette.using_context('content'):
return win.marionette.get_url() == url
self.windows.switch_to(find_by_url)
self.puppeteer.windows.switch_to(find_by_url)
self.assertEquals(windows[1].handle, self.marionette.current_chrome_window_handle)
self.windows.switch_to(find_by_url)
self.puppeteer.windows.switch_to(find_by_url)
# Switching to an unknown handles has to fail
self.assertRaises(NoSuchWindowException,
self.windows.switch_to, "humbug")
self.puppeteer.windows.switch_to, "humbug")
self.assertRaises(NoSuchWindowException,
self.windows.switch_to, lambda win: False)
self.puppeteer.windows.switch_to, lambda win: False)
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
self.browser.switch_to()
self.assertEqual(len(self.windows.all), 1)
self.assertEqual(len(self.puppeteer.windows.all), 1)
def test_switch_to_unknown_window_type(self):
def open_by_js(_):
@ -104,13 +104,13 @@ class TestBaseWindow(BaseWindowTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
BaseWindowTestCase.tearDown(self)
def test_basics(self):
# force BaseWindow instance
win1 = BaseWindow(lambda: self.marionette, self.browser.handle)
win1 = BaseWindow(self.marionette, self.browser.handle)
self.assertEquals(win1.handle, self.marionette.current_chrome_window_handle)
self.assertEquals(win1.window_element,
@ -120,10 +120,8 @@ class TestBaseWindow(BaseWindowTestCase):
self.assertFalse(win1.closed)
# Test invalid parameters for BaseWindow constructor
self.assertRaises(TypeError,
BaseWindow, self.marionette, self.browser.handle)
self.assertRaises(errors.UnknownWindowError,
BaseWindow, lambda: self.marionette, 10)
BaseWindow, self.marionette, 10)
# Test invalid shortcuts
self.assertRaises(KeyError,
@ -131,13 +129,13 @@ class TestBaseWindow(BaseWindowTestCase):
def test_open_close(self):
# force BaseWindow instance
win1 = BaseWindow(lambda: self.marionette, self.browser.handle)
win1 = BaseWindow(self.marionette, self.browser.handle)
# Open a new window (will be focused), and check states
win2 = win1.open_window()
# force BaseWindow instance
win2 = BaseWindow(lambda: self.marionette, win2.handle)
win2 = BaseWindow(self.marionette, win2.handle)
self.assertEquals(len(self.marionette.chrome_window_handles), 2)
self.assertNotEquals(win1.handle, win2.handle)
@ -162,7 +160,7 @@ class TestBaseWindow(BaseWindowTestCase):
win2 = win1.open_window(callback=opener)
# force BaseWindow instance
win2 = BaseWindow(lambda: self.marionette, win2.handle)
win2 = BaseWindow(self.marionette, win2.handle)
self.assertEquals(len(self.marionette.chrome_window_handles), 2)
win2.close(callback=closer)
@ -172,20 +170,20 @@ class TestBaseWindow(BaseWindowTestCase):
# Check for an unexpected window class
self.assertRaises(errors.UnexpectedWindowTypeError,
win1.open_window, expected_window_class=BaseWindow)
self.windows.close_all([win1])
self.puppeteer.windows.close_all([win1])
def test_switch_to_and_focus(self):
# force BaseWindow instance
win1 = BaseWindow(lambda: self.marionette, self.browser.handle)
win1 = BaseWindow(self.marionette, self.browser.handle)
# Open a new window (will be focused), and check states
win2 = win1.open_window()
# force BaseWindow instance
win2 = BaseWindow(lambda: self.marionette, win2.handle)
win2 = BaseWindow(self.marionette, win2.handle)
self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle)
self.assertEquals(win2.handle, self.windows.focused_chrome_window_handle)
self.assertEquals(win2.handle, self.puppeteer.windows.focused_chrome_window_handle)
self.assertFalse(win1.focused)
self.assertTrue(win2.focused)
@ -200,7 +198,7 @@ class TestBaseWindow(BaseWindowTestCase):
# Switch back to win2 by focusing it directly
win2.focus()
self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle)
self.assertEquals(win2.handle, self.windows.focused_chrome_window_handle)
self.assertEquals(win2.handle, self.puppeteer.windows.focused_chrome_window_handle)
self.assertTrue(win2.focused)
# Close win2, and check that it keeps active but looses focus
@ -214,7 +212,7 @@ class TestBrowserWindow(BaseWindowTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
BaseWindowTestCase.tearDown(self)
@ -231,29 +229,29 @@ class TestBrowserWindow(BaseWindowTestCase):
def test_open_close(self):
# open and close a new browser windows by menu
win2 = self.browser.open_browser(trigger='menu')
self.assertEquals(win2, self.windows.current)
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertFalse(self.browser.is_private)
win2.close(trigger='menu')
# open and close a new browser window by shortcut
win2 = self.browser.open_browser(trigger='shortcut')
self.assertEquals(win2, self.windows.current)
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertFalse(self.browser.is_private)
win2.close(trigger='shortcut')
# open and close a new private browsing window
win2 = self.browser.open_browser(is_private=True)
self.assertEquals(win2, self.windows.current)
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertTrue(win2.is_private)
win2.close()
# open and close a new private browsing window
win2 = self.browser.open_browser(trigger='shortcut', is_private=True)
self.assertEquals(win2, self.windows.current)
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertTrue(win2.is_private)
win2.close()
# force closing a window
win2 = self.browser.open_browser()
self.assertEquals(win2, self.windows.current)
self.assertEquals(win2, self.puppeteer.windows.current)
win2.close(force=True)

View File

@ -12,7 +12,7 @@ class TestDirectUpdate(UpdateTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
UpdateTestCase.tearDown(self)

View File

@ -12,7 +12,7 @@ class TestFallbackUpdate(UpdateTestCase):
def tearDown(self):
try:
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
finally:
UpdateTestCase.tearDown(self)

View File

@ -2,89 +2,8 @@
# 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 decorators import use_class_as_property
from firefox_puppeteer.mixins import PuppeteerMixin
from firefox_puppeteer.puppeteer import Puppeteer
__version__ = '52.0.0'
class Puppeteer(object):
"""The puppeteer class is used to expose libraries to test cases.
example:
`class MyTestCase(MarionetteTestCase, Puppeteer)`
Each library can be referenced by its puppeteer name as a member of a
the TestCase instance. For example, from within a test method, the
"current_window" member of the "Browser" class can be accessed via
"self.browser.current_window".
"""
def __init__(self):
self.marionette = None
def get_marionette(self):
return self.marionette
@use_class_as_property('api.appinfo.AppInfo')
def appinfo(self):
"""
Provides access to members of the appinfo api.
See the :class:`~api.appinfo.AppInfo` reference.
"""
@use_class_as_property('api.keys.Keys')
def keys(self):
"""
Provides a definition of control keys to use with keyboard shortcuts.
For example, keys.CONTROL or keys.ALT.
See the :class:`~api.keys.Keys` reference.
"""
@use_class_as_property('api.places.Places')
def places(self):
"""Provides low-level access to several bookmark and history related actions.
See the :class:`~api.places.Places` reference.
"""
@use_class_as_property('api.utils.Utils')
def utils(self):
"""Provides an api for interacting with utility actions.
See the :class:`~api.utils.Utils` reference.
"""
@property
def platform(self):
"""Returns the lowercased platform name.
:returns: Platform name
"""
return self.marionette.session_capabilities['platformName']
@use_class_as_property('api.prefs.Preferences')
def prefs(self):
"""
Provides an api for setting and inspecting preferences, as see in
about:config.
See the :class:`~api.prefs.Preferences` reference.
"""
@use_class_as_property('api.security.Security')
def security(self):
"""
Provides an api for accessing security related properties and helpers.
See the :class:`~api.security.Security` reference.
"""
@use_class_as_property('ui.windows.Windows')
def windows(self):
"""
Provides shortcuts to the top-level windows.
See the :class:`~ui.window.Windows` reference.
"""
__version__ = '52.1.0'

View File

@ -9,11 +9,8 @@ class Keys(marionette_driver.keys.Keys):
"""Proxy to marionette's keys with an "accel" provided for convenience
testing across platforms."""
def __init__(self, marionette_getter):
self.marionette_getter = marionette_getter
caps = self.marionette_getter().session_capabilities
self.isDarwin = caps['platformName'] == 'darwin'
def __init__(self, marionette):
self.isDarwin = marionette.session_capabilities['platformName'] == 'darwin'
@property
def ACCEL(self):

View File

@ -82,8 +82,8 @@ class MARChannels(BaseLib):
INI_SECTION = 'Settings'
INI_OPTION = 'ACCEPTED_MAR_CHANNEL_IDS'
def __init__(self, marionette_getter):
BaseLib.__init__(self, marionette_getter)
def __init__(self, marionette):
BaseLib.__init__(self, marionette)
self._ini_file_path = self.marionette.execute_script("""
Components.utils.import('resource://gre/modules/Services.jsm');
@ -168,15 +168,15 @@ class SoftwareUpdate(BaseLib):
PREF_APP_UPDATE_URL_OVERRIDE = 'app.update.url.override'
PREF_DISABLED_ADDONS = 'extensions.disabledAddons'
def __init__(self, marionette_getter):
BaseLib.__init__(self, marionette_getter)
def __init__(self, marionette):
BaseLib.__init__(self, marionette)
self.app_info = AppInfo(marionette_getter)
self.prefs = Preferences(marionette_getter)
self.app_info = AppInfo(marionette)
self.prefs = Preferences(marionette)
self._update_channel = UpdateChannel(marionette_getter)
self._mar_channels = MARChannels(marionette_getter)
self._active_update = ActiveUpdate(marionette_getter)
self._update_channel = UpdateChannel(marionette)
self._mar_channels = MARChannels(marionette)
self._active_update = ActiveUpdate(marionette)
@property
def ABI(self):
@ -378,10 +378,10 @@ class UpdateChannel(BaseLib):
"""Class to handle the update channel as listed in channel-prefs.js"""
REGEX_UPDATE_CHANNEL = re.compile(r'("app\.update\.channel", ")([^"].*)(?=")')
def __init__(self, marionette_getter):
BaseLib.__init__(self, marionette_getter)
def __init__(self, marionette):
BaseLib.__init__(self, marionette)
self.prefs = Preferences(marionette_getter)
self.prefs = Preferences(marionette)
self.file_path = self.marionette.execute_script("""
Components.utils.import('resource://gre/modules/Services.jsm');

View File

@ -13,7 +13,7 @@ class Utils(BaseLib):
def __init__(self, *args, **kwargs):
BaseLib.__init__(self, *args, **kwargs)
self._permissions = Permissions(lambda: self.marionette)
self._permissions = Permissions(self.marionette)
@property
def permissions(self):

View File

@ -6,18 +6,9 @@
class BaseLib(object):
"""A base class that handles lazily setting the "client" class attribute."""
def __init__(self, marionette_getter):
if not callable(marionette_getter):
raise TypeError('Invalid callback for "marionette_getter": %s' % marionette_getter)
self._marionette = None
self._marionette_getter = marionette_getter
def __init__(self, marionette):
self._marionette = marionette
@property
def marionette(self):
if self._marionette is None:
self._marionette = self._marionette_getter()
return self._marionette
def get_marionette(self):
return self.marionette

View File

@ -28,7 +28,7 @@ class use_class_as_property(object):
if not prop:
module = import_module('.{}'.format(self.mod_name),
'firefox_puppeteer')
prop = getattr(module, self.cls_name)(cls.get_marionette)
prop = getattr(module, self.cls_name)(cls.marionette)
setattr(cls, tag, prop)
func(cls, *args, **kwargs)
return prop

View File

@ -2,28 +2,24 @@
# 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 unittest
from firefox_puppeteer import Puppeteer
from firefox_puppeteer.puppeteer import Puppeteer
from firefox_puppeteer.ui.browser.window import BrowserWindow
class BaseFirefoxTestCase(unittest.TestCase, Puppeteer):
"""Base TestCase class for Firefox Desktop tests.
class PuppeteerMixin(object):
"""Mix-in class for Firefox specific API modules exposed to test scope.
This is designed to enhance MarionetteTestCase by inserting the Puppeteer
mixin class (so Firefox specific API modules are exposed to test scope) and
providing common set-up and tear-down code for Firefox tests.
It also provides common set-up and tear-down code for Firefox tests.
Child classes are expected to also subclass MarionetteTestCase such that
MarionetteTestCase is inserted into the MRO after FirefoxTestCase but before
unittest.TestCase.
Child test case classes are expected to also subclass MarionetteTestCase such
that PuppeteerMixin is followed by MarionetteTestCase. This will insert the
Puppeteer mixin before the MarionetteTestCase into the MRO.
example:
`class AwesomeTestCase(FirefoxTestCase, MarionetteTestCase)`
`class MyTestCase(PuppeteerMixin, MarionetteTestCase)`
The key role of MarionetteTestCase is to set self.marionette appropriately
in `__init__`. Any TestCase class that satisfies this requirement is
in `setUp()`. Any TestCase class that satisfies this requirement is
compatible with this class.
If you're extending the inheritance tree further to make specialized
@ -31,9 +27,6 @@ class BaseFirefoxTestCase(unittest.TestCase, Puppeteer):
parent class.
"""
def __init__(self, *args, **kwargs):
super(BaseFirefoxTestCase, self).__init__(*args, **kwargs)
def _check_and_fix_leaked_handles(self):
handle_count = len(self.marionette.window_handles)
url = []
@ -55,11 +48,12 @@ class BaseFirefoxTestCase(unittest.TestCase, Puppeteer):
if not self.browser or self.browser.closed:
# Find a proper replacement browser window
# TODO: We have to make this less error prone in case no browser is open.
self.browser = self.windows.switch_to(lambda win: type(win) is BrowserWindow)
self.browser = self.puppeteer.windows.switch_to(
lambda win: type(win) is BrowserWindow)
# Ensure to close all the remaining chrome windows to give following
# tests a proper start condition and make them not fail.
self.windows.close_all([self.browser])
self.puppeteer.windows.close_all([self.browser])
self.browser.focus()
# Also close all remaining tabs
@ -74,20 +68,21 @@ class BaseFirefoxTestCase(unittest.TestCase, Puppeteer):
self.marionette.restart(in_app=not kwargs.get('clean'), **kwargs)
# Ensure that we always have a valid browser instance available
self.browser = self.windows.switch_to(lambda win: type(win) is BrowserWindow)
self.browser = self.puppeteer.windows.switch_to(lambda win: type(win) is BrowserWindow)
def setUp(self, *args, **kwargs):
super(BaseFirefoxTestCase, self).setUp(*args, **kwargs)
super(PuppeteerMixin, self).setUp(*args, **kwargs)
self._start_handle_count = len(self.marionette.window_handles)
self._init_tab_handles = self.marionette.window_handles
self.marionette.set_context('chrome')
self.browser = self.windows.current
self.puppeteer = Puppeteer(self.marionette)
self.browser = self.puppeteer.windows.current
self.browser.focus()
with self.marionette.using_context(self.marionette.CONTEXT_CONTENT):
# Ensure that we have a default page opened
self.marionette.navigate(self.prefs.get_pref('browser.newtab.url'))
self.marionette.navigate(self.puppeteer.prefs.get_pref('browser.newtab.url'))
def tearDown(self, *args, **kwargs):
self.marionette.set_context('chrome')
@ -98,4 +93,4 @@ class BaseFirefoxTestCase(unittest.TestCase, Puppeteer):
# in a state that is more inconsistent than necessary.
self._check_and_fix_leaked_handles()
finally:
super(BaseFirefoxTestCase, self).tearDown(*args, **kwargs)
super(PuppeteerMixin, self).tearDown(*args, **kwargs)

View File

@ -0,0 +1,84 @@
# 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 decorators import use_class_as_property
class Puppeteer(object):
"""The puppeteer class is used to expose additional API and UI libraries.
Each library can be referenced by its puppeteer name as a member of a
Puppeteer instance. For example, the `current_window` member of the
`Browser` class can be accessed via `puppeteer.browser.current_window`.
"""
def __init__(self, marionette):
self._marionette = marionette
@property
def marionette(self):
return self._marionette
@use_class_as_property('api.appinfo.AppInfo')
def appinfo(self):
"""
Provides access to members of the appinfo api.
See the :class:`~api.appinfo.AppInfo` reference.
"""
@use_class_as_property('api.keys.Keys')
def keys(self):
"""
Provides a definition of control keys to use with keyboard shortcuts.
For example, keys.CONTROL or keys.ALT.
See the :class:`~api.keys.Keys` reference.
"""
@use_class_as_property('api.places.Places')
def places(self):
"""Provides low-level access to several bookmark and history related actions.
See the :class:`~api.places.Places` reference.
"""
@use_class_as_property('api.utils.Utils')
def utils(self):
"""Provides an api for interacting with utility actions.
See the :class:`~api.utils.Utils` reference.
"""
@property
def platform(self):
"""Returns the lowercased platform name.
:returns: Platform name
"""
return self.marionette.session_capabilities['platformName']
@use_class_as_property('api.prefs.Preferences')
def prefs(self):
"""
Provides an api for setting and inspecting preferences, as see in
about:config.
See the :class:`~api.prefs.Preferences` reference.
"""
@use_class_as_property('api.security.Security')
def security(self):
"""
Provides an api for accessing security related properties and helpers.
See the :class:`~api.security.Security` reference.
"""
@use_class_as_property('ui.windows.Windows')
def windows(self):
"""
Provides shortcuts to the top-level windows.
See the :class:`~ui.window.Windows` reference.
"""

View File

@ -1,5 +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 firefox_puppeteer.testcases.base import BaseFirefoxTestCase

View File

@ -27,7 +27,7 @@ class Deck(UIBaseLib):
}
panel = self.element.find_element(By.ID, panel_id)
return mapping.get(panel_id, Panel)(lambda: self.marionette, self.window, panel)
return mapping.get(panel_id, Panel)(self.marionette, self.window, panel)
# Properties for visual elements of the deck #

View File

@ -29,7 +29,7 @@ class AboutWindow(BaseWindow):
self.switch_to()
deck = self.window_element.find_element(By.ID, 'updateDeck')
return Deck(lambda: self.marionette, self, deck)
return Deck(self.marionette, self, deck)
Windows.register_window(AboutWindow.window_type, AboutWindow)

View File

@ -11,12 +11,12 @@ from firefox_puppeteer.ui.windows import BaseWindow
class UIBaseLib(BaseLib):
"""A base class for all UI element wrapper classes inside a chrome window."""
def __init__(self, marionette_getter, window, element):
def __init__(self, marionette, window, element):
assert isinstance(window, BaseWindow)
assert isinstance(element, HTMLElement)
BaseLib.__init__(self, marionette_getter)
BaseLib.__init__(self, marionette)
self._window = window
self._element = element

View File

@ -26,7 +26,7 @@ class TabBar(UIBaseLib):
:returns: :class:`MenuPanel` instance.
"""
return MenuPanel(lambda: self.marionette, self.window)
return MenuPanel(self.marionette, self.window)
@property
def newtab_button(self):
@ -44,7 +44,7 @@ class TabBar(UIBaseLib):
"""
tabs = self.toolbar.find_elements(By.TAG_NAME, 'tab')
return [Tab(lambda: self.marionette, self.window, tab) for tab in tabs]
return [Tab(self.marionette, self.window, tab) for tab in tabs]
@property
def toolbar(self):
@ -206,10 +206,10 @@ class TabBar(UIBaseLib):
class Tab(UIBaseLib):
"""Wraps a tab DOM element."""
def __init__(self, marionette_getter, window, element):
UIBaseLib.__init__(self, marionette_getter, window, element)
def __init__(self, marionette, window, element):
UIBaseLib.__init__(self, marionette, window, element)
self._security = Security(lambda: self.marionette)
self._security = Security(self.marionette)
self._handle = None
# Properties for visual elements of tabs #

View File

@ -49,7 +49,7 @@ class NavBar(UIBaseLib):
"""
if not self._locationbar:
urlbar = self.marionette.find_element(By.ID, 'urlbar')
self._locationbar = LocationBar(lambda: self.marionette, self.window, urlbar)
self._locationbar = LocationBar(self.marionette, self.window, urlbar)
return self._locationbar
@ -88,7 +88,7 @@ class LocationBar(UIBaseLib):
See the :class:`AutocompleteResults` reference."""
if not self._autocomplete_results:
popup = self.marionette.find_element(By.ID, 'PopupAutoCompleteRichResult')
self._autocomplete_results = AutocompleteResults(lambda: self.marionette,
self._autocomplete_results = AutocompleteResults(self.marionette,
self.window, popup)
return self._autocomplete_results
@ -212,7 +212,7 @@ class LocationBar(UIBaseLib):
"""
if not self._identity_popup:
popup = self.marionette.find_element(By.ID, 'identity-popup')
self._identity_popup = IdentityPopup(lambda: self.marionette,
self._identity_popup = IdentityPopup(self.marionette,
self.window, popup)
return self._identity_popup
@ -452,7 +452,7 @@ class IdentityPopup(UIBaseLib):
"""
if not self._view:
view = self.marionette.find_element(By.ID, 'identity-popup-multiView')
self._view = IdentityPopupMultiView(lambda: self.marionette, self.window, view)
self._view = IdentityPopupMultiView(self.marionette, self.window, view)
return self._view
@ -471,7 +471,7 @@ class IdentityPopupMultiView(UIBaseLib):
}
view = self.marionette.find_element(By.ID, view_id)
return mapping.get(view_id, IdentityPopupView)(lambda: self.marionette, self.window, view)
return mapping.get(view_id, IdentityPopupView)(self.marionette, self.window, view)
@property
def main(self):

View File

@ -4,6 +4,7 @@
from marionette_driver import By, Wait
from marionette_driver.errors import NoSuchElementException
from firefox_puppeteer.ui.about_window.window import AboutWindow
from firefox_puppeteer.ui.browser.notifications import (
AddOnInstallBlockedNotification,
@ -79,7 +80,7 @@ class BrowserWindow(BaseWindow):
if not self._navbar:
navbar = self.window_element.find_element(By.ID, 'nav-bar')
self._navbar = NavBar(lambda: self.marionette, self, navbar)
self._navbar = NavBar(self.marionette, self, navbar)
return self._navbar
@ -101,7 +102,7 @@ class BrowserWindow(BaseWindow):
notification_id = notification.get_attribute('id')
return notifications_map.get(notification_id, BaseNotification)(
lambda: self.marionette, self, notification)
self.marionette, self, notification)
except NoSuchElementException:
return None # no notification is displayed
@ -142,7 +143,7 @@ class BrowserWindow(BaseWindow):
if not self._tabbar:
tabbrowser = self.window_element.find_element(By.ID, 'tabbrowser-tabs')
self._tabbar = TabBar(lambda: self.marionette, self, tabbrowser)
self._tabbar = TabBar(self.marionette, self, tabbrowser)
return self._tabbar

View File

@ -25,7 +25,7 @@ class Deck(UIBaseLib):
}
panel = self.element.find_element(By.ID, panel_id)
return mapping.get(panel_id, Panel)(lambda: self.marionette, self.window, panel)
return mapping.get(panel_id, Panel)(self.marionette, self.window, panel)
# Properties for visual elements of the deck #

View File

@ -33,7 +33,7 @@ class PageInfoWindow(BaseWindow):
:returns: Reference to the deck.
"""
deck = self.window_element.find_element(By.ID, 'mainDeck')
return Deck(lambda: self.marionette, self, deck)
return Deck(self.marionette, self, deck)
def close(self, trigger='shortcut', force=False):
"""Closes the current page info window by using the specified trigger.

View File

@ -34,7 +34,7 @@ class UpdateWizardDialog(BaseWindow):
"""
# The deck is also the root element
wizard = self.marionette.find_element(By.ID, 'updates')
return Wizard(lambda: self.marionette, self, wizard)
return Wizard(self.marionette, self, wizard)
def select_next_page(self):
"""Clicks on "Next" button, and waits for the next page to show up."""

View File

@ -42,7 +42,7 @@ class Wizard(UIBaseLib):
}
panel = self.element.find_element(By.ID, panel_id)
return mapping.get(panel_id, Panel)(lambda: self.marionette, self.window, panel)
return mapping.get(panel_id, Panel)(self.marionette, self.window, panel)
# Properties for visual buttons of the wizard #

View File

@ -113,9 +113,9 @@ class Windows(BaseLib):
self.switch_to(current_handle)
if window_type in self.windows_map:
window = self.windows_map[window_type](lambda: self.marionette, handle)
window = self.windows_map[window_type](self.marionette, handle)
else:
window = BaseWindow(lambda: self.marionette, handle)
window = BaseWindow(self.marionette, handle)
if expected_class is not None and type(window) is not expected_class:
raise errors.UnexpectedWindowTypeError('Expected window "%s" but got "%s"' %
@ -213,11 +213,11 @@ class BaseWindow(BaseLib):
dtds = []
properties = []
def __init__(self, marionette_getter, window_handle):
BaseLib.__init__(self, marionette_getter)
self._l10n = L10n(self.get_marionette)
self._prefs = Preferences(self.get_marionette)
self._windows = Windows(self.get_marionette)
def __init__(self, marionette, window_handle):
BaseLib.__init__(self, marionette)
self._l10n = L10n(self.marionette)
self._prefs = Preferences(self.marionette)
self._windows = Windows(self.marionette)
if window_handle not in self.marionette.chrome_window_handles:
raise errors.UnknownWindowError('Window with handle "%s" does not exist' %