summaryrefslogtreecommitdiffstats
path: root/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py')
-rw-r--r--testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py260
1 files changed, 260 insertions, 0 deletions
diff --git a/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py b/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py
new file mode 100644
index 000000000..728a2fd20
--- /dev/null
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py
@@ -0,0 +1,260 @@
+# 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 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,
+ AddOnInstallConfirmationNotification,
+ AddOnInstallCompleteNotification,
+ AddOnInstallFailedNotification,
+ AddOnProgressNotification,
+ BaseNotification)
+from firefox_puppeteer.ui.browser.tabbar import TabBar
+from firefox_puppeteer.ui.browser.toolbars import NavBar
+from firefox_puppeteer.ui.pageinfo.window import PageInfoWindow
+from firefox_puppeteer.ui.windows import BaseWindow, Windows
+
+
+class BrowserWindow(BaseWindow):
+ """Representation of a browser window."""
+
+ window_type = 'navigator:browser'
+
+ dtds = [
+ 'chrome://branding/locale/brand.dtd',
+ 'chrome://browser/locale/aboutPrivateBrowsing.dtd',
+ 'chrome://browser/locale/browser.dtd',
+ 'chrome://browser/locale/netError.dtd',
+ ]
+
+ properties = [
+ 'chrome://branding/locale/brand.properties',
+ 'chrome://branding/locale/browserconfig.properties',
+ 'chrome://browser/locale/browser.properties',
+ 'chrome://browser/locale/preferences/preferences.properties',
+ 'chrome://global/locale/browser.properties',
+ ]
+
+ def __init__(self, *args, **kwargs):
+ super(BrowserWindow, self).__init__(*args, **kwargs)
+
+ self._navbar = None
+ self._tabbar = None
+
+ @property
+ def default_homepage(self):
+ """The default homepage as used by the current locale.
+
+ :returns: The default homepage for the current locale.
+ """
+ return self.marionette.get_pref('browser.startup.homepage',
+ value_type='nsIPrefLocalizedString')
+
+ @property
+ def is_private(self):
+ """Returns True if this is a Private Browsing window."""
+ self.switch_to()
+
+ with self.marionette.using_context('chrome'):
+ return self.marionette.execute_script("""
+ Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+ let chromeWindow = arguments[0].ownerDocument.defaultView;
+ return PrivateBrowsingUtils.isWindowPrivate(chromeWindow);
+ """, script_args=[self.window_element])
+
+ @property
+ def navbar(self):
+ """Provides access to the navigation bar. This is the toolbar containing
+ the back, forward and home buttons. It also contains the location bar.
+
+ See the :class:`~ui.browser.toolbars.NavBar` reference.
+ """
+ self.switch_to()
+
+ if not self._navbar:
+ navbar = self.window_element.find_element(By.ID, 'nav-bar')
+ self._navbar = NavBar(self.marionette, self, navbar)
+
+ return self._navbar
+
+ @property
+ def notification(self):
+ """Provides access to the currently displayed notification."""
+
+ notifications_map = {
+ 'addon-install-blocked-notification': AddOnInstallBlockedNotification,
+ 'addon-install-confirmation-notification': AddOnInstallConfirmationNotification,
+ 'addon-install-complete-notification': AddOnInstallCompleteNotification,
+ 'addon-install-failed-notification': AddOnInstallFailedNotification,
+ 'addon-progress-notification': AddOnProgressNotification,
+ }
+
+ try:
+ notification = self.window_element.find_element(
+ By.CSS_SELECTOR, '#notification-popup popupnotification')
+
+ notification_id = notification.get_attribute('id')
+ return notifications_map.get(notification_id, BaseNotification)(
+ self.marionette, self, notification)
+
+ except NoSuchElementException:
+ return None # no notification is displayed
+
+ def wait_for_notification(self, notification_class=BaseNotification,
+ timeout=5):
+ """Waits for the specified notification to be displayed.
+
+ :param notification_class: Optional, the notification class to wait for.
+ If `None` is specified it will wait for any notification to be closed.
+ Defaults to `BaseNotification`.
+ :param timeout: Optional, how long to wait for the expected notification.
+ Defaults to 5 seconds.
+ """
+ wait = Wait(self.marionette, timeout=timeout)
+
+ if notification_class:
+ if notification_class is BaseNotification:
+ message = 'No notification was shown.'
+ else:
+ message = '{0} was not shown.'.format(notification_class.__name__)
+ wait.until(
+ lambda _: isinstance(self.notification, notification_class),
+ message=message)
+ else:
+ message = 'Unexpected notification shown.'
+ wait.until(
+ lambda _: self.notification is None,
+ message='Unexpected notification shown.')
+
+ @property
+ def tabbar(self):
+ """Provides access to the tab bar.
+
+ See the :class:`~ui.browser.tabbar.TabBar` reference.
+ """
+ self.switch_to()
+
+ if not self._tabbar:
+ tabbrowser = self.window_element.find_element(By.ID, 'tabbrowser-tabs')
+ self._tabbar = TabBar(self.marionette, self, tabbrowser)
+
+ return self._tabbar
+
+ def close(self, trigger='menu', force=False):
+ """Closes the current browser window by using the specified trigger.
+
+ :param trigger: Optional, method to close the current browser window. This can
+ be a string with one of `menu` or `shortcut`, or a callback which gets triggered
+ with the current :class:`BrowserWindow` as parameter. Defaults to `menu`.
+
+ :param force: Optional, forces the closing of the window by using the Gecko API.
+ Defaults to `False`.
+ """
+ def callback(win):
+ # Prepare action which triggers the opening of the browser window
+ if callable(trigger):
+ trigger(win)
+ elif trigger == 'menu':
+ self.menubar.select_by_id('file-menu', 'menu_closeWindow')
+ elif trigger == 'shortcut':
+ win.send_shortcut(win.localize_entity('closeCmd.key'),
+ accel=True, shift=True)
+ else:
+ raise ValueError('Unknown closing method: "%s"' % trigger)
+
+ BaseWindow.close(self, callback, force)
+
+ def get_final_url(self, url):
+ """Loads the page at `url` and returns the resulting url.
+
+ This function enables testing redirects.
+
+ :param url: The url to test.
+ :returns: The resulting loaded url.
+ """
+ with self.marionette.using_context('content'):
+ self.marionette.navigate(url)
+ return self.marionette.get_url()
+
+ def open_browser(self, trigger='menu', is_private=False):
+ """Opens a new browser window by using the specified trigger.
+
+ :param trigger: Optional, method in how to open the new browser window. This can
+ be a string with one of `menu` or `shortcut`, or a callback which gets triggered
+ with the current :class:`BrowserWindow` as parameter. Defaults to `menu`.
+
+ :param is_private: Optional, if True the new window will be a private browsing one.
+
+ :returns: :class:`BrowserWindow` instance for the new browser window.
+ """
+ def callback(win):
+ # Prepare action which triggers the opening of the browser window
+ if callable(trigger):
+ trigger(win)
+ elif trigger == 'menu':
+ menu_id = 'menu_newPrivateWindow' if is_private else 'menu_newNavigator'
+ self.menubar.select_by_id('file-menu', menu_id)
+ elif trigger == 'shortcut':
+ cmd_key = 'privateBrowsingCmd.commandkey' if is_private else 'newNavigatorCmd.key'
+ win.send_shortcut(win.localize_entity(cmd_key),
+ accel=True, shift=is_private)
+ else:
+ raise ValueError('Unknown opening method: "%s"' % trigger)
+
+ return BaseWindow.open_window(self, callback, BrowserWindow)
+
+ def open_about_window(self, trigger='menu'):
+ """Opens the about window by using the specified trigger.
+
+ :param trigger: Optional, method in how to open the new browser window. This can
+ either the string `menu` or a callback which gets triggered
+ with the current :class:`BrowserWindow` as parameter. Defaults to `menu`.
+
+ :returns: :class:`AboutWindow` instance of the opened window.
+ """
+ def callback(win):
+ # Prepare action which triggers the opening of the browser window
+ if callable(trigger):
+ trigger(win)
+ elif trigger == 'menu':
+ self.menubar.select_by_id('helpMenu', 'aboutName')
+ else:
+ raise ValueError('Unknown opening method: "%s"' % trigger)
+
+ return BaseWindow.open_window(self, callback, AboutWindow)
+
+ def open_page_info_window(self, trigger='menu'):
+ """Opens the page info window by using the specified trigger.
+
+ :param trigger: Optional, method in how to open the new browser window. This can
+ be a string with one of `menu` or `shortcut`, or a callback which gets triggered
+ with the current :class:`BrowserWindow` as parameter. Defaults to `menu`.
+
+ :returns: :class:`PageInfoWindow` instance of the opened window.
+ """
+ def callback(win):
+ # Prepare action which triggers the opening of the browser window
+ if callable(trigger):
+ trigger(win)
+ elif trigger == 'menu':
+ self.menubar.select_by_id('tools-menu', 'menu_pageInfo')
+ elif trigger == 'shortcut':
+ if win.marionette.session_capabilities['platformName'] == 'windows_nt':
+ raise ValueError('Page info shortcut not available on Windows.')
+ win.send_shortcut(win.localize_entity('pageInfoCmd.commandkey'),
+ accel=True)
+ elif trigger == 'context_menu':
+ # TODO: Add once we can do right clicks
+ pass
+ else:
+ raise ValueError('Unknown opening method: "%s"' % trigger)
+
+ return BaseWindow.open_window(self, callback, PageInfoWindow)
+
+
+Windows.register_window(BrowserWindow.window_type, BrowserWindow)