import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1 @@
var testAnotherFunc = function() { return "i'm yet another test function!";};

View file

@ -0,0 +1 @@
var testFunc = function() { return "i'm a test function!";};

View file

@ -0,0 +1,131 @@
from marionette_driver.marionette import Actions
from marionette_driver.errors import TimeoutException
from marionette_driver.by import By
def wait_for_condition_else_raise(marionette, wait_for_condition, expected, script):
try:
wait_for_condition(lambda m: expected in m.execute_script(script))
except TimeoutException as e:
raise TimeoutException("{0} got {1} instead of {2}".format(
e.message, marionette.execute_script(script), expected))
def press_release(marionette, times, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
action = Actions(marionette)
button = marionette.find_element(By.ID, "button1")
action.press(button).release()
# Insert wait between each press and release chain.
for _ in range(times-1):
action.wait(0.1)
action.press(button).release()
action.perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def move_element(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
ele = marionette.find_element(By.ID, "button1")
drop = marionette.find_element(By.ID, "button2")
action = Actions(marionette)
action.press(ele).move(drop).release()
action.perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected1, "return document.getElementById('button1').innerHTML;")
wait_for_condition_else_raise(marionette, wait_for_condition, expected2, "return document.getElementById('button2').innerHTML;")
def move_element_offset(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
ele = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.press(ele).move_by_offset(0,150).move_by_offset(0, 150).release()
action.perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected1, "return document.getElementById('button1').innerHTML;")
wait_for_condition_else_raise(marionette, wait_for_condition, expected2, "return document.getElementById('button2').innerHTML;")
def chain(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
marionette.timeout.implicit = 15
action = Actions(marionette)
button1 = marionette.find_element(By.ID, "button1")
action.press(button1).perform()
button2 = marionette.find_element(By.ID, "delayed")
wait_for_condition_else_raise(marionette, wait_for_condition, expected1, "return document.getElementById('button1').innerHTML;")
action.move(button2).release().perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected2, "return document.getElementById('delayed').innerHTML;")
def chain_flick(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.flick(button, 0, 0, 0, 200).perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected1,"return document.getElementById('button1').innerHTML;")
wait_for_condition_else_raise(marionette, wait_for_condition, expected2,"return document.getElementById('buttonFlick').innerHTML;")
def wait(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
action = Actions(marionette)
button = marionette.find_element(By.ID, "button1")
action.press(button).wait().release().perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def wait_with_value(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.press(button).wait(0.01).release()
action.perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def context_menu(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.press(button).wait(5).perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected1, "return document.getElementById('button1').innerHTML;")
action.release().perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected2, "return document.getElementById('button1').innerHTML;")
def long_press_action(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.long_press(button, 5).perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def long_press_on_xy_action(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
html = marionette.find_element(By.TAG_NAME, "html")
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
# Press the center of the button with respect to html.
x = button.rect['x'] + button.rect['width'] / 2.0
y = button.rect['y'] + button.rect['height'] / 2.0
action.long_press(html, 5, x, y).perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def single_tap(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.tap(button).perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def double_tap(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element(By.ID, "button1")
action = Actions(marionette)
action.double_tap(button).perform()
wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")

View file

@ -0,0 +1,134 @@
# 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.keys import Keys
from marionette_harness import MarionetteTestCase, skip, skip_if_mobile, WindowManagerMixin
class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestAboutPages, self).setUp()
if self.marionette.session_capabilities['platformName'] == 'darwin':
self.mod_key = Keys.META
else:
self.mod_key = Keys.CONTROL
self.remote_uri = self.marionette.absolute_url("windowHandles.html")
def tearDown(self):
self.close_all_tabs()
super(TestAboutPages, self).tearDown()
def open_tab_with_link(self):
with self.marionette.using_context("content"):
self.marionette.navigate(self.remote_uri)
link = self.marionette.find_element(By.ID, "new-tab")
link.click()
@skip_if_mobile("Bug 1333209 - Process killed because of connection loss")
def test_back_forward(self):
# Bug 1311041 - Prevent changing of window handle by forcing the test
# to be run in a new tab.
new_tab = self.open_tab(trigger=self.open_tab_with_link)
self.marionette.switch_to_window(new_tab)
self.marionette.navigate("about:blank")
self.marionette.navigate(self.remote_uri)
self.marionette.navigate("about:support")
self.marionette.go_back()
self.assertEqual(self.marionette.get_url(), self.remote_uri)
self.marionette.go_forward()
self.assertEqual(self.marionette.get_url(), "about:support")
self.marionette.close()
self.marionette.switch_to_window(self.start_tab)
@skip_if_mobile("Bug 1333209 - Process killed because of connection loss")
def test_navigate_non_remote_about_pages(self):
# Bug 1311041 - Prevent changing of window handle by forcing the test
# to be run in a new tab.
new_tab = self.open_tab(trigger=self.open_tab_with_link)
self.marionette.switch_to_window(new_tab)
self.marionette.navigate("about:blank")
self.assertEqual(self.marionette.get_url(), "about:blank")
self.marionette.navigate("about:support")
self.assertEqual(self.marionette.get_url(), "about:support")
self.marionette.close()
self.marionette.switch_to_window(self.start_tab)
@skip_if_mobile("On Android no shortcuts are available")
def test_navigate_shortcut_key(self):
def open_with_shortcut():
self.marionette.navigate(self.remote_uri)
with self.marionette.using_context("chrome"):
main_win = self.marionette.find_element(By.ID, "main-window")
main_win.send_keys(self.mod_key, Keys.SHIFT, 'a')
new_tab = self.open_tab(trigger=open_with_shortcut)
self.marionette.switch_to_window(new_tab)
Wait(self.marionette).until(lambda mn: mn.get_url() == "about:addons",
message="'about:addons' hasn't been loaded")
self.marionette.close()
self.marionette.switch_to_window(self.start_tab)
@skip("Bug 1334137 - Intermittent: Process killed because of hang in getCurrentUrl()")
@skip_if_mobile("Interacting with chrome elements not available for Fennec")
def test_type_to_non_remote_tab(self):
# Bug 1311041 - Prevent changing of window handle by forcing the test
# to be run in a new tab.
new_tab = self.open_tab(trigger=self.open_tab_with_link)
self.marionette.switch_to_window(new_tab)
with self.marionette.using_context("chrome"):
urlbar = self.marionette.find_element(By.ID, 'urlbar')
urlbar.send_keys(self.mod_key + 'a')
urlbar.send_keys(self.mod_key + 'x')
urlbar.send_keys('about:support' + Keys.ENTER)
Wait(self.marionette).until(lambda mn: mn.get_url() == "about:support",
message="'about:support' hasn't been loaded")
self.marionette.close()
self.marionette.switch_to_window(self.start_tab)
@skip_if_mobile("Interacting with chrome elements not available for Fennec")
def test_type_to_remote_tab(self):
# Bug 1311041 - Prevent changing of window handle by forcing the test
# to be run in a new tab.
new_tab = self.open_tab(trigger=self.open_tab_with_link)
self.marionette.switch_to_window(new_tab)
# about:blank keeps remoteness from remote_uri
self.marionette.navigate("about:blank")
with self.marionette.using_context("chrome"):
urlbar = self.marionette.find_element(By.ID, 'urlbar')
urlbar.send_keys(self.mod_key + 'a')
urlbar.send_keys(self.mod_key + 'x')
urlbar.send_keys(self.remote_uri + Keys.ENTER)
Wait(self.marionette).until(lambda mn: mn.get_url() == self.remote_uri,
message="'{}' hasn't been loaded".format(self.remote_uri))
@skip_if_mobile("Needs application independent method to open a new tab")
def test_hang(self):
# Bug 1311041 - Prevent changing of window handle by forcing the test
# to be run in a new tab.
new_tab = self.open_tab(trigger=self.open_tab_with_link)
# Close the start tab
self.marionette.close()
self.marionette.switch_to_window(new_tab)
self.marionette.navigate(self.remote_uri)

View file

@ -0,0 +1,210 @@
# 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.by import By
from marionette_driver.errors import (
ElementNotAccessibleException,
ElementNotInteractableException
)
from marionette_harness import MarionetteTestCase
class TestAccessibility(MarionetteTestCase):
def setUp(self):
super(TestAccessibility, self).setUp()
with self.marionette.using_context("chrome"):
self.marionette.set_pref("dom.ipc.processCount", 1)
def tearDown(self):
with self.marionette.using_context("chrome"):
self.marionette.clear_pref("dom.ipc.processCount")
# Elements that are accessible with and without the accessibliity API
valid_elementIDs = [
# Button1 is an accessible button with a valid accessible name
# computed from subtree
"button1",
# Button2 is an accessible button with a valid accessible name
# computed from aria-label
"button2",
# Button13 is an accessible button that is implemented via role="button"
# and is explorable using tabindex="0"
"button13",
# button17 is an accessible button that overrides parent's
# pointer-events:none; property with its own pointer-events:all;
"button17"
]
# Elements that are not accessible with the accessibility API
invalid_elementIDs = [
# Button3 does not have an accessible object
"button3",
# Button4 does not support any accessible actions
"button4",
# Button5 does not have a correct accessibility role and may not be
# manipulated via the accessibility API
"button5",
# Button6 is missing an accesible name
"button6",
# Button7 is not currently visible via the accessibility API and may
# not be manipulated by it
"button7",
# Button8 is not currently visible via the accessibility API and may
# not be manipulated by it (in hidden subtree)
"button8",
# Button14 is accessible button but is not explorable because of lack
# of tabindex that would make it focusable.
"button14"
]
# Elements that are either accessible to accessibility API or not accessible
# at all
falsy_elements = [
# Element is only visible to the accessibility API and may be
# manipulated by it
"button9",
# Element is not currently visible
"button10"
]
displayed_elementIDs = [
"button1", "button2", "button3", "button4", "button5", "button6",
"button9", "no_accessible_but_displayed"
]
displayed_but_a11y_hidden_elementIDs = ["button7", "button8"]
disabled_elementIDs = ["button11", "no_accessible_but_disabled"]
# Elements that are enabled but otherwise disabled or not explorable via the accessibility API
disabled_accessibility_elementIDs = ["button12", "button15", "button16"]
# Elements that are reporting selected state
valid_option_elementIDs = ["option1", "option2"]
def run_element_test(self, ids, testFn):
for id in ids:
element = self.marionette.find_element(By.ID, id)
testFn(element)
def setup_accessibility(self, enable_a11y_checks=True, navigate=True):
self.marionette.delete_session()
self.marionette.start_session(
{"requiredCapabilities": {"moz:accessibilityChecks": enable_a11y_checks}})
self.assertEqual(
self.marionette.session_capabilities["moz:accessibilityChecks"],
enable_a11y_checks)
# Navigate to test_accessibility.html
if navigate:
test_accessibility = self.marionette.absolute_url("test_accessibility.html")
self.marionette.navigate(test_accessibility)
def test_valid_single_tap(self):
self.setup_accessibility()
# No exception should be raised
self.run_element_test(self.valid_elementIDs, lambda button: button.tap())
def test_single_tap_raises_element_not_accessible(self):
self.setup_accessibility()
self.run_element_test(self.invalid_elementIDs,
lambda button: self.assertRaises(ElementNotAccessibleException,
button.tap))
self.run_element_test(self.falsy_elements,
lambda button: self.assertRaises(ElementNotInteractableException,
button.tap))
def test_single_tap_raises_no_exceptions(self):
self.setup_accessibility(False, True)
# No exception should be raised
self.run_element_test(self.invalid_elementIDs, lambda button: button.tap())
# Elements are invisible
self.run_element_test(self.falsy_elements,
lambda button: self.assertRaises(ElementNotInteractableException,
button.tap))
def test_valid_click(self):
self.setup_accessibility()
# No exception should be raised
self.run_element_test(self.valid_elementIDs, lambda button: button.click())
def test_click_raises_element_not_accessible(self):
self.setup_accessibility()
self.run_element_test(self.invalid_elementIDs,
lambda button: self.assertRaises(ElementNotAccessibleException,
button.click))
self.run_element_test(self.falsy_elements,
lambda button: self.assertRaises(ElementNotInteractableException,
button.click))
def test_click_raises_no_exceptions(self):
self.setup_accessibility(False, True)
# No exception should be raised
self.run_element_test(self.invalid_elementIDs, lambda button: button.click())
# Elements are invisible
self.run_element_test(self.falsy_elements,
lambda button: self.assertRaises(ElementNotInteractableException,
button.click))
def test_element_visible_but_not_visible_to_accessbility(self):
self.setup_accessibility()
# Elements are displayed but hidden from accessibility API
self.run_element_test(self.displayed_but_a11y_hidden_elementIDs,
lambda element: self.assertRaises(ElementNotAccessibleException,
element.is_displayed))
def test_element_is_visible_to_accessibility(self):
self.setup_accessibility()
# No exception should be raised
self.run_element_test(self.displayed_elementIDs, lambda element: element.is_displayed())
def test_element_is_not_enabled_to_accessbility(self):
self.setup_accessibility()
# Buttons are enabled but disabled/not-explorable via the accessibility API
self.run_element_test(self.disabled_accessibility_elementIDs,
lambda element: self.assertRaises(ElementNotAccessibleException,
element.is_enabled))
# Buttons are enabled but disabled/not-explorable via the accessibility API and thus are not
# clickable via the accessibility API
self.run_element_test(self.disabled_accessibility_elementIDs,
lambda element: self.assertRaises(ElementNotAccessibleException,
element.click))
self.setup_accessibility(False, False)
self.run_element_test(self.disabled_accessibility_elementIDs,
lambda element: element.is_enabled())
self.run_element_test(self.disabled_accessibility_elementIDs,
lambda element: element.click())
def test_element_is_enabled_to_accessibility(self):
self.setup_accessibility()
# No exception should be raised
self.run_element_test(self.disabled_elementIDs, lambda element: element.is_enabled())
def test_send_keys_raises_no_exception(self):
self.setup_accessibility()
# Sending keys to valid input should not raise any exceptions
self.run_element_test(['input1'], lambda element: element.send_keys("a"))
self.setup_accessibility(False, False)
# Sending keys to invalid element should not raise any exceptions when raising accessibility
# exceptions is disabled
self.run_element_test(['button5'], lambda element: element.send_keys("abc"))
def test_send_keys_raises_element_not_accessible(self):
self.setup_accessibility()
# Sending keys to invalid element should raise an exception
self.run_element_test(['button5'],
lambda element: self.assertRaises(ElementNotAccessibleException,
element.send_keys))
def test_is_selected_raises_no_exception(self):
self.setup_accessibility()
# No exception should be raised for valid options
self.run_element_test(self.valid_option_elementIDs, lambda element: element.is_selected())
# No exception should be raised for non-selectable elements
self.run_element_test(self.valid_elementIDs, lambda element: element.is_selected())

View file

@ -0,0 +1,58 @@
# 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 marionette_driver.addons import Addons, AddonInstallException
from marionette_harness import MarionetteTestCase, skip
here = os.path.abspath(os.path.dirname(__file__))
class TestAddons(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.addons = Addons(self.marionette)
@property
def all_addon_ids(self):
with self.marionette.using_context('chrome'):
addons = self.marionette.execute_async_script("""
Components.utils.import("resource://gre/modules/AddonManager.jsm");
AddonManager.getAllAddons(function(addons){
let ids = addons.map(function(x) {
return x.id;
});
marionetteScriptFinished(ids);
});
""")
return addons
def test_install_and_remove_temporary_unsigned_addon(self):
addon_path = os.path.join(here, 'mn-restartless-unsigned.xpi')
addon_id = self.addons.install(addon_path, temp=True)
self.assertIn(addon_id, self.all_addon_ids)
self.addons.uninstall(addon_id)
self.assertNotIn(addon_id, self.all_addon_ids)
def test_install_unsigned_addon(self):
addon_path = os.path.join(here, 'mn-restartless-unsigned.xpi')
with self.assertRaises(AddonInstallException):
self.addons.install(addon_path)
@skip("Need to get the test extension signed")
def test_install_and_remove_signed_addon(self):
addon_path = os.path.join(here, 'mn-restartless-signed.xpi')
addon_id = self.addons.install(addon_path)
self.assertIn(addon_id, self.all_addon_ids)
self.addons.uninstall(addon_id)
self.assertNotIn(addon_id, self.all_addon_ids)

View file

@ -0,0 +1,90 @@
# 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.by import By
from marionette_driver.errors import NoSuchElementException
from marionette_driver.marionette import HTMLElement
from marionette_harness import MarionetteTestCase, WindowManagerMixin
class TestAnonymousNodes(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestAnonymousNodes, self).setUp()
self.marionette.set_context("chrome")
def open_window_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test_anonymous_content.xul',
'foo', 'chrome,centerscreen');
""")
new_window = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(new_window)
def tearDown(self):
self.close_all_windows()
super(TestAnonymousNodes, self).tearDown()
def test_switch_to_anonymous_frame(self):
self.marionette.find_element(By.ID, "testAnonymousContentBox")
anon_browser_el = self.marionette.find_element(By.ID, "browser")
self.assertTrue("test_anonymous_content.xul" in self.marionette.get_url())
self.marionette.switch_to_frame(anon_browser_el)
self.assertTrue("test.xul" in self.marionette.get_url())
self.marionette.find_element(By.ID, "testXulBox")
self.assertRaises(NoSuchElementException,
self.marionette.find_element, By.ID, "testAnonymousContentBox")
def test_switch_to_anonymous_iframe(self):
self.marionette.find_element(By.ID, "testAnonymousContentBox")
el = self.marionette.find_element(By.ID, "container2")
anon_iframe_el = el.find_element(By.ANON_ATTRIBUTE, {"anonid": "iframe"})
self.marionette.switch_to_frame(anon_iframe_el)
self.assertTrue("test.xul" in self.marionette.get_url())
self.marionette.find_element(By.ID, "testXulBox")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID,
"testAnonymousContentBox")
def test_find_anonymous_element_by_attribute(self):
accept_button = (By.ANON_ATTRIBUTE, {"dlgtype": "accept"},)
not_existent = (By.ANON_ATTRIBUTE, {"anonid": "notexistent"},)
# By using the window document element
start_node = self.marionette.find_element(By.CSS_SELECTOR, ":root")
button = start_node.find_element(*accept_button)
self.assertEquals(HTMLElement, type(button))
with self.assertRaises(NoSuchElementException):
start_node.find_element(*not_existent)
# By using the default start node
self.assertEquals(button, self.marionette.find_element(*accept_button))
with self.assertRaises(NoSuchElementException):
self.marionette.find_element(*not_existent)
def test_find_anonymous_elements_by_attribute(self):
dialog_buttons = (By.ANON_ATTRIBUTE, {"anonid": "buttons"},)
not_existent = (By.ANON_ATTRIBUTE, {"anonid": "notexistent"},)
# By using the window document element
start_node = self.marionette.find_element(By.CSS_SELECTOR, ":root")
buttons = start_node.find_elements(*dialog_buttons)
self.assertEquals(1, len(buttons))
self.assertEquals(HTMLElement, type(buttons[0]))
self.assertListEqual([], start_node.find_elements(*not_existent))
# By using the default start node
self.assertListEqual(buttons, self.marionette.find_elements(*dialog_buttons))
self.assertListEqual([], self.marionette.find_elements(*not_existent))
def test_find_anonymous_children(self):
self.assertEquals(HTMLElement, type(self.marionette.find_element(By.ANON, None)))
self.assertEquals(2, len(self.marionette.find_elements(By.ANON, None)))
frame = self.marionette.find_element(By.ID, "framebox")
with self.assertRaises(NoSuchElementException):
frame.find_element(By.ANON, None)
self.assertListEqual([], frame.find_elements(By.ANON, None))

View file

@ -0,0 +1,34 @@
import datetime
from marionette_harness.runner import BrowserMobTestCase
class TestBrowserMobProxy(BrowserMobTestCase):
"""To run this test, you'll need to download the browsermob-proxy from
http://bmp.lightbody.net/, and then pass the path to the startup
script (typically /path/to/browsermob-proxy-2.0.0/bin/browsermob-proxy)
as the --browsermob-script argument when running runtests.py.
You can additionally pass --browsermob-port to specify the port that
the proxy will run on; it defaults to 8080.
This test is NOT run in CI, as bmp and dependencies aren't available
there.
"""
def test_browsermob_proxy_limits(self):
"""This illustrates the use of download limits in the proxy,
and verifies that it's slower to load a page @100kbps
than it is to download the same page @1000kbps.
"""
proxy = self.create_browsermob_proxy()
proxy.limits({'downstream_kbps': 1000})
time1 = datetime.datetime.now()
self.marionette.navigate('http://forecast.weather.gov')
time2 = datetime.datetime.now()
proxy.limits({'downstream_kbps': 100})
time3 = datetime.datetime.now()
self.marionette.refresh()
time4 = datetime.datetime.now()
self.assertTrue(time4 - time3 > time2 - time1,
"page load @ 100kbps not slower than page load @ 1000kbps")

View file

@ -0,0 +1,253 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import SessionNotCreatedException
from marionette_harness import MarionetteTestCase
class TestCapabilities(MarionetteTestCase):
def setUp(self):
super(TestCapabilities, self).setUp()
self.caps = self.marionette.session_capabilities
with self.marionette.using_context("chrome"):
self.appinfo = self.marionette.execute_script(
"return Services.appinfo")
self.os_name = self.marionette.execute_script(
"return Services.sysinfo.getProperty('name')").lower()
self.os_version = self.marionette.execute_script(
"return Services.sysinfo.getProperty('version')")
def test_mandated_capabilities(self):
self.assertIn("browserName", self.caps)
self.assertIn("browserVersion", self.caps)
self.assertIn("platformName", self.caps)
self.assertIn("platformVersion", self.caps)
self.assertIn("acceptInsecureCerts", self.caps)
self.assertIn("timeouts", self.caps)
self.assertEqual(self.caps["browserName"], self.appinfo["name"].lower())
self.assertEqual(self.caps["browserVersion"], self.appinfo["version"])
self.assertEqual(self.caps["platformName"], self.os_name)
self.assertEqual(self.caps["platformVersion"], self.os_version)
self.assertFalse(self.caps["acceptInsecureCerts"])
self.assertDictEqual(self.caps["timeouts"],
{"implicit": 0,
"page load": 300000,
"script": 30000})
def test_supported_features(self):
self.assertIn("rotatable", self.caps)
def test_additional_capabilities(self):
self.assertIn("moz:processID", self.caps)
self.assertEqual(self.caps["moz:processID"], self.appinfo["processID"])
self.assertEqual(self.marionette.process_id, self.appinfo["processID"])
self.assertIn("moz:profile", self.caps)
if self.marionette.instance is not None:
if self.caps["browserName"] == "fennec":
current_profile = self.marionette.instance.runner.device.app_ctx.remote_profile
else:
current_profile = self.marionette.instance.runner.profile.profile
self.assertEqual(self.caps["moz:profile"], current_profile)
self.assertEqual(self.marionette.profile, current_profile)
self.assertIn("moz:accessibilityChecks", self.caps)
self.assertFalse(self.caps["moz:accessibilityChecks"])
self.assertIn("specificationLevel", self.caps)
self.assertEqual(self.caps["specificationLevel"], 0)
def test_set_specification_level(self):
self.marionette.delete_session()
self.marionette.start_session({"desiredCapabilities": {"specificationLevel": 2}})
caps = self.marionette.session_capabilities
self.assertEqual(2, caps["specificationLevel"])
self.marionette.delete_session()
self.marionette.start_session({"requiredCapabilities": {"specificationLevel": 3}})
caps = self.marionette.session_capabilities
self.assertEqual(3, caps["specificationLevel"])
def test_we_can_pass_in_required_capabilities_on_session_start(self):
self.marionette.delete_session()
capabilities = {"requiredCapabilities": {"browserName": self.appinfo["name"].lower()}}
self.marionette.start_session(capabilities)
caps = self.marionette.session_capabilities
self.assertIn("browserName", caps)
# Start a new session just to make sure we leave the browser in the
# same state it was before it started the test
self.marionette.start_session()
def test_capability_types(self):
for value in ["", "invalid", True, 42, []]:
print("testing value {}".format(value))
with self.assertRaises(SessionNotCreatedException):
print(" with desiredCapabilities")
self.marionette.delete_session()
self.marionette.start_session({"desiredCapabilities": value})
with self.assertRaises(SessionNotCreatedException):
print(" with requiredCapabilities")
self.marionette.delete_session()
self.marionette.start_session({"requiredCapabilities": value})
def test_we_get_valid_uuid4_when_creating_a_session(self):
self.assertNotIn("{", self.marionette.session_id,
"Session ID has {{}} in it: {}".format(
self.marionette.session_id))
class TestCapabilityMatching(MarionetteTestCase):
allowed = [None, "*"]
disallowed = ["", 42, True, {}, []]
def setUp(self):
MarionetteTestCase.setUp(self)
self.browser_name = self.marionette.session_capabilities["browserName"]
self.platform_name = self.marionette.session_capabilities["platformName"]
self.delete_session()
def delete_session(self):
if self.marionette.session is not None:
self.marionette.delete_session()
def test_browser_name_desired(self):
self.marionette.start_session({"desiredCapabilities": {"browserName": self.browser_name}})
self.assertEqual(self.marionette.session_capabilities["browserName"], self.browser_name)
def test_browser_name_required(self):
self.marionette.start_session({"requiredCapabilities": {"browserName": self.browser_name}})
self.assertEqual(self.marionette.session_capabilities["browserName"], self.browser_name)
def test_browser_name_desired_allowed_types(self):
for typ in self.allowed:
self.delete_session()
self.marionette.start_session({"desiredCapabilities": {"browserName": typ}})
self.assertEqual(self.marionette.session_capabilities["browserName"], self.browser_name)
def test_browser_name_desired_disallowed_types(self):
for typ in self.disallowed:
with self.assertRaises(SessionNotCreatedException):
self.marionette.start_session({"desiredCapabilities": {"browserName": typ}})
def test_browser_name_required_allowed_types(self):
for typ in self.allowed:
self.delete_session()
self.marionette.start_session({"requiredCapabilities": {"browserName": typ}})
self.assertEqual(self.marionette.session_capabilities["browserName"], self.browser_name)
def test_browser_name_requried_disallowed_types(self):
for typ in self.disallowed:
with self.assertRaises(SessionNotCreatedException):
self.marionette.start_session({"requiredCapabilities": {"browserName": typ}})
def test_browser_name_prefers_required(self):
caps = {"desiredCapabilities": {"browserName": "invalid"},
"requiredCapabilities": {"browserName": "*"}}
self.marionette.start_session(caps)
def test_browser_name_error_on_invalid_required(self):
with self.assertRaises(SessionNotCreatedException):
caps = {"desiredCapabilities": {"browserName": "*"},
"requiredCapabilities": {"browserName": "invalid"}}
self.marionette.start_session(caps)
# TODO(ato): browser version comparison not implemented yet
def test_platform_name_desired(self):
self.marionette.start_session({"desiredCapabilities": {"platformName": self.platform_name}})
self.assertEqual(self.marionette.session_capabilities["platformName"], self.platform_name)
def test_platform_name_required(self):
self.marionette.start_session({"requiredCapabilities": {"platformName": self.platform_name}})
self.assertEqual(self.marionette.session_capabilities["platformName"], self.platform_name)
def test_platform_name_desired_allowed_types(self):
for typ in self.allowed:
self.delete_session()
self.marionette.start_session({"desiredCapabilities": {"platformName": typ}})
self.assertEqual(self.marionette.session_capabilities["platformName"], self.platform_name)
def test_platform_name_desired_disallowed_types(self):
for typ in self.disallowed:
with self.assertRaises(SessionNotCreatedException):
self.marionette.start_session({"desiredCapabilities": {"platformName": typ}})
def test_platform_name_required_allowed_types(self):
for typ in self.allowed:
self.delete_session()
self.marionette.start_session({"requiredCapabilities": {"platformName": typ}})
self.assertEqual(self.marionette.session_capabilities["platformName"], self.platform_name)
def test_platform_name_requried_disallowed_types(self):
for typ in self.disallowed:
with self.assertRaises(SessionNotCreatedException):
self.marionette.start_session({"requiredCapabilities": {"platformName": typ}})
def test_platform_name_prefers_required(self):
caps = {"desiredCapabilities": {"platformName": "invalid"},
"requiredCapabilities": {"platformName": "*"}}
self.marionette.start_session(caps)
def test_platform_name_error_on_invalid_required(self):
with self.assertRaises(SessionNotCreatedException):
caps = {"desiredCapabilities": {"platformName": "*"},
"requiredCapabilities": {"platformName": "invalid"}}
self.marionette.start_session(caps)
# TODO(ato): platform version comparison not imlpemented yet
def test_accept_insecure_certs(self):
for capability_type in ["desiredCapabilities", "requiredCapabilities"]:
print("testing {}".format(capability_type))
for value in ["", 42, {}, []]:
print(" type {}".format(type(value)))
with self.assertRaises(SessionNotCreatedException):
self.marionette.start_session({capability_type: {"acceptInsecureCerts": value}})
self.delete_session()
self.marionette.start_session({"desiredCapabilities": {"acceptInsecureCerts": True}})
self.assertTrue(self.marionette.session_capabilities["acceptInsecureCerts"])
self.delete_session()
self.marionette.start_session({"requiredCapabilities": {"acceptInsecureCerts": True}})
self.assertTrue(self.marionette.session_capabilities["acceptInsecureCerts"])
def test_page_load_strategy(self):
for strategy in ["none", "eager", "normal"]:
print("valid strategy {}".format(strategy))
self.delete_session()
self.marionette.start_session({"desiredCapabilities": {"pageLoadStrategy": strategy}})
self.assertEqual(self.marionette.session_capabilities["pageLoadStrategy"], strategy)
for value in ["", "EAGER", True, 42, {}, []]:
print("invalid strategy {}".format(value))
with self.assertRaises(SessionNotCreatedException):
self.marionette.start_session({"desiredCapabilities": {"pageLoadStrategy": value}})
def test_proxy_default(self):
self.marionette.start_session()
self.assertNotIn("proxy", self.marionette.session_capabilities)
def test_proxy_desired(self):
self.marionette.start_session({"desiredCapabilities": {"proxy": {"proxyType": "manual"}}})
self.assertIn("proxy", self.marionette.session_capabilities)
self.assertEqual(self.marionette.session_capabilities["proxy"]["proxyType"], "manual")
self.assertEqual(self.marionette.get_pref("network.proxy.type"), 1)
def test_proxy_required(self):
self.marionette.start_session({"requiredCapabilities": {"proxy": {"proxyType": "manual"}}})
self.assertIn("proxy", self.marionette.session_capabilities)
self.assertEqual(self.marionette.session_capabilities["proxy"]["proxyType"], "manual")
self.assertEqual(self.marionette.get_pref("network.proxy.type"), 1)
def test_timeouts(self):
timeouts = {u"implicit": 123, u"page load": 456, u"script": 789}
caps = {"desiredCapabilities": {"timeouts": timeouts}}
self.marionette.start_session(caps)
self.assertIn("timeouts", self.marionette.session_capabilities)
self.assertDictEqual(self.marionette.session_capabilities["timeouts"], timeouts)
self.assertDictEqual(self.marionette._send_message("getTimeouts"), timeouts)

View file

@ -0,0 +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_driver.by import By
from marionette_harness import MarionetteTestCase
class TestCheckbox(MarionetteTestCase):
def test_selected(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
box = self.marionette.find_element(By.NAME, "myCheckBox")
self.assertFalse(box.is_selected())
box.click()
self.assertTrue(box.is_selected())

View file

@ -0,0 +1,36 @@
# 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.by import By
from marionette_harness import MarionetteTestCase, WindowManagerMixin
class TestSelectedChrome(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestSelectedChrome, self).setUp()
self.marionette.set_context("chrome")
def open_window_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test.xul',
'_blank', 'chrome,centerscreen');
""")
new_window = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(new_window)
def tearDown(self):
try:
self.close_all_windows()
finally:
super(TestSelectedChrome, self).tearDown()
def test_selected(self):
box = self.marionette.find_element(By.ID, "testBox")
self.assertFalse(box.is_selected())
self.assertFalse(self.marionette.execute_script("arguments[0].checked = true;", [box]))
self.assertTrue(box.is_selected())

View file

@ -0,0 +1,51 @@
#Copyright 2007-2009 WebDriver committers
#Copyright 2007-2009 Google Inc.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from marionette_driver import By
from marionette_harness import MarionetteTestCase, WindowManagerMixin
class ChromeTests(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(ChromeTests, self).setUp()
self.marionette.set_context('chrome')
def tearDown(self):
self.close_all_windows()
super(ChromeTests, self).tearDown()
def test_hang_until_timeout(self):
def open_with_menu():
menu = self.marionette.find_element(By.ID, 'aboutName')
menu.click()
new_window = self.open_window(trigger=open_with_menu)
self.marionette.switch_to_window(new_window)
try:
try:
# Raise an exception type which should not be thrown by Marionette
# while running this test. Otherwise it would mask eg. IOError as
# thrown for a socket timeout.
raise NotImplementedError('Exception should not cause a hang when '
'closing the chrome window')
finally:
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
except NotImplementedError:
pass

View file

@ -0,0 +1,6 @@
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_CONTEXT = "chrome";
ok(true);
(function () {
finish();
})();

View file

@ -0,0 +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 marionette_driver.by import By
from marionette_harness import MarionetteTestCase
class TestChromeElementCSS(MarionetteTestCase):
def test_we_can_get_css_value_on_chrome_element(self):
self.marionette.navigate("about:blank")
with self.marionette.using_context("chrome"):
element = self.marionette.find_element(By.ID, "identity-icon")
favicon_image = element.value_of_css_property("list-style-image")
self.assertIn("identity-icon.svg", favicon_image)
element = self.marionette.find_element(By.ID, "identity-box")
background_colour = element.value_of_css_property("background-color")
self.assertEqual("transparent", background_colour)

View file

@ -0,0 +1,72 @@
# 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.by import By
from marionette_driver.errors import InvalidElementStateException
from marionette_harness import MarionetteTestCase
class TestClear(MarionetteTestCase):
def testWriteableTextInputShouldClear(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "writableTextInput")
element.clear()
self.assertEqual("", element.get_property("value"))
def testTextInputShouldNotClearWhenReadOnly(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID,"readOnlyTextInput")
try:
element.clear()
self.fail("Should not have been able to clear")
except InvalidElementStateException:
pass
def testWritableTextAreaShouldClear(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID,"writableTextArea")
element.clear()
self.assertEqual("", element.get_property("value"))
def testTextAreaShouldNotClearWhenDisabled(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID,"textAreaNotenabled")
try:
element.clear()
self.fail("Should not have been able to clear")
except InvalidElementStateException:
pass
def testTextAreaShouldNotClearWhenReadOnly(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID,"textAreaReadOnly")
try:
element.clear()
self.fail("Should not have been able to clear")
except InvalidElementStateException:
pass
def testContentEditableAreaShouldClear(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID,"content-editable")
element.clear()
self.assertEqual("", element.text)
def testTextInputShouldNotClearWhenDisabled(self):
test_html = self.marionette.absolute_url("test_clearing.html")
self.marionette.navigate(test_html)
try:
element = self.marionette.find_element(By.ID,"textInputnotenabled")
self.assertFalse(element.is_enabled())
element.clear()
self.fail("Should not have been able to clear")
except InvalidElementStateException:
pass

View file

@ -0,0 +1,254 @@
# 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 urllib
from marionette_driver.by import By
from marionette_driver import errors
from marionette_driver.wait import Wait
from marionette_harness import MarionetteTestCase
def inline(doc):
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
# The <a> element in the following HTML is not interactable because it
# is hidden by an overlay when scrolled into the top of the viewport.
# It should be interactable when scrolled in at the bottom of the
# viewport.
fixed_overlay = inline("""
<style>
* { margin: 0; padding: 0; }
body { height: 300vh }
div, a { display: block }
div {
background-color: pink;
position: fixed;
width: 100%;
height: 40px;
top: 0;
}
a {
margin-top: 1000px;
}
</style>
<div>overlay</div>
<a href=#>link</a>
<script>
window.clicked = false;
let link = document.querySelector("a");
link.addEventListener("click", () => window.clicked = true);
</script>
""")
obscured_overlay = inline("""
<style>
* { margin: 0; padding: 0; }
body { height: 100vh }
#overlay {
background-color: pink;
position: absolute;
width: 100%;
height: 100%;
}
</style>
<div id=overlay></div>
<a id=obscured href=#>link</a>
<script>
window.clicked = false;
let link = document.querySelector("#obscured");
link.addEventListener("click", () => window.clicked = true);
</script>
""")
class TestLegacyClick(MarionetteTestCase):
"""Uses legacy Selenium element displayedness checks."""
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.delete_session()
self.marionette.start_session()
def test_click(self):
self.marionette.navigate(inline("""
<button>click me</button>
<script>
window.clicks = 0;
let button = document.querySelector("button");
button.addEventListener("click", () => window.clicks++);
</script>
"""))
button = self.marionette.find_element(By.TAG_NAME, "button")
button.click()
self.assertEqual(1, self.marionette.execute_script("return window.clicks", sandbox=None))
def test_click_number_link(self):
test_html = self.marionette.absolute_url("clicks.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.LINK_TEXT, "333333").click()
Wait(self.marionette, timeout=30, ignored_exceptions=errors.NoSuchElementException).until(
lambda m: m.find_element(By.ID, "username"))
self.assertEqual(self.marionette.title, "XHTML Test Page")
def test_clicking_an_element_that_is_not_displayed_raises(self):
test_html = self.marionette.absolute_url("hidden.html")
self.marionette.navigate(test_html)
with self.assertRaises(errors.ElementNotInteractableException):
self.marionette.find_element(By.ID, "child").click()
def test_clicking_on_a_multiline_link(self):
test_html = self.marionette.absolute_url("clicks.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.ID, "overflowLink").click()
self.wait_for_condition(lambda mn: self.marionette.title == "XHTML Test Page")
def test_scroll_into_view_near_end(self):
self.marionette.navigate(fixed_overlay)
link = self.marionette.find_element(By.TAG_NAME, "a")
link.click()
self.assertTrue(self.marionette.execute_script("return window.clicked", sandbox=None))
class TestClick(TestLegacyClick):
"""Uses WebDriver specification compatible element interactability
checks.
"""
def setUp(self):
TestLegacyClick.setUp(self)
self.marionette.delete_session()
self.marionette.start_session(
{"requiredCapabilities": {"specificationLevel": 1}})
def test_click_element_obscured_by_absolute_positioned_element(self):
self.marionette.navigate(obscured_overlay)
overlay = self.marionette.find_element(By.ID, "overlay")
obscured = self.marionette.find_element(By.ID, "obscured")
overlay.click()
with self.assertRaises(errors.ElementClickInterceptedException):
obscured.click()
def test_centre_outside_viewport_vertically(self):
self.marionette.navigate(inline("""
<style>
* { margin: 0; padding: 0; }
div {
display: block;
position: absolute;
background-color: blue;
width: 200px;
height: 200px;
/* move centre point off viewport vertically */
top: -105px;
}
</style>
<div></div>"""))
self.marionette.find_element(By.TAG_NAME, "div").click()
def test_centre_outside_viewport_horizontally(self):
self.marionette.navigate(inline("""
<style>
* { margin: 0; padding: 0; }
div {
display: block;
position: absolute;
background-color: blue;
width: 200px;
height: 200px;
/* move centre point off viewport horizontally */
left: -105px;
}
</style>
<div></div>"""))
self.marionette.find_element(By.TAG_NAME, "div").click()
def test_centre_outside_viewport(self):
self.marionette.navigate(inline("""
<style>
* { margin: 0; padding: 0; }
div {
display: block;
position: absolute;
background-color: blue;
width: 200px;
height: 200px;
/* move centre point off viewport */
left: -105px;
top: -105px;
}
</style>
<div></div>"""))
self.marionette.find_element(By.TAG_NAME, "div").click()
def test_css_transforms(self):
self.marionette.navigate(inline("""
<style>
* { margin: 0; padding: 0; }
div {
display: block;
background-color: blue;
width: 200px;
height: 200px;
transform: translateX(-105px);
}
</style>
<div></div>"""))
self.marionette.find_element(By.TAG_NAME, "div").click()
def test_input_file(self):
self.marionette.navigate(inline("<input type=file>"))
with self.assertRaises(errors.InvalidArgumentException):
self.marionette.find_element(By.TAG_NAME, "input").click()
def test_container_element(self):
self.marionette.navigate(inline("""
<select>
<option>foo</option>
</select>"""))
option = self.marionette.find_element(By.TAG_NAME, "option")
option.click()
self.assertTrue(option.get_property("selected"))
def test_container_element_outside_view(self):
self.marionette.navigate(inline("""
<select style="margin-top: 100vh">
<option>foo</option>
</select>"""))
option = self.marionette.find_element(By.TAG_NAME, "option")
option.click()
self.assertTrue(option.get_property("selected"))
def test_obscured_element(self):
self.marionette.navigate(obscured_overlay)
overlay = self.marionette.find_element(By.ID, "overlay")
obscured = self.marionette.find_element(By.ID, "obscured")
overlay.click()
with self.assertRaises(errors.ElementClickInterceptedException):
obscured.click()
self.assertFalse(self.marionette.execute_script("return window.clicked", sandbox=None))

View file

@ -0,0 +1,35 @@
# 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.by import By
from marionette_harness import MarionetteTestCase
class TestClickChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.root_window = self.marionette.current_window_handle
self.marionette.set_context("chrome")
self.marionette.execute_script(
"window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen')")
self.marionette.switch_to_window("foo")
self.assertNotEqual(self.root_window, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.root_window, self.marionette.current_window_handle)
self.marionette.execute_script("window.close()")
self.marionette.switch_to_window(self.root_window)
MarionetteTestCase.tearDown(self)
def test_click(self):
def checked():
return self.marionette.execute_script(
"return arguments[0].checked",
script_args=[box])
box = self.marionette.find_element(By.ID, "testBox")
self.assertFalse(checked())
box.click()
self.assertTrue(checked())

View file

@ -0,0 +1,117 @@
# 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.by import By
from marionette_driver.errors import MoveTargetOutOfBoundsException
from marionette_harness import MarionetteTestCase, skip, skip_if_mobile
class TestClickScrolling(MarionetteTestCase):
def test_clicking_on_anchor_scrolls_page(self):
scrollScript = """
var pageY;
if (typeof(window.pageYOffset) == 'number') {
pageY = window.pageYOffset;
} else {
pageY = document.documentElement.scrollTop;
}
return pageY;"""
test_html = self.marionette.absolute_url("macbeth.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.PARTIAL_LINK_TEXT, "last speech").click()
y_offset = self.marionette.execute_script(scrollScript)
# Focusing on to click, but not actually following,
# the link will scroll it in to view, which is a few
# pixels further than 0
self.assertTrue(y_offset > 300)
def test_should_scroll_to_click_on_an_element_hidden_by_overflow(self):
test_html = self.marionette.absolute_url("click_out_of_bounds_overflow.html")
self.marionette.navigate(test_html)
link = self.marionette.find_element(By.ID, "link")
try:
link.click()
except MoveTargetOutOfBoundsException:
self.fail("Should not be out of bounds")
@skip("Bug 1200197 - Cannot interact with elements hidden inside overflow:scroll")
def test_should_be_able_to_click_on_an_element_hidden_by_overflow(self):
test_html = self.marionette.absolute_url("scroll.html")
self.marionette.navigate(test_html)
link = self.marionette.find_element(By.ID, "line8")
link.click()
self.assertEqual("line8", self.marionette.find_element(By.ID, "clicked").text)
def test_should_not_scroll_overflow_elements_which_are_visible(self):
test_html = self.marionette.absolute_url("scroll2.html")
self.marionette.navigate(test_html)
list_el = self.marionette.find_element(By.TAG_NAME, "ul")
item = list_el.find_element(By.ID, "desired")
item.click()
y_offset = self.marionette.execute_script("return arguments[0].scrollTop;", script_args=[list_el])
self.assertEqual(0, y_offset)
def test_should_not_scroll_if_already_scrolled_and_element_is_in_view(self):
test_html = self.marionette.absolute_url("scroll3.html")
self.marionette.navigate(test_html)
button1 = self.marionette.find_element(By.ID, "button1")
button2 = self.marionette.find_element(By.ID, "button2")
button2.click()
scroll_top = self.marionette.execute_script("return document.body.scrollTop;")
button1.click()
self.assertEqual(scroll_top, self.marionette.execute_script("return document.body.scrollTop;"))
def test_should_be_able_to_click_radio_button_scrolled_into_view(self):
test_html = self.marionette.absolute_url("scroll4.html")
self.marionette.navigate(test_html)
# If we dont throw we are good
self.marionette.find_element(By.ID, "radio").click()
def test_should_scroll_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
test_html = self.marionette.absolute_url("element_outside_viewport.html")
for s in ["top", "bottom"]:
self.marionette.navigate(test_html)
scroll_y = self.marionette.execute_script("return window.scrollY;")
self.marionette.find_element(By.ID, "{}-70".format(s)).click()
self.assertNotEqual(scroll_y, self.marionette.execute_script("return window.scrollY;"))
for s in ["left", "right"]:
self.marionette.navigate(test_html)
scroll_x = self.marionette.execute_script("return window.scrollX;")
self.marionette.find_element(By.ID, "{}-70".format(s)).click()
self.assertNotEqual(scroll_x, self.marionette.execute_script("return window.scrollX;"))
@skip_if_mobile("Bug 1293855 - Lists differ: [70, 70] != [70, 120]")
def test_should_not_scroll_elements_if_click_point_is_in_view(self):
test_html = self.marionette.absolute_url("element_outside_viewport.html")
for s in ["top", "right", "bottom", "left"]:
for p in ["50", "30"]:
self.marionette.navigate(test_html)
scroll = self.marionette.execute_script("return [window.scrollX, window.scrollY];")
self.marionette.find_element(By.ID, "{0}-{1}".format(s, p)).click()
self.assertEqual(scroll, self.marionette.execute_script("return [window.scrollX, window.scrollY];"))
@skip("Bug 1003687")
def test_should_scroll_overflow_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
test_html = self.marionette.absolute_url("scroll5.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.ID, "inner").click()
self.assertEqual("clicked", self.marionette.find_element(By.ID, "clicked").text)

View file

@ -0,0 +1,115 @@
# 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 calendar
import random
import time
from marionette_driver.errors import UnsupportedOperationException
from marionette_harness import MarionetteTestCase
class CookieTest(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
test_url = self.marionette.absolute_url('test.html')
self.marionette.navigate(test_url)
self.COOKIE_A = {"name": "foo",
"value": "bar",
"path": "/",
"secure": False}
def tearDown(self):
self.marionette.delete_all_cookies()
MarionetteTestCase.tearDown(self)
def test_add_cookie(self):
self.marionette.add_cookie(self.COOKIE_A)
cookie_returned = str(self.marionette.execute_script("return document.cookie"))
self.assertTrue(self.COOKIE_A["name"] in cookie_returned)
def test_adding_a_cookie_that_expired_in_the_past(self):
cookie = self.COOKIE_A.copy()
cookie["expiry"] = calendar.timegm(time.gmtime()) - 1
self.marionette.add_cookie(cookie)
cookies = self.marionette.get_cookies()
self.assertEquals(0, len(cookies))
def test_chrome_error(self):
with self.marionette.using_context("chrome"):
self.assertRaises(UnsupportedOperationException,
self.marionette.add_cookie, self.COOKIE_A)
self.assertRaises(UnsupportedOperationException,
self.marionette.delete_cookie, self.COOKIE_A)
self.assertRaises(UnsupportedOperationException,
self.marionette.delete_all_cookies)
self.assertRaises(UnsupportedOperationException,
self.marionette.get_cookies)
def test_delete_all_cookie(self):
self.marionette.add_cookie(self.COOKIE_A)
cookie_returned = str(self.marionette.execute_script("return document.cookie"))
print cookie_returned
self.assertTrue(self.COOKIE_A["name"] in cookie_returned)
self.marionette.delete_all_cookies()
self.assertFalse(self.marionette.get_cookies())
def test_delete_cookie(self):
self.marionette.add_cookie(self.COOKIE_A)
cookie_returned = str(self.marionette.execute_script("return document.cookie"))
self.assertTrue(self.COOKIE_A["name"] in cookie_returned)
self.marionette.delete_cookie("foo")
cookie_returned = str(self.marionette.execute_script("return document.cookie"))
self.assertFalse(self.COOKIE_A["name"] in cookie_returned)
def test_should_get_cookie_by_name(self):
key = "key_{}".format(int(random.random()*10000000))
self.marionette.execute_script("document.cookie = arguments[0] + '=set';", [key])
cookie = self.marionette.get_cookie(key)
self.assertEquals("set", cookie["value"])
def test_get_all_cookies(self):
key1 = "key_{}".format(int(random.random()*10000000))
key2 = "key_{}".format(int(random.random()*10000000))
cookies = self.marionette.get_cookies()
count = len(cookies)
one = {"name" :key1,
"value": "value"}
two = {"name":key2,
"value": "value"}
self.marionette.add_cookie(one)
self.marionette.add_cookie(two)
test_url = self.marionette.absolute_url('test.html')
self.marionette.navigate(test_url)
cookies = self.marionette.get_cookies()
self.assertEquals(count + 2, len(cookies))
def test_should_not_delete_cookies_with_a_similar_name(self):
cookieOneName = "fish"
cookie1 = {"name" :cookieOneName,
"value":"cod"}
cookie2 = {"name" :cookieOneName + "x",
"value": "earth"}
self.marionette.add_cookie(cookie1)
self.marionette.add_cookie(cookie2)
self.marionette.delete_cookie(cookieOneName)
cookies = self.marionette.get_cookies()
self.assertFalse(cookie1["name"] == cookies[0]["name"], msg=str(cookies))
self.assertEquals(cookie2["name"] , cookies[0]["name"], msg=str(cookies))
def test_we_get_required_elements_when_available(self):
self.marionette.add_cookie(self.COOKIE_A)
cookies = self.marionette.get_cookies()
self.assertIn("name", cookies[0], 'name not available')
self.assertIn("value", cookies[0], 'value not available')
self.assertIn("httpOnly", cookies[0], 'httpOnly not available')

View file

@ -0,0 +1,155 @@
# 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 glob
import shutil
from marionette_driver.errors import MarionetteException
# Import runner module to monkey patch mozcrash module
from mozrunner.base import runner
from marionette_harness import MarionetteTestCase, expectedFailure, run_if_e10s
class MockMozCrash(object):
"""Mock object to replace original mozcrash methods."""
def __init__(self, marionette):
self.marionette = marionette
with self.marionette.using_context('chrome'):
self.crash_reporter_enabled = self.marionette.execute_script("""
try {
Components.classes["@mozilla.org/toolkit/crash-reporter;1"].
getService(Components.interfaces.nsICrashReporter);
return true;
} catch (exc) {
return false;
}
""")
def check_for_crashes(self, dump_directory, *args, **kwargs):
minidump_files = glob.glob('{}/*.dmp'.format(dump_directory))
shutil.rmtree(dump_directory, ignore_errors=True)
if self.crash_reporter_enabled:
return len(minidump_files)
else:
return len(minidump_files) == 0
def log_crashes(self, logger, dump_directory, *args, **kwargs):
return self.check_for_crashes(dump_directory, *args, **kwargs)
class BaseCrashTestCase(MarionetteTestCase):
# Reduce the timeout for faster processing of the tests
socket_timeout = 10
def setUp(self):
super(BaseCrashTestCase, self).setUp()
self.mozcrash_mock = MockMozCrash(self.marionette)
self.crash_count = self.marionette.crashed
self.pid = self.marionette.process_id
self.remote_uri = self.marionette.absolute_url("javascriptPage.html")
def tearDown(self):
self.marionette.crashed = self.crash_count
super(BaseCrashTestCase, self).tearDown()
def crash(self, chrome=True):
context = 'chrome' if chrome else 'content'
sandbox = None if chrome else 'system'
# Monkey patch mozcrash to avoid crash info output only for our triggered crashes.
mozcrash = runner.mozcrash
runner.mozcrash = self.mozcrash_mock
socket_timeout = self.marionette.client.socket_timeout
self.marionette.set_context(context)
try:
self.marionette.client.socket_timeout = self.socket_timeout
self.marionette.execute_script("""
// Copied from crash me simple
Components.utils.import("resource://gre/modules/ctypes.jsm");
// ctypes checks for NULL pointer derefs, so just go near-NULL.
var zero = new ctypes.intptr_t(8);
var badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
var crash = badptr.contents;
""", sandbox=sandbox)
finally:
runner.mozcrash = mozcrash
self.marionette.client.socket_timeout = socket_timeout
class TestCrash(BaseCrashTestCase):
def test_crash_chrome_process(self):
self.assertRaisesRegexp(IOError, 'Process crashed',
self.crash, chrome=True)
self.assertEqual(self.marionette.crashed, 1)
self.assertIsNone(self.marionette.session)
self.assertRaisesRegexp(MarionetteException, 'Please start a session',
self.marionette.get_url)
self.marionette.start_session()
self.assertNotEqual(self.marionette.process_id, self.pid)
# TODO: Bug 1314594 - Causes a hang for the communication between the
# chrome and frame script.
# self.marionette.get_url()
@run_if_e10s("Content crashes only exist in e10s mode")
def test_crash_content_process(self):
# If e10s is disabled the chrome process crashes
self.marionette.navigate(self.remote_uri)
self.assertRaisesRegexp(IOError, 'Content process crashed',
self.crash, chrome=False)
self.assertEqual(self.marionette.crashed, 1)
self.assertIsNone(self.marionette.session)
self.assertRaisesRegexp(MarionetteException, 'Please start a session',
self.marionette.get_url)
self.marionette.start_session()
self.assertNotEqual(self.marionette.process_id, self.pid)
self.marionette.get_url()
@expectedFailure
def test_unexpected_crash(self):
self.crash(chrome=True)
class TestCrashInSetUp(BaseCrashTestCase):
def setUp(self):
super(TestCrashInSetUp, self).setUp()
self.assertRaisesRegexp(IOError, 'Process crashed',
self.crash, chrome=True)
self.assertEqual(self.marionette.crashed, 1)
self.assertIsNone(self.marionette.session)
def test_crash_in_setup(self):
self.marionette.start_session()
self.assertNotEqual(self.marionette.process_id, self.pid)
class TestCrashInTearDown(BaseCrashTestCase):
def tearDown(self):
try:
self.assertRaisesRegexp(IOError, 'Process crashed',
self.crash, chrome=True)
finally:
self.assertEqual(self.marionette.crashed, 1)
self.assertIsNone(self.marionette.session)
super(TestCrashInTearDown, self).tearDown()
def test_crash_in_teardown(self):
pass

View file

@ -0,0 +1,67 @@
# 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_harness.marionette_test import (
parameterized,
with_parameters,
MetaParameterized,
MarionetteTestCase
)
class Parameterizable(object):
__metaclass__ = MetaParameterized
class TestDataDriven(MarionetteTestCase):
def test_parameterized(self):
class Test(Parameterizable):
def __init__(self):
self.parameters = []
@parameterized('1', 'thing', named=43)
@parameterized('2', 'thing2')
def test(self, thing, named=None):
self.parameters.append((thing, named))
self.assertFalse(hasattr(Test, 'test'))
self.assertTrue(hasattr(Test, 'test_1'))
self.assertTrue(hasattr(Test, 'test_2'))
test = Test()
test.test_1()
test.test_2()
self.assertEquals(test.parameters, [('thing', 43), ('thing2', None)])
def test_with_parameters(self):
DATA = [('1', ('thing',), {'named': 43}),
('2', ('thing2',), {'named': None})]
class Test(Parameterizable):
def __init__(self):
self.parameters = []
@with_parameters(DATA)
def test(self, thing, named=None):
self.parameters.append((thing, named))
self.assertFalse(hasattr(Test, 'test'))
self.assertTrue(hasattr(Test, 'test_1'))
self.assertTrue(hasattr(Test, 'test_2'))
test = Test()
test.test_1()
test.test_2()
self.assertEquals(test.parameters, [('thing', 43), ('thing2', None)])
def test_parameterized_same_name_raises_error(self):
with self.assertRaises(KeyError):
class Test(Parameterizable):
@parameterized('1', 'thing', named=43)
@parameterized('1', 'thing2')
def test(self, thing, named=None):
pass
def test_marionette_test_case_is_parameterizable(self):
self.assertTrue(issubclass(MarionetteTestCase.__metaclass__, MetaParameterized))

View file

@ -0,0 +1,29 @@
# 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 datetime import datetime
from marionette_driver.by import By
from marionette_driver.date_time_value import DateTimeValue
from marionette_harness import MarionetteTestCase
class TestDateTime(MarionetteTestCase):
def test_set_date(self):
test_html = self.marionette.absolute_url("datetimePage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "date-test")
dt_value = DateTimeValue(element)
dt_value.date = datetime(1998, 6, 2)
self.assertEqual("1998-06-02", element.get_property("value"))
def test_set_time(self):
test_html = self.marionette.absolute_url("datetimePage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "time-test")
dt_value = DateTimeValue(element)
dt_value.time = datetime(1998, 11, 19, 9, 8, 7)
self.assertEqual("09:08:07", element.get_property("value"))

View file

@ -0,0 +1,483 @@
# 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 re
import urllib
from marionette_driver.by import By
from marionette_driver.errors import NoSuchElementException, InvalidSelectorException
from marionette_driver.marionette import HTMLElement
from marionette_harness import MarionetteTestCase, skip
def inline(doc, doctype="html"):
if doctype == "html":
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
elif doctype == "xhtml":
return "data:application/xhtml+xml,{}".format(urllib.quote(
r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>XHTML might be the future</title>
</head>
<body>
{}
</body>
</html>""".format(doc)))
id_html = inline("<p id=foo></p>", doctype="html")
id_xhtml = inline('<p id="foo"></p>', doctype="xhtml")
parent_child_html = inline("<div id=parent><p id=child></p></div>", doctype="html")
parent_child_xhtml = inline('<div id="parent"><p id="child"></p></div>', doctype="xhtml")
children_html = inline("<div><p>foo <p>bar</div>", doctype="html")
children_xhtml = inline("<div><p>foo</p> <p>bar</p></div>", doctype="xhtml")
class_html = inline("<p class='foo bar'>", doctype="html")
class_xhtml = inline('<p class="foo bar"></p>', doctype="xhtml")
name_html = inline("<p name=foo>", doctype="html")
name_xhtml = inline('<p name="foo"></p>', doctype="xhtml")
link_html = inline("<p><a href=#>foo bar</a>", doctype="html")
link_html_with_trailing_space = inline("<p><a href=#>a link with a trailing space </a>")
link_xhtml = inline('<p><a href="#">foo bar</a></p>', doctype="xhtml")
class TestFindElementHTML(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.timeout.implicit = 0
def test_id(self):
self.marionette.navigate(id_html)
expected = self.marionette.execute_script("return document.querySelector('p')")
found = self.marionette.find_element(By.ID, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(expected, found)
def test_child_element(self):
self.marionette.navigate(parent_child_html)
parent = self.marionette.find_element(By.ID, "parent")
child = self.marionette.find_element(By.ID, "child")
found = parent.find_element(By.TAG_NAME, "p")
self.assertEqual(found.tag_name, "p")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(child, found)
def test_tag_name(self):
self.marionette.navigate(children_html)
el = self.marionette.execute_script("return document.querySelector('p')")
found = self.marionette.find_element(By.TAG_NAME, "p")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_class_name(self):
self.marionette.navigate(class_html)
el = self.marionette.execute_script("return document.querySelector('.foo')")
found = self.marionette.find_element(By.CLASS_NAME, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_by_name(self):
self.marionette.navigate(name_html)
el = self.marionette.execute_script("return document.querySelector('[name=foo]')")
found = self.marionette.find_element(By.NAME, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_css_selector(self):
self.marionette.navigate(children_html)
el = self.marionette.execute_script("return document.querySelector('p')")
found = self.marionette.find_element(By.CSS_SELECTOR, "p")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_invalid_css_selector_should_throw(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_element(By.CSS_SELECTOR, "#")
def test_link_text(self):
self.marionette.navigate(link_html)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.LINK_TEXT, "foo bar")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_link_text_with_trailing_space(self):
self.marionette.navigate(link_html_with_trailing_space)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.LINK_TEXT, "a link with a trailing space")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_partial_link_text(self):
self.marionette.navigate(link_html)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.PARTIAL_LINK_TEXT, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_xpath(self):
self.marionette.navigate(id_html)
el = self.marionette.execute_script("return document.querySelector('#foo')")
found = self.marionette.find_element(By.XPATH, "id('foo')")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_not_found(self):
self.marionette.timeout.implicit = 0
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.CLASS_NAME, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.CSS_SELECTOR, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.NAME, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.PARTIAL_LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.TAG_NAME, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.XPATH, "cheese")
def test_not_found_implicit_wait(self):
self.marionette.timeout.implicit = 0.5
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.CLASS_NAME, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.CSS_SELECTOR, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.NAME, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.PARTIAL_LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.TAG_NAME, "cheese")
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.XPATH, "cheese")
def test_not_found_from_element(self):
self.marionette.timeout.implicit = 0
self.marionette.navigate(id_html)
el = self.marionette.find_element(By.ID, "foo")
self.assertRaises(NoSuchElementException, el.find_element, By.CLASS_NAME, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.CSS_SELECTOR, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.ID, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.NAME, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.PARTIAL_LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.TAG_NAME, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.XPATH, "cheese")
def test_not_found_implicit_wait_from_element(self):
self.marionette.timeout.implicit = 0.5
self.marionette.navigate(id_html)
el = self.marionette.find_element(By.ID, "foo")
self.assertRaises(NoSuchElementException, el.find_element, By.CLASS_NAME, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.CSS_SELECTOR, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.ID, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.NAME, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.PARTIAL_LINK_TEXT, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.TAG_NAME, "cheese")
self.assertRaises(NoSuchElementException, el.find_element, By.XPATH, "cheese")
def test_css_selector_scope_doesnt_start_at_rootnode(self):
self.marionette.navigate(parent_child_html)
el = self.marionette.find_element(By.ID, "child")
parent = self.marionette.find_element(By.ID, "parent")
found = parent.find_element(By.CSS_SELECTOR, "p")
self.assertEqual(el, found)
def test_unknown_selector(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_elements("foo", "bar")
def test_element_id_is_valid_uuid(self):
self.marionette.navigate(id_html)
el = self.marionette.find_element(By.TAG_NAME, "p")
uuid_regex = re.compile('^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')
self.assertIsNotNone(re.search(uuid_regex, el.id),
'UUID for the WebElement is not valid. ID is {}'\
.format(el.id))
def test_invalid_xpath_selector(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_element(By.XPATH, "count(//input)")
with self.assertRaises(InvalidSelectorException):
parent = self.marionette.execute_script("return document.documentElement")
parent.find_element(By.XPATH, "count(//input)")
def test_invalid_css_selector(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_element(By.CSS_SELECTOR, "")
with self.assertRaises(InvalidSelectorException):
parent = self.marionette.execute_script("return document.documentElement")
parent.find_element(By.CSS_SELECTOR, "")
def test_finding_active_element_returns_element(self):
self.marionette.navigate(id_html)
active = self.marionette.execute_script("return document.activeElement")
self.assertEqual(active, self.marionette.get_active_element())
class TestFindElementXHTML(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.timeout.implicit = 0
def test_id(self):
self.marionette.navigate(id_xhtml)
expected = self.marionette.execute_script("return document.querySelector('p')")
found = self.marionette.find_element(By.ID, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(expected, found)
def test_child_element(self):
self.marionette.navigate(parent_child_xhtml)
parent = self.marionette.find_element(By.ID, "parent")
child = self.marionette.find_element(By.ID, "child")
found = parent.find_element(By.TAG_NAME, "p")
self.assertEqual(found.tag_name, "p")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(child, found)
def test_tag_name(self):
self.marionette.navigate(children_xhtml)
el = self.marionette.execute_script("return document.querySelector('p')")
found = self.marionette.find_element(By.TAG_NAME, "p")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_class_name(self):
self.marionette.navigate(class_xhtml)
el = self.marionette.execute_script("return document.querySelector('.foo')")
found = self.marionette.find_element(By.CLASS_NAME, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_by_name(self):
self.marionette.navigate(name_xhtml)
el = self.marionette.execute_script("return document.querySelector('[name=foo]')")
found = self.marionette.find_element(By.NAME, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_css_selector(self):
self.marionette.navigate(children_xhtml)
el = self.marionette.execute_script("return document.querySelector('p')")
found = self.marionette.find_element(By.CSS_SELECTOR, "p")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_link_text(self):
self.marionette.navigate(link_xhtml)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.LINK_TEXT, "foo bar")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_partial_link_text(self):
self.marionette.navigate(link_xhtml)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.PARTIAL_LINK_TEXT, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_xpath(self):
self.marionette.navigate(id_xhtml)
el = self.marionette.execute_script("return document.querySelector('#foo')")
found = self.marionette.find_element(By.XPATH, "id('foo')")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_css_selector_scope_does_not_start_at_rootnode(self):
self.marionette.navigate(parent_child_xhtml)
el = self.marionette.find_element(By.ID, "child")
parent = self.marionette.find_element(By.ID, "parent")
found = parent.find_element(By.CSS_SELECTOR, "p")
self.assertEqual(el, found)
def test_active_element(self):
self.marionette.navigate(id_xhtml)
active = self.marionette.execute_script("return document.activeElement")
self.assertEqual(active, self.marionette.get_active_element())
class TestFindElementsHTML(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.timeout.implicit = 0
def assertItemsIsInstance(self, items, typ):
for item in items:
self.assertIsInstance(item, typ)
def test_child_elements(self):
self.marionette.navigate(children_html)
parent = self.marionette.find_element(By.TAG_NAME, "div")
children = self.marionette.find_elements(By.TAG_NAME, "p")
found = parent.find_elements(By.TAG_NAME, "p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(found, children)
def test_tag_name(self):
self.marionette.navigate(children_html)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
found = self.marionette.find_elements(By.TAG_NAME, "p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_class_name(self):
self.marionette.navigate(class_html)
els = self.marionette.execute_script("return document.querySelectorAll('.foo')")
found = self.marionette.find_elements(By.CLASS_NAME, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_by_name(self):
self.marionette.navigate(name_html)
els = self.marionette.execute_script("return document.querySelectorAll('[name=foo]')")
found = self.marionette.find_elements(By.NAME, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_css_selector(self):
self.marionette.navigate(children_html)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
found = self.marionette.find_elements(By.CSS_SELECTOR, "p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_invalid_css_selector_should_throw(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_elements(By.CSS_SELECTOR, "#")
def test_link_text(self):
self.marionette.navigate(link_html)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.LINK_TEXT, "foo bar")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_link_text_with_trailing_space(self):
self.marionette.navigate(link_html_with_trailing_space)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.LINK_TEXT, "a link with a trailing space")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_partial_link_text(self):
self.marionette.navigate(link_html)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.PARTIAL_LINK_TEXT, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_xpath(self):
self.marionette.navigate(children_html)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
found = self.marionette.find_elements(By.XPATH, ".//p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_css_selector_scope_doesnt_start_at_rootnode(self):
self.marionette.navigate(parent_child_html)
els = self.marionette.find_elements(By.ID, "child")
parent = self.marionette.find_element(By.ID, "parent")
found = parent.find_elements(By.CSS_SELECTOR, "p")
self.assertSequenceEqual(els, found)
def test_unknown_selector(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_element("foo", "bar")
def test_element_id_is_valid_uuid(self):
self.marionette.navigate(id_html)
els = self.marionette.find_elements(By.TAG_NAME, "p")
uuid_regex = re.compile('^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')
self.assertIsNotNone(re.search(uuid_regex, els[0].id),
'UUID for the WebElement is not valid. ID is {}'\
.format(els[0].id))
def test_invalid_xpath_selector(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_elements(By.XPATH, "count(//input)")
with self.assertRaises(InvalidSelectorException):
parent = self.marionette.execute_script("return document.documentElement")
parent.find_elements(By.XPATH, "count(//input)")
def test_invalid_css_selector(self):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_elements(By.CSS_SELECTOR, "")
with self.assertRaises(InvalidSelectorException):
parent = self.marionette.execute_script("return document.documentElement")
parent.find_elements(By.CSS_SELECTOR, "")
class TestFindElementsXHTML(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.timeout.implicit = 0
def assertItemsIsInstance(self, items, typ):
for item in items:
self.assertIsInstance(item, typ)
def test_child_elements(self):
self.marionette.navigate(children_xhtml)
parent = self.marionette.find_element(By.TAG_NAME, "div")
children = self.marionette.find_elements(By.TAG_NAME, "p")
found = parent.find_elements(By.TAG_NAME, "p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(found, children)
def test_tag_name(self):
self.marionette.navigate(children_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
found = self.marionette.find_elements(By.TAG_NAME, "p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_class_name(self):
self.marionette.navigate(class_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('.foo')")
found = self.marionette.find_elements(By.CLASS_NAME, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_by_name(self):
self.marionette.navigate(name_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('[name=foo]')")
found = self.marionette.find_elements(By.NAME, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_css_selector(self):
self.marionette.navigate(children_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
found = self.marionette.find_elements(By.CSS_SELECTOR, "p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_link_text(self):
self.marionette.navigate(link_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.LINK_TEXT, "foo bar")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_partial_link_text(self):
self.marionette.navigate(link_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.PARTIAL_LINK_TEXT, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
@skip("XHTML namespace not yet supported")
def test_xpath(self):
self.marionette.navigate(children_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
found = self.marionette.find_elements(By.XPATH, "//xhtml:p")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_css_selector_scope_doesnt_start_at_rootnode(self):
self.marionette.navigate(parent_child_xhtml)
els = self.marionette.find_elements(By.ID, "child")
parent = self.marionette.find_element(By.ID, "parent")
found = parent.find_elements(By.CSS_SELECTOR, "p")
self.assertSequenceEqual(els, found)

View file

@ -0,0 +1,162 @@
# 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 types
import urllib
from marionette_driver.by import By
from marionette_harness import MarionetteTestCase
boolean_attributes = {
"audio": ["autoplay", "controls", "loop", "muted"],
"button": ["autofocus", "disabled", "formnovalidate"],
"details": ["open"],
"dialog": ["open"],
"fieldset": ["disabled"],
"form": ["novalidate"],
"iframe": ["allowfullscreen"],
"img": ["ismap"],
"input": ["autofocus", "checked", "disabled", "formnovalidate", "multiple", "readonly", "required"],
"menuitem": ["checked", "default", "disabled"],
"object": ["typemustmatch"],
"ol": ["reversed"],
"optgroup": ["disabled"],
"option": ["disabled", "selected"],
"script": ["async", "defer"],
"select": ["autofocus", "disabled", "multiple", "required"],
"textarea": ["autofocus", "disabled", "readonly", "required"],
"track": ["default"],
"video": ["autoplay", "controls", "loop", "muted"],
}
def inline(doc, doctype="html"):
if doctype == "html":
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
elif doctype == "xhtml":
return "data:application/xhtml+xml,{}".format(urllib.quote(
r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>XHTML might be the future</title>
</head>
<body>
{}
</body>
</html>""".format(doc)))
attribute = inline("<input foo=bar>")
input = inline("<input>")
disabled = inline("<input disabled=baz>")
check = inline("<input type=checkbox>")
class TestIsElementEnabled(MarionetteTestCase):
def test_is_enabled(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
l = self.marionette.find_element(By.NAME, "myCheckBox")
self.assertTrue(l.is_enabled())
self.marionette.execute_script("arguments[0].disabled = true;", [l])
self.assertFalse(l.is_enabled())
class TestIsElementDisplayed(MarionetteTestCase):
def test_is_displayed(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
l = self.marionette.find_element(By.NAME, "myCheckBox")
self.assertTrue(l.is_displayed())
self.marionette.execute_script("arguments[0].hidden = true;", [l])
self.assertFalse(l.is_displayed())
class TestGetElementAttribute(MarionetteTestCase):
def test_normal_attribute(self):
self.marionette.navigate(inline("<p style=foo>"))
el = self.marionette.find_element(By.TAG_NAME, "p")
attr = el.get_attribute("style")
self.assertIsInstance(attr, types.StringTypes)
self.assertEqual("foo", attr)
def test_boolean_attributes(self):
for tag, attrs in boolean_attributes.iteritems():
for attr in attrs:
print("testing boolean attribute <{0} {1}>".format(tag, attr))
doc = inline("<{0} {1}>".format(tag, attr))
self.marionette.navigate(doc)
el = self.marionette.find_element(By.TAG_NAME, tag)
res = el.get_attribute(attr)
self.assertIsInstance(res, types.StringTypes)
self.assertEqual("true", res)
def test_global_boolean_attributes(self):
self.marionette.navigate(inline("<p hidden>foo"))
el = self.marionette.find_element(By.TAG_NAME, "p")
attr = el.get_attribute("hidden")
self.assertIsInstance(attr, types.StringTypes)
self.assertEqual("true", attr)
self.marionette.navigate(inline("<p>foo"))
el = self.marionette.find_element(By.TAG_NAME, "p")
attr = el.get_attribute("hidden")
self.assertIsNone(attr)
self.marionette.navigate(inline("<p itemscope>foo"))
el = self.marionette.find_element(By.TAG_NAME, "p")
attr = el.get_attribute("itemscope")
self.assertIsInstance(attr, types.StringTypes)
self.assertEqual("true", attr)
self.marionette.navigate(inline("<p>foo"))
el = self.marionette.find_element(By.TAG_NAME, "p")
attr = el.get_attribute("itemscope")
self.assertIsNone(attr)
# TODO(ato): Test for custom elements
def test_xhtml(self):
doc = inline("<p hidden=\"true\">foo</p>", doctype="xhtml")
self.marionette.navigate(doc)
el = self.marionette.find_element(By.TAG_NAME, "p")
attr = el.get_attribute("hidden")
self.assertIsInstance(attr, types.StringTypes)
self.assertEqual("true", attr)
class TestGetElementProperty(MarionetteTestCase):
def test_get(self):
self.marionette.navigate(disabled)
el = self.marionette.find_element(By.TAG_NAME, "input")
prop = el.get_property("disabled")
self.assertIsInstance(prop, bool)
self.assertTrue(prop)
def test_missing_property_returns_default(self):
self.marionette.navigate(input)
el = self.marionette.find_element(By.TAG_NAME, "input")
prop = el.get_property("checked")
self.assertIsInstance(prop, bool)
self.assertFalse(prop)
def test_attribute_not_returned(self):
self.marionette.navigate(attribute)
el = self.marionette.find_element(By.TAG_NAME, "input")
self.assertEqual(el.get_property("foo"), None)
def test_manipulated_element(self):
self.marionette.navigate(check)
el = self.marionette.find_element(By.TAG_NAME, "input")
self.assertEqual(el.get_property("checked"), False)
el.click()
self.assertEqual(el.get_property("checked"), True)
el.click()
self.assertEqual(el.get_property("checked"), False)

View file

@ -0,0 +1,85 @@
# 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.by import By
from marionette_harness import MarionetteTestCase, skip
class TestIsElementEnabledChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_enabled(self):
l = self.marionette.find_element(By.ID, "textInput")
self.assertTrue(l.is_enabled())
self.marionette.execute_script("arguments[0].disabled = true;", [l])
self.assertFalse(l.is_enabled())
self.marionette.execute_script("arguments[0].disabled = false;", [l])
def test_can_get_element_rect(self):
l = self.marionette.find_element(By.ID, "textInput")
rect = l.rect
self.assertTrue(rect['x'] > 0)
self.assertTrue(rect['y'] > 0)
@skip("Switched off in bug 896043, and to be turned on in bug 896046")
class TestIsElementDisplayed(MarionetteTestCase):
def test_isDisplayed(self):
l = self.marionette.find_element(By.ID, "textInput")
self.assertTrue(l.is_displayed())
self.marionette.execute_script("arguments[0].hidden = true;", [l])
self.assertFalse(l.is_displayed())
self.marionette.execute_script("arguments[0].hidden = false;", [l])
class TestGetElementAttributeChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_get(self):
el = self.marionette.execute_script("return window.document.getElementById('textInput');")
self.assertEqual(el.get_attribute("id"), "textInput")
class TestGetElementProperty(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_get(self):
el = self.marionette.execute_script("return window.document.getElementById('textInput');")
self.assertEqual(el.get_property("id"), "textInput")

View file

@ -0,0 +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_driver.by import By
from marionette_harness import MarionetteTestCase
class TestElementSize(MarionetteTestCase):
def testShouldReturnTheSizeOfALink(self):
test_html = self.marionette.absolute_url("testSize.html")
self.marionette.navigate(test_html)
shrinko = self.marionette.find_element(By.ID, 'linkId')
size = shrinko.rect
self.assertTrue(size['width'] > 0)
self.assertTrue(size['height'] > 0)

View file

@ -0,0 +1,34 @@
# 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.by import By
from marionette_harness import MarionetteTestCase, WindowManagerMixin
class TestElementSizeChrome(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestElementSizeChrome, self).setUp()
self.marionette.set_context("chrome")
def open_window_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test2.xul',
'foo', 'chrome,centerscreen');
""")
new_window = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(new_window)
def tearDown(self):
self.close_all_windows()
super(TestElementSizeChrome, self).tearDown()
def testShouldReturnTheSizeOfAnInput(self):
shrinko = self.marionette.find_element(By.ID, 'textInput')
size = shrinko.rect
self.assertTrue(size['width'] > 0)
self.assertTrue(size['height'] > 0)

View file

@ -0,0 +1,77 @@
# 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 sys
from marionette_driver import errors
from marionette_harness import marionette_test
def fake_cause():
try:
raise ValueError("bar")
except ValueError as e:
return sys.exc_info()
message = "foo"
cause = fake_cause()
stacktrace = "first\nsecond"
class TestErrors(marionette_test.MarionetteTestCase):
def test_defaults(self):
exc = errors.MarionetteException()
self.assertIsNone(exc.message)
self.assertIsNone(exc.cause)
self.assertIsNone(exc.stacktrace)
def test_construction(self):
exc = errors.MarionetteException(
message=message, cause=cause, stacktrace=stacktrace)
self.assertEquals(exc.message, message)
self.assertEquals(exc.cause, cause)
self.assertEquals(exc.stacktrace, stacktrace)
def test_str(self):
exc = errors.MarionetteException(
message=message, cause=cause, stacktrace=stacktrace)
r = str(exc)
self.assertIn(message, r)
self.assertIn(", caused by {0!r}".format(cause[0]), r)
self.assertIn("\nstacktrace:\n\tfirst\n\tsecond", r)
def test_cause_string(self):
exc = errors.MarionetteException(cause="foo")
self.assertEqual(exc.cause, "foo")
r = str(exc)
self.assertIn(", caused by foo", r)
def test_cause_tuple(self):
exc = errors.MarionetteException(cause=cause)
self.assertEqual(exc.cause, cause)
r = str(exc)
self.assertIn(", caused by {0!r}".format(cause[0]), r)
class TestLookup(marionette_test.MarionetteTestCase):
def test_by_unknown_number(self):
self.assertEqual(errors.MarionetteException, errors.lookup(123456))
def test_by_known_string(self):
self.assertEqual(errors.NoSuchElementException,
errors.lookup("no such element"))
def test_by_unknown_string(self):
self.assertEqual(errors.MarionetteException, errors.lookup("barbera"))
def test_by_known_unicode_string(self):
self.assertEqual(errors.NoSuchElementException,
errors.lookup(u"no such element"))
class TestAllErrors(marionette_test.MarionetteTestCase):
def test_properties(self):
for exc in errors.es_:
self.assertTrue(hasattr(exc, "status"),
"expected exception to have attribute `status'")

View file

@ -0,0 +1,156 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import (
JavascriptException,
ScriptTimeoutException,
)
from marionette_harness import MarionetteTestCase
class TestExecuteAsyncContent(MarionetteTestCase):
def setUp(self):
super(TestExecuteAsyncContent, self).setUp()
self.marionette.timeout.script = 1
def test_execute_async_simple(self):
self.assertEqual(1, self.marionette.execute_async_script("arguments[arguments.length-1](1);"))
def test_execute_async_ours(self):
self.assertEqual(1, self.marionette.execute_async_script("marionetteScriptFinished(1);"))
def test_execute_async_timeout(self):
self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "var x = 1;")
def test_execute_async_unique_timeout(self):
self.assertEqual(2, self.marionette.execute_async_script("setTimeout(function() {marionetteScriptFinished(2);}, 2000);", script_timeout=5000))
self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "setTimeout(function() {marionetteScriptFinished(3);}, 2000);")
def test_no_timeout(self):
self.marionette.timeout.script = 10
self.assertTrue(self.marionette.execute_async_script("""
var callback = arguments[arguments.length - 1];
setTimeout(function() { callback(true); }, 500);
"""))
def test_execute_async_unload(self):
self.marionette.timeout.script = 5
unload = """
window.location.href = "about:blank";
"""
self.assertRaises(JavascriptException, self.marionette.execute_async_script, unload)
def test_check_window(self):
self.assertTrue(self.marionette.execute_async_script("marionetteScriptFinished(window !=null && window != undefined);"))
def test_same_context(self):
var1 = 'testing'
self.assertEqual(self.marionette.execute_script("""
this.testvar = '{}';
return this.testvar;
""".format(var1)), var1)
self.assertEqual(self.marionette.execute_async_script(
"marionetteScriptFinished(this.testvar);", new_sandbox=False), var1)
def test_execute_no_return(self):
self.assertEqual(self.marionette.execute_async_script("marionetteScriptFinished()"), None)
def test_execute_js_exception(self):
try:
self.marionette.execute_async_script("""
let a = 1;
foo(bar);
""")
self.assertFalse(True)
except JavascriptException, inst:
self.assertTrue('foo(bar)' in inst.stacktrace)
def test_execute_async_js_exception(self):
self.assertRaises(JavascriptException,
self.marionette.execute_async_script, """
var callback = arguments[arguments.length - 1];
callback(foo());
""")
def test_script_finished(self):
self.assertTrue(self.marionette.execute_async_script("""
marionetteScriptFinished(true);
"""))
def test_execute_permission(self):
self.assertRaises(JavascriptException, self.marionette.execute_async_script, """
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
marionetteScriptFinished(4);
""")
def test_sandbox_reuse(self):
# Sandboxes between `execute_script()` invocations are shared.
self.marionette.execute_async_script("this.foobar = [23, 42];"
"marionetteScriptFinished();")
self.assertEqual(self.marionette.execute_async_script(
"marionetteScriptFinished(this.foobar);", new_sandbox=False), [23, 42])
self.marionette.execute_async_script("global.barfoo = [42, 23];"
"marionetteScriptFinished();")
self.assertEqual(self.marionette.execute_async_script(
"marionetteScriptFinished(global.barfoo);", new_sandbox=False), [42, 23])
def test_sandbox_refresh_arguments(self):
self.marionette.execute_async_script("this.foobar = [arguments[0], arguments[1]];"
"marionetteScriptFinished();",
script_args=[23, 42])
self.assertEqual(self.marionette.execute_async_script(
"marionetteScriptFinished(this.foobar);", new_sandbox=False),
[23, 42])
self.marionette.execute_async_script("global.barfoo = [arguments[0], arguments[1]];"
"marionetteScriptFinished()",
script_args=[42, 23], new_sandbox=False)
self.assertEqual(self.marionette.execute_async_script(
"marionetteScriptFinished(global.barfoo);", new_sandbox=False),
[42, 23])
# Functions defined in higher privilege scopes, such as the privileged
# content frame script listener.js runs in, cannot be accessed from
# content. This tests that it is possible to introspect the objects on
# `arguments` without getting permission defined errors. This is made
# possible because the last argument is always the callback/complete
# function.
#
# See bug 1290966.
def test_introspection_of_arguments(self):
self.marionette.execute_async_script(
"arguments[0].cheese; __webDriverCallback();",
script_args=[], sandbox=None)
class TestExecuteAsyncChrome(TestExecuteAsyncContent):
def setUp(self):
super(TestExecuteAsyncChrome, self).setUp()
self.marionette.set_context("chrome")
def test_execute_async_unload(self):
pass
def test_execute_permission(self):
self.assertEqual(5, self.marionette.execute_async_script("""
var c = Components.classes;
marionetteScriptFinished(5);
"""))
def test_execute_async_js_exception(self):
# Javascript exceptions are not propagated in chrome code
self.marionette.timeout.script = 0.2
self.assertRaises(ScriptTimeoutException,
self.marionette.execute_async_script, """
var callback = arguments[arguments.length - 1];
setTimeout("callback(foo())", 50);
""")
self.assertRaises(JavascriptException,
self.marionette.execute_async_script, """
var callback = arguments[arguments.length - 1];
setTimeout("callback(foo())", 50);
""", debug_script=True)

View file

@ -0,0 +1,37 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import ScriptTimeoutException
from marionette_harness import MarionetteTestCase
class TestExecuteIsolationContent(MarionetteTestCase):
def setUp(self):
super(TestExecuteIsolationContent, self).setUp()
self.content = True
def test_execute_async_isolate(self):
# Results from one execute call that has timed out should not
# contaminate a future call.
multiplier = "*3" if self.content else "*1"
self.marionette.timeout.script = 0.5
self.assertRaises(ScriptTimeoutException,
self.marionette.execute_async_script,
("setTimeout(function() {{ marionetteScriptFinished(5{}); }}, 3000);"
.format(multiplier)))
self.marionette.timeout.script = 6
result = self.marionette.execute_async_script("""
setTimeout(function() {{ marionetteScriptFinished(10{}); }}, 5000);
""".format(multiplier))
self.assertEqual(result, 30 if self.content else 10)
class TestExecuteIsolationChrome(TestExecuteIsolationContent):
def setUp(self):
super(TestExecuteIsolationChrome, self).setUp()
self.marionette.set_context("chrome")
self.content = False

View file

@ -0,0 +1,79 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import JavascriptException
from marionette_harness import MarionetteTestCase
class TestExecuteSandboxes(MarionetteTestCase):
def setUp(self):
super(TestExecuteSandboxes, self).setUp()
def test_execute_system_sandbox(self):
# Test that "system" sandbox has elevated privileges in execute_script
result = self.marionette.execute_script(
"return Components.interfaces.nsIPermissionManager.ALLOW_ACTION",
sandbox="system")
self.assertEqual(result, 1)
def test_execute_async_system_sandbox(self):
# Test that "system" sandbox has elevated privileges in
# execute_async_script.
result = self.marionette.execute_async_script("""
const Ci = Components.interfaces;
let result = Ci.nsIPermissionManager.ALLOW_ACTION;
marionetteScriptFinished(result);""",
sandbox="system")
self.assertEqual(result, 1)
def test_execute_switch_sandboxes(self):
# Test that sandboxes are retained when switching between them
# for execute_script.
self.marionette.execute_script("foo = 1", sandbox="1")
self.marionette.execute_script("foo = 2", sandbox="2")
foo = self.marionette.execute_script(
"return foo", sandbox="1", new_sandbox=False)
self.assertEqual(foo, 1)
foo = self.marionette.execute_script(
"return foo", sandbox="2", new_sandbox=False)
self.assertEqual(foo, 2)
def test_execute_new_sandbox(self):
# test that clearing a sandbox does not affect other sandboxes
self.marionette.execute_script("foo = 1", sandbox="1")
self.marionette.execute_script("foo = 2", sandbox="2")
# deprecate sandbox 1 by asking explicitly for a fresh one
with self.assertRaises(JavascriptException):
self.marionette.execute_script("return foo",
sandbox="1", new_sandbox=True)
foo = self.marionette.execute_script(
"return foo", sandbox="2", new_sandbox=False)
self.assertEqual(foo, 2)
def test_execute_async_switch_sandboxes(self):
# Test that sandboxes are retained when switching between them
# for execute_async_script.
self.marionette.execute_async_script(
"foo = 1; marionetteScriptFinished()", sandbox="1")
self.marionette.execute_async_script(
"foo = 2; marionetteScriptFinished()", sandbox='2')
foo = self.marionette.execute_async_script(
"marionetteScriptFinished(foo)",
sandbox="1",
new_sandbox=False)
self.assertEqual(foo, 1)
foo = self.marionette.execute_async_script(
"marionetteScriptFinished(foo)",
sandbox="2",
new_sandbox=False)
self.assertEqual(foo, 2)
class TestExecuteSandboxesChrome(TestExecuteSandboxes):
def setUp(self):
super(TestExecuteSandboxesChrome, self).setUp()
self.marionette.set_context("chrome")

View file

@ -0,0 +1,402 @@
# 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
import urllib
from marionette_driver import By, errors
from marionette_driver.marionette import HTMLElement
from marionette_driver.wait import Wait
from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin
def inline(doc):
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
elements = inline("<p>foo</p> <p>bar</p>")
globals = set([
"atob",
"Audio",
"btoa",
"document",
"navigator",
"URL",
"window",
])
class TestExecuteSimpleTestContent(MarionetteTestCase):
def test_stack_trace(self):
try:
self.marionette.execute_js_script("""
let a = 1;
throwHere();
""", filename="file.js")
self.assertFalse(True)
except errors.JavascriptException as e:
self.assertIn("throwHere is not defined", e.message)
self.assertIn("@file.js:2", e.stacktrace)
class TestExecuteContent(MarionetteTestCase):
def assert_is_defined(self, property, sandbox="default"):
self.assertTrue(self.marionette.execute_script(
"return typeof arguments[0] != 'undefined'", [property], sandbox=sandbox),
"property {} is undefined".format(property))
def test_return_number(self):
self.assertEqual(1, self.marionette.execute_script("return 1"))
self.assertEqual(1.5, self.marionette.execute_script("return 1.5"))
def test_return_boolean(self):
self.assertTrue(self.marionette.execute_script("return true"))
def test_return_string(self):
self.assertEqual("foo", self.marionette.execute_script("return 'foo'"))
def test_return_array(self):
self.assertEqual(
[1, 2], self.marionette.execute_script("return [1, 2]"))
self.assertEqual(
[1.25, 1.75], self.marionette.execute_script("return [1.25, 1.75]"))
self.assertEqual(
[True, False], self.marionette.execute_script("return [true, false]"))
self.assertEqual(
["foo", "bar"], self.marionette.execute_script("return ['foo', 'bar']"))
self.assertEqual(
[1, 1.5, True, "foo"], self.marionette.execute_script("return [1, 1.5, true, 'foo']"))
self.assertEqual(
[1, [2]], self.marionette.execute_script("return [1, [2]]"))
def test_return_object(self):
self.assertEqual(
{"foo": 1}, self.marionette.execute_script("return {foo: 1}"))
self.assertEqual(
{"foo": 1.5}, self.marionette.execute_script("return {foo: 1.5}"))
self.assertEqual(
{"foo": True}, self.marionette.execute_script("return {foo: true}"))
self.assertEqual(
{"foo": "bar"}, self.marionette.execute_script("return {foo: 'bar'}"))
self.assertEqual(
{"foo": [1, 2]}, self.marionette.execute_script("return {foo: [1, 2]}"))
self.assertEqual(
{"foo": {"bar": [1, 2]}},
self.marionette.execute_script("return {foo: {bar: [1, 2]}}"))
def test_no_return_value(self):
self.assertIsNone(self.marionette.execute_script("true"))
def test_argument_null(self):
self.assertIsNone(self.marionette.execute_script("return arguments[0]", [None]))
def test_argument_number(self):
self.assertEqual(
1, self.marionette.execute_script("return arguments[0]", [1]))
self.assertEqual(
1.5, self.marionette.execute_script("return arguments[0]", [1.5]))
def test_argument_boolean(self):
self.assertTrue(self.marionette.execute_script("return arguments[0]", [True]))
def test_argument_string(self):
self.assertEqual(
"foo", self.marionette.execute_script("return arguments[0]", ["foo"]))
def test_argument_array(self):
self.assertEqual(
[1, 2], self.marionette.execute_script("return arguments[0]", [[1, 2]]))
def test_argument_object(self):
self.assertEqual({"foo": 1}, self.marionette.execute_script(
"return arguments[0]", [{"foo": 1}]))
def test_globals(self):
for property in globals:
self.assert_is_defined(property)
self.assert_is_defined("Components")
self.assert_is_defined("window.wrappedJSObject")
def test_system_globals(self):
for property in globals:
self.assert_is_defined(property, sandbox="system")
self.assert_is_defined("Components", sandbox="system")
self.assert_is_defined("window.wrappedJSObject")
def test_exception(self):
self.assertRaises(errors.JavascriptException,
self.marionette.execute_script, "return foo")
def test_stacktrace(self):
with self.assertRaises(errors.JavascriptException) as cm:
self.marionette.execute_script("return b")
# by default execute_script pass the name of the python file
self.assertIn(os.path.basename(__file__.replace(".pyc", ".py")),
cm.exception.stacktrace)
self.assertIn("b is not defined", cm.exception.message)
self.assertIn("return b", cm.exception.stacktrace)
def test_permission(self):
with self.assertRaises(errors.JavascriptException):
self.marionette.execute_script("""
var c = Components.classes["@mozilla.org/preferences-service;1"];
""")
def test_return_web_element(self):
self.marionette.navigate(elements)
expected = self.marionette.find_element(By.TAG_NAME, "p")
actual = self.marionette.execute_script(
"return document.querySelector('p')")
self.assertEqual(expected, actual)
def test_return_web_element_array(self):
self.marionette.navigate(elements)
expected = self.marionette.find_elements(By.TAG_NAME, "p")
actual = self.marionette.execute_script("""
let els = document.querySelectorAll('p')
return [els[0], els[1]]""")
self.assertEqual(expected, actual)
# Bug 938228 identifies a problem with unmarshaling NodeList
# objects from the DOM. document.querySelectorAll returns this
# construct.
def test_return_web_element_nodelist(self):
self.marionette.navigate(elements)
expected = self.marionette.find_elements(By.TAG_NAME, "p")
actual = self.marionette.execute_script(
"return document.querySelectorAll('p')")
self.assertEqual(expected, actual)
def test_sandbox_reuse(self):
# Sandboxes between `execute_script()` invocations are shared.
self.marionette.execute_script("this.foobar = [23, 42];")
self.assertEqual(self.marionette.execute_script(
"return this.foobar;", new_sandbox=False), [23, 42])
self.marionette.execute_script("global.barfoo = [42, 23];")
self.assertEqual(self.marionette.execute_script(
"return global.barfoo;", new_sandbox=False), [42, 23])
def test_sandbox_refresh_arguments(self):
self.marionette.execute_script(
"this.foobar = [arguments[0], arguments[1]]", [23, 42])
self.assertEqual(self.marionette.execute_script(
"return this.foobar", new_sandbox=False), [23, 42])
def test_wrappedjsobject(self):
try:
self.marionette.execute_script("window.wrappedJSObject.foo = 3")
self.assertEqual(
self.marionette.execute_script("return window.wrappedJSObject.foo"), 3)
finally:
self.marionette.execute_script("delete window.wrappedJSObject.foo")
def test_system_sandbox_wrappedjsobject(self):
self.marionette.execute_script(
"window.wrappedJSObject.foo = 4", sandbox="system")
self.assertEqual(self.marionette.execute_script(
"return window.wrappedJSObject.foo", sandbox="system"), 4)
def test_system_dead_object(self):
self.marionette.execute_script(
"window.wrappedJSObject.foo = function() { return 'yo' }",
sandbox="system")
self.marionette.execute_script(
"dump(window.wrappedJSObject.foo)", sandbox="system")
self.marionette.execute_script(
"window.wrappedJSObject.foo = function() { return 'yolo' }",
sandbox="system")
typ = self.marionette.execute_script(
"return typeof window.wrappedJSObject.foo", sandbox="system")
self.assertEqual("function", typ)
obj = self.marionette.execute_script(
"return window.wrappedJSObject.foo.toString()", sandbox="system")
self.assertIn("yolo", obj)
def test_lasting_side_effects(self):
def send(script):
return self.marionette._send_message(
"executeScript", {"script": script}, key="value")
send("window.foo = 1")
foo = send("return window.foo")
self.assertEqual(1, foo)
for property in globals:
exists = send("return typeof {} != 'undefined'".format(property))
self.assertTrue(exists, "property {} is undefined".format(property))
self.assertTrue(send("return typeof Components.utils == 'undefined'"))
self.assertTrue(send("return typeof window.wrappedJSObject == 'undefined'"))
def test_no_callback(self):
self.assertTrue(self.marionette.execute_script(
"return typeof arguments[0] == 'undefined'"))
def test_window_set_timeout_is_not_cancelled(self):
def content_timeout_triggered(mn):
return mn.execute_script("return window.n", sandbox=None) > 0
# subsequent call to execute_script after this
# should not cancel the setTimeout event
self.marionette.navigate(inline("""
<script>
window.n = 0;
setTimeout(() => ++window.n, 4000);
</script>"""))
# as debug builds are inherently slow,
# we need to assert the event did not already fire
self.assertEqual(0, self.marionette.execute_script(
"return window.n", sandbox=None),
"setTimeout already fired")
# if event was cancelled, this will time out
Wait(self.marionette, timeout=8).until(
content_timeout_triggered,
message="Scheduled setTimeout event was cancelled by call to execute_script")
def test_privileged_code_inspection(self):
# test permission denied on toString of unload event handler
self.marionette.navigate(inline("""
<script>
window.addEventListener = (type, handler) => handler.toString();
</script>"""))
self.marionette.execute_script("", sandbox=None)
# test inspection of arguments
self.marionette.execute_script("__webDriverArguments.toString()")
class TestExecuteChrome(WindowManagerMixin, TestExecuteContent):
def setUp(self):
super(TestExecuteChrome, self).setUp()
self.marionette.set_context("chrome")
def tearDown(self):
super(TestExecuteChrome, self).tearDown()
def test_permission(self):
self.assertEqual(1, self.marionette.execute_script("""
var c = Components.classes["@mozilla.org/preferences-service;1"]; return 1;"""))
@skip_if_mobile("New windows not supported in Fennec")
def test_unmarshal_element_collection(self):
def open_window_with_js():
self.marionette.execute_script(
"window.open('chrome://marionette/content/test.xul', 'xul', 'chrome');")
try:
win = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(win)
expected = self.marionette.find_elements(By.TAG_NAME, "textbox")
actual = self.marionette.execute_script(
"return document.querySelectorAll('textbox')")
self.assertEqual(expected, actual)
finally:
self.close_all_windows()
def test_async_script_timeout(self):
with self.assertRaises(errors.ScriptTimeoutException):
self.marionette.execute_async_script("""
var cb = arguments[arguments.length - 1];
setTimeout(function() { cb() }, 250);
""", script_timeout=100)
@skip_if_mobile("New windows not supported in Fennec")
def test_invalid_chrome_handle(self):
try:
win = self.open_window()
self.marionette.switch_to_window(win)
# Close new window and don't switch back to the original one
self.marionette.close_chrome_window()
self.assertNotEqual(self.start_window, win)
# Call execute_script on an invalid chrome handle
with self.marionette.using_context('chrome'):
self.marionette.execute_script("""
return true;
""")
finally:
self.close_all_windows()
def test_lasting_side_effects(self):
pass
def test_return_web_element(self):
pass
def test_return_web_element_array(self):
pass
def test_return_web_element_nodelist(self):
pass
def test_window_set_timeout_is_not_cancelled(self):
pass
def test_privileged_code_inspection(self):
pass
class TestElementCollections(MarionetteTestCase):
def assertSequenceIsInstance(self, seq, typ):
for item in seq:
self.assertIsInstance(item, typ)
def test_array(self):
self.marionette.navigate(inline("<p>foo <p>bar"))
els = self.marionette.execute_script("return Array.from(document.querySelectorAll('p'))")
self.assertIsInstance(els, list)
self.assertEqual(2, len(els))
self.assertSequenceIsInstance(els, HTMLElement)
def test_html_all_collection(self):
self.marionette.navigate(inline("<p>foo <p>bar"))
els = self.marionette.execute_script("return document.all")
self.assertIsInstance(els, list)
# <html>, <head>, <body>, <p>, <p>
self.assertEqual(5, len(els))
self.assertSequenceIsInstance(els, HTMLElement)
def test_html_collection(self):
self.marionette.navigate(inline("<p>foo <p>bar"))
els = self.marionette.execute_script("return document.getElementsByTagName('p')")
self.assertIsInstance(els, list)
self.assertEqual(2, len(els))
self.assertSequenceIsInstance(els, HTMLElement)
def test_html_form_controls_collection(self):
self.marionette.navigate(inline("<form><input><input></form>"))
els = self.marionette.execute_script("return document.forms[0].elements")
self.assertIsInstance(els, list)
self.assertEqual(2, len(els))
self.assertSequenceIsInstance(els, HTMLElement)
def test_html_options_collection(self):
self.marionette.navigate(inline("<select><option><option></select>"))
els = self.marionette.execute_script("return document.querySelector('select').options")
self.assertIsInstance(els, list)
self.assertEqual(2, len(els))
self.assertSequenceIsInstance(els, HTMLElement)
def test_node_list(self):
self.marionette.navigate(inline("<p>foo <p>bar"))
els = self.marionette.execute_script("return document.querySelectorAll('p')")
self.assertIsInstance(els, list)
self.assertEqual(2, len(els))
self.assertSequenceIsInstance(els, HTMLElement)

View file

@ -0,0 +1,228 @@
# 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 urllib
from marionette_driver import expected
from marionette_driver.by import By
from marionette_harness import marionette_test
def inline(doc):
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
static_element = inline("""<p>foo</p>""")
static_elements = static_element + static_element
remove_element_by_tag_name = \
"""var el = document.getElementsByTagName('{}')[0];
document.getElementsByTagName("body")[0].remove(el);"""
hidden_element = inline("<p style='display: none'>hidden</p>")
selected_element = inline("<option selected>selected</option>")
unselected_element = inline("<option>unselected</option>")
enabled_element = inline("<input>")
disabled_element = inline("<input disabled>")
def no_such_element(marionette):
return marionette.find_element(By.ID, "nosuchelement")
def no_such_elements(marionette):
return marionette.find_elements(By.ID, "nosuchelement")
def p(marionette):
return marionette.find_element(By.TAG_NAME, "p")
def ps(marionette):
return marionette.find_elements(By.TAG_NAME, "p")
class TestExpected(marionette_test.MarionetteTestCase):
def test_element_present_func(self):
self.marionette.navigate(static_element)
el = expected.element_present(p)(self.marionette)
self.assertIsNotNone(el)
def test_element_present_locator(self):
self.marionette.navigate(static_element)
el = expected.element_present(By.TAG_NAME, "p")(self.marionette)
self.assertIsNotNone(el)
def test_element_present_not_present(self):
r = expected.element_present(no_such_element)(self.marionette)
self.assertIsInstance(r, bool)
self.assertFalse(r)
def test_element_not_present_func(self):
r = expected.element_not_present(no_such_element)(self.marionette)
self.assertIsInstance(r, bool)
self.assertTrue(r)
def test_element_not_present_locator(self):
r = expected.element_not_present(By.ID, "nosuchelement")(self.marionette)
self.assertIsInstance(r, bool)
self.assertTrue(r)
def test_element_not_present_is_present(self):
self.marionette.navigate(static_element)
r = expected.element_not_present(p)(self.marionette)
self.assertIsInstance(r, bool)
self.assertFalse(r)
def test_element_stale(self):
self.marionette.navigate(static_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
self.assertIsNotNone(el)
self.marionette.execute_script(remove_element_by_tag_name.format("p"))
r = expected.element_stale(el)(self.marionette)
self.assertTrue(r)
def test_element_stale_is_not_stale(self):
self.marionette.navigate(static_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
r = expected.element_stale(el)(self.marionette)
self.assertFalse(r)
def test_elements_present_func(self):
self.marionette.navigate(static_elements)
els = expected.elements_present(ps)(self.marionette)
self.assertEqual(len(els), 2)
def test_elements_present_locator(self):
self.marionette.navigate(static_elements)
els = expected.elements_present(By.TAG_NAME, "p")(self.marionette)
self.assertEqual(len(els), 2)
def test_elements_present_not_present(self):
r = expected.elements_present(no_such_elements)(self.marionette)
self.assertEqual(r, [])
def test_elements_not_present_func(self):
r = expected.element_not_present(no_such_elements)(self.marionette)
self.assertIsInstance(r, bool)
self.assertTrue(r)
def test_elements_not_present_locator(self):
r = expected.element_not_present(By.ID, "nosuchelement")(self.marionette)
self.assertIsInstance(r, bool)
self.assertTrue(r)
def test_elements_not_present_is_present(self):
self.marionette.navigate(static_elements)
r = expected.elements_not_present(ps)(self.marionette)
self.assertIsInstance(r, bool)
self.assertFalse(r)
def test_element_displayed(self):
self.marionette.navigate(static_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
visible = expected.element_displayed(el)(self.marionette)
self.assertTrue(visible)
def test_element_displayed_locator(self):
self.marionette.navigate(static_element)
visible = expected.element_displayed(By.TAG_NAME, "p")(self.marionette)
self.assertTrue(visible)
def test_element_displayed_when_hidden(self):
self.marionette.navigate(hidden_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
visible = expected.element_displayed(el)(self.marionette)
self.assertFalse(visible)
def test_element_displayed_when_hidden_locator(self):
self.marionette.navigate(hidden_element)
visible = expected.element_displayed(By.TAG_NAME, "p")(self.marionette)
self.assertFalse(visible)
def test_element_displayed_when_not_present(self):
self.marionette.navigate("about:blank")
visible = expected.element_displayed(By.TAG_NAME, "p")(self.marionette)
self.assertFalse(visible)
def test_element_displayed_when_stale_element(self):
self.marionette.navigate(static_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
self.marionette.navigate("about:blank")
missing = expected.element_displayed(el)(self.marionette)
self.assertFalse(missing)
def test_element_not_displayed(self):
self.marionette.navigate(hidden_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
hidden = expected.element_not_displayed(el)(self.marionette)
self.assertTrue(hidden)
def test_element_not_displayed_locator(self):
self.marionette.navigate(hidden_element)
hidden = expected.element_not_displayed(By.TAG_NAME, "p")(self.marionette)
self.assertTrue(hidden)
def test_element_not_displayed_when_visible(self):
self.marionette.navigate(static_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
hidden = expected.element_not_displayed(el)(self.marionette)
self.assertFalse(hidden)
def test_element_not_displayed_when_visible_locator(self):
self.marionette.navigate(static_element)
hidden = expected.element_not_displayed(By.TAG_NAME, "p")(self.marionette)
self.assertFalse(hidden)
def test_element_not_displayed_when_stale_element(self):
self.marionette.navigate(static_element)
el = self.marionette.find_element(By.TAG_NAME, "p")
self.marionette.navigate("about:blank")
missing = expected.element_not_displayed(el)(self.marionette)
self.assertTrue(missing)
def test_element_selected(self):
self.marionette.navigate(selected_element)
el = self.marionette.find_element(By.TAG_NAME, "option")
selected = expected.element_selected(el)(self.marionette)
self.assertTrue(selected)
def test_element_selected_when_not_selected(self):
self.marionette.navigate(unselected_element)
el = self.marionette.find_element(By.TAG_NAME, "option")
unselected = expected.element_selected(el)(self.marionette)
self.assertFalse(unselected)
def test_element_not_selected(self):
self.marionette.navigate(unselected_element)
el = self.marionette.find_element(By.TAG_NAME, "option")
unselected = expected.element_not_selected(el)(self.marionette)
self.assertTrue(unselected)
def test_element_not_selected_when_selected(self):
self.marionette.navigate(selected_element)
el = self.marionette.find_element(By.TAG_NAME, "option")
selected = expected.element_not_selected(el)(self.marionette)
self.assertFalse(selected)
def test_element_enabled(self):
self.marionette.navigate(enabled_element)
el = self.marionette.find_element(By.TAG_NAME, "input")
enabled = expected.element_enabled(el)(self.marionette)
self.assertTrue(enabled)
def test_element_enabled_when_disabled(self):
self.marionette.navigate(disabled_element)
el = self.marionette.find_element(By.TAG_NAME, "input")
disabled = expected.element_enabled(el)(self.marionette)
self.assertFalse(disabled)
def test_element_not_enabled(self):
self.marionette.navigate(disabled_element)
el = self.marionette.find_element(By.TAG_NAME, "input")
disabled = expected.element_not_enabled(el)(self.marionette)
self.assertTrue(disabled)
def test_element_not_enabled_when_enabled(self):
self.marionette.navigate(enabled_element)
el = self.marionette.find_element(By.TAG_NAME, "input")
enabled = expected.element_not_enabled(el)(self.marionette)
self.assertFalse(enabled)

View file

@ -0,0 +1,11 @@
# 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_harness import MarionetteTestCase
class TestFail(MarionetteTestCase):
def test_fails(self):
# this test is supposed to fail!
self.assertEquals(True, False)

View file

@ -0,0 +1,152 @@
# 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 contextlib
import urllib
from tempfile import NamedTemporaryFile as tempfile
from marionette_driver import By, errors, expected
from marionette_driver.wait import Wait
from marionette_harness import MarionetteTestCase, skip
single = "data:text/html,{}".format(urllib.quote("<input type=file>"))
multiple = "data:text/html,{}".format(urllib.quote("<input type=file multiple>"))
upload = lambda url: "data:text/html,{}".format(urllib.quote("""
<form action='{}' method=post enctype='multipart/form-data'>
<input type=file>
<input type=submit>
</form>""".format(url)))
class TestFileUpload(MarionetteTestCase):
def test_sets_one_file(self):
self.marionette.navigate(single)
input = self.input
exp = None
with tempfile() as f:
input.send_keys(f.name)
exp = [f.name]
files = self.get_file_names(input)
self.assertEqual(len(files), 1)
self.assertFileNamesEqual(files, exp)
def test_sets_multiple_files(self):
self.marionette.navigate(multiple)
input = self.input
exp = None
with contextlib.nested(tempfile(), tempfile()) as (a, b):
input.send_keys(a.name)
input.send_keys(b.name)
exp = [a.name, b.name]
files = self.get_file_names(input)
self.assertEqual(len(files), 2)
self.assertFileNamesEqual(files, exp)
def test_sets_multiple_indentical_files(self):
self.marionette.navigate(multiple)
input = self.input
exp = []
with tempfile() as f:
input.send_keys(f.name)
input.send_keys(f.name)
exp = f.name
files = self.get_file_names(input)
self.assertEqual(len(files), 2)
self.assertFileNamesEqual(files, exp)
def test_clear_file(self):
self.marionette.navigate(single)
input = self.input
with tempfile() as f:
input.send_keys(f.name)
self.assertEqual(len(self.get_files(input)), 1)
input.clear()
self.assertEqual(len(self.get_files(input)), 0)
def test_clear_files(self):
self.marionette.navigate(multiple)
input = self.input
with contextlib.nested(tempfile(), tempfile()) as (a, b):
input.send_keys(a.name)
input.send_keys(b.name)
self.assertEqual(len(self.get_files(input)), 2)
input.clear()
self.assertEqual(len(self.get_files(input)), 0)
def test_illegal_file(self):
self.marionette.navigate(single)
with self.assertRaisesRegexp(errors.MarionetteException, "File not found"):
self.input.send_keys("rochefort")
def test_upload(self):
self.marionette.navigate(
upload(self.marionette.absolute_url("file_upload")))
url = self.marionette.get_url()
with tempfile() as f:
f.write("camembert")
f.flush()
self.input.send_keys(f.name)
self.submit.click()
Wait(self.marionette).until(lambda m: m.get_url() != url)
self.assertIn("multipart/form-data", self.body.text)
def test_change_event(self):
self.marionette.navigate(single)
self.marionette.execute_script("""
window.changeEvs = [];
let el = arguments[arguments.length - 1];
el.addEventListener("change", ev => window.changeEvs.push(ev));
console.log(window.changeEvs.length);
""", script_args=(self.input,), sandbox=None)
with tempfile() as f:
self.input.send_keys(f.name)
nevs = self.marionette.execute_script(
"return window.changeEvs.length", sandbox=None)
self.assertEqual(1, nevs)
def find_inputs(self):
return self.marionette.find_elements(By.TAG_NAME, "input")
@property
def input(self):
return self.find_inputs()[0]
@property
def submit(self):
return self.find_inputs()[1]
@property
def body(self):
return Wait(self.marionette).until(
expected.element_present(By.TAG_NAME, "body"))
def get_file_names(self, el):
fl = self.get_files(el)
return [f["name"] for f in fl]
def get_files(self, el):
return self.marionette.execute_script(
"return arguments[0].files", script_args=[el])
def assertFileNamesEqual(self, act, exp):
# File array returned from browser doesn't contain full path names,
# this cuts off the path of the expected files.
filenames = [f.rsplit("/", 0)[-1] for f in act]
self.assertListEqual(filenames, act)

View file

@ -0,0 +1,82 @@
# 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.by import By
from marionette_driver.errors import NoSuchElementException
from marionette_driver.marionette import HTMLElement
from marionette_harness import MarionetteTestCase
class TestElementsChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_id(self):
el = self.marionette.execute_script("return window.document.getElementById('textInput');")
found_el = self.marionette.find_element(By.ID, "textInput")
self.assertEqual(HTMLElement, type(found_el))
self.assertEqual(el, found_el)
def test_that_we_can_find_elements_from_css_selectors(self):
el = self.marionette.execute_script("return window.document.getElementById('textInput');")
found_el = self.marionette.find_element(By.CSS_SELECTOR, "#textInput")
self.assertEqual(HTMLElement, type(found_el))
self.assertEqual(el, found_el)
def test_child_element(self):
el = self.marionette.find_element(By.ID, "textInput")
parent = self.marionette.find_element(By.ID, "things")
found_el = parent.find_element(By.TAG_NAME, "textbox")
self.assertEqual(HTMLElement, type(found_el))
self.assertEqual(el, found_el)
def test_child_elements(self):
el = self.marionette.find_element(By.ID, "textInput3")
parent = self.marionette.find_element(By.ID, "things")
found_els = parent.find_elements(By.TAG_NAME, "textbox")
self.assertTrue(el.id in [found_el.id for found_el in found_els])
def test_tag_name(self):
el = self.marionette.execute_script("return window.document.getElementsByTagName('vbox')[0];")
found_el = self.marionette.find_element(By.TAG_NAME, "vbox")
self.assertEquals('vbox', found_el.tag_name)
self.assertEqual(HTMLElement, type(found_el))
self.assertEqual(el, found_el)
def test_class_name(self):
el = self.marionette.execute_script("return window.document.getElementsByClassName('asdf')[0];")
found_el = self.marionette.find_element(By.CLASS_NAME, "asdf")
self.assertEqual(HTMLElement, type(found_el))
self.assertEqual(el, found_el)
def test_xpath(self):
el = self.marionette.execute_script("return window.document.getElementById('testBox');")
found_el = self.marionette.find_element(By.XPATH, "id('testBox')")
self.assertEqual(HTMLElement, type(found_el))
self.assertEqual(el, found_el)
def test_not_found(self):
self.marionette.timeout.implicit = 1
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "I'm not on the page")
self.marionette.timeout.implicit = 0
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "I'm not on the page")
def test_timeout(self):
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "myid")
self.marionette.timeout.implicit = 4
self.marionette.execute_script("window.setTimeout(function() {var b = window.document.createElement('button'); b.id = 'myid'; document.getElementById('things').appendChild(b);}, 1000)")
self.assertEqual(HTMLElement, type(self.marionette.find_element(By.ID, "myid")))
self.marionette.execute_script("window.document.getElementById('things').removeChild(window.document.getElementById('myid'));")

View file

@ -0,0 +1,25 @@
# 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.geckoinstance import apps, GeckoInstance
from marionette_harness import MarionetteTestCase
class TestGeckoInstance(MarionetteTestCase):
def test_create(self):
"""Test that the correct gecko instance is determined."""
for app in apps:
# If app has been specified we directly return the appropriate instance class
self.assertEqual(type(GeckoInstance.create(app=app, bin="n/a")),
apps[app])
# Unknown applications and binaries should fail
self.assertRaises(NotImplementedError, GeckoInstance.create,
app="n/a", bin=self.marionette.bin)
self.assertRaises(NotImplementedError, GeckoInstance.create,
bin="n/a")
self.assertRaises(NotImplementedError, GeckoInstance.create,
bin=None)

View file

@ -0,0 +1,93 @@
# 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.by import By
from marionette_harness import MarionetteTestCase
OOP_BY_DEFAULT = "dom.ipc.browser_frames.oop_by_default"
BROWSER_FRAMES_ENABLED = "dom.mozBrowserFramesEnabeld"
class TestGetActiveFrameOOP(MarionetteTestCase):
def setUp(self):
super(TestGetActiveFrameOOP, self).setUp()
with self.marionette.using_context("chrome"):
self.oop_by_default = self.marionette.get_pref(OOP_BY_DEFAULT)
self.mozBrowserFramesEnabled = self.marionette.get_pref(BROWSER_FRAMES_ENABLED)
self.marionette.set_pref(OOP_BY_DEFAULT, True)
self.marionette.set_pref(BROWSER_FRAMES_ENABLED, True)
def tearDown(self):
with self.marionette.using_context("chrome"):
if self.oop_by_default is None:
self.marionette.clear_pref(OOP_BY_DEFAULT)
else:
self.marionette.set_pref(OOP_BY_DEFAULT, self.oop_by_default)
if self.mozBrowserFramesEnabled is None:
self.marionette.clear_pref(BROWSER_FRAMES_ENABLED)
else:
self.marionette.set_pref(BROWSER_FRAMES_ENABLED, self.mozBrowserFramesEnabled)
def test_active_frame_oop(self):
self.marionette.navigate(self.marionette.absolute_url("test.html"))
self.marionette.push_permission('browser', True)
# Create first OOP frame
self.marionette.execute_script("""
let iframe1 = document.createElement("iframe");
iframe1.id = "remote_iframe1";
iframe1.setAttribute('remote', true);
iframe1.setAttribute('mozbrowser', true);
iframe1.style.height = "100px";
iframe1.style.width = "100%%";
iframe1.src = "{}";
document.body.appendChild(iframe1);
""".format(self.marionette.absolute_url("test_oop_1.html")))
# Currently no active frame
self.assertEqual(self.marionette.get_active_frame(), None)
self.assertTrue("test.html" in self.marionette.get_url())
# Switch to iframe1, get active frame
frame = self.marionette.find_element(By.ID, 'remote_iframe1')
self.marionette.switch_to_frame(frame)
active_frame1 = self.marionette.get_active_frame()
self.assertNotEqual(active_frame1.id, None)
# Switch to top-level then back to active frame, verify correct frame
self.marionette.switch_to_frame()
self.marionette.switch_to_frame(active_frame1)
self.assertTrue("test_oop_1.html" in self.marionette.execute_script("return document.wrappedJSObject.location.href"))
# Create another OOP frame
self.marionette.switch_to_frame()
self.marionette.execute_script("""
let iframe2 = document.createElement("iframe");
iframe2.setAttribute('mozbrowser', true);
iframe2.setAttribute('remote', true);
iframe2.id = "remote_iframe2";
iframe2.style.height = "100px";
iframe2.style.width = "100%%";
iframe2.src = "{}";
document.body.appendChild(iframe2);
""".format(self.marionette.absolute_url("test_oop_2.html")))
# Switch to iframe2, get active frame
frame2 = self.marionette.find_element(By.ID, 'remote_iframe2')
self.marionette.switch_to_frame(frame2)
active_frame2 = self.marionette.get_active_frame()
self.assertNotEqual(active_frame2.id, None)
# Switch to top-level then back to active frame 1, verify correct frame
self.marionette.switch_to_frame()
self.marionette.switch_to_frame(active_frame1)
self.assertTrue("test_oop_1.html" in self.marionette.execute_script("return document.wrappedJSObject.location.href"))
# Switch to top-level then back to active frame 2, verify correct frame
self.marionette.switch_to_frame()
self.marionette.switch_to_frame(active_frame2)
self.assertTrue("test_oop_2.html" in self.marionette.execute_script("return document.wrappedJSObject.location.href"))

View file

@ -0,0 +1,26 @@
# 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.by import By
from marionette_driver.errors import NoSuchElementException
from marionette_harness import MarionetteTestCase
class TestImplicitWaits(MarionetteTestCase):
def test_implicitly_wait_for_single_element(self):
test_html = self.marionette.absolute_url("test_dynamic.html")
self.marionette.navigate(test_html)
add = self.marionette.find_element(By.ID, "adder")
self.marionette.timeout.implicit = 30
add.click()
# all is well if this does not throw
self.marionette.find_element(By.ID, "box0")
def test_implicit_wait_reaches_timeout(self):
test_html = self.marionette.absolute_url("test_dynamic.html")
self.marionette.navigate(test_html)
self.marionette.timeout.implicit = 3
with self.assertRaises(NoSuchElementException):
self.marionette.find_element(By.ID, "box0")

View file

@ -0,0 +1,138 @@
# 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 marionette_driver.by import By
from marionette_driver.errors import JavascriptException
from marionette_harness import (
MarionetteTestCase,
skip_if_chrome,
skip_if_mobile,
WindowManagerMixin,
)
class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase):
contexts = set(["chrome", "content"])
script_file = os.path.abspath(
os.path.join(__file__, os.path.pardir, "importscript.js"))
another_script_file = os.path.abspath(
os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
def setUp(self):
super(TestImportScriptContent, self).setUp()
for context in self.contexts:
with self.marionette.using_context(context):
self.marionette.clear_imported_scripts()
self.reset_context()
def tearDown(self):
self.close_all_windows()
super(TestImportScriptContent, self).tearDown()
def reset_context(self):
self.marionette.set_context("content")
@property
def current_context(self):
return self.marionette._send_message("getContext", key="value")
@property
def other_context(self):
return self.contexts.copy().difference([self.current_context]).pop()
def is_defined(self, symbol):
return self.marionette.execute_script(
"return typeof {} != 'undefined'".format(symbol))
def assert_defined(self, symbol, msg=None):
if msg is None:
msg = "Expected symbol {} to be defined".format(symbol)
self.assertTrue(self.is_defined(symbol), msg)
def assert_undefined(self, symbol, msg=None):
if msg is None:
msg = "Expected symbol {} to be undefined".format(symbol)
self.assertFalse(self.is_defined(symbol), msg)
def assert_scripts_cleared(self):
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
self.marionette.clear_imported_scripts()
self.assert_undefined("testFunc")
def test_import_script(self):
self.marionette.import_script(self.script_file)
self.assertEqual(
"i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script(
"marionetteScriptFinished(testFunc());"))
def test_import_script_twice(self):
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
# TODO(ato): Note that the WebDriver command primitives
# does not allow us to check what scripts have been imported.
# I suspect we must to do this through an xpcshell test.
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
def test_import_script_and_clear(self):
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
self.marionette.clear_imported_scripts()
self.assert_scripts_cleared()
self.assert_undefined("testFunc")
with self.assertRaises(JavascriptException):
self.marionette.execute_script("return testFunc()")
with self.assertRaises(JavascriptException):
self.marionette.execute_async_script(
"marionetteScriptFinished(testFunc())")
def test_clear_scripts_in_other_context(self):
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
# clearing other context's script file should not affect ours
with self.marionette.using_context(self.other_context):
self.marionette.clear_imported_scripts()
self.assert_undefined("testFunc")
self.assert_defined("testFunc")
def test_multiple_imports(self):
self.marionette.import_script(self.script_file)
self.marionette.import_script(self.another_script_file)
self.assert_defined("testFunc")
self.assert_defined("testAnotherFunc")
@skip_if_chrome("Needs content scope")
@skip_if_mobile("New windows not supported in Fennec")
def test_imports_apply_globally(self):
self.marionette.navigate(
self.marionette.absolute_url("test_windows.html"))
def open_window_with_link():
self.marionette.find_element(By.LINK_TEXT, "Open new window").click()
new_window = self.open_window(trigger=open_window_with_link)
self.marionette.switch_to_window(new_window)
self.marionette.import_script(self.script_file)
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
self.assert_defined("testFunc")
class TestImportScriptChrome(TestImportScriptContent):
def reset_context(self):
self.marionette.set_context("chrome")

View file

@ -0,0 +1,91 @@
# 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.by import By
from marionette_driver.keys import Keys
from marionette_driver.marionette import Actions
from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin
class TestKeyActions(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestKeyActions, self).setUp()
if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META
else:
self.mod_key = Keys.CONTROL
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
self.reporter_element = self.marionette.find_element(By.ID, "keyReporter")
self.reporter_element.click()
self.key_action = Actions(self.marionette)
@property
def key_reporter_value(self):
return self.reporter_element.get_property("value")
def test_key_action_basic_input(self):
self.key_action.key_down("a").key_down("b").key_down("c").perform()
self.assertEqual(self.key_reporter_value, "abc")
def test_upcase_input(self):
(self.key_action.key_down(Keys.SHIFT)
.key_down("a")
.key_up(Keys.SHIFT)
.key_down("b")
.key_down("c")
.perform())
self.assertEqual(self.key_reporter_value, "Abc")
def test_replace_input(self):
self.key_action.key_down("a").key_down("b").key_down("c").perform()
self.assertEqual(self.key_reporter_value, "abc")
(self.key_action.key_down(self.mod_key)
.key_down("a")
.key_up(self.mod_key)
.key_down("x")
.perform())
self.assertEqual(self.key_reporter_value, "x")
def test_clear_input(self):
self.key_action.key_down("a").key_down("b").key_down("c").perform()
self.assertEqual(self.key_reporter_value, "abc")
(self.key_action.key_down(self.mod_key)
.key_down("a")
.key_down("x")
.perform())
self.assertEqual(self.key_reporter_value, "")
self.key_action.key_down("a").key_down("b").key_down("c").perform()
self.assertEqual(self.key_reporter_value, "abc")
def test_input_with_wait(self):
self.key_action.key_down("a").key_down("b").key_down("c").perform()
(self.key_action.key_down(self.mod_key)
.key_down("a")
.wait(.5)
.key_down("x")
.perform())
self.assertEqual(self.key_reporter_value, "")
@skip_if_mobile("Interacting with chrome windows not available for Fennec")
def test_open_in_new_window_shortcut(self):
def open_window_with_action():
el = self.marionette.find_element(By.ID, "updatediv")
# Ensure that the element is in the current view port because press() doesn't
# handle that inside the action chain (bug 1295538).
self.marionette.execute_script('arguments[0].scrollIntoView()', script_args=[el])
(self.key_action.key_down(Keys.SHIFT)
.press(el)
.release()
.key_up(Keys.SHIFT)
.perform())
new_window = self.open_window(trigger=open_window_with_action)
self.marionette.switch_to_window(new_window)
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
self.assertEqual(self.key_reporter_value, "")

View file

@ -0,0 +1,56 @@
# 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
from marionette_driver.errors import (
InvalidArgumentException,
NoSuchElementException,
UnknownException
)
from marionette_driver.localization import L10n
from marionette_harness import MarionetteTestCase
class TestL10n(MarionetteTestCase):
def setUp(self):
super(TestL10n, self).setUp()
self.l10n = L10n(self.marionette)
def test_localize_entity(self):
dtds = ['chrome://marionette/content/test_dialog.dtd']
value = self.l10n.localize_entity(dtds, 'testDialog.title')
self.assertEqual(value, 'Test Dialog')
def test_localize_entity_invalid_arguments(self):
dtds = ['chrome://marionette/content/test_dialog.dtd']
self.assertRaises(NoSuchElementException,
self.l10n.localize_entity, dtds, 'notExistent')
self.assertRaises(InvalidArgumentException,
self.l10n.localize_entity, dtds[0], 'notExistent')
self.assertRaises(InvalidArgumentException,
self.l10n.localize_entity, dtds, True)
def test_localize_property(self):
properties = ['chrome://marionette/content/test_dialog.properties']
value = self.l10n.localize_property(properties, 'testDialog.title')
self.assertEqual(value, 'Test Dialog')
self.assertRaises(NoSuchElementException,
self.l10n.localize_property, properties, 'notExistent')
def test_localize_property_invalid_arguments(self):
properties = ['chrome://global/locale/filepicker.properties']
self.assertRaises(NoSuchElementException,
self.l10n.localize_property, properties, 'notExistent')
self.assertRaises(InvalidArgumentException,
self.l10n.localize_property, properties[0], 'notExistent')
self.assertRaises(InvalidArgumentException,
self.l10n.localize_property, properties, True)

View file

@ -0,0 +1,64 @@
# 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_harness import MarionetteTestCase
class TestLog(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
# clears log cache
self.marionette.get_logs()
def test_log(self):
self.marionette.log("foo")
logs = self.marionette.get_logs()
self.assertEqual("INFO", logs[0][0])
self.assertEqual("foo", logs[0][1])
def test_log_level(self):
self.marionette.log("foo", "ERROR")
logs = self.marionette.get_logs()
self.assertEqual("ERROR", logs[0][0])
self.assertEqual("foo", logs[0][1])
def test_clear(self):
self.marionette.log("foo")
self.assertEqual(1, len(self.marionette.get_logs()))
self.assertEqual(0, len(self.marionette.get_logs()))
def test_multiple_entries(self):
self.marionette.log("foo")
self.marionette.log("bar")
self.assertEqual(2, len(self.marionette.get_logs()))
def test_log_from_sync_script(self):
self.marionette.execute_script("log('foo')")
logs = self.marionette.get_logs()
self.assertEqual("INFO", logs[0][0])
self.assertEqual("foo", logs[0][1])
def test_log_from_sync_script_level(self):
self.marionette.execute_script("log('foo', 'ERROR')")
logs = self.marionette.get_logs()
self.assertEqual("ERROR", logs[0][0])
self.assertEqual("foo", logs[0][1])
def test_log_from_async_script(self):
self.marionette.execute_async_script("log('foo'); arguments[0]();")
logs = self.marionette.get_logs()
self.assertEqual("INFO", logs[0][0])
self.assertEqual("foo", logs[0][1])
def test_log_from_async_script_variable_arguments(self):
self.marionette.execute_async_script("log('foo', 'ERROR'); arguments[0]();")
logs = self.marionette.get_logs()
self.assertEqual("ERROR", logs[0][0])
self.assertEqual("foo", logs[0][1])
class TestLogChrome(TestLog):
def setUp(self):
TestLog.setUp(self)
self.marionette.set_context("chrome")

View file

@ -0,0 +1,67 @@
# 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 itertools
import time
from marionette_driver import errors
from marionette_harness import MarionetteTestCase, run_if_manage_instance, skip_if_mobile
class TestMarionette(MarionetteTestCase):
def test_correct_test_name(self):
"""Test that the correct test name gets set."""
expected_test_name = '{module}.py {cls}.{func}'.format(
module=__name__,
cls=self.__class__.__name__,
func=self.test_correct_test_name.__name__,
)
self.assertEqual(self.marionette.test_name, expected_test_name)
@run_if_manage_instance("Only runnable if Marionette manages the instance")
@skip_if_mobile("Bug 1322993 - Missing temporary folder")
def test_wait_for_port_non_existing_process(self):
"""Test that wait_for_port doesn't run into a timeout if instance is not running."""
self.marionette.quit()
self.assertIsNotNone(self.marionette.instance.runner.returncode)
start_time = time.time()
self.assertFalse(self.marionette.wait_for_port(timeout=5))
self.assertLess(time.time() - start_time, 5)
class TestProtocol2Errors(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.op = self.marionette.protocol
self.marionette.protocol = 2
def tearDown(self):
self.marionette.protocol = self.op
MarionetteTestCase.tearDown(self)
def test_malformed_packet(self):
req = ["error", "message", "stacktrace"]
ps = []
for p in [p for i in range(0, len(req) + 1) for p in itertools.permutations(req, i)]:
ps.append(dict((x, None) for x in p))
for p in filter(lambda p: len(p) < 3, ps):
self.assertRaises(KeyError, self.marionette._handle_error, p)
def test_known_error_status(self):
with self.assertRaises(errors.NoSuchElementException):
self.marionette._handle_error(
{"error": errors.NoSuchElementException.status,
"message": None,
"stacktrace": None})
def test_unknown_error_status(self):
with self.assertRaises(errors.MarionetteException):
self.marionette._handle_error(
{"error": "barbera",
"message": None,
"stacktrace": None})

View file

@ -0,0 +1,198 @@
# 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.by import By
from marionette_driver.errors import NoAlertPresentException, ElementNotInteractableException
from marionette_driver.marionette import Alert
from marionette_driver.wait import Wait
from marionette_harness import MarionetteTestCase, skip_if_e10s
class TestTabModals(MarionetteTestCase):
def setUp(self):
super(TestTabModals, self).setUp()
self.marionette.set_pref("prompts.tab_modal.enabled", True)
self.marionette.navigate(self.marionette.absolute_url('modal_dialogs.html'))
def tearDown(self):
# Ensure an alert is absent before proceeding past this test.
Wait(self.marionette).until(lambda _: not self.alert_present())
self.marionette.execute_script("window.onbeforeunload = null;")
self.marionette.clear_pref("prompts.tab_modal.enabled")
super(TestTabModals, self).tearDown()
def alert_present(self):
try:
Alert(self.marionette).text
return True
except NoAlertPresentException:
return False
def wait_for_alert(self):
Wait(self.marionette).until(lambda _: self.alert_present())
def test_no_alert_raises(self):
self.assertRaises(NoAlertPresentException, Alert(self.marionette).accept)
self.assertRaises(NoAlertPresentException, Alert(self.marionette).dismiss)
def test_alert_accept(self):
self.marionette.find_element(By.ID, 'modal-alert').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.accept()
def test_alert_dismiss(self):
self.marionette.find_element(By.ID, 'modal-alert').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.dismiss()
def test_confirm_accept(self):
self.marionette.find_element(By.ID, 'modal-confirm').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.accept()
self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'confirm-result').text == 'true')
def test_confirm_dismiss(self):
self.marionette.find_element(By.ID, 'modal-confirm').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.dismiss()
self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'confirm-result').text == 'false')
def test_prompt_accept(self):
self.marionette.find_element(By.ID, 'modal-prompt').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.accept()
self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == '')
def test_prompt_dismiss(self):
self.marionette.find_element(By.ID, 'modal-prompt').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.dismiss()
self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == 'null')
def test_alert_text(self):
with self.assertRaises(NoAlertPresentException):
alert = self.marionette.switch_to_alert()
alert.text
self.marionette.find_element(By.ID, 'modal-alert').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
self.assertEqual(alert.text, 'Marionette alert')
alert.accept()
def test_prompt_text(self):
with self.assertRaises(NoAlertPresentException):
alert = self.marionette.switch_to_alert()
alert.text
self.marionette.find_element(By.ID, 'modal-prompt').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
self.assertEqual(alert.text, 'Marionette prompt')
alert.accept()
def test_confirm_text(self):
with self.assertRaises(NoAlertPresentException):
alert = self.marionette.switch_to_alert()
alert.text
self.marionette.find_element(By.ID, 'modal-confirm').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
self.assertEqual(alert.text, 'Marionette confirm')
alert.accept()
def test_set_text_throws(self):
self.assertRaises(NoAlertPresentException, Alert(self.marionette).send_keys, "Foo")
self.marionette.find_element(By.ID, 'modal-alert').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
self.assertRaises(ElementNotInteractableException, alert.send_keys, "Foo")
alert.accept()
def test_set_text_accept(self):
self.marionette.find_element(By.ID, 'modal-prompt').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.send_keys("Some text!");
alert.accept()
self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == 'Some text!')
def test_set_text_dismiss(self):
self.marionette.find_element(By.ID, 'modal-prompt').click()
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
alert.send_keys("Some text!");
alert.dismiss()
self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == 'null')
def test_onbeforeunload_dismiss(self):
start_url = self.marionette.get_url()
self.marionette.find_element(By.ID, 'onbeforeunload-handler').click()
self.wait_for_condition(
lambda mn: mn.execute_script("""
return window.onbeforeunload !== null;
"""))
self.marionette.navigate("about:blank")
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
self.assertTrue(alert.text.startswith("This page is asking you to confirm"))
alert.dismiss()
self.assertTrue(self.marionette.get_url().startswith(start_url))
def test_onbeforeunload_accept(self):
self.marionette.find_element(By.ID, 'onbeforeunload-handler').click()
self.wait_for_condition(
lambda mn: mn.execute_script("""
return window.onbeforeunload !== null;
"""))
self.marionette.navigate("about:blank")
self.wait_for_alert()
alert = self.marionette.switch_to_alert()
self.assertTrue(alert.text.startswith("This page is asking you to confirm"))
alert.accept()
self.wait_for_condition(lambda mn: mn.get_url() == "about:blank")
@skip_if_e10s("Bug 1325044")
def test_unrelated_command_when_alert_present(self):
click_handler = self.marionette.find_element(By.ID, 'click-handler')
text = self.marionette.find_element(By.ID, 'click-result').text
self.assertEqual(text, '')
self.marionette.find_element(By.ID, 'modal-alert').click()
self.wait_for_alert()
# Commands succeed, but because the dialog blocks the event loop,
# our actions aren't reflected on the page.
text = self.marionette.find_element(By.ID, 'click-result').text
self.assertEqual(text, '')
click_handler.click()
text = self.marionette.find_element(By.ID, 'click-result').text
self.assertEqual(text, '')
alert = self.marionette.switch_to_alert()
alert.accept()
Wait(self.marionette).until(lambda _: not self.alert_present())
click_handler.click()
text = self.marionette.find_element(By.ID, 'click-result').text
self.assertEqual(text, 'result')
class TestGlobalModals(TestTabModals):
def setUp(self):
super(TestGlobalModals, self).setUp()
self.marionette.set_pref("prompts.tab_modal.enabled", False)
def test_unrelated_command_when_alert_present(self):
# The assumptions in this test do not hold on certain platforms, and not when
# e10s is enabled.
pass

View file

@ -0,0 +1,114 @@
# 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.by import By
from marionette_driver.keys import Keys
from marionette_driver.marionette import Actions
from marionette_harness import MarionetteTestCase
class TestMouseAction(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META
else:
self.mod_key = Keys.CONTROL
self.action = Actions(self.marionette)
def test_click_action(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
link = self.marionette.find_element(By.ID, "mozLink")
self.action.click(link).perform()
self.assertEqual("Clicked", self.marionette.execute_script(
"return document.getElementById('mozLink').innerHTML"))
def test_clicking_element_out_of_view_succeeds(self):
# The action based click doesn"t check for visibility.
test_html = self.marionette.absolute_url("hidden.html")
self.marionette.navigate(test_html)
el = self.marionette.find_element(By.ID, "child")
self.action.click(el).perform()
def test_double_click_action(self):
test_html = self.marionette.absolute_url("double_click.html")
self.marionette.navigate(test_html)
el = self.marionette.find_element(By.ID, "one-word-div")
self.action.double_click(el).perform()
el.send_keys(self.mod_key + "c")
rel = self.marionette.find_element(By.ID, "input-field")
rel.send_keys(self.mod_key + "v")
self.assertEqual("zyxw", rel.get_property("value"))
def test_context_click_action(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
click_el = self.marionette.find_element(By.ID, "resultContainer")
def context_menu_state():
with self.marionette.using_context("chrome"):
cm_el = self.marionette.find_element(By.ID, "contentAreaContextMenu")
return cm_el.get_property("state")
self.assertEqual("closed", context_menu_state())
self.action.context_click(click_el).perform()
self.wait_for_condition(lambda _: context_menu_state() == "open")
with self.marionette.using_context("chrome"):
self.marionette.find_element(By.ID, "main-window").send_keys(Keys.ESCAPE)
self.wait_for_condition(lambda _: context_menu_state() == "closed")
def test_middle_click_action(self):
test_html = self.marionette.absolute_url("clicks.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.ID, "addbuttonlistener").click()
el = self.marionette.find_element(By.ID, "showbutton")
self.action.middle_click(el).perform()
self.wait_for_condition(lambda _: el.get_property("innerHTML") == "1")
def test_chrome_click(self):
self.marionette.navigate("about:blank")
data_uri = "data:text/html,<html></html>"
with self.marionette.using_context("chrome"):
urlbar = self.marionette.find_element(By.ID, "urlbar")
urlbar.send_keys(data_uri)
go_button = self.marionette.find_element(By.ID, "urlbar-go-button")
self.action.click(go_button).perform()
self.wait_for_condition(lambda mn: mn.get_url() == data_uri)
def test_chrome_double_click(self):
self.marionette.navigate("about:blank")
test_word = "quux"
with self.marionette.using_context("chrome"):
urlbar = self.marionette.find_element(By.ID, "urlbar")
self.assertEqual("", urlbar.get_property("value"))
urlbar.send_keys(test_word)
self.assertEqual(urlbar.get_property("value"), test_word)
(self.action.double_click(urlbar).perform()
.key_down(self.mod_key)
.key_down("x").perform())
self.assertEqual(urlbar.get_property("value"), "")
def test_chrome_context_click_action(self):
self.marionette.set_context("chrome")
def context_menu_state():
cm_el = self.marionette.find_element(By.ID, "tabContextMenu")
return cm_el.get_property("state")
currtab = self.marionette.execute_script("return gBrowser.selectedTab")
self.assertEqual("closed", context_menu_state())
self.action.context_click(currtab).perform()
self.wait_for_condition(lambda _: context_menu_state() == "open")
(self.marionette.find_element(By.ID, "main-window")
.send_keys(Keys.ESCAPE))
self.wait_for_condition(lambda _: context_menu_state() == "closed")

View file

@ -0,0 +1,447 @@
# 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 contextlib
import time
import urllib
from marionette_driver import By, errors, expected, Wait
from marionette_harness import (
MarionetteTestCase,
run_if_e10s,
run_if_manage_instance,
skip,
skip_if_mobile,
WindowManagerMixin,
)
def inline(doc):
return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
class TestBackForwardNavigation(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestBackForwardNavigation, self).setUp()
self.test_page = self.marionette.absolute_url('test.html')
def open_with_link():
link = self.marionette.find_element(By.ID, "new-blank-tab")
link.click()
# Always use a blank new tab for an empty history
self.marionette.navigate(self.marionette.absolute_url("windowHandles.html"))
self.new_tab = self.open_tab(open_with_link)
self.marionette.switch_to_window(self.new_tab)
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
lambda _: self.history_length == 1,
message="The newly opened tab doesn't have a browser history length of 1")
def tearDown(self):
self.marionette.switch_to_parent_frame()
self.close_all_tabs()
super(TestBackForwardNavigation, self).tearDown()
@property
def history_length(self):
return self.marionette.execute_script("return window.history.length;")
def run_test(self, test_pages):
# Helper method to run simple back and forward testcases.
for index, page in enumerate(test_pages):
if "error" in page:
with self.assertRaises(page["error"]):
self.marionette.navigate(page["url"])
else:
self.marionette.navigate(page["url"])
self.assertEqual(page["url"], self.marionette.get_url())
self.assertEqual(self.history_length, index + 1)
for page in test_pages[-2::-1]:
if "error" in page:
with self.assertRaises(page["error"]):
self.marionette.go_back()
else:
self.marionette.go_back()
self.assertEqual(page["url"], self.marionette.get_url())
for page in test_pages[1::]:
if "error" in page:
with self.assertRaises(page["error"]):
self.marionette.go_forward()
else:
self.marionette.go_forward()
self.assertEqual(page["url"], self.marionette.get_url())
def test_no_history_items(self):
# Both methods should not raise a failure if no navigation is possible
self.marionette.go_back()
self.marionette.go_forward()
def test_data_urls(self):
test_pages = [
{"url": inline("<p>foobar</p>")},
{"url": self.test_page},
{"url": inline("<p>foobar</p>")},
]
self.run_test(test_pages)
def test_same_document_hash_change(self):
test_pages = [
{"url": "{}#23".format(self.test_page)},
{"url": self.test_page},
{"url": "{}#42".format(self.test_page)},
]
self.run_test(test_pages)
@skip("Causes crashes for JS GC (bug 1344863) and a11y (bug 1344868)")
def test_frameset(self):
test_pages = [
{"url": self.marionette.absolute_url("frameset.html")},
{"url": self.test_page},
{"url": self.marionette.absolute_url("frameset.html")},
]
self.run_test(test_pages)
def test_frameset_after_navigating_in_frame(self):
test_element_locator = (By.ID, "email")
self.marionette.navigate(self.test_page)
self.assertEqual(self.marionette.get_url(), self.test_page)
self.assertEqual(self.history_length, 1)
page = self.marionette.absolute_url("frameset.html")
self.marionette.navigate(page)
self.assertEqual(self.marionette.get_url(), page)
self.assertEqual(self.history_length, 2)
frame = self.marionette.find_element(By.ID, "fifth")
self.marionette.switch_to_frame(frame)
link = self.marionette.find_element(By.ID, "linkId")
link.click()
# We cannot use get_url() to wait until the target page has been loaded,
# because it will return the URL of the top browsing context and doesn't
# wait for the page load to be complete.
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
expected.element_present(*test_element_locator),
message="Target element 'email' has not been found")
self.assertEqual(self.history_length, 3)
# Go back to the frame the click navigated away from
self.marionette.go_back()
self.assertEqual(self.marionette.get_url(), page)
with self.assertRaises(errors.NoSuchElementException):
self.marionette.find_element(*test_element_locator)
# Go back to the non-frameset page
self.marionette.switch_to_parent_frame()
self.marionette.go_back()
self.assertEqual(self.marionette.get_url(), self.test_page)
# Go forward to the frameset page
self.marionette.go_forward()
self.assertEqual(self.marionette.get_url(), page)
# Go forward to the frame the click navigated to
# TODO: See above for automatic browser context switches. Hard to do here
frame = self.marionette.find_element(By.ID, "fifth")
self.marionette.switch_to_frame(frame)
self.marionette.go_forward()
self.marionette.find_element(*test_element_locator)
self.assertEqual(self.marionette.get_url(), page)
def test_image_document_to_html(self):
test_pages = [
{"url": self.marionette.absolute_url('black.png')},
{"url": self.test_page},
{"url": self.marionette.absolute_url('white.png')},
]
self.run_test(test_pages)
def test_image_document_to_image_document(self):
test_pages = [
{"url": self.marionette.absolute_url('black.png')},
{"url": self.marionette.absolute_url('white.png')},
]
self.run_test(test_pages)
@run_if_e10s("Requires e10s mode enabled")
def test_remoteness_change(self):
# TODO: Verify that a remoteness change happened
# like: self.assertNotEqual(self.marionette.current_window_handle, self.new_tab)
# about:robots is always a non-remote page for now
test_pages = [
{"url": "about:robots"},
{"url": self.test_page},
{"url": "about:robots"},
]
self.run_test(test_pages)
def test_navigate_to_requested_about_page_after_error_page(self):
test_pages = [
{"url": "about:neterror"},
{"url": self.marionette.absolute_url("test.html")},
{"url": "about:blocked"},
]
self.run_test(test_pages)
def test_timeout_error(self):
# Bug 1354908 - Disabled on Windows XP due to intermittent failures
caps = self.marionette.session_capabilities
if caps["platformName"] == "windows_nt" and float(caps["platformVersion"]) < 6:
return
urls = [
self.marionette.absolute_url('slow'),
self.test_page,
self.marionette.absolute_url('slow'),
]
# First, load all pages completely to get them added to the cache
for index, url in enumerate(urls):
self.marionette.navigate(url)
self.assertEqual(url, self.marionette.get_url())
self.assertEqual(self.history_length, index + 1)
self.marionette.go_back()
self.assertEqual(urls[1], self.marionette.get_url())
# Force triggering a timeout error
self.marionette.timeout.page_load = 0.1
with self.assertRaises(errors.TimeoutException):
self.marionette.go_back()
self.assertEqual(urls[0], self.marionette.get_url())
self.marionette.timeout.page_load = 300000
self.marionette.go_forward()
self.assertEqual(urls[1], self.marionette.get_url())
# Force triggering a timeout error
self.marionette.timeout.page_load = 0.1
with self.assertRaises(errors.TimeoutException):
self.marionette.go_forward()
self.assertEqual(urls[2], self.marionette.get_url())
self.marionette.timeout.page_load = 300000
def test_certificate_error(self):
test_pages = [
{"url": self.fixtures.where_is("/test.html", on="https"),
"error": errors.InsecureCertificateException},
{"url": self.test_page},
{"url": self.fixtures.where_is("/test.html", on="https"),
"error": errors.InsecureCertificateException},
]
self.run_test(test_pages)
class TestNavigate(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestNavigate, self).setUp()
self.marionette.navigate("about:")
self.test_doc = self.marionette.absolute_url("test.html")
self.iframe_doc = self.marionette.absolute_url("test_iframe.html")
def tearDown(self):
self.marionette.timeout.reset()
self.close_all_tabs()
super(TestNavigate, self).tearDown()
@property
def location_href(self):
# Windows 8 has recently seen a proliferation of intermittent
# test failures to do with failing to compare "about:blank" ==
# u"about:blank". For the sake of consistenty, we encode the
# returned URL as Unicode here to ensure that the values are
# absolutely of the same type.
#
# (https://bugzilla.mozilla.org/show_bug.cgi?id=1322862)
return self.marionette.execute_script("return window.location.href").encode("utf-8")
def test_set_location_through_execute_script(self):
self.marionette.execute_script(
"window.location.href = '%s'" % self.test_doc)
Wait(self.marionette).until(
lambda _: self.test_doc == self.location_href)
self.assertEqual("Marionette Test", self.marionette.title)
def test_navigate_chrome_error(self):
with self.marionette.using_context("chrome"):
self.assertRaises(errors.UnsupportedOperationException,
self.marionette.navigate, "about:blank")
self.assertRaises(errors.UnsupportedOperationException, self.marionette.go_back)
self.assertRaises(errors.UnsupportedOperationException, self.marionette.go_forward)
self.assertRaises(errors.UnsupportedOperationException, self.marionette.refresh)
def test_get_current_url_returns_top_level_browsing_context_url(self):
self.marionette.navigate(self.iframe_doc)
self.assertEqual(self.iframe_doc, self.location_href)
frame = self.marionette.find_element(By.CSS_SELECTOR, "#test_iframe")
self.marionette.switch_to_frame(frame)
self.assertEqual(self.iframe_doc, self.marionette.get_url())
def test_get_current_url(self):
self.marionette.navigate(self.test_doc)
self.assertEqual(self.test_doc, self.marionette.get_url())
self.marionette.navigate("about:blank")
self.assertEqual("about:blank", self.marionette.get_url())
def test_refresh(self):
self.marionette.navigate(self.test_doc)
self.assertEqual("Marionette Test", self.marionette.title)
self.assertTrue(self.marionette.execute_script(
"""var elem = window.document.createElement('div'); elem.id = 'someDiv';
window.document.body.appendChild(elem); return true;"""))
self.assertFalse(self.marionette.execute_script(
"return window.document.getElementById('someDiv') == undefined"))
self.marionette.refresh()
# TODO(ato): Bug 1291320
time.sleep(0.2)
self.assertEqual("Marionette Test", self.marionette.title)
self.assertTrue(self.marionette.execute_script(
"return window.document.getElementById('someDiv') == undefined"))
def test_navigate_in_child_frame_changes_to_top(self):
frame_html = self.marionette.absolute_url("frameset.html")
self.marionette.navigate(frame_html)
frame = self.marionette.find_element(By.NAME, "third")
self.marionette.switch_to_frame(frame)
self.assertRaises(errors.NoSuchElementException,
self.marionette.find_element, By.NAME, "third")
self.marionette.navigate(frame_html)
self.marionette.find_element(By.NAME, "third")
@skip_if_mobile("Bug 1323755 - Socket timeout")
def test_invalid_protocol(self):
with self.assertRaises(errors.MarionetteException):
self.marionette.navigate("thisprotocoldoesnotexist://")
def test_find_element_state_complete(self):
self.marionette.navigate(self.test_doc)
state = self.marionette.execute_script(
"return window.document.readyState")
self.assertEqual("complete", state)
self.assertTrue(self.marionette.find_element(By.ID, "mozLink"))
def test_error_when_exceeding_page_load_timeout(self):
self.marionette.timeout.page_load = 0.1
with self.assertRaises(errors.TimeoutException):
self.marionette.navigate(self.marionette.absolute_url("slow"))
def test_navigate_to_same_image_document_twice(self):
self.marionette.navigate(self.fixtures.where_is("black.png"))
self.assertIn("black.png", self.marionette.title)
self.marionette.navigate(self.fixtures.where_is("black.png"))
self.assertIn("black.png", self.marionette.title)
def test_navigate_hash_change(self):
doc = inline("<p id=foo>")
self.marionette.navigate(doc)
self.marionette.execute_script("window.visited = true", sandbox=None)
self.marionette.navigate("{}#foo".format(doc))
self.assertTrue(self.marionette.execute_script(
"return window.visited", sandbox=None))
@skip_if_mobile("Bug 1334095 - Timeout: No new tab has been opened")
def test_about_blank_for_new_docshell(self):
""" Bug 1312674 - Hang when loading about:blank for a new docshell."""
def open_with_link():
link = self.marionette.find_element(By.ID, "new-blank-tab")
link.click()
# Open a new tab to get a new docshell created
self.marionette.navigate(self.marionette.absolute_url("windowHandles.html"))
new_tab = self.open_tab(trigger=open_with_link)
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.get_url(), "about:blank")
self.marionette.navigate('about:blank')
self.marionette.close()
self.marionette.switch_to_window(self.start_window)
@skip("Bug 1332064 - NoSuchElementException: Unable to locate element: :focus")
@run_if_manage_instance("Only runnable if Marionette manages the instance")
@skip_if_mobile("Bug 1322993 - Missing temporary folder")
def test_focus_after_navigation(self):
self.marionette.quit()
self.marionette.start_session()
self.marionette.navigate(inline("<input autofocus>"))
active_el = self.marionette.execute_script("return document.activeElement")
focus_el = self.marionette.find_element(By.CSS_SELECTOR, ":focus")
self.assertEqual(active_el, focus_el)
class TestTLSNavigation(MarionetteTestCase):
insecure_tls = {"acceptInsecureCerts": True}
secure_tls = {"acceptInsecureCerts": False}
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.delete_session()
self.capabilities = self.marionette.start_session(
{"requiredCapabilities": self.insecure_tls})
def tearDown(self):
try:
self.marionette.delete_session()
except:
pass
MarionetteTestCase.tearDown(self)
@contextlib.contextmanager
def safe_session(self):
try:
self.capabilities = self.marionette.start_session(
{"requiredCapabilities": self.secure_tls})
self.assertFalse(self.capabilities["acceptInsecureCerts"])
yield self.marionette
finally:
self.marionette.delete_session()
@contextlib.contextmanager
def unsafe_session(self):
try:
self.capabilities = self.marionette.start_session(
{"requiredCapabilities": self.insecure_tls})
self.assertTrue(self.capabilities["acceptInsecureCerts"])
yield self.marionette
finally:
self.marionette.delete_session()
def test_navigate_by_command(self):
self.marionette.navigate(
self.fixtures.where_is("/test.html", on="https"))
self.assertIn("https", self.marionette.get_url())
def test_navigate_by_click(self):
link_url = self.fixtures.where_is("/test.html", on="https")
self.marionette.navigate(
inline("<a href=%s>https is the future</a>" % link_url))
self.marionette.find_element(By.TAG_NAME, "a").click()
self.assertIn("https", self.marionette.get_url())
def test_deactivation(self):
invalid_cert_url = self.fixtures.where_is("/test.html", on="https")
print "with safe session"
with self.safe_session() as session:
with self.assertRaises(errors.InsecureCertificateException):
session.navigate(invalid_cert_url)
print "with unsafe session"
with self.unsafe_session() as session:
session.navigate(invalid_cert_url)
print "with safe session again"
with self.safe_session() as session:
with self.assertRaises(errors.InsecureCertificateException):
session.navigate(invalid_cert_url)

View file

@ -0,0 +1,33 @@
# 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_harness import MarionetteTestCase
class TestPageSource(MarionetteTestCase):
def testShouldReturnTheSourceOfAPage(self):
test_html = self.marionette.absolute_url("testPageSource.html")
self.marionette.navigate(test_html)
source = self.marionette.page_source
from_web_api = self.marionette.execute_script("return document.documentElement.outerHTML")
self.assertTrue("<html" in source)
self.assertTrue("PageSource" in source)
self.assertEqual(source, from_web_api)
def testShouldReturnTheSourceOfAPageWhenThereAreUnicodeChars(self):
test_html = self.marionette.absolute_url("testPageSourceWithUnicodeChars.html")
self.marionette.navigate(test_html)
# if we don't throw on the next line we are good!
source = self.marionette.page_source
from_web_api = self.marionette.execute_script("return document.documentElement.outerHTML")
self.assertEqual(source, from_web_api)
def testShouldReturnAXMLDocumentSource(self):
test_xml = self.marionette.absolute_url("testPageSource.xml")
self.marionette.navigate(test_xml)
source = self.marionette.page_source
from_web_api = self.marionette.execute_script("return document.documentElement.outerHTML")
import re
self.assertEqual(re.sub("\s", "", source), "<xml><foo><bar>baz</bar></foo></xml>")
self.assertEqual(source, from_web_api)

View file

@ -0,0 +1,29 @@
# 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_harness import MarionetteTestCase, WindowManagerMixin
class TestPageSourceChrome(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestPageSourceChrome, self).setUp()
self.marionette.set_context("chrome")
def open_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test.xul',
'foo', 'chrome,centerscreen');
""")
new_window = self.open_window(open_with_js)
self.marionette.switch_to_window(new_window)
def tearDown(self):
self.close_all_windows()
super(TestPageSourceChrome, self).tearDown()
def testShouldReturnXULDetails(self):
source = self.marionette.page_source
self.assertTrue('<textbox id="textInput"' in source)

View file

@ -0,0 +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.by import By
from marionette_harness import MarionetteTestCase
class TestPosition(MarionetteTestCase):
def test_should_get_element_position_back(self):
test_url = self.marionette.absolute_url('rectangles.html')
self.marionette.navigate(test_url)
r2 = self.marionette.find_element(By.ID, "r2")
location = r2.rect
self.assertEqual(11, location['x'])
self.assertEqual(10, location['y'])

View file

@ -0,0 +1,167 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import JavascriptException
from marionette_harness import MarionetteTestCase
class TestPreferences(MarionetteTestCase):
prefs = {
"bool": "marionette.test.bool",
"int": "marionette.test.int",
"string": "marionette.test.string",
}
def tearDown(self):
for pref in self.prefs.values():
self.marionette.clear_pref(pref)
super(TestPreferences, self).tearDown()
def test_clear_pref(self):
self.assertIsNone(self.marionette.get_pref(self.prefs["bool"]))
self.marionette.set_pref(self.prefs["bool"], True)
self.assertTrue(self.marionette.get_pref(self.prefs["bool"]))
self.marionette.clear_pref(self.prefs["bool"])
self.assertIsNone(self.marionette.get_pref(self.prefs["bool"]))
def test_get_and_set_pref(self):
# By default none of the preferences are set
self.assertIsNone(self.marionette.get_pref(self.prefs["bool"]))
self.assertIsNone(self.marionette.get_pref(self.prefs["int"]))
self.assertIsNone(self.marionette.get_pref(self.prefs["string"]))
# Test boolean values
self.marionette.set_pref(self.prefs["bool"], True)
value = self.marionette.get_pref(self.prefs["bool"])
self.assertTrue(value)
self.assertEqual(type(value), bool)
# Test int values
self.marionette.set_pref(self.prefs["int"], 42)
value = self.marionette.get_pref(self.prefs["int"])
self.assertEqual(value, 42)
self.assertEqual(type(value), int)
# Test string values
self.marionette.set_pref(self.prefs["string"], "abc")
value = self.marionette.get_pref(self.prefs["string"])
self.assertEqual(value, "abc")
self.assertTrue(isinstance(value, basestring))
# Test reset value
self.marionette.set_pref(self.prefs["string"], None)
self.assertIsNone(self.marionette.get_pref(self.prefs["string"]))
def test_get_set_pref_default_branch(self):
pref_default = "marionette.test.pref_default1"
self.assertIsNone(self.marionette.get_pref(self.prefs["string"]))
self.marionette.set_pref(pref_default, "default_value", default_branch=True)
self.assertEqual(self.marionette.get_pref(pref_default), "default_value")
self.assertEqual(self.marionette.get_pref(pref_default, default_branch=True),
"default_value")
self.marionette.set_pref(pref_default, "user_value")
self.assertEqual(self.marionette.get_pref(pref_default), "user_value")
self.assertEqual(self.marionette.get_pref(pref_default, default_branch=True),
"default_value")
self.marionette.clear_pref(pref_default)
self.assertEqual(self.marionette.get_pref(pref_default), "default_value")
def test_get_pref_value_type(self):
# Without a given value type the properties URL will be returned only
pref_complex = "browser.menu.showCharacterEncoding"
properties_file = "chrome://browser/locale/browser.properties"
self.assertEqual(self.marionette.get_pref(pref_complex, default_branch=True),
properties_file)
# Otherwise the property named like the pref will be translated
value = self.marionette.get_pref(pref_complex, default_branch=True,
value_type="nsIPrefLocalizedString")
self.assertNotEqual(value, properties_file)
def test_set_prefs(self):
# By default none of the preferences are set
self.assertIsNone(self.marionette.get_pref(self.prefs["bool"]))
self.assertIsNone(self.marionette.get_pref(self.prefs["int"]))
self.assertIsNone(self.marionette.get_pref(self.prefs["string"]))
# Set a value on the default branch first
pref_default = "marionette.test.pref_default2"
self.assertIsNone(self.marionette.get_pref(pref_default))
self.marionette.set_prefs({pref_default: "default_value"}, default_branch=True)
# Set user values
prefs = {self.prefs["bool"]: True, self.prefs["int"]: 42,
self.prefs["string"]: "abc", pref_default: "user_value"}
self.marionette.set_prefs(prefs)
self.assertTrue(self.marionette.get_pref(self.prefs["bool"]))
self.assertEqual(self.marionette.get_pref(self.prefs["int"]), 42)
self.assertEqual(self.marionette.get_pref(self.prefs["string"]), "abc")
self.assertEqual(self.marionette.get_pref(pref_default), "user_value")
self.assertEqual(self.marionette.get_pref(pref_default, default_branch=True),
"default_value")
def test_using_prefs(self):
# Test that multiple preferences can be set with "using_prefs", and that
# they are set correctly and unset correctly after leaving the context
# manager.
pref_not_existent = "marionette.test.not_existent1"
pref_default = "marionette.test.pref_default3"
self.marionette.set_prefs({self.prefs["string"]: "abc",
self.prefs["int"]: 42,
self.prefs["bool"]: False,
})
self.assertFalse(self.marionette.get_pref(self.prefs["bool"]))
self.assertEqual(self.marionette.get_pref(self.prefs["int"]), 42)
self.assertEqual(self.marionette.get_pref(self.prefs["string"]), "abc")
self.assertIsNone(self.marionette.get_pref(pref_not_existent))
with self.marionette.using_prefs({self.prefs["bool"]: True,
self.prefs["int"]: 24,
self.prefs["string"]: "def",
pref_not_existent: "existent"}):
self.assertTrue(self.marionette.get_pref(self.prefs["bool"]), True)
self.assertEquals(self.marionette.get_pref(self.prefs["int"]), 24)
self.assertEquals(self.marionette.get_pref(self.prefs["string"]), "def")
self.assertEquals(self.marionette.get_pref(pref_not_existent), "existent")
self.assertFalse(self.marionette.get_pref(self.prefs["bool"]))
self.assertEqual(self.marionette.get_pref(self.prefs["int"]), 42)
self.assertEqual(self.marionette.get_pref(self.prefs["string"]), "abc")
self.assertIsNone(self.marionette.get_pref(pref_not_existent))
# Using context with default branch
self.marionette.set_pref(pref_default, "default_value", default_branch=True)
self.assertEqual(self.marionette.get_pref(pref_default, default_branch=True),
"default_value")
with self.marionette.using_prefs({pref_default: "new_value"}, default_branch=True):
self.assertEqual(self.marionette.get_pref(pref_default, default_branch=True),
"new_value")
self.assertEqual(self.marionette.get_pref(pref_default, default_branch=True),
"default_value")
def test_using_prefs_exception(self):
# Test that throwing an exception inside the context manager doesn"t
# prevent the preferences from being restored at context manager exit.
self.marionette.set_pref(self.prefs["string"], "abc")
try:
with self.marionette.using_prefs({self.prefs["string"]: "def"}):
self.assertEquals(self.marionette.get_pref(self.prefs["string"]), "def")
self.marionette.execute_script("return foo.bar.baz;")
except JavascriptException:
pass
self.assertEquals(self.marionette.get_pref(self.prefs["string"]), "abc")

View file

@ -0,0 +1,34 @@
# 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_harness import MarionetteTestCase
class TestProfileManagement(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.enforce_gecko_prefs(
{"marionette.test.bool": True,
"marionette.test.string": "testing",
"marionette.test.int": 3
})
self.marionette.set_context("chrome")
def test_preferences_are_set(self):
self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
self.assertEqual(self.marionette.get_pref("marionette.test.string"), "testing")
self.assertEqual(self.marionette.get_pref("marionette.test.int"), 3)
def test_change_preference(self):
self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
self.marionette.enforce_gecko_prefs({"marionette.test.bool": False})
self.assertFalse(self.marionette.get_pref("marionette.test.bool"))
def test_clean_profile(self):
self.marionette.restart(clean=True)
self.assertEqual(self.marionette.get_pref("marionette.test.bool"), None)

View file

@ -0,0 +1,252 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import InvalidArgumentException
from marionette_harness import MarionetteTestCase
class TestProxy(MarionetteTestCase):
def setUp(self):
super(TestProxy, self).setUp()
self.marionette.delete_session()
def test_that_we_can_set_a_autodetect_proxy(self):
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "autodetect",
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
}
""")
self.assertEqual(result["proxyType"], 4)
def test_that_capabilities_returned_have_proxy_details(self):
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "autodetect",
}
}
}
self.marionette.start_session(capabilities)
result = self.marionette.session_capabilities
self.assertEqual(result["proxy"]["proxyType"], "autodetect")
def test_that_we_can_set_a_system_proxy(self):
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "system",
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
}
""")
self.assertEqual(result["proxyType"], 5)
def test_we_can_set_a_pac_proxy(self):
url = "http://marionette.test"
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "pac",
"proxyAutoconfigUrl": url,
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
"proxyAutoconfigUrl" : Services.prefs.getCharPref('network.proxy.autoconfig_url'),
}
""")
self.assertEqual(result["proxyType"], 2)
self.assertEqual(result["proxyAutoconfigUrl"], url, 'proxyAutoconfigUrl was not set')
def test_that_we_can_set_a_manual_proxy(self):
port = 4444
url = "http://marionette.test"
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "manual",
"ftpProxy": url,
"ftpProxyPort": port,
"httpProxy": url,
"httpProxyPort": port,
"sslProxy": url,
"sslProxyPort": port,
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
"httpProxy" : Services.prefs.getCharPref('network.proxy.http'),
"httpProxyPort": Services.prefs.getIntPref('network.proxy.http_port'),
"sslProxy": Services.prefs.getCharPref('network.proxy.ssl'),
"sslProxyPort": Services.prefs.getIntPref('network.proxy.ssl_port'),
"ftpProxy": Services.prefs.getCharPref('network.proxy.ftp'),
"ftpProxyPort": Services.prefs.getIntPref('network.proxy.ftp_port'),
}
""")
self.assertEqual(result["proxyType"], 1)
self.assertEqual(result["httpProxy"], url, 'httpProxy was not set')
self.assertEqual(result["httpProxyPort"], port, 'httpProxyPort was not set')
self.assertEqual(result["sslProxy"], url, 'sslProxy url was not set')
self.assertEqual(result["sslProxyPort"], port, 'sslProxyPort was not set')
self.assertEqual(result["ftpProxy"], url, 'ftpProxy was not set')
self.assertEqual(result["ftpProxyPort"], port, 'ftpProxyPort was not set')
def test_we_can_set_a_manual_proxy_with_a_socks_proxy_with_socks_version(self):
port = 4444
url = "http://marionette.test"
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "manual",
"socksProxy": url,
"socksProxyPort": port,
"socksVersion": 4,
"socksUsername": "cake",
"socksPassword": "made with cake"
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
"socksProxy" : Services.prefs.getCharPref('network.proxy.socks'),
"socksProxyPort": Services.prefs.getIntPref('network.proxy.socks_port'),
"socksVersion": Services.prefs.getIntPref('network.proxy.socks_version'),
}
""")
self.assertEqual(result["socksProxy"], url, 'socksProxy was not set')
self.assertEqual(result["socksProxyPort"], port, 'socksProxyPort was not set')
self.assertEqual(result["socksVersion"], 4, 'socksVersion was not set to 4')
def test_we_can_set_a_manual_proxy_with_a_socks_proxy_with_no_socks_version(self):
port = 4444
url = "http://marionette.test"
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "manual",
"socksProxy": url,
"socksProxyPort": port,
"socksUsername": "cake",
"socksPassword": "made with cake"
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
"socksProxy" : Services.prefs.getCharPref('network.proxy.socks'),
"socksProxyPort": Services.prefs.getIntPref('network.proxy.socks_port'),
"socksVersion": Services.prefs.getIntPref('network.proxy.socks_version'),
}
""")
self.assertEqual(result["socksProxy"], url, 'socksProxy was not set')
self.assertEqual(result["socksProxyPort"], port, 'socksProxyPort was not set')
self.assertEqual(result["socksVersion"], 5, 'socksVersion was not set to 5')
def test_when_not_all_manual_proxy_details_are_in_capabilities(self):
port = 4444
url = "http://marionette.test"
capabilities = {"requiredCapabilities":
{
"proxy":{
"proxyType": "manual",
"ftpProxy": url,
"ftpProxyPort": port,
}
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType" : Services.prefs.getIntPref('network.proxy.type'),
"httpProxy" : Services.prefs.getCharPref('network.proxy.http'),
"httpProxyPort": Services.prefs.getIntPref('network.proxy.http_port'),
"sslProxy": Services.prefs.getCharPref('network.proxy.ssl'),
"sslProxyPort": Services.prefs.getIntPref('network.proxy.ssl_port'),
"ftpProxy": Services.prefs.getCharPref('network.proxy.ftp'),
"ftpProxyPort": Services.prefs.getIntPref('network.proxy.ftp_port'),
}
""")
self.assertEqual(result["proxyType"], 1)
self.assertNotEqual(result["httpProxy"], url,
'httpProxy was set. {}'.format(result["httpProxy"]))
self.assertNotEqual(result["httpProxyPort"], port, 'httpProxyPort was set')
self.assertNotEqual(result["sslProxy"], url, 'sslProxy url was set')
self.assertNotEqual(result["sslProxyPort"], port, 'sslProxyPort was set')
self.assertEqual(result["ftpProxy"], url, 'ftpProxy was set')
self.assertEqual(result["ftpProxyPort"], port, 'ftpProxyPort was set')
def test_proxy_is_a_string_should_throw_invalid_argument(self):
capabilities = {"requiredCapabilities":
{
"proxy":"I really should be a dictionary"
}
}
try:
self.marionette.start_session(capabilities)
self.fail("We should have started a session because proxy should be a dict")
except InvalidArgumentException as e:
assert e.message == "Value of 'proxy' should be an object"
def test_proxy_is_passed_in_with_no_proxy_doesnt_set_it(self):
capabilities = {"requiredCapabilities":
{
"proxy": {"proxyType": "NOPROXY"},
}
}
self.marionette.start_session(capabilities)
result = None
with self.marionette.using_context('chrome'):
result = self.marionette.execute_script("""return {
"proxyType": Services.prefs.getIntPref('network.proxy.type'),
};
""")
self.assertEqual(result["proxyType"], 0)
def tearDown(self):
if not self.marionette.session:
self.marionette.start_session()
else:
self.marionette.restart(clean=True)

View file

@ -0,0 +1,173 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import MarionetteException
from marionette_harness import MarionetteTestCase
class TestQuitRestart(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.pid = self.marionette.process_id
self.session_id = self.marionette.session_id
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
self.marionette.set_pref("browser.startup.page", 3)
def tearDown(self):
# Ensure to restart a session if none exist for clean-up
if not self.marionette.session:
self.marionette.start_session()
self.marionette.clear_pref("browser.startup.page")
MarionetteTestCase.tearDown(self)
def test_force_restart(self):
self.marionette.restart()
self.assertEqual(self.marionette.session_id, self.session_id)
# A forced restart will cause a new process id
self.assertNotEqual(self.marionette.process_id, self.pid)
# If a preference value is not forced, a restart will cause a reset
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
def test_force_quit(self):
self.marionette.quit()
self.assertEqual(self.marionette.session, None)
with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
self.marionette.get_url()
self.marionette.start_session()
self.assertNotEqual(self.marionette.session_id, self.session_id)
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
def test_in_app_clean_restart(self):
with self.assertRaises(ValueError):
self.marionette.restart(in_app=True, clean=True)
def test_in_app_restart(self):
self.marionette.restart(in_app=True)
self.assertEqual(self.marionette.session_id, self.session_id)
# An in-app restart will keep the same process id only on Linux
if self.marionette.session_capabilities['platformName'] == 'linux':
self.assertEqual(self.marionette.process_id, self.pid)
else:
self.assertNotEqual(self.marionette.process_id, self.pid)
# If a preference value is not forced, a restart will cause a reset
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
def test_in_app_restart_with_callback(self):
self.marionette.restart(in_app=True,
callback=lambda: self.shutdown(restart=True))
self.assertEqual(self.marionette.session_id, self.session_id)
# An in-app restart will keep the same process id only on Linux
if self.marionette.session_capabilities['platformName'] == 'linux':
self.assertEqual(self.marionette.process_id, self.pid)
else:
self.assertNotEqual(self.marionette.process_id, self.pid)
# If a preference value is not forced, a restart will cause a reset
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
def test_in_app_quit(self):
self.marionette.quit(in_app=True)
self.assertEqual(self.marionette.session, None)
with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
self.marionette.get_url()
self.marionette.start_session()
self.assertNotEqual(self.marionette.session_id, self.session_id)
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
def test_in_app_quit_with_callback(self):
self.marionette.quit(in_app=True, callback=self.shutdown)
self.assertEqual(self.marionette.session, None)
with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
self.marionette.get_url()
self.marionette.start_session()
self.assertNotEqual(self.marionette.session_id, self.session_id)
self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
def test_reset_context_after_quit_by_set_context(self):
# Check that we are in content context which is used by default in Marionette
self.assertNotIn('chrome://', self.marionette.get_url(),
"Context doesn't default to content")
self.marionette.set_context('chrome')
self.marionette.quit(in_app=True)
self.assertEqual(self.marionette.session, None)
self.marionette.start_session()
self.assertNotIn('chrome://', self.marionette.get_url(),
"Not in content context after quit with using_context")
def test_reset_context_after_quit_by_using_context(self):
# Check that we are in content context which is used by default in Marionette
self.assertNotIn('chrome://', self.marionette.get_url(),
"Context doesn't default to content")
with self.marionette.using_context('chrome'):
self.marionette.quit(in_app=True)
self.assertEqual(self.marionette.session, None)
self.marionette.start_session()
self.assertNotIn('chrome://', self.marionette.get_url(),
"Not in content context after quit with using_context")
def test_keep_context_after_restart_by_set_context(self):
# Check that we are in content context which is used by default in Marionette
self.assertNotIn('chrome://', self.marionette.get_url(),
"Context doesn't default to content")
# restart while we are in chrome context
self.marionette.set_context('chrome')
self.marionette.restart(in_app=True)
# An in-app restart will keep the same process id only on Linux
if self.marionette.session_capabilities['platformName'] == 'linux':
self.assertEqual(self.marionette.process_id, self.pid)
else:
self.assertNotEqual(self.marionette.process_id, self.pid)
self.assertIn('chrome://', self.marionette.get_url(),
"Not in chrome context after a restart with set_context")
def test_keep_context_after_restart_by_using_context(self):
# Check that we are in content context which is used by default in Marionette
self.assertNotIn('chrome://', self.marionette.get_url(),
"Context doesn't default to content")
# restart while we are in chrome context
with self.marionette.using_context('chrome'):
self.marionette.restart(in_app=True)
# An in-app restart will keep the same process id only on Linux
if self.marionette.session_capabilities['platformName'] == 'linux':
self.assertEqual(self.marionette.process_id, self.pid)
else:
self.assertNotEqual(self.marionette.process_id, self.pid)
self.assertIn('chrome://', self.marionette.get_url(),
"Not in chrome context after a restart with using_context")
def shutdown(self, restart=False):
self.marionette.set_context("chrome")
self.marionette.execute_script("""
Components.utils.import("resource://gre/modules/Services.jsm");
let flags = Ci.nsIAppStartup.eAttemptQuit
if(arguments[0]) {
flags |= Ci.nsIAppStartup.eRestart;
}
Services.startup.quit(flags);
""", script_args=[restart])

View file

@ -0,0 +1,34 @@
#Copyright 2007-2009 WebDriver committers
#Copyright 2007-2009 Google Inc.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from marionette_driver.by import By
from marionette_harness import MarionetteTestCase
class RenderedElementTests(MarionetteTestCase):
def testWeCanGetComputedStyleValueOnElement(self):
test_url = self.marionette.absolute_url('javascriptPage.html')
self.marionette.navigate(test_url)
element = self.marionette.find_element(By.ID, "green-parent")
backgroundColour = element.value_of_css_property("background-color")
self.assertEqual("rgb(0, 128, 0)", backgroundColour)
element = self.marionette.find_element(By.ID, "red-item")
backgroundColour = element.value_of_css_property("background-color")
self.assertEqual("rgb(255, 0, 0)", backgroundColour)

View file

@ -0,0 +1,29 @@
# 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_harness import MarionetteTestCase, expectedFailure, skip
class TestReport(MarionetteTestCase):
def test_pass(self):
assert True
def test_fail(self):
assert False
@skip('Skip Message')
def test_skip(self):
assert False
@expectedFailure
def test_expected_fail(self):
assert False
@expectedFailure
def test_unexpected_pass(self):
assert True
def test_error(self):
raise Exception()

View file

@ -0,0 +1,10 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
from marionette_harness import MarionetteTestCase
class TestRunJSTest(MarionetteTestCase):
def test_basic(self):
self.run_js_test('test_simpletest_pass.js')
self.run_js_test('test_simpletest_fail.js')

View file

@ -0,0 +1,86 @@
# 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 errors
from mozrunner.devices.emulator_screen import EmulatorScreen
from marionette_harness import MarionetteTestCase, skip_if_desktop, skip_if_mobile
default_orientation = "portrait-primary"
unknown_orientation = "Unknown screen orientation: {}"
class TestScreenOrientation(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.is_mobile = self.marionette.session_capabilities.get("rotatable", False)
def tearDown(self):
if self.is_mobile:
self.marionette.set_orientation(default_orientation)
self.assertEqual(self.marionette.orientation, default_orientation, "invalid state")
MarionetteTestCase.tearDown(self)
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_to_portrait_primary(self):
self.marionette.set_orientation("portrait-primary")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "portrait-primary")
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_to_landscape_primary(self):
self.marionette.set_orientation("landscape-primary")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "landscape-primary")
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_to_portrait_secondary(self):
self.marionette.set_orientation("portrait-secondary")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "portrait-secondary")
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_to_landscape_secondary(self):
self.marionette.set_orientation("landscape-secondary")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "landscape-secondary")
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_to_shorthand_portrait(self):
# Set orientation to something other than portrait-primary first, since the default is
# portrait-primary.
self.marionette.set_orientation("landscape-primary")
self.assertEqual(self.marionette.orientation, "landscape-primary", "invalid state")
self.marionette.set_orientation("portrait")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "portrait-primary")
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_to_shorthand_landscape(self):
self.marionette.set_orientation("landscape")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "landscape-primary")
@skip_if_desktop("Not supported in Firefox")
def test_set_orientation_with_mixed_casing(self):
self.marionette.set_orientation("lAnDsCaPe")
new_orientation = self.marionette.orientation
self.assertEqual(new_orientation, "landscape-primary")
@skip_if_desktop("Not supported in Firefox")
def test_set_invalid_orientation(self):
with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("cheese")):
self.marionette.set_orientation("cheese")
@skip_if_desktop("Not supported in Firefox")
def test_set_null_orientation(self):
with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("null")):
self.marionette.set_orientation(None)
@skip_if_mobile("Specific test for Firefox")
def test_unsupported_operation_on_desktop(self):
with self.assertRaises(errors.UnsupportedOperationException):
self.marionette.set_orientation("landscape-primary")

View file

@ -0,0 +1,428 @@
# 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 base64
import hashlib
import imghdr
import struct
import urllib
from marionette_driver import By
from marionette_driver.errors import JavascriptException, NoSuchWindowException
from marionette_harness import (
MarionetteTestCase,
skip,
skip_if_mobile,
WindowManagerMixin,
)
def inline(doc, mime="text/html;charset=utf-8"):
return "data:{0},{1}".format(mime, urllib.quote(doc))
box = inline("<body><div id='box'><p id='green' style='width: 50px; height: 50px; "
"background: silver;'></p></div></body>")
input = inline("<body><input id='text-input'></input></body>")
long = inline("<body style='height: 300vh'><p style='margin-top: 100vh'>foo</p></body>")
short = inline("<body style='height: 10vh'></body>")
svg = inline("""
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20">
<rect height="20" width="20"/>
</svg>""", mime="image/svg+xml")
class ScreenCaptureTestCase(MarionetteTestCase):
def setUp(self):
super(ScreenCaptureTestCase, self).setUp()
self._device_pixel_ratio = None
@property
def device_pixel_ratio(self):
if self._device_pixel_ratio is None:
self._device_pixel_ratio = self.marionette.execute_script("""
return window.devicePixelRatio
""")
return self._device_pixel_ratio
@property
def document_element(self):
return self.marionette.find_element(By.CSS_SELECTOR, ":root")
@property
def page_y_offset(self):
return self.marionette.execute_script("return window.pageYOffset")
@property
def viewport_dimensions(self):
return self.marionette.execute_script("""
return [arguments[0].clientWidth,
arguments[0].clientHeight];
""", script_args=[self.document_element])
def assert_png(self, screenshot):
"""Test that screenshot is a Base64 encoded PNG file."""
image = base64.decodestring(screenshot)
self.assertEqual(imghdr.what("", image), "png")
def assert_formats(self, element=None):
if element is None:
element = self.document_element
screenshot_default = self.marionette.screenshot(element=element)
screenshot_image = self.marionette.screenshot(element=element, format="base64")
binary1 = self.marionette.screenshot(element=element, format="binary")
binary2 = self.marionette.screenshot(element=element, format="binary")
hash1 = self.marionette.screenshot(element=element, format="hash")
hash2 = self.marionette.screenshot(element=element, format="hash")
# Valid data should have been returned
self.assert_png(screenshot_image)
self.assertEqual(imghdr.what("", binary1), "png")
self.assertEqual(screenshot_image, base64.b64encode(binary1))
self.assertEqual(hash1, hashlib.sha256(screenshot_image).hexdigest())
# Different formats produce different data
self.assertNotEqual(screenshot_image, binary1)
self.assertNotEqual(screenshot_image, hash1)
self.assertNotEqual(binary1, hash1)
# A second capture should be identical
self.assertEqual(screenshot_image, screenshot_default)
self.assertEqual(binary1, binary2)
self.assertEqual(hash1, hash2)
def get_element_dimensions(self, element):
rect = element.rect
return rect["width"], rect["height"]
def get_image_dimensions(self, screenshot):
self.assert_png(screenshot)
image = base64.decodestring(screenshot)
width, height = struct.unpack(">LL", image[16:24])
return int(width), int(height)
def scale(self, rect):
return (int(rect[0] * self.device_pixel_ratio),
int(rect[1] * self.device_pixel_ratio))
class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase):
def setUp(self):
super(TestScreenCaptureChrome, self).setUp()
self.marionette.set_context("chrome")
def tearDown(self):
self.close_all_windows()
super(TestScreenCaptureChrome, self).tearDown()
@property
def window_dimensions(self):
return tuple(self.marionette.execute_script("""
let el = document.documentElement;
let rect = el.getBoundingClientRect();
return [rect.width, rect.height];
"""))
def open_dialog(self, url=None, width=None, height=None):
if url is None:
url = "chrome://marionette/content/test_dialog.xul"
def opener():
features = "chrome"
if height is not None:
features += ",height={}".format(height)
if width is not None:
features += ",width={}".format(width)
self.marionette.execute_script("""
window.open(arguments[0], "", arguments[1]);
""", script_args=[url, features])
return self.open_window(opener)
def test_capture_different_context(self):
"""Check that screenshots in content and chrome are different."""
with self.marionette.using_context("content"):
screenshot_content = self.marionette.screenshot()
screenshot_chrome = self.marionette.screenshot()
self.assertNotEqual(screenshot_content, screenshot_chrome)
@skip_if_mobile("Fennec doesn't support other chrome windows")
def test_capture_element(self):
dialog = self.open_dialog()
self.marionette.switch_to_window(dialog)
# Ensure we only capture the element
el = self.marionette.find_element(By.ID, "test-list")
screenshot_element = self.marionette.screenshot(element=el)
self.assertEqual(self.scale(self.get_element_dimensions(el)),
self.get_image_dimensions(screenshot_element))
# Ensure we do not capture the full window
screenshot_dialog = self.marionette.screenshot()
self.assertNotEqual(screenshot_dialog, screenshot_element)
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
@skip_if_mobile("Fennec doesn't support other chrome windows")
def test_capture_flags(self):
dialog = self.open_dialog()
self.marionette.switch_to_window(dialog)
textbox = self.marionette.find_element(By.ID, "text-box")
textbox.send_keys("")
screenshot_focus = self.marionette.screenshot()
self.marionette.execute_script("arguments[0].blur();", script_args=[textbox])
screenshot_no_focus = self.marionette.screenshot()
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
self.assertNotEqual(screenshot_focus, screenshot_no_focus)
def test_capture_full_area(self):
# A full capture is not the outer dimensions of the window,
# but instead the bounding box of the window's root node (documentElement).
screenshot_full = self.marionette.screenshot()
screenshot_root = self.marionette.screenshot(element=self.document_element)
self.assert_png(screenshot_full)
self.assert_png(screenshot_root)
self.assertEqual(screenshot_root, screenshot_full)
self.assertEqual(self.scale(self.get_element_dimensions(self.document_element)),
self.get_image_dimensions(screenshot_full))
@skip_if_mobile("Fennec doesn't support other chrome windows")
def test_capture_viewport(self):
# Load a HTML test page into the chrome window to get scrollbars
test_page = self.marionette.absolute_url("test.html")
dialog = self.open_dialog(url=test_page, width=50, height=50)
self.marionette.switch_to_window(dialog)
# Size of screenshot has to match viewport size
screenshot = self.marionette.screenshot(full=False)
self.assert_png(screenshot)
self.assertEqual(self.scale(self.viewport_dimensions),
self.get_image_dimensions(screenshot))
self.assertNotEqual(self.scale(self.window_dimensions),
self.get_image_dimensions(screenshot))
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
@skip_if_mobile("Fennec doesn't support other chrome windows")
def test_capture_window_already_closed(self):
dialog = self.open_dialog()
self.marionette.switch_to_window(dialog)
self.marionette.close_chrome_window()
self.assertRaises(NoSuchWindowException, self.marionette.screenshot)
self.marionette.switch_to_window(self.start_window)
@skip_if_mobile("Fennec doesn't support other chrome windows")
def test_formats(self):
dialog = self.open_dialog()
self.marionette.switch_to_window(dialog)
self.assert_formats()
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
def test_format_unknown(self):
with self.assertRaises(ValueError):
self.marionette.screenshot(format="cheese")
@skip_if_mobile("Fennec doesn't support other chrome windows")
def test_highlight_elements(self):
dialog = self.open_dialog()
self.marionette.switch_to_window(dialog)
# Highlighting the element itself shouldn't make the image larger
element = self.marionette.find_element(By.ID, "test-list")
screenshot_element = self.marionette.screenshot(element=element)
screenshot_highlight = self.marionette.screenshot(element=element,
highlights=[element])
self.assertEqual(self.scale(self.get_element_dimensions(element)),
self.get_image_dimensions(screenshot_element))
self.assertNotEqual(screenshot_element, screenshot_highlight)
# Highlighting a sub element
button = self.marionette.find_element(By.ID, "choose-button")
screenshot_highlight_button = self.marionette.screenshot(element=element,
highlights=[button])
self.assertNotEqual(screenshot_element, screenshot_highlight_button)
self.assertNotEqual(screenshot_highlight, screenshot_highlight_button)
self.marionette.close_chrome_window()
self.marionette.switch_to_window(self.start_window)
def test_highlight_element_not_seen(self):
"""Check that for not found elements an exception is raised."""
with self.marionette.using_context('content'):
self.marionette.navigate(box)
content_element = self.marionette.find_element(By.ID, "green")
self.assertRaisesRegexp(JavascriptException, "Element reference not seen before",
self.marionette.screenshot, highlights=[content_element])
chrome_document_element = self.document_element
with self.marionette.using_context('content'):
self.assertRaisesRegexp(JavascriptException, "Element reference not seen before",
self.marionette.screenshot,
highlights=[chrome_document_element])
class TestScreenCaptureContent(WindowManagerMixin, ScreenCaptureTestCase):
def setUp(self):
super(TestScreenCaptureContent, self).setUp()
self.marionette.set_context("content")
def tearDown(self):
self.close_all_tabs()
super(TestScreenCaptureContent, self).tearDown()
@property
def scroll_dimensions(self):
return tuple(self.marionette.execute_script("""
return [document.body.scrollWidth, document.body.scrollHeight]
"""))
@skip_if_mobile("Needs application independent method to open a new tab")
def test_capture_tab_already_closed(self):
tab = self.open_tab()
self.marionette.switch_to_window(tab)
self.marionette.close()
self.assertRaises(NoSuchWindowException, self.marionette.screenshot)
self.marionette.switch_to_window(self.start_tab)
def test_capture_element(self):
self.marionette.navigate(box)
el = self.marionette.find_element(By.TAG_NAME, "div")
screenshot = self.marionette.screenshot(element=el)
self.assert_png(screenshot)
self.assertEqual(self.scale(self.get_element_dimensions(el)),
self.get_image_dimensions(screenshot))
@skip("Bug 1213875")
def test_capture_element_scrolled_into_view(self):
self.marionette.navigate(long)
el = self.marionette.find_element(By.TAG_NAME, "p")
screenshot = self.marionette.screenshot(element=el)
self.assert_png(screenshot)
self.assertEqual(self.scale(self.get_element_dimensions(el)),
self.get_image_dimensions(screenshot))
self.assertGreater(self.page_y_offset, 0)
@skip("Bug 1330560 - AssertionError: u'iVBORw0KGgoA... (images unexpectedly equal)")
def test_capture_flags(self):
self.marionette.navigate(input)
textbox = self.marionette.find_element(By.ID, "text-input")
textbox.send_keys("")
screenshot_focus = self.marionette.screenshot()
self.marionette.execute_script("arguments[0].blur();", script_args=[textbox])
screenshot_no_focus = self.marionette.screenshot()
self.assertNotEqual(screenshot_focus, screenshot_no_focus)
@skip_if_mobile("Bug 1330642 - Tuples differ: (1960, 11130) != (1960, 11129)")
def test_capture_html_document_element(self):
self.marionette.navigate(long)
screenshot = self.marionette.screenshot()
self.assert_png(screenshot)
self.assertEqual(self.scale(self.scroll_dimensions),
self.get_image_dimensions(screenshot))
def test_capture_svg_document_element(self):
self.marionette.navigate(svg)
screenshot = self.marionette.screenshot()
self.assert_png(screenshot)
self.assertEqual(self.scale(self.get_element_dimensions(self.document_element)),
self.get_image_dimensions(screenshot))
def test_capture_viewport(self):
url = self.marionette.absolute_url("clicks.html")
self.marionette.navigate(short)
self.marionette.navigate(url)
screenshot = self.marionette.screenshot(full=False)
self.assert_png(screenshot)
self.assertEqual(self.scale(self.viewport_dimensions),
self.get_image_dimensions(screenshot))
def test_capture_viewport_after_scroll(self):
self.marionette.navigate(long)
before = self.marionette.screenshot()
el = self.marionette.find_element(By.TAG_NAME, "p")
self.marionette.execute_script(
"arguments[0].scrollIntoView()", script_args=[el])
after = self.marionette.screenshot(full=False)
self.assertNotEqual(before, after)
self.assertGreater(self.page_y_offset, 0)
def test_formats(self):
self.marionette.navigate(box)
# Use a smaller region to speed up the test
element = self.marionette.find_element(By.TAG_NAME, "div")
self.assert_formats(element=element)
def test_format_unknown(self):
with self.assertRaises(ValueError):
self.marionette.screenshot(format="cheese")
def test_highlight_elements(self):
self.marionette.navigate(box)
element = self.marionette.find_element(By.TAG_NAME, "div")
# Highlighting the element itself shouldn't make the image larger
screenshot_element = self.marionette.screenshot(element=element)
screenshot_highlight = self.marionette.screenshot(element=element,
highlights=[element])
self.assertEqual(self.scale(self.get_element_dimensions(element)),
self.get_image_dimensions(screenshot_highlight))
self.assertNotEqual(screenshot_element, screenshot_highlight)
# Highlighting a sub element
paragraph = self.marionette.find_element(By.ID, "green")
screenshot_highlight_paragraph = self.marionette.screenshot(element=element,
highlights=[paragraph])
self.assertNotEqual(screenshot_element, screenshot_highlight_paragraph)
self.assertNotEqual(screenshot_highlight, screenshot_highlight_paragraph)
def test_scroll_default(self):
self.marionette.navigate(long)
before = self.page_y_offset
el = self.marionette.find_element(By.TAG_NAME, "p")
self.marionette.screenshot(element=el, format="hash")
self.assertNotEqual(before, self.page_y_offset)
def test_scroll(self):
self.marionette.navigate(long)
before = self.page_y_offset
el = self.marionette.find_element(By.TAG_NAME, "p")
self.marionette.screenshot(element=el, format="hash", scroll=True)
self.assertNotEqual(before, self.page_y_offset)
def test_scroll_off(self):
self.marionette.navigate(long)
el = self.marionette.find_element(By.TAG_NAME, "p")
before = self.page_y_offset
self.marionette.screenshot(element=el, format="hash", scroll=False)
self.assertEqual(before, self.page_y_offset)
def test_scroll_no_element(self):
self.marionette.navigate(long)
before = self.page_y_offset
self.marionette.screenshot(format="hash", scroll=True)
self.assertEqual(before, self.page_y_offset)

View file

@ -0,0 +1,164 @@
# 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 urllib
from marionette_driver.by import By
from marionette_harness import MarionetteTestCase
def inline(doc):
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
class SelectTestCase(MarionetteTestCase):
def assertSelected(self, option_element):
self.assertTrue(option_element.is_selected(), "<option> element not selected")
self.assertTrue(self.marionette.execute_script(
"return arguments[0].selected", script_args=[option_element], sandbox=None),
"<option> selected attribute not updated")
def assertNotSelected(self, option_element):
self.assertFalse(option_element.is_selected(), "<option> is selected")
self.assertFalse(self.marionette.execute_script(
"return arguments[0].selected", script_args=[option_element], sandbox=None),
"<option> selected attribute not updated")
class TestSelect(SelectTestCase):
def test_single(self):
self.marionette.navigate(inline("""
<select>
<option>first
<option>second
</select>"""))
select = self.marionette.find_element(By.TAG_NAME, "select")
options = self.marionette.find_elements(By.TAG_NAME, "option")
self.assertSelected(options[0])
options[1].click()
self.assertSelected(options[1])
def test_deselect(self):
self.marionette.navigate(inline("""
<select>
<option>first
<option>second
<option>third
</select>"""))
select = self.marionette.find_element(By.TAG_NAME, "select")
options = self.marionette.find_elements(By.TAG_NAME, "option")
options[0].click()
self.assertSelected(options[0])
options[1].click()
self.assertSelected(options[1])
options[2].click()
self.assertSelected(options[2])
options[0].click()
self.assertSelected(options[0])
def test_out_of_view(self):
self.marionette.navigate(inline("""
<select>
<option>1
<option>2
<option>3
<option>4
<option>5
<option>6
<option>7
<option>8
<option>9
<option>10
<option>11
<option>12
<option>13
<option>14
<option>15
<option>16
<option>17
<option>18
<option>19
<option>20
</select>"""))
select = self.marionette.find_element(By.TAG_NAME, "select")
options = self.marionette.find_elements(By.TAG_NAME, "option")
options[14].click()
self.assertSelected(options[14])
class TestSelectMultiple(SelectTestCase):
def test_single(self):
self.marionette.navigate(inline("<select multiple> <option>first </select>"))
option = self.marionette.find_element(By.TAG_NAME, "option")
option.click()
self.assertSelected(option)
def test_multiple(self):
self.marionette.navigate(inline("""
<select multiple>
<option>first
<option>second
<option>third
</select>"""))
select = self.marionette.find_element(By.TAG_NAME, "select")
options = select.find_elements(By.TAG_NAME, "option")
options[1].click()
self.assertSelected(options[1])
options[2].click()
self.assertSelected(options[2])
self.assertSelected(options[1])
def test_deselect_selected(self):
self.marionette.navigate(inline("<select multiple> <option>first </select>"))
option = self.marionette.find_element(By.TAG_NAME, "option")
option.click()
self.assertSelected(option)
option.click()
self.assertNotSelected(option)
def test_deselect_preselected(self):
self.marionette.navigate(inline("""
<select multiple>
<option selected>first
</select>"""))
option = self.marionette.find_element(By.TAG_NAME, "option")
self.assertSelected(option)
option.click()
self.assertNotSelected(option)
def test_out_of_view(self):
self.marionette.navigate(inline("""
<select multiple>
<option>1
<option>2
<option>3
<option>4
<option>5
<option>6
<option>7
<option>8
<option>9
<option>10
<option>11
<option>12
<option>13
<option>14
<option>15
<option>16
<option>17
<option>18
<option>19
<option>20
</select>"""))
select = self.marionette.find_element(By.TAG_NAME, "select")
options = self.marionette.find_elements(By.TAG_NAME, "option")
options[-1].click()
self.assertSelected(options[-1])

View file

@ -0,0 +1,56 @@
# 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 errors
from marionette_harness import MarionetteTestCase
class TestSession(MarionetteTestCase):
def setUp(self):
super(TestSession, self).setUp()
self.marionette.delete_session()
def test_new_session_returns_capabilities(self):
# Sends newSession
caps = self.marionette.start_session()
# Check that session was created. This implies the server
# sent us the sessionId and status fields.
self.assertIsNotNone(self.marionette.session)
# Required capabilities mandated by WebDriver spec
self.assertIn("browserName", caps)
self.assertIn("browserVersion", caps)
self.assertIn("platformName", caps)
self.assertIn("platformVersion", caps)
# Optional capabilities we want Marionette to support
self.assertIn("rotatable", caps)
def test_get_session_id(self):
# Sends newSession
self.marionette.start_session()
self.assertTrue(self.marionette.session_id is not None)
self.assertTrue(isinstance(self.marionette.session_id, unicode))
def test_set_the_session_id(self):
# Sends newSession
self.marionette.start_session(session_id="ILoveCheese")
self.assertEqual(self.marionette.session_id, "ILoveCheese")
self.assertTrue(isinstance(self.marionette.session_id, unicode))
def test_session_already_started(self):
self.marionette.start_session()
self.assertTrue(isinstance(self.marionette.session_id, unicode))
with self.assertRaises(errors.SessionNotCreatedException):
self.marionette._send_message("newSession", {})
def test_no_session(self):
with self.assertRaises(errors.InvalidSessionIdException):
self.marionette.get_url()
self.marionette.start_session()
self.marionette.get_url()

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 marionette_harness import MarionetteTestCase
class TestSetWindowSize(MarionetteTestCase):
def setUp(self):
super(MarionetteTestCase, self).setUp()
self.start_size = self.marionette.window_size
self.max_width = self.marionette.execute_script("return window.screen.availWidth;")
self.max_height = self.marionette.execute_script("return window.screen.availHeight;")
def tearDown(self):
# WebDriver spec says a resize cannot result in window being maximized, an
# error is returned if that is the case; therefore if the window is maximized
# at the start of this test, returning to the original size via set_window_size
# size will result in error; so reset to original size minus 1 pixel width
if self.start_size['width'] == self.max_width and self.start_size['height'] == self.max_height:
self.start_size['width']-=1
self.marionette.set_window_size(self.start_size['width'], self.start_size['height'])
super(MarionetteTestCase, self).tearDown()
def test_that_we_can_get_and_set_window_size(self):
# event handler
self.marionette.execute_script("""
window.wrappedJSObject.rcvd_event = false;
window.onresize = function() {
window.wrappedJSObject.rcvd_event = true;
};
""")
# valid size
width = self.max_width - 100
height = self.max_height - 100
self.marionette.set_window_size(width, height)
self.wait_for_condition(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_event;"))
size = self.marionette.window_size
self.assertEqual(size['width'], width,
"Window width is {0} but should be {1}".format(size['width'], width))
self.assertEqual(size['height'], height,
"Window height is {0} but should be {1}".format(size['height'], height))
def test_that_we_can_get_new_size_when_set_window_size(self):
actual = self.marionette.window_size
width = actual['width'] - 50
height = actual['height'] - 50
size = self.marionette.set_window_size(width, height)
self.assertIsNotNone(size, "Response is None")
self.assertEqual(size['width'], width,
"New width is {0} but should be {1}".format(size['width'], width))
self.assertEqual(size['height'], height,
"New height is {0} but should be {1}".format(size['height'], height))
def test_possible_to_request_window_larger_than_screen(self):
self.marionette.set_window_size(4 * self.max_width, 4 * self.max_height)
size = self.marionette.window_size
# In X the window size may be greater than the bounds of the screen
self.assertGreaterEqual(size["width"], self.max_width)
self.assertGreaterEqual(size["height"], self.max_height)
def test_that_we_can_maximise_the_window(self):
# valid size
width = self.max_width - 100
height = self.max_height - 100
self.marionette.set_window_size(width, height)
# event handler
self.marionette.execute_script("""
window.wrappedJSObject.rcvd_event = false;
window.onresize = function() {
window.wrappedJSObject.rcvd_event = true;
};
""")
self.marionette.maximize_window()
self.wait_for_condition(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_event;"))
size = self.marionette.window_size
self.assertGreaterEqual(size['width'], self.max_width,
"Window width does not use availWidth, current width: {0}, max width: {1}".format(size['width'], self.max_width))
self.assertGreaterEqual(size['height'], self.max_height,
"Window height does not use availHeight. current width: {0}, max width: {1}".format(size['height'], self.max_height))

View file

@ -0,0 +1,80 @@
# 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.by import By
from marionette_driver.errors import (
NoSuchElementException,
StaleElementException,
UnsupportedOperationException,
)
from marionette_harness import MarionetteTestCase
class TestShadowDom(MarionetteTestCase):
def setUp(self):
super(TestShadowDom, self).setUp()
self.marionette.set_pref("dom.webcomponents.enabled", True)
self.marionette.navigate(self.marionette.absolute_url("test_shadow_dom.html"))
self.host = self.marionette.find_element(By.ID, "host")
self.marionette.switch_to_shadow_root(self.host)
self.button = self.marionette.find_element(By.ID, "button")
def tearDown(self):
self.marionette.clear_pref("dom.webcomponents.enabled")
super(TestShadowDom, self).tearDown()
def test_chrome_error(self):
with self.marionette.using_context("chrome"):
self.assertRaises(UnsupportedOperationException,
self.marionette.switch_to_shadow_root)
def test_shadow_dom(self):
# Button in shadow root should be actionable
self.button.click()
def test_shadow_dom_after_switch_away_from_shadow_root(self):
# Button in shadow root should be actionable
self.button.click()
self.marionette.switch_to_shadow_root()
# After switching back to top content, button should be stale
self.assertRaises(StaleElementException, self.button.click)
def test_shadow_dom_raises_stale_element_exception_when_button_remove(self):
self.marionette.execute_script(
'document.getElementById("host").shadowRoot.getElementById("button").remove();')
# After removing button from shadow DOM, button should be stale
self.assertRaises(StaleElementException, self.button.click)
def test_shadow_dom_raises_stale_element_exception_when_host_removed(self):
self.marionette.execute_script('document.getElementById("host").remove();')
# After removing shadow DOM host element, button should be stale
self.assertRaises(StaleElementException, self.button.click)
def test_non_existent_shadow_dom(self):
# Jump back to top level content
self.marionette.switch_to_shadow_root()
# When no ShadowRoot is found, switch_to_shadow_root throws NoSuchElementException
self.assertRaises(NoSuchElementException, self.marionette.switch_to_shadow_root,
self.marionette.find_element(By.ID, "empty-host"))
def test_inner_shadow_dom(self):
# Button in shadow root should be actionable
self.button.click()
self.inner_host = self.marionette.find_element(By.ID, "inner-host")
self.marionette.switch_to_shadow_root(self.inner_host)
self.inner_button = self.marionette.find_element(By.ID, "inner-button")
# Nested nutton in nested shadow root should be actionable
self.inner_button.click()
self.marionette.switch_to_shadow_root()
# After jumping back to parent shadow root, button should again be actionable but inner
# button should now be stale
self.button.click()
self.assertRaises(StaleElementException, self.inner_button.click)
self.marionette.switch_to_shadow_root()
# After switching back to top content, both buttons should now be stale
self.assertRaises(StaleElementException, self.button.click)
self.assertRaises(StaleElementException, self.inner_button.click)

View file

@ -0,0 +1,12 @@
/* 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/. */
MARIONETTE_TIMEOUT = 1000;
MARIONETTE_CONTEXT = 'chrome';
is(2, 2, "test for is()");
isnot(2, 3, "test for isnot()");
ok(2 == 2, "test for ok()");
finish();

View file

@ -0,0 +1,16 @@
/* 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/. */
MARIONETTE_TIMEOUT = 1000;
/* this test will fail */
setTimeout(function() {
is(1, 2, "is(1,2) should fail", TEST_UNEXPECTED_FAIL, TEST_PASS);
finish();
}, 100);
isnot(1, 1, "isnot(1,1) should fail", TEST_UNEXPECTED_FAIL, TEST_PASS);
ok(1 == 2, "ok(1==2) should fail", TEST_UNEXPECTED_FAIL, TEST_PASS);

View file

@ -0,0 +1,12 @@
/* 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/. */
MARIONETTE_TIMEOUT = 1000;
is(2, 2, "test for is()");
isnot(2, 3, "test for isnot()");
ok(2 == 2, "test for ok()");
setTimeout(finish, 100);

View file

@ -0,0 +1,107 @@
# 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_harness import MarionetteTestCase
class SimpletestSanityTest(MarionetteTestCase):
callFinish = "return finish();"
def run_sync(self, test):
return self.marionette.execute_js_script(test, async=False)
def run_async(self, test):
return self.marionette.execute_js_script(test)
def test_is(self):
def runtests():
sentFail1 = "is(true, false, 'isTest1', TEST_UNEXPECTED_FAIL, TEST_PASS);" + self.callFinish
sentFail2 = "is(true, false, 'isTest2', TEST_UNEXPECTED_FAIL, TEST_PASS);" + self.callFinish
sentPass1 = "is(true, true, 'isTest3');" + self.callFinish
sentPass2 = "is(true, true, 'isTest4');" + self.callFinish
self.assertEqual(1, len(self.run_sync(sentFail1)["failures"]))
self.assertEqual(0, self.run_sync(sentFail2)["passed"])
self.assertEqual(1, self.run_sync(sentPass1)["passed"])
self.assertEqual(0, len(self.run_sync(sentPass2)["failures"]))
self.marionette.timeout.script = 1
self.assertEqual(1, len(self.run_async(sentFail1)["failures"]))
self.assertEqual(0, self.run_async(sentFail2)["passed"])
self.assertEqual(1, self.run_async(sentPass1)["passed"])
self.assertEqual(0, len(self.run_async(sentPass2)["failures"]))
self.marionette.set_context("content")
runtests()
self.marionette.set_context("chrome")
runtests()
def test_isnot(self):
def runtests():
sentFail1 = "isnot(true, true, 'isnotTest3', TEST_UNEXPECTED_FAIL, TEST_PASS);" + self.callFinish
sentFail2 = "isnot(true, true, 'isnotTest4', TEST_UNEXPECTED_FAIL, TEST_PASS);" + self.callFinish
sentPass1 = "isnot(true, false, 'isnotTest1');" + self.callFinish
sentPass2 = "isnot(true, false, 'isnotTest2');" + self.callFinish
self.assertEqual(1, len(self.run_sync(sentFail1)["failures"]));
self.assertEqual(0, self.run_sync(sentFail2)["passed"]);
self.assertEqual(0, len(self.run_sync(sentPass1)["failures"]));
self.assertEqual(1, self.run_sync(sentPass2)["passed"]);
self.marionette.timeout.script = 1
self.assertEqual(1, len(self.run_async(sentFail1)["failures"]));
self.assertEqual(0, self.run_async(sentFail2)["passed"]);
self.assertEqual(0, len(self.run_async(sentPass1)["failures"]));
self.assertEqual(1, self.run_async(sentPass2)["passed"]);
self.marionette.set_context("content")
runtests()
self.marionette.set_context("chrome")
runtests()
def test_ok(self):
def runtests():
sentFail1 = "ok(1==2, 'testOk1', TEST_UNEXPECTED_FAIL, TEST_PASS);" + self.callFinish
sentFail2 = "ok(1==2, 'testOk2', TEST_UNEXPECTED_FAIL, TEST_PASS);" + self.callFinish
sentPass1 = "ok(1==1, 'testOk3');" + self.callFinish
sentPass2 = "ok(1==1, 'testOk4');" + self.callFinish
self.assertEqual(1, len(self.run_sync(sentFail1)["failures"]));
self.assertEqual(0, self.run_sync(sentFail2)["passed"]);
self.assertEqual(0, len(self.run_sync(sentPass1)["failures"]));
self.assertEqual(1, self.run_sync(sentPass2)["passed"]);
self.marionette.timeout.script = 1
self.assertEqual(1, len(self.run_async(sentFail1)["failures"]));
self.assertEqual(0, self.run_async(sentFail2)["passed"]);
self.assertEqual(0, len(self.run_async(sentPass1)["failures"]));
self.assertEqual(1, self.run_async(sentPass2)["passed"]);
self.marionette.set_context("content")
runtests()
self.marionette.set_context("chrome")
runtests()
def test_todo(self):
def runtests():
sentFail1 = "todo(1==1, 'testTodo1', TEST_UNEXPECTED_PASS, TEST_KNOWN_FAIL);" + self.callFinish
sentFail2 = "todo(1==1, 'testTodo2', TEST_UNEXPECTED_PASS, TEST_KNOWN_FAIL);" + self.callFinish
sentPass1 = "todo(1==2, 'testTodo3');" + self.callFinish
sentPass2 = "todo(1==2, 'testTodo4');" + self.callFinish
self.assertEqual(1, len(self.run_sync(sentFail1)["unexpectedSuccesses"]));
self.assertEqual(0, len(self.run_sync(sentFail2)["expectedFailures"]));
self.assertEqual(0, len(self.run_sync(sentPass1)["unexpectedSuccesses"]));
self.assertEqual(1, len(self.run_sync(sentPass2)["expectedFailures"]));
self.marionette.timeout.script = 1
self.assertEqual(1, len(self.run_async(sentFail1)["unexpectedSuccesses"]));
self.assertEqual(0, len(self.run_async(sentFail2)["expectedFailures"]));
self.assertEqual(0, len(self.run_async(sentPass1)["unexpectedSuccesses"]));
self.assertEqual(1, len(self.run_async(sentPass2)["expectedFailures"]));
self.marionette.set_context("content")
runtests()
self.marionette.set_context("chrome")
runtests()

View file

@ -0,0 +1,16 @@
/* 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/. */
MARIONETTE_TIMEOUT = 100;
/* this test will timeout */
function do_test() {
is(1, 1);
isnot(1, 2);
ok(1 == 1);
finish();
}
setTimeout(do_test, 1000);

View file

@ -0,0 +1,123 @@
# 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
import sys
from marionette_driver.errors import MarionetteException
from marionette_driver import Actions, By
from marionette_harness import MarionetteTestCase, skip
# add this directory to the path
sys.path.append(os.path.dirname(__file__))
from single_finger_functions import (
chain, chain_flick, context_menu, double_tap,
long_press_action, long_press_on_xy_action,
move_element, move_element_offset, press_release, single_tap, wait,
wait_with_value
)
class testSingleFingerMouse(MarionetteTestCase):
def setUp(self):
super(MarionetteTestCase, self).setUp()
# set context menu related preferences needed for some tests
self.marionette.set_context("chrome")
self.enabled = self.marionette.execute_script("""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let value = false;
try {
value = prefs.getBoolPref("ui.click_hold_context_menus");
}
catch (e) {}
prefs.setBoolPref("ui.click_hold_context_menus", true);
return value;
""")
self.wait_time = self.marionette.execute_script("""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let value = 750;
try {
value = prefs.getIntPref("ui.click_hold_context_menus.delay");
}
catch (e) {}
prefs.setIntPref("ui.click_hold_context_menus.delay", value);
return value;
""")
self.marionette.set_context("content")
def tearDown(self):
self.marionette.set_context("chrome")
self.marionette.execute_script(
"""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setBoolPref("ui.click_hold_context_menus", arguments[0]);
""", [self.enabled])
self.marionette.execute_script(
"""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]);
""", [self.wait_time])
self.marionette.set_context("content")
super(MarionetteTestCase, self).tearDown()
def test_press_release(self):
press_release(self.marionette, 1, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_press_release_twice(self):
press_release(self.marionette, 2, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click-mousemove-mousedown-mouseup-click")
def test_move_element(self):
move_element(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "button2-mousemove-mouseup")
def test_move_by_offset(self):
move_element_offset(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "button2-mousemove-mouseup")
def test_wait(self):
wait(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_wait_with_value(self):
wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
@skip("Bug 1191066")
def test_context_menu(self):
context_menu(self.marionette, self.wait_for_condition,
"button1-mousemove-mousedown-contextmenu",
"button1-mousemove-mousedown-contextmenu-mouseup-click")
@skip("Bug 1191066")
def test_long_press_action(self):
long_press_action(self.marionette, self.wait_for_condition,
"button1-mousemove-mousedown-contextmenu-mouseup-click")
@skip("Bug 1191066")
def test_long_press_on_xy_action(self):
long_press_on_xy_action(self.marionette, self.wait_for_condition,
"button1-mousemove-mousedown-contextmenu-mouseup-click")
@skip("Bug 865334")
def test_long_press_fail(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element(By.ID, "button1Copy")
action = Actions(self.marionette)
action.press(button).long_press(button, 5)
self.assertRaises(MarionetteException, action.perform)
def test_chain(self):
chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup")
def test_chain_flick(self):
chain_flick(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mousemove", "buttonFlick-mousemove-mouseup")
def test_single_tap(self):
single_tap(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_double_tap(self):
double_tap(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click-mousemove-mousedown-mouseup-click")

View file

@ -0,0 +1,35 @@
# 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_harness import MarionetteTestCase, SkipTest
class TestSetUpSkipped(MarionetteTestCase):
testVar = {'test':'SkipTest'}
def setUp(self):
try:
self.testVar['email']
except KeyError:
raise SkipTest('email key not present in dict, skip ...')
MarionetteTestCase.setUp(self)
def test_assert(self):
assert True
class TestSetUpNotSkipped(MarionetteTestCase):
testVar = {'test':'SkipTest'}
def setUp(self):
try:
self.testVar['test']
except KeyError:
raise SkipTest('email key not present in dict, skip ...')
MarionetteTestCase.setUp(self)
def test_assert(self):
assert True

View file

@ -0,0 +1,183 @@
# 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.by import By
from marionette_driver.errors import (
JavascriptException,
NoSuchFrameException,
)
from marionette_harness import MarionetteTestCase
class TestSwitchFrame(MarionetteTestCase):
def test_switch_simple(self):
start_url = "test_iframe.html"
verify_title = "Marionette IFrame Test"
test_html = self.marionette.absolute_url(start_url)
self.marionette.navigate(test_html)
self.assertEqual(self.marionette.get_active_frame(), None)
frame = self.marionette.find_element(By.ID, "test_iframe")
self.marionette.switch_to_frame(frame)
self.assertTrue(start_url in self.marionette.get_url())
inner_frame_element = self.marionette.get_active_frame()
# test that we can switch back to main frame, then switch back to the
# inner frame with the value we got from get_active_frame
self.marionette.switch_to_frame()
self.assertEqual(verify_title, self.marionette.title)
self.marionette.switch_to_frame(inner_frame_element)
self.assertTrue(start_url in self.marionette.get_url())
def test_switch_nested(self):
start_url = "test_nested_iframe.html"
verify_title = "Marionette IFrame Test"
test_html = self.marionette.absolute_url(start_url)
self.marionette.navigate(test_html)
frame = self.marionette.find_element(By.ID, "test_iframe")
self.assertEqual(self.marionette.get_active_frame(), None)
self.marionette.switch_to_frame(frame)
self.assertTrue(start_url in self.marionette.get_url())
inner_frame_element = self.marionette.get_active_frame()
# test that we can switch back to main frame, then switch back to the
# inner frame with the value we got from get_active_frame
self.marionette.switch_to_frame()
self.assertEqual(verify_title, self.marionette.title)
self.marionette.switch_to_frame(inner_frame_element)
self.assertTrue(start_url in self.marionette.get_url())
inner_frame = self.marionette.find_element(By.ID, 'inner_frame')
self.marionette.switch_to_frame(inner_frame)
self.assertTrue(start_url in self.marionette.get_url())
self.marionette.switch_to_frame() # go back to main frame
self.assertTrue(start_url in self.marionette.get_url())
#test that we're using the right window object server-side
self.assertTrue("test_nested_iframe.html" in self.marionette.execute_script("return window.location.href;"))
def test_stack_trace(self):
start_url = "test_iframe.html"
verify_title = "Marionette IFrame Test"
test_html = self.marionette.absolute_url(start_url)
self.marionette.navigate(test_html)
frame = self.marionette.find_element(By.ID, "test_iframe")
self.assertEqual(self.marionette.get_active_frame(), None)
self.marionette.switch_to_frame(frame)
self.assertTrue(start_url in self.marionette.get_url())
inner_frame_element = self.marionette.get_active_frame()
# test that we can switch back to main frame, then switch back to the
# inner frame with the value we got from get_active_frame
self.marionette.switch_to_frame()
self.assertEqual(verify_title, self.marionette.title)
self.marionette.switch_to_frame(inner_frame_element)
self.assertTrue(start_url in self.marionette.get_url())
try:
self.marionette.execute_async_script("foo();")
except JavascriptException as e:
self.assertTrue("foo" in e.message)
def test_should_be_able_to_carry_on_working_if_the_frame_is_deleted_from_under_us(self):
test_html = self.marionette.absolute_url("deletingFrame.html")
self.marionette.navigate(test_html)
self.marionette.switch_to_frame(self.marionette.find_element(By.ID,
'iframe1'))
killIframe = self.marionette.find_element(By.ID, "killIframe")
killIframe.click()
self.marionette.switch_to_frame()
self.assertEqual(0, len(self.marionette.find_elements(By.ID, "iframe1")))
addIFrame = self.marionette.find_element(By.ID, "addBackFrame")
addIFrame.click()
self.marionette.find_element(By.ID, "iframe1")
self.marionette.switch_to_frame(self.marionette.find_element(By.ID,
"iframe1"))
self.marionette.find_element(By.ID, "checkbox")
def test_should_allow_a_user_to_switch_from_an_iframe_back_to_the_main_content_of_the_page(self):
test_iframe = self.marionette.absolute_url("test_iframe.html")
self.marionette.navigate(test_iframe)
self.marionette.switch_to_frame(0)
self.marionette.switch_to_default_content()
header = self.marionette.find_element(By.ID, "iframe_page_heading")
self.assertEqual(header.text, "This is the heading")
def test_should_be_able_to_switch_to_a_frame_by_its_index(self):
test_html = self.marionette.absolute_url("frameset.html")
self.marionette.navigate(test_html)
self.marionette.switch_to_frame(2)
element = self.marionette.find_element(By.ID, "email")
self.assertEquals("email", element.get_attribute("type"))
def test_should_be_able_to_switch_to_a_frame_using_a_previously_located_element(self):
test_html = self.marionette.absolute_url("frameset.html")
self.marionette.navigate(test_html)
frame = self.marionette.find_element(By.NAME, "third")
self.marionette.switch_to_frame(frame)
element = self.marionette.find_element(By.ID, "email")
self.assertEquals("email", element.get_attribute("type"))
def test_switch_to_frame_with_out_of_bounds_index(self):
self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
count = self.marionette.execute_script("return window.frames.length;")
self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, count)
def test_switch_to_frame_with_negative_index(self):
self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, -1)
def test_switch_to_parent_frame(self):
frame_html = self.marionette.absolute_url("frameset.html")
self.marionette.navigate(frame_html)
frame = self.marionette.find_element(By.NAME, "third")
self.marionette.switch_to_frame(frame)
# If we don't find the following element we aren't on the right page
self.marionette.find_element(By.ID, "checky")
form_page_title = self.marionette.execute_script("return document.title")
self.assertEqual("We Leave From Here", form_page_title)
self.marionette.switch_to_parent_frame()
current_page_title = self.marionette.execute_script("return document.title")
self.assertEqual("Unique title", current_page_title)
def test_switch_to_parent_frame_from_default_context_is_a_noop(self):
formpage = self.marionette.absolute_url("formPage.html")
self.marionette.navigate(formpage)
self.marionette.switch_to_parent_frame()
form_page_title = self.marionette.execute_script("return document.title")
self.assertEqual("We Leave From Here", form_page_title)
def test_should_be_able_to_switch_to_parent_from_second_level(self):
frame_html = self.marionette.absolute_url("frameset.html")
self.marionette.navigate(frame_html)
frame = self.marionette.find_element(By.NAME, "fourth")
self.marionette.switch_to_frame(frame)
second_level = self.marionette.find_element(By.NAME, "child1")
self.marionette.switch_to_frame(second_level)
self.marionette.find_element(By.NAME, "myCheckBox")
self.marionette.switch_to_parent_frame()
second_level = self.marionette.find_element(By.NAME, "child1")
def test_should_be_able_to_switch_to_parent_from_iframe(self):
frame_html = self.marionette.absolute_url("test_iframe.html")
self.marionette.navigate(frame_html)
frame = self.marionette.find_element(By.ID, "test_iframe")
self.marionette.switch_to_frame(frame)
current_page_title = self.marionette.execute_script("return document.title")
self.assertEqual("Marionette Test", current_page_title)
self.marionette.switch_to_parent_frame()
parent_page_title = self.marionette.execute_script("return document.title")
self.assertEqual("Marionette IFrame Test", parent_page_title)

View file

@ -0,0 +1,56 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import JavascriptException
from marionette_harness import MarionetteTestCase, WindowManagerMixin
class TestSwitchFrameChrome(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestSwitchFrameChrome, self).setUp()
self.marionette.set_context("chrome")
def open_window_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test.xul',
'foo', 'chrome,centerscreen');
""")
new_window = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(new_window)
self.assertNotEqual(self.start_window, self.marionette.current_chrome_window_handle)
def tearDown(self):
self.close_all_windows()
super(TestSwitchFrameChrome, self).tearDown()
def test_switch_simple(self):
self.assertIn("test.xul", self.marionette.get_url(), "Initial navigation has failed")
self.marionette.switch_to_frame(0)
self.assertIn("test2.xul", self.marionette.get_url(),"Switching by index failed")
self.marionette.switch_to_frame()
self.assertEqual(None, self.marionette.get_active_frame(), "Switiching by null failed")
self.assertIn("test.xul", self.marionette.get_url(), "Switching by null failed")
self.marionette.switch_to_frame("iframe")
self.assertIn("test2.xul", self.marionette.get_url(), "Switching by name failed")
self.marionette.switch_to_frame()
self.assertIn("test.xul", self.marionette.get_url(), "Switching by null failed")
self.marionette.switch_to_frame("iframename")
self.assertIn("test2.xul", self.marionette.get_url(), "Switching by name failed")
iframe_element = self.marionette.get_active_frame()
self.marionette.switch_to_frame()
self.assertIn("test.xul", self.marionette.get_url(), "Switching by null failed")
self.marionette.switch_to_frame(iframe_element)
self.assertIn("test2.xul", self.marionette.get_url(), "Switching by element failed")
def test_stack_trace(self):
self.assertIn("test.xul", self.marionette.get_url(), "Initial navigation has failed")
self.marionette.switch_to_frame(0)
self.assertRaises(JavascriptException, self.marionette.execute_async_script, "foo();")
try:
self.marionette.execute_async_script("foo();")
except JavascriptException as e:
self.assertIn("foo", e.message)

View file

@ -0,0 +1,118 @@
# 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.by import By
from marionette_harness import MarionetteTestCase
OOP_BY_DEFAULT = "dom.ipc.browser_frames.oop_by_default"
BROWSER_FRAMES_ENABLED = "dom.mozBrowserFramesEnabled"
class TestSwitchRemoteFrame(MarionetteTestCase):
def setUp(self):
super(TestSwitchRemoteFrame, self).setUp()
with self.marionette.using_context('chrome'):
self.oop_by_default = self.marionette.get_pref(OOP_BY_DEFAULT)
self.mozBrowserFramesEnabled = self.marionette.get_pref(BROWSER_FRAMES_ENABLED)
self.marionette.set_pref(OOP_BY_DEFAULT, True)
self.marionette.set_pref(BROWSER_FRAMES_ENABLED, True)
self.multi_process_browser = self.marionette.execute_script("""
try {
return Services.appinfo.browserTabsRemoteAutostart;
} catch (e) {
return false;
}""")
def tearDown(self):
with self.marionette.using_context("chrome"):
if self.oop_by_default is None:
self.marionette.clear_pref(OOP_BY_DEFAULT)
else:
self.marionette.set_pref(OOP_BY_DEFAULT, self.oop_by_default)
if self.mozBrowserFramesEnabled is None:
self.marionette.clear_pref(BROWSER_FRAMES_ENABLED)
else:
self.marionette.set_pref(BROWSER_FRAMES_ENABLED, self.mozBrowserFramesEnabled)
@property
def is_main_process(self):
return self.marionette.execute_script("""
return Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULRuntime).
processType == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
""", sandbox="system")
def test_remote_frame(self):
self.marionette.navigate(self.marionette.absolute_url("test.html"))
self.marionette.push_permission('browser', True)
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('remote', true);
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
iframe.src = "{}";
document.body.appendChild(iframe);
""".format(self.marionette.absolute_url("test.html")))
remote_iframe = self.marionette.find_element(By.ID, "remote_iframe")
self.marionette.switch_to_frame(remote_iframe)
main_process = self.is_main_process
self.assertFalse(main_process)
def test_remote_frame_revisit(self):
# test if we can revisit a remote frame (this takes a different codepath)
self.marionette.navigate(self.marionette.absolute_url("test.html"))
self.marionette.push_permission('browser', True)
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('remote', true);
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
iframe.src = "{}";
document.body.appendChild(iframe);
""".format(self.marionette.absolute_url("test.html")))
self.marionette.switch_to_frame(self.marionette.find_element(By.ID,
"remote_iframe"))
main_process = self.is_main_process
self.assertFalse(main_process)
self.marionette.switch_to_frame()
main_process = self.is_main_process
should_be_main_process = not self.multi_process_browser
self.assertEqual(main_process, should_be_main_process)
self.marionette.switch_to_frame(self.marionette.find_element(By.ID,
"remote_iframe"))
main_process = self.is_main_process
self.assertFalse(main_process)
def test_we_can_switch_to_a_remote_frame_by_index(self):
# test if we can revisit a remote frame (this takes a different codepath)
self.marionette.navigate(self.marionette.absolute_url("test.html"))
self.marionette.push_permission('browser', True)
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('remote', true);
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
iframe.src = "{}";
document.body.appendChild(iframe);
""".format(self.marionette.absolute_url("test.html")))
self.marionette.switch_to_frame(0)
main_process = self.is_main_process
self.assertFalse(main_process)
self.marionette.switch_to_frame()
main_process = self.is_main_process
should_be_main_process = not self.multi_process_browser
self.assertEqual(main_process, should_be_main_process)
self.marionette.switch_to_frame(0)
main_process = self.is_main_process
self.assertFalse(main_process)

View file

@ -0,0 +1,124 @@
# 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
import sys
from unittest import skipIf
from marionette_driver import By
# add this directory to the path
sys.path.append(os.path.dirname(__file__))
from test_switch_window_content import TestSwitchToWindowContent
class TestSwitchWindowChrome(TestSwitchToWindowContent):
def setUp(self):
super(TestSwitchWindowChrome, self).setUp()
self.marionette.set_context("chrome")
def tearDown(self):
self.close_all_windows()
super(TestSwitchWindowChrome, self).tearDown()
def open_window_in_background(self):
with self.marionette.using_context("chrome"):
self.marionette.execute_script("""
window.open("about:blank", null, "location=1,toolbar=1");
window.focus();
""")
def open_window_in_foreground(self):
with self.marionette.using_context("content"):
self.marionette.navigate(self.test_page)
link = self.marionette.find_element(By.ID, "new-window")
link.click()
@skipIf(sys.platform.startswith("linux"),
"Bug 1335457 - Fails to open a background window on Linux")
def test_switch_tabs_for_new_background_window_without_focus_change(self):
# Bug 1334981 - with testmode enabled getMostRecentWindow detects the wrong window
with self.marionette.using_prefs({"focusmanager.testmode": False}):
# Open an addition tab in the original window so we can better check
# the selected index in thew new window to be opened.
second_tab = self.open_tab(trigger=self.open_tab_in_foreground)
self.marionette.switch_to_window(second_tab, focus=True)
second_tab_index = self.get_selected_tab_index()
self.assertNotEqual(second_tab_index, self.selected_tab_index)
# Opens a new background window, but we are interested in the tab
tab_in_new_window = self.open_tab(trigger=self.open_window_in_background)
self.assertEqual(self.marionette.current_window_handle, second_tab)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.assertEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.empty_page)
# Switch to the tab in the new window but don't focus it
self.marionette.switch_to_window(tab_in_new_window, focus=False)
self.assertEqual(self.marionette.current_window_handle, tab_in_new_window)
self.assertNotEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.assertEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), "about:blank")
def test_switch_tabs_for_new_foreground_window_with_focus_change(self):
# Open an addition tab in the original window so we can better check
# the selected index in thew new window to be opened.
second_tab = self.open_tab(trigger=self.open_tab_in_foreground)
self.marionette.switch_to_window(second_tab, focus=True)
second_tab_index = self.get_selected_tab_index()
self.assertNotEqual(second_tab_index, self.selected_tab_index)
# Opens a new window, but we are interested in the tab
tab_in_new_window = self.open_tab(trigger=self.open_window_in_foreground)
self.assertEqual(self.marionette.current_window_handle, second_tab)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.assertNotEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
self.marionette.switch_to_window(tab_in_new_window)
self.assertEqual(self.marionette.current_window_handle, tab_in_new_window)
self.assertNotEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.assertNotEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.empty_page)
self.marionette.switch_to_window(second_tab, focus=True)
self.assertEqual(self.marionette.current_window_handle, second_tab)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
# Bug 1335085 - The focus doesn't change even as requested so.
# self.assertEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
def test_switch_tabs_for_new_foreground_window_without_focus_change(self):
# Open an addition tab in the original window so we can better check
# the selected index in thew new window to be opened.
second_tab = self.open_tab(trigger=self.open_tab_in_foreground)
self.marionette.switch_to_window(second_tab, focus=True)
second_tab_index = self.get_selected_tab_index()
self.assertNotEqual(second_tab_index, self.selected_tab_index)
# Opens a new window, but we are interested in the tab which automatically
# gets the focus.
self.open_tab(trigger=self.open_window_in_foreground)
self.assertEqual(self.marionette.current_window_handle, second_tab)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.assertNotEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
# Switch to the second tab in the first window, but don't focus it.
self.marionette.switch_to_window(second_tab, focus=False)
self.assertEqual(self.marionette.current_window_handle, second_tab)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.assertNotEqual(self.get_selected_tab_index(), second_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)

View file

@ -0,0 +1,171 @@
# This Source Code Form is subject to the terms of the Mozilla ublic
# 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 Actions, By, Wait
from marionette_driver.keys import Keys
from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin
class TestSwitchToWindowContent(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestSwitchToWindowContent, self).setUp()
if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META
else:
self.mod_key = Keys.CONTROL
self.empty_page = self.marionette.absolute_url("empty.html")
self.test_page = self.marionette.absolute_url("windowHandles.html")
self.selected_tab_index = self.get_selected_tab_index()
with self.marionette.using_context("content"):
self.marionette.navigate(self.test_page)
def tearDown(self):
self.close_all_tabs()
super(TestSwitchToWindowContent, self).tearDown()
def get_selected_tab_index(self):
with self.marionette.using_context("chrome"):
return self.marionette.execute_script("""
Components.utils.import("resource://gre/modules/AppConstants.jsm");
let win = null;
if (AppConstants.MOZ_APP_NAME == "fennec") {
Components.utils.import("resource://gre/modules/Services.jsm");
win = Services.wm.getMostRecentWindow("navigator:browser");
} else {
Components.utils.import("resource:///modules/RecentWindow.jsm");
win = RecentWindow.getMostRecentBrowserWindow();
}
let tabBrowser = null;
// Fennec
if (win.BrowserApp) {
tabBrowser = win.BrowserApp;
// Firefox
} else if (win.gBrowser) {
tabBrowser = win.gBrowser;
} else {
return null;
}
for (let i = 0; i < tabBrowser.tabs.length; i++) {
if (tabBrowser.tabs[i] == tabBrowser.selectedTab) {
return i;
}
}
""")
def open_tab_in_background(self):
with self.marionette.using_context("content"):
link = self.marionette.find_element(By.ID, "new-tab")
action = Actions(self.marionette)
action.key_down(self.mod_key).click(link).perform()
def open_tab_in_foreground(self):
with self.marionette.using_context("content"):
link = self.marionette.find_element(By.ID, "new-tab")
link.click()
def test_switch_tabs_with_focus_change(self):
new_tab = self.open_tab(self.open_tab_in_foreground)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
Wait(self.marionette).until(
lambda _: self.marionette.get_url() == self.empty_page,
message="{} has been loaded in the newly opened tab.".format(self.empty_page))
self.marionette.switch_to_window(self.start_tab, focus=True)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
self.marionette.switch_to_window(new_tab)
self.marionette.close()
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
def test_switch_tabs_without_focus_change(self):
new_tab = self.open_tab(self.open_tab_in_foreground)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
# Switch to new tab first because it is already selected
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
self.marionette.switch_to_window(self.start_tab, focus=False)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
self.marionette.switch_to_window(new_tab)
self.marionette.close()
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
def test_switch_from_content_to_chrome_window_should_not_change_selected_tab(self):
new_tab = self.open_tab(self.open_tab_in_foreground)
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
new_tab_index = self.get_selected_tab_index()
self.marionette.switch_to_window(self.start_window)
self.assertEqual(self.marionette.current_window_handle, new_tab)
self.assertEqual(self.get_selected_tab_index(), new_tab_index)
@skip_if_mobile("New windows not supported in Fennec")
def test_switch_to_new_private_browsing_window_has_to_register_browsers(self):
# Test that tabs (browsers) are correctly registered for a newly opened
# private browsing window. This has to also happen without explicitely
# switching to the tab itself before using any commands in content scope.
#
# Note: Not sure why this only affects private browsing windows only.
def open_private_browsing_window():
with self.marionette.using_context("content"):
self.marionette.navigate("about:privatebrowsing")
button = self.marionette.find_element(By.ID, "startPrivateBrowsing")
button.click()
new_window = self.open_window(open_private_browsing_window)
self.marionette.switch_to_window(new_window)
self.assertEqual(self.marionette.current_chrome_window_handle, new_window)
self.assertNotEqual(self.marionette.current_window_handle, self.start_tab)
with self.marionette.using_context("content"):
self.marionette.execute_script(" return true; ")

View file

@ -0,0 +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/.
from marionette_harness import MarionetteTestCase, SkipTest
class TestTearDownContext(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
def tearDown(self):
self.assertEqual(self.get_context(), self.marionette.CONTEXT_CHROME)
MarionetteTestCase.tearDown(self)
def get_context(self):
return self.marionette._send_message("getContext", key="value")
def test_skipped_teardown_ok(self):
raise SkipTest("This should leave our teardown method in chrome context")

View file

@ -0,0 +1,224 @@
# 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.by import By
from marionette_driver.keys import Keys
from marionette_harness import MarionetteTestCase, skip_if_mobile
class TestText(MarionetteTestCase):
def test_getText(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
l = self.marionette.find_element(By.ID, "mozLink")
self.assertEqual("Click me!", l.text)
def test_clearText(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
l = self.marionette.find_element(By.NAME, "myInput")
self.assertEqual("asdf", self.marionette.execute_script("return arguments[0].value;", [l]))
l.clear()
self.assertEqual("", self.marionette.execute_script("return arguments[0].value;", [l]))
def test_sendKeys(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
l = self.marionette.find_element(By.NAME, "myInput")
self.assertEqual("asdf", self.marionette.execute_script("return arguments[0].value;", [l]))
# Set caret position to the middle of the input text.
self.marionette.execute_script(
"""var el = arguments[0];
el.selectionStart = el.selectionEnd = el.value.length / 2;""",
script_args=[l])
l.send_keys("o")
self.assertEqual("asodf", self.marionette.execute_script("return arguments[0].value;", [l]))
def test_send_keys_to_type_input(self):
test_html = self.marionette.absolute_url("html5/test_html_inputs.html")
self.marionette.navigate(test_html)
num_input = self.marionette.find_element(By.ID, 'number')
self.assertEqual("", self.marionette.execute_script("return arguments[0].value", [num_input]))
num_input.send_keys("1234")
self.assertEqual('1234', self.marionette.execute_script("return arguments[0].value", [num_input]))
def test_should_fire_key_press_events(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys("a")
result = self.marionette.find_element(By.ID, "result")
self.assertIn("press:", result.text)
def test_should_fire_key_down_events(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys("a")
result = self.marionette.find_element(By.ID, "result")
self.assertIn("down:", result.text)
def test_should_fire_key_up_events(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys("a")
result = self.marionette.find_element(By.ID, "result")
self.assertIn("up:", result.text)
def test_should_type_lowercase_characters(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys("abc def")
self.assertEqual("abc def", key_reporter.get_property("value"))
def test_should_type_uppercase_characters(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys("ABC DEF")
self.assertEqual("ABC DEF", key_reporter.get_property("value"))
def test_should_type_a_quote_characters(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys('"')
self.assertEqual('"', key_reporter.get_property("value"))
def test_should_type_an_at_character(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys('@')
self.assertEqual("@", key_reporter.get_property("value"))
def test_should_type_a_mix_of_upper_and_lower_case_character(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys("me@EXampLe.com")
self.assertEqual("me@EXampLe.com", key_reporter.get_property("value"))
def test_arrow_keys_are_not_printable(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
key_reporter = self.marionette.find_element(By.ID, "keyReporter")
key_reporter.send_keys(Keys.ARROW_LEFT)
self.assertEqual("", key_reporter.get_property("value"))
def test_will_simulate_a_key_up_when_entering_text_into_input_elements(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyUp")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
self.assertEqual(result.text, "I like cheese")
def test_will_simulate_a_key_down_when_entering_text_into_input_elements(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyDown")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
def test_will_simulate_a_key_press_when_entering_text_into_input_elements(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyPress")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
def test_will_simulate_a_keyup_when_entering_text_into_textareas(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyUpArea")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
self.assertEqual(result.text, "I like cheese")
def test_will_simulate_a_keydown_when_entering_text_into_textareas(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyDownArea")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
def test_will_simulate_a_keypress_when_entering_text_into_textareas(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyPressArea")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
@skip_if_mobile("Bug 1333069 - Assertion: 'down: 40' not found in u''")
def test_should_report_key_code_of_arrow_keys_up_down_events(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
result = self.marionette.find_element(By.ID, "result")
element = self.marionette.find_element(By.ID, "keyReporter")
element.send_keys(Keys.ARROW_DOWN)
self.assertIn("down: 40", result.text.strip())
self.assertIn("up: 40", result.text.strip())
element.send_keys(Keys.ARROW_UP)
self.assertIn("down: 38", result.text.strip())
self.assertIn("up: 38", result.text.strip())
element.send_keys(Keys.ARROW_LEFT)
self.assertIn("down: 37", result.text.strip())
self.assertIn("up: 37", result.text.strip())
element.send_keys(Keys.ARROW_RIGHT)
self.assertIn("down: 39", result.text.strip())
self.assertIn("up: 39", result.text.strip())
# And leave no rubbish/printable keys in the "keyReporter"
self.assertEqual("", element.get_property("value"))
def testNumericNonShiftKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyReporter")
numericLineCharsNonShifted = "`1234567890-=[]\\,.'/42"
element.send_keys(numericLineCharsNonShifted)
self.assertEqual(numericLineCharsNonShifted, element.get_property("value"))
def testShouldTypeAnInteger(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyReporter")
element.send_keys(1234)
self.assertEqual("1234", element.get_property("value"))

View file

@ -0,0 +1,44 @@
# 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.by import By
from marionette_harness import MarionetteTestCase, skip, WindowManagerMixin
@skip("Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046")
class TestTextChrome(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestTextChrome, self).setUp()
self.marionette.set_context("chrome")
def open_window_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test.xul',
'foo', 'chrome,centerscreen');
""")
new_window = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(new_window)
def tearDown(self):
self.close_all_windows()
super(TestTextChrome, self).tearDown()
def test_getText(self):
box = self.marionette.find_element(By.ID, "textInput")
self.assertEqual("test", box.text)
def test_clearText(self):
box = self.marionette.find_element(By.ID, "textInput")
self.assertEqual("test", box.text)
box.clear()
self.assertEqual("", box.text)
def test_sendKeys(self):
box = self.marionette.find_element(By.ID, "textInput")
self.assertEqual("test", box.text)
box.send_keys("at")
self.assertEqual("attest", box.text)

View file

@ -0,0 +1,115 @@
# 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.by import By
from marionette_driver.errors import (
MarionetteException,
NoSuchElementException,
ScriptTimeoutException,
)
from marionette_driver.marionette import HTMLElement
from marionette_harness import MarionetteTestCase, run_if_manage_instance, skip_if_mobile
class TestTimeouts(MarionetteTestCase):
def tearDown(self):
self.marionette.timeout.reset()
MarionetteTestCase.tearDown(self)
def test_page_timeout_notdefinetimeout_pass(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
def test_page_timeout_fail(self):
self.marionette.timeout.page_load = 0
test_html = self.marionette.absolute_url("test.html")
self.assertRaises(MarionetteException, self.marionette.navigate, test_html)
def test_page_timeout_pass(self):
self.marionette.timeout.page_load = 60
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
def test_search_timeout_notfound_settimeout(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
self.marionette.timeout.implicit = 1
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "I'm not on the page")
self.marionette.timeout.implicit = 0
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "I'm not on the page")
def test_search_timeout_found_settimeout(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
button = self.marionette.find_element(By.ID, "createDivButton")
button.click()
self.marionette.timeout.implicit = 8
self.assertEqual(HTMLElement, type(self.marionette.find_element(By.ID, "newDiv")))
def test_search_timeout_found(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
button = self.marionette.find_element(By.ID, "createDivButton")
button.click()
self.assertRaises(NoSuchElementException, self.marionette.find_element, By.ID, "newDiv")
@run_if_manage_instance("Only runnable if Marionette manages the instance")
@skip_if_mobile("Bug 1322993 - Missing temporary folder")
def test_reset_timeout(self):
timeouts = [getattr(self.marionette.timeout, f) for f in (
'implicit', 'page_load', 'script',)]
def do_check(callback):
for timeout in timeouts:
timeout = 10000
self.assertEqual(timeout, 10000)
callback()
for timeout in timeouts:
self.assertNotEqual(timeout, 10000)
def callback_quit():
self.marionette.quit()
self.marionette.start_session()
do_check(self.marionette.restart)
do_check(callback_quit)
def test_execute_async_timeout_settimeout(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
self.marionette.timeout.script = 1
self.assertRaises(ScriptTimeoutException, self.marionette.execute_async_script, "var x = 1;")
def test_no_timeout_settimeout(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
self.marionette.timeout.script = 1
self.assertTrue(self.marionette.execute_async_script("""
var callback = arguments[arguments.length - 1];
setTimeout(function() { callback(true); }, 500);
"""))
def test_compat_input_types(self):
# When using the spec-incompatible input format which we have
# for backwards compatibility, it should be possible to send ms
# as a string type and have the server parseInt it to an integer.
body = {"type": "script", "ms": "30000"}
self.marionette._send_message("setTimeouts", body)
def test_deprecated_set_timeouts_command(self):
body = {"implicit": 3000}
self.marionette._send_message("timeouts", body)
def test_deprecated_set_search_timeout(self):
self.marionette.set_search_timeout(1000)
self.assertEqual(1, self.marionette.timeout.implicit)
def test_deprecated_set_script_timeout(self):
self.marionette.set_script_timeout(2000)
self.assertEqual(2, self.marionette.timeout.script)
def test_deprecated_set_page_load_timeout(self):
self.marionette.set_page_load_timeout(3000)
self.assertEqual(3, self.marionette.timeout.page_load)

View file

@ -0,0 +1,172 @@
# 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 json
from marionette_driver.transport import (
Command,
Proto2Command,
Proto2Response,
Response,
)
from marionette_harness import MarionetteTestCase, skip_unless_protocol
get_current_url = ("getCurrentUrl", None)
execute_script = ("executeScript", {"script": "return 42"})
class TestMessageSequencing(MarionetteTestCase):
@property
def last_id(self):
return self.marionette.client.last_id
@last_id.setter
def last_id(self, new_id):
self.marionette.client.last_id = new_id
def send(self, name, params):
self.last_id = self.last_id + 1
cmd = Command(self.last_id, name, params)
self.marionette.client.send(cmd)
return self.last_id
@skip_unless_protocol("Skip for level < 3", lambda level: level >= 3)
def test_discard_older_messages(self):
first = self.send(*get_current_url)
second = self.send(*execute_script)
resp = self.marionette.client.receive()
self.assertEqual(second, resp.id)
@skip_unless_protocol("Skip for level < 3", lambda level: level >= 3)
def test_last_id_incremented(self):
before = self.last_id
self.send(*get_current_url)
self.assertGreater(self.last_id, before)
class MessageTestCase(MarionetteTestCase):
def assert_attr(self, obj, attr):
self.assertTrue(hasattr(obj, attr),
"object does not have attribute {}".format(attr))
class TestCommand(MessageTestCase):
def create(self, msgid="msgid", name="name", params="params"):
return Command(msgid, name, params)
def test_initialise(self):
cmd = self.create()
self.assert_attr(cmd, "id")
self.assert_attr(cmd, "name")
self.assert_attr(cmd, "params")
self.assertEqual("msgid", cmd.id)
self.assertEqual("name", cmd.name)
self.assertEqual("params", cmd.params)
def test_stringify(self):
cmd = self.create()
string = str(cmd)
self.assertIn("Command", string)
self.assertIn("id=msgid", string)
self.assertIn("name=name", string)
self.assertIn("params=params", string)
def test_to_msg(self):
cmd = self.create()
msg = json.loads(cmd.to_msg())
self.assertEquals(msg[0], Command.TYPE)
self.assertEquals(msg[1], "msgid")
self.assertEquals(msg[2], "name")
self.assertEquals(msg[3], "params")
def test_from_msg(self):
msg = [Command.TYPE, "msgid", "name", "params"]
payload = json.dumps(msg)
cmd = Command.from_msg(payload)
self.assertEquals(msg[1], cmd.id)
self.assertEquals(msg[2], cmd.name)
self.assertEquals(msg[3], cmd.params)
class TestResponse(MessageTestCase):
def create(self, msgid="msgid", error="error", result="result"):
return Response(msgid, error, result)
def test_initialise(self):
resp = self.create()
self.assert_attr(resp, "id")
self.assert_attr(resp, "error")
self.assert_attr(resp, "result")
self.assertEqual("msgid", resp.id)
self.assertEqual("error", resp.error)
self.assertEqual("result", resp.result)
def test_stringify(self):
resp = self.create()
string = str(resp)
self.assertIn("Response", string)
self.assertIn("id=msgid", string)
self.assertIn("error=error", string)
self.assertIn("result=result", string)
def test_to_msg(self):
resp = self.create()
msg = json.loads(resp.to_msg())
self.assertEquals(msg[0], Response.TYPE)
self.assertEquals(msg[1], "msgid")
self.assertEquals(msg[2], "error")
self.assertEquals(msg[3], "result")
def test_from_msg(self):
msg = [Response.TYPE, "msgid", "error", "result"]
payload = json.dumps(msg)
resp = Response.from_msg(payload)
self.assertEquals(msg[1], resp.id)
self.assertEquals(msg[2], resp.error)
self.assertEquals(msg[3], resp.result)
class TestProto2Command(MessageTestCase):
def create(self, name="name", params="params"):
return Proto2Command(name, params)
def test_initialise(self):
cmd = self.create()
self.assert_attr(cmd, "id")
self.assert_attr(cmd, "name")
self.assert_attr(cmd, "params")
self.assertEqual(None, cmd.id)
self.assertEqual("name", cmd.name)
self.assertEqual("params", cmd.params)
def test_from_data_unknown(self):
with self.assertRaises(ValueError):
cmd = Proto2Command.from_data({})
class TestProto2Response(MessageTestCase):
def create(self, error="error", result="result"):
return Proto2Response(error, result)
def test_initialise(self):
resp = self.create()
self.assert_attr(resp, "id")
self.assert_attr(resp, "error")
self.assert_attr(resp, "result")
self.assertEqual(None, resp.id)
self.assertEqual("error", resp.error)
self.assertEqual("result", resp.result)
def test_from_data_error(self):
data = {"error": "error"}
resp = Proto2Response.from_data(data)
self.assertEqual(data, resp.error)
self.assertEqual(None, resp.result)
def test_from_data_result(self):
resp = Proto2Response.from_data("result")
self.assertEqual(None, resp.error)
self.assertEqual("result", resp.result)

View file

@ -0,0 +1,332 @@
# 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 urllib
from marionette_driver.by import By
from marionette_driver.errors import ElementNotInteractableException
from marionette_driver.keys import Keys
from marionette_harness import MarionetteTestCase, skip, skip_if_mobile
def inline(doc):
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
class TypingTestCase(MarionetteTestCase):
def setUp(self):
super(TypingTestCase, self).setUp()
if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META
else:
self.mod_key = Keys.CONTROL
class TestTypingChrome(TypingTestCase):
def setUp(self):
super(TestTypingChrome, self).setUp()
self.marionette.set_context("chrome")
@skip_if_mobile("Interacting with chrome elements not available for Fennec")
def test_cut_and_paste_shortcuts(self):
with self.marionette.using_context("content"):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
self.assertEqual("", keyReporter.get_property("value"))
keyReporter.send_keys("zyxwvutsr")
self.assertEqual("zyxwvutsr", keyReporter.get_property("value"))
# select all and cut
keyReporter.send_keys(self.mod_key, "a")
keyReporter.send_keys(self.mod_key, "x")
self.assertEqual("", keyReporter.get_property("value"))
url_bar = self.marionette.find_element(By.ID, "urlbar")
# Clear contents first
url_bar.send_keys(self.mod_key, "a")
url_bar.send_keys(Keys.BACK_SPACE)
self.assertEqual("", url_bar.get_attribute("value"))
url_bar.send_keys(self.mod_key, "v")
self.assertEqual("zyxwvutsr", url_bar.get_property("value"))
class TestTypingContent(TypingTestCase):
def testShouldFireKeyPressEvents(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("a")
result = self.marionette.find_element(By.ID, "result")
self.assertTrue("press:" in result.text)
def testShouldFireKeyDownEvents(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("I")
result = self.marionette.find_element(By.ID, "result")
self.assertTrue("down" in result.text)
def testShouldFireKeyUpEvents(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("a")
result = self.marionette.find_element(By.ID, "result")
self.assertTrue("up:" in result.text)
def testShouldTypeLowerCaseLetters(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("abc def")
self.assertEqual("abc def", keyReporter.get_property("value"))
def testShouldBeAbleToTypeCapitalLetters(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("ABC DEF")
self.assertEqual("ABC DEF", keyReporter.get_property("value"))
def testCutAndPasteShortcuts(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
self.assertEqual("", keyReporter.get_property("value"))
keyReporter.send_keys("zyxwvutsr")
self.assertEqual("zyxwvutsr", keyReporter.get_property("value"))
# select all and cut
keyReporter.send_keys(self.mod_key, "a")
keyReporter.send_keys(self.mod_key, "x")
self.assertEqual("", keyReporter.get_property("value"))
keyReporter.send_keys(self.mod_key, "v")
self.assertEqual("zyxwvutsr", keyReporter.get_property("value"))
def testShouldBeAbleToTypeQuoteMarks(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("\"")
self.assertEqual("\"", keyReporter.get_property("value"))
def testShouldBeAbleToTypeTheAtCharacter(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("@")
self.assertEqual("@", keyReporter.get_property("value"))
def testShouldBeAbleToMixUpperAndLowerCaseLetters(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys("me@eXample.com")
self.assertEqual("me@eXample.com", keyReporter.get_property("value"))
def testArrowKeysShouldNotBePrintable(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
keyReporter = self.marionette.find_element(By.ID, "keyReporter")
keyReporter.send_keys(Keys.ARROW_LEFT)
self.assertEqual("", keyReporter.get_property("value"))
def testWillSimulateAKeyUpWhenEnteringTextIntoInputElements(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyUp")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
self.assertEqual(result.text, "I like cheese")
def testWillSimulateAKeyDownWhenEnteringTextIntoInputElements(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyDown")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
def testWillSimulateAKeyPressWhenEnteringTextIntoInputElements(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyPress")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
def testWillSimulateAKeyUpWhenEnteringTextIntoTextAreas(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyUpArea")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
self.assertEqual("I like cheese", result.text)
def testWillSimulateAKeyDownWhenEnteringTextIntoTextAreas(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyDownArea")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
def testWillSimulateAKeyPressWhenEnteringTextIntoTextAreas(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyPressArea")
element.send_keys("I like cheese")
result = self.marionette.find_element(By.ID, "result")
# Because the key down gets the result before the input element is
# filled, we're a letter short here
self.assertEqual(result.text, "I like chees")
@skip_if_mobile("Bug 1324752 - Arrow keys cannot be sent in Fennec")
def testShouldReportKeyCodeOfArrowKeysUpDownEvents(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
result = self.marionette.find_element(By.ID, "result")
element = self.marionette.find_element(By.ID, "keyReporter")
element.send_keys(Keys.ARROW_DOWN)
self.assertIn("down: 40", result.text.strip())
self.assertIn("up: 40", result.text.strip())
element.send_keys(Keys.ARROW_UP)
self.assertIn("down: 38", result.text.strip())
self.assertIn("up: 38", result.text.strip())
element.send_keys(Keys.ARROW_LEFT)
self.assertIn("down: 37", result.text.strip())
self.assertIn("up: 37", result.text.strip())
element.send_keys(Keys.ARROW_RIGHT)
self.assertIn("down: 39", result.text.strip())
self.assertIn("up: 39", result.text.strip())
# And leave no rubbish/printable keys in the "keyReporter"
self.assertEqual("", element.get_property("value"))
@skip("Reenable in Bug 1068728")
def testNumericShiftKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
result = self.marionette.find_element(By.ID, "result")
element = self.marionette.find_element(By.ID, "keyReporter")
numericShiftsEtc = "~!@#$%^&*()_+{}:i\"<>?|END~"
element.send_keys(numericShiftsEtc)
self.assertEqual(numericShiftsEtc, element.get_property("value"))
self.assertIn(" up: 16", result.text.strip())
def testLowerCaseAlphaKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyReporter")
lowerAlphas = "abcdefghijklmnopqrstuvwxyz"
element.send_keys(lowerAlphas)
self.assertEqual(lowerAlphas, element.get_property("value"))
@skip("Reenable in Bug 1068735")
def testUppercaseAlphaKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
result = self.marionette.find_element(By.ID, "result")
element = self.marionette.find_element(By.ID, "keyReporter")
upperAlphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
element.send_keys(upperAlphas)
self.assertEqual(upperAlphas, element.get_property("value"))
self.assertIn(" up: 16", result.text.strip())
@skip("Reenable in Bug 1068726")
def testAllPrintableKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
result = self.marionette.find_element(By.ID, "result")
element = self.marionette.find_element(By.ID, "keyReporter")
allPrintable = "!\"#$%&'()*+,-./0123456789:<=>?@ ABCDEFGHIJKLMNOPQRSTUVWXYZ [\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
element.send_keys(allPrintable)
self.assertTrue(allPrintable, element.get_property("value"))
self.assertIn(" up: 16", result.text.strip())
@skip("Reenable in Bug 1068733")
def testSpecialSpaceKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyReporter")
element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij")
self.assertEqual("abcd fgh ij", element.get_property("value"))
def testShouldTypeAnInteger(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "keyReporter")
element.send_keys(1234)
self.assertEqual("1234", element.get_property("value"))
def testShouldSendKeysToElementsWithoutTheValueAttribute(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
# If we don't get an error below we are good
self.marionette.find_element(By.TAG_NAME, "body").send_keys("foo")
def test_not_interactable_if_hidden(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
not_displayed = self.marionette.find_element(By.ID, "notDisplayed")
self.assertRaises(ElementNotInteractableException, not_displayed.send_keys, "foo")
def test_appends_to_input_text(self):
self.marionette.navigate(inline("<input>"))
el = self.marionette.find_element(By.TAG_NAME, "input")
el.send_keys("foo")
el.send_keys("bar")
self.assertEqual("foobar", el.get_property("value"))
def test_appends_to_textarea(self):
self.marionette.navigate(inline("<textarea></textarea>"))
textarea = self.marionette.find_element(By.TAG_NAME, "textarea")
textarea.send_keys("foo")
textarea.send_keys("bar")
self.assertEqual("foobar", textarea.get_property("value"))

View file

@ -0,0 +1,46 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.errors import JavascriptException
from marionette_harness import MarionetteTestCase
class TestUsingPermssions(MarionetteTestCase):
def test_using_permissions(self):
# Test that multiple permissions can be set with 'using_permissions',
# and that they are set correctly and unset correctly after leaving
# the context manager.
original_perm = self.marionette.get_permission('systemXHR')
original_alarm = self.marionette.get_permission('alarms')
new_perm = True if original_perm != 1 else False
new_alarm = True if original_alarm != 1 else False
with self.marionette.using_permissions({'systemXHR': new_perm,
'alarms': new_alarm}):
now_perm = self.marionette.get_permission('systemXHR')
now_alarm = self.marionette.get_permission('alarms')
self.assertEquals(new_perm, now_perm)
self.assertNotEquals(now_perm, original_perm)
self.assertEquals(new_alarm, now_alarm)
self.assertNotEquals(now_alarm, original_alarm)
self.assertEquals(original_perm,
self.marionette.get_permission('systemXHR'))
self.assertEquals(original_alarm,
self.marionette.get_permission('alarms'))
def test_exception_using_permissions(self):
# Test that throwing an exception inside the context manager doesn't
# prevent the permissions from being restored at context manager exit.
original_perm = self.marionette.get_permission('systemXHR')
new_perm = True if original_perm != 1 else False
with self.marionette.using_permissions({'systemXHR': new_perm}):
now_perm = self.marionette.get_permission('systemXHR')
self.assertEquals(new_perm, now_perm)
self.assertNotEquals(now_perm, original_perm)
self.assertRaises(JavascriptException,
self.marionette.execute_script,
"return foo.bar.baz;")
self.assertEquals(original_perm,
self.marionette.get_permission('systemXHR'))

View file

@ -0,0 +1,121 @@
# 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.by import By
from marionette_harness import MarionetteTestCase
class TestVisibility(MarionetteTestCase):
def testShouldAllowTheUserToTellIfAnElementIsDisplayedOrNot(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
self.assertTrue(self.marionette.find_element(By.ID, "displayed").is_displayed())
self.assertFalse(self.marionette.find_element(By.ID, "none").is_displayed())
self.assertFalse(self.marionette.find_element(By.ID,
"suppressedParagraph").is_displayed())
self.assertFalse(self.marionette.find_element(By.ID, "hidden").is_displayed())
def testVisibilityShouldTakeIntoAccountParentVisibility(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
childDiv = self.marionette.find_element(By.ID, "hiddenchild")
hiddenLink = self.marionette.find_element(By.ID, "hiddenlink")
self.assertFalse(childDiv.is_displayed())
self.assertFalse(hiddenLink.is_displayed())
def testShouldCountElementsAsVisibleIfStylePropertyHasBeenSet(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
shown = self.marionette.find_element(By.ID, "visibleSubElement")
self.assertTrue(shown.is_displayed())
def testShouldModifyTheVisibilityOfAnElementDynamically(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
element = self.marionette.find_element(By.ID, "hideMe")
self.assertTrue(element.is_displayed())
element.click()
self.assertFalse(element.is_displayed())
def testHiddenInputElementsAreNeverVisible(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
shown = self.marionette.find_element(By.NAME, "hidden")
self.assertFalse(shown.is_displayed())
def testShouldSayElementsWithNegativeTransformAreNotDisplayed(self):
test_html = self.marionette.absolute_url("cssTransform.html")
self.marionette.navigate(test_html)
elementX = self.marionette.find_element(By.ID, 'parentX')
self.assertFalse(elementX.is_displayed())
elementY = self.marionette.find_element(By.ID, 'parentY')
self.assertFalse(elementY.is_displayed())
def testShouldSayElementsWithParentWithNegativeTransformAreNotDisplayed(self):
test_html = self.marionette.absolute_url("cssTransform.html")
self.marionette.navigate(test_html)
elementX = self.marionette.find_element(By.ID, 'childX')
self.assertFalse(elementX.is_displayed())
elementY = self.marionette.find_element(By.ID, 'childY')
self.assertFalse(elementY.is_displayed())
def testShouldSayElementWithZeroTransformIsVisible(self):
test_html = self.marionette.absolute_url("cssTransform.html")
self.marionette.navigate(test_html)
zero_tranform = self.marionette.find_element(By.ID, 'zero-tranform')
self.assertTrue(zero_tranform.is_displayed())
def testShouldSayElementIsVisibleWhenItHasNegativeTransformButElementisntInANegativeSpace(self):
test_html = self.marionette.absolute_url("cssTransform2.html")
self.marionette.navigate(test_html)
negative_percent__tranform = self.marionette.find_element(By.ID, 'negative-percentage-transformY')
self.assertTrue(negative_percent__tranform.is_displayed())
def testShouldSayElementIsInvisibleWhenOverflowXIsHiddenAndOutOfViewport(self):
test_html = self.marionette.absolute_url("bug814037.html")
self.marionette.navigate(test_html)
overflow_x = self.marionette.find_element(By.ID, "assertMe2")
self.assertFalse(overflow_x.is_displayed())
def testShouldShowElementNotVisibleWithHiddenAttribute(self):
test_html = self.marionette.absolute_url("hidden.html")
self.marionette.navigate(test_html)
singleHidden = self.marionette.find_element(By.ID, 'singleHidden')
self.assertFalse(singleHidden.is_displayed())
def testShouldShowElementNotVisibleWhenParentElementHasHiddenAttribute(self):
test_html = self.marionette.absolute_url("hidden.html")
self.marionette.navigate(test_html)
child = self.marionette.find_element(By.ID, 'child')
self.assertFalse(child.is_displayed())
def testShouldClickOnELementPartiallyOffLeft(self):
test_html = self.marionette.absolute_url("element_left.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.CSS_SELECTOR, '.element').click()
def testShouldClickOnELementPartiallyOffRight(self):
test_html = self.marionette.absolute_url("element_right.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.CSS_SELECTOR, '.element').click()
def testShouldClickOnELementPartiallyOffTop(self):
test_html = self.marionette.absolute_url("element_top.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.CSS_SELECTOR, '.element').click()
def testShouldClickOnELementPartiallyOffBottom(self):
test_html = self.marionette.absolute_url("element_bottom.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.CSS_SELECTOR, '.element').click()

View file

@ -0,0 +1,347 @@
# 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 sys
import time
from marionette_driver import errors, wait
from marionette_driver.wait import Wait
from marionette_harness import MarionetteTestCase
class TickingClock(object):
def __init__(self, incr=1):
self.ticks = 0
self.increment = incr
def sleep(self, dur=None):
dur = dur if dur is not None else self.increment
self.ticks += dur
@property
def now(self):
return self.ticks
class SequenceClock(object):
def __init__(self, times):
self.times = times
self.i = 0
@property
def now(self):
if len(self.times) > self.i:
self.i += 1
return self.times[self.i - 1]
def sleep(self, dur):
pass
class MockMarionette(object):
def __init__(self):
self.waited = 0
def exception(self, e=None, wait=1):
self.wait()
if self.waited == wait:
if e is None:
e = Exception
raise e
def true(self, wait=1):
self.wait()
if self.waited == wait:
return True
return None
def false(self, wait=1):
self.wait()
return False
def none(self, wait=1):
self.wait()
return None
def value(self, value, wait=1):
self.wait()
if self.waited == wait:
return value
return None
def wait(self):
self.waited += 1
def at_third_attempt(clock, end):
return clock.now == 2
def now(clock, end):
return True
class SystemClockTest(MarionetteTestCase):
def setUp(self):
super(SystemClockTest, self).setUp()
self.clock = wait.SystemClock()
def test_construction_initializes_time(self):
self.assertEqual(self.clock._time, time)
def test_sleep(self):
start = time.time()
self.clock.sleep(0.1)
end = time.time() - start
self.assertGreater(end, 0)
def test_time_now(self):
self.assertIsNotNone(self.clock.now)
class FormalWaitTest(MarionetteTestCase):
def setUp(self):
super(FormalWaitTest, self).setUp()
self.m = MockMarionette()
self.m.timeout = 123
def test_construction_with_custom_timeout(self):
wt = Wait(self.m, timeout=42)
self.assertEqual(wt.timeout, 42)
def test_construction_with_custom_interval(self):
wt = Wait(self.m, interval=42)
self.assertEqual(wt.interval, 42)
def test_construction_with_custom_clock(self):
c = TickingClock(1)
wt = Wait(self.m, clock=c)
self.assertEqual(wt.clock, c)
def test_construction_with_custom_exception(self):
wt = Wait(self.m, ignored_exceptions=Exception)
self.assertIn(Exception, wt.exceptions)
self.assertEqual(len(wt.exceptions), 1)
def test_construction_with_custom_exception_list(self):
exc = [Exception, ValueError]
wt = Wait(self.m, ignored_exceptions=exc)
for e in exc:
self.assertIn(e, wt.exceptions)
self.assertEqual(len(wt.exceptions), len(exc))
def test_construction_with_custom_exception_tuple(self):
exc = (Exception, ValueError)
wt = Wait(self.m, ignored_exceptions=exc)
for e in exc:
self.assertIn(e, wt.exceptions)
self.assertEqual(len(wt.exceptions), len(exc))
def test_duplicate_exceptions(self):
wt = Wait(self.m, ignored_exceptions=[Exception, Exception])
self.assertIn(Exception, wt.exceptions)
self.assertEqual(len(wt.exceptions), 1)
def test_default_timeout(self):
self.assertEqual(wait.DEFAULT_TIMEOUT, 5)
def test_default_interval(self):
self.assertEqual(wait.DEFAULT_INTERVAL, 0.1)
def test_end_property(self):
wt = Wait(self.m)
self.assertIsNotNone(wt.end)
def test_marionette_property(self):
wt = Wait(self.m)
self.assertEqual(wt.marionette, self.m)
def test_clock_property(self):
wt = Wait(self.m)
self.assertIsInstance(wt.clock, wait.SystemClock)
def test_timeout_uses_default_if_marionette_timeout_is_none(self):
self.m.timeout = None
wt = Wait(self.m)
self.assertEqual(wt.timeout, wait.DEFAULT_TIMEOUT)
class PredicatesTest(MarionetteTestCase):
def test_until(self):
c = wait.SystemClock()
self.assertFalse(wait.until_pred(c, sys.maxint))
self.assertTrue(wait.until_pred(c, 0))
class WaitUntilTest(MarionetteTestCase):
def setUp(self):
super(WaitUntilTest, self).setUp()
self.m = MockMarionette()
self.clock = TickingClock()
self.wt = Wait(self.m, timeout=10, interval=1, clock=self.clock)
def test_true(self):
r = self.wt.until(lambda x: x.true())
self.assertTrue(r)
self.assertEqual(self.clock.ticks, 0)
def test_true_within_timeout(self):
r = self.wt.until(lambda x: x.true(wait=5))
self.assertTrue(r)
self.assertEqual(self.clock.ticks, 4)
def test_timeout(self):
with self.assertRaises(errors.TimeoutException):
r = self.wt.until(lambda x: x.true(wait=15))
self.assertEqual(self.clock.ticks, 10)
def test_exception_raises_immediately(self):
with self.assertRaises(TypeError):
self.wt.until(lambda x: x.exception(e=TypeError))
self.assertEqual(self.clock.ticks, 0)
def test_ignored_exception(self):
self.wt.exceptions = (TypeError,)
with self.assertRaises(errors.TimeoutException):
self.wt.until(lambda x: x.exception(e=TypeError))
def test_ignored_exception_wrapped_in_timeoutexception(self):
self.wt.exceptions = (TypeError,)
exc = None
try:
self.wt.until(lambda x: x.exception(e=TypeError))
except Exception as e:
exc = e
s = str(exc)
self.assertIsNotNone(exc)
self.assertIsInstance(exc, errors.TimeoutException)
self.assertIn(", caused by {0!r}".format(TypeError), s)
self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s)
def test_ignored_exception_after_timeout_is_not_raised(self):
with self.assertRaises(errors.TimeoutException):
r = self.wt.until(lambda x: x.exception(wait=15))
self.assertEqual(self.clock.ticks, 10)
def test_keyboard_interrupt(self):
with self.assertRaises(KeyboardInterrupt):
self.wt.until(lambda x: x.exception(e=KeyboardInterrupt))
def test_system_exit(self):
with self.assertRaises(SystemExit):
self.wt.until(lambda x: x.exception(SystemExit))
def test_true_condition_returns_immediately(self):
r = self.wt.until(lambda x: x.true())
self.assertIsInstance(r, bool)
self.assertTrue(r)
self.assertEqual(self.clock.ticks, 0)
def test_value(self):
r = self.wt.until(lambda x: "foo")
self.assertEqual(r, "foo")
self.assertEqual(self.clock.ticks, 0)
def test_custom_predicate(self):
r = self.wt.until(lambda x: x.true(wait=2), is_true=at_third_attempt)
self.assertTrue(r)
self.assertEqual(self.clock.ticks, 1)
def test_custom_predicate_times_out(self):
with self.assertRaises(errors.TimeoutException):
self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
self.assertEqual(self.clock.ticks, 2)
def test_timeout_elapsed_duration(self):
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 2.0 seconds"):
self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
def test_timeout_elapsed_rounding(self):
wt = Wait(self.m, clock=SequenceClock([1, 0.01, 1]), timeout=0)
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 1.0 seconds"):
wt.until(lambda x: x.true(), is_true=now)
def test_timeout_elapsed_interval_by_delayed_condition_return(self):
def callback(mn):
self.clock.sleep(11)
return mn.false()
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 11.0 seconds"):
self.wt.until(callback)
# With a delayed conditional return > timeout, only 1 iteration is
# possible
self.assertEqual(self.m.waited, 1)
def test_timeout_with_delayed_condition_return(self):
def callback(mn):
self.clock.sleep(.5)
return mn.false()
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 10.0 seconds"):
self.wt.until(callback)
# With a delayed conditional return < interval, 10 iterations should be
# possible
self.assertEqual(self.m.waited, 10)
def test_timeout_interval_shorter_than_delayed_condition_return(self):
def callback(mn):
self.clock.sleep(2)
return mn.false()
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 10.0 seconds"):
self.wt.until(callback)
# With a delayed return of the conditional which takes twice that long than the interval,
# half of the iterations should be possible
self.assertEqual(self.m.waited, 5)
def test_message(self):
self.wt.exceptions = (TypeError,)
exc = None
try:
self.wt.until(lambda x: x.exception(e=TypeError), message="hooba")
except errors.TimeoutException as e:
exc = e
result = str(exc)
self.assertIn("seconds with message: hooba, caused by", result)
def test_no_message(self):
self.wt.exceptions = (TypeError,)
exc = None
try:
self.wt.until(lambda x: x.exception(e=TypeError), message="")
except errors.TimeoutException as e:
exc = e
result = str(exc)
self.assertIn("seconds, caused by", result)
def test_message_has_none_as_its_value(self):
self.wt.exceptions = (TypeError,)
exc = None
try:
self.wt.until(False, None, None)
except errors.TimeoutException as e:
exc = e
result = str(exc)
self.assertNotIn("with message:", result)
self.assertNotIn("secondsNone", result)

View file

@ -0,0 +1,80 @@
# 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_harness import MarionetteTestCase, WindowManagerMixin
class TestCloseWindow(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestCloseWindow, self).setUp()
self.marionette.set_context("chrome")
def tearDown(self):
self.close_all_windows()
self.close_all_tabs()
super(TestCloseWindow, self).tearDown()
def test_close_chrome_window_for_browser_window(self):
win = self.open_window()
self.marionette.switch_to_window(win)
self.assertNotIn(win, self.marionette.window_handles)
chrome_window_handles = self.marionette.close_chrome_window()
self.assertNotIn(win, chrome_window_handles)
self.assertListEqual(self.start_windows, chrome_window_handles)
self.assertNotIn(win, self.marionette.window_handles)
def test_close_chrome_window_for_non_browser_window(self):
def open_window_with_js():
self.marionette.execute_script("""
window.open('chrome://marionette/content/test.xul',
'foo', 'chrome,centerscreen');
""")
win = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(win)
self.assertIn(win, self.marionette.window_handles)
chrome_window_handles = self.marionette.close_chrome_window()
self.assertNotIn(win, chrome_window_handles)
self.assertListEqual(self.start_windows, chrome_window_handles)
self.assertNotIn(win, self.marionette.window_handles)
def test_close_chrome_window_for_last_open_window(self):
self.close_all_windows()
self.assertListEqual([], self.marionette.close_chrome_window())
self.assertListEqual([self.start_tab], self.marionette.window_handles)
self.assertListEqual([self.start_window], self.marionette.chrome_window_handles)
self.assertIsNotNone(self.marionette.session)
def test_close_window_for_browser_tab(self):
tab = self.open_tab()
self.marionette.switch_to_window(tab)
window_handles = self.marionette.close()
self.assertNotIn(tab, window_handles)
self.assertListEqual(self.start_tabs, window_handles)
def test_close_window_for_browser_window_with_single_tab(self):
win = self.open_window()
self.marionette.switch_to_window(win)
self.assertEqual(len(self.start_tabs) + 1, len(self.marionette.window_handles))
window_handles = self.marionette.close()
self.assertNotIn(win, window_handles)
self.assertListEqual(self.start_tabs, window_handles)
self.assertListEqual(self.start_windows, self.marionette.chrome_window_handles)
def test_close_window_for_last_open_tab(self):
self.close_all_tabs()
self.assertListEqual([], self.marionette.close())
self.assertListEqual([self.start_tab], self.marionette.window_handles)
self.assertListEqual([self.start_window], self.marionette.chrome_window_handles)
self.assertIsNotNone(self.marionette.session)

View file

@ -0,0 +1,81 @@
# 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_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin
class TestCloseWindow(WindowManagerMixin, MarionetteTestCase):
def tearDown(self):
self.close_all_windows()
self.close_all_tabs()
super(TestCloseWindow, self).tearDown()
@skip_if_mobile("Interacting with chrome windows not available for Fennec")
def test_close_chrome_window_for_browser_window(self):
win = self.open_window()
self.marionette.switch_to_window(win)
self.assertNotIn(win, self.marionette.window_handles)
chrome_window_handles = self.marionette.close_chrome_window()
self.assertNotIn(win, chrome_window_handles)
self.assertListEqual(self.start_windows, chrome_window_handles)
self.assertNotIn(win, self.marionette.window_handles)
@skip_if_mobile("Interacting with chrome windows not available for Fennec")
def test_close_chrome_window_for_non_browser_window(self):
def open_window_with_js():
with self.marionette.using_context("chrome"):
self.marionette.execute_script("""
window.open('chrome://marionette/content/test.xul',
'foo', 'chrome,centerscreen');
""")
win = self.open_window(trigger=open_window_with_js)
self.marionette.switch_to_window(win)
self.assertIn(win, self.marionette.window_handles)
chrome_window_handles = self.marionette.close_chrome_window()
self.assertNotIn(win, chrome_window_handles)
self.assertListEqual(self.start_windows, chrome_window_handles)
self.assertNotIn(win, self.marionette.window_handles)
@skip_if_mobile("Interacting with chrome windows not available for Fennec")
def test_close_chrome_window_for_last_open_window(self):
self.close_all_windows()
self.assertListEqual([], self.marionette.close_chrome_window())
self.assertListEqual([self.start_tab], self.marionette.window_handles)
self.assertListEqual([self.start_window], self.marionette.chrome_window_handles)
self.assertIsNotNone(self.marionette.session)
@skip_if_mobile("Needs application independent method to open a new tab")
def test_close_window_for_browser_tab(self):
tab = self.open_tab()
self.marionette.switch_to_window(tab)
window_handles = self.marionette.close()
self.assertNotIn(tab, window_handles)
self.assertListEqual(self.start_tabs, window_handles)
@skip_if_mobile("Interacting with chrome windows not available for Fennec")
def test_close_window_for_browser_window_with_single_tab(self):
win = self.open_window()
self.marionette.switch_to_window(win)
self.assertEqual(len(self.start_tabs) + 1, len(self.marionette.window_handles))
window_handles = self.marionette.close()
self.assertNotIn(win, window_handles)
self.assertListEqual(self.start_tabs, window_handles)
self.assertListEqual(self.start_windows, self.marionette.chrome_window_handles)
def test_close_window_for_last_open_tab(self):
self.close_all_tabs()
self.assertListEqual([], self.marionette.close())
self.assertListEqual([self.start_tab], self.marionette.window_handles)
self.assertListEqual([self.start_window], self.marionette.chrome_window_handles)
self.assertIsNotNone(self.marionette.session)

View file

@ -0,0 +1,207 @@
# 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_harness import MarionetteTestCase, WindowManagerMixin
class TestWindowHandles(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestWindowHandles, self).setUp()
self.empty_page = self.marionette.absolute_url("empty.html")
self.test_page = self.marionette.absolute_url("windowHandles.html")
self.marionette.navigate(self.test_page)
self.marionette.set_context("chrome")
def tearDown(self):
self.close_all_windows()
self.close_all_tabs()
super(TestWindowHandles, self).tearDown()
def test_chrome_window_handles_with_scopes(self):
# Open a browser and a non-browser (about window) chrome window
self.open_window(
trigger=lambda: self.marionette.execute_script("window.open();"))
self.assertEqual(len(self.marionette.chrome_window_handles), len(self.start_windows) + 1)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
self.open_window(
trigger=lambda: self.marionette.find_element(By.ID, "aboutName").click())
self.assertEqual(len(self.marionette.chrome_window_handles), len(self.start_windows) + 2)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
chrome_window_handles_in_chrome_scope = self.marionette.chrome_window_handles
window_handles_in_chrome_scope = self.marionette.window_handles
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.chrome_window_handles,
chrome_window_handles_in_chrome_scope)
self.assertEqual(self.marionette.window_handles,
window_handles_in_chrome_scope)
def test_chrome_window_handles_after_opening_new_window(self):
def open_with_link():
with self.marionette.using_context("content"):
link = self.marionette.find_element(By.ID, "new-window")
link.click()
# We open a new window but are actually interested in the new tab
new_win = self.open_window(trigger=open_with_link)
self.assertEqual(len(self.marionette.chrome_window_handles), len(self.start_windows) + 1)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
# Check that the new tab has the correct page loaded
self.marionette.switch_to_window(new_win)
self.assertEqual(self.marionette.current_chrome_window_handle, new_win)
with self.marionette.using_context("content"):
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
lambda mn: mn.get_url() == self.empty_page,
message="{} did not load after opening a new tab".format(self.empty_page))
# Ensure navigate works in our current window
other_page = self.marionette.absolute_url("test.html")
with self.marionette.using_context("content"):
self.marionette.navigate(other_page)
self.assertEqual(self.marionette.get_url(), other_page)
# Close the opened window and carry on in our original tab.
self.marionette.close()
self.assertEqual(len(self.marionette.chrome_window_handles), len(self.start_windows))
self.marionette.switch_to_window(self.start_window)
self.assertEqual(self.marionette.current_chrome_window_handle, self.start_window)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
def test_window_handles_after_opening_new_tab(self):
def open_with_link():
with self.marionette.using_context("content"):
link = self.marionette.find_element(By.ID, "new-tab")
link.click()
new_tab = self.open_tab(trigger=open_with_link)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
with self.marionette.using_context("content"):
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
lambda mn: mn.get_url() == self.empty_page,
message="{} did not load after opening a new tab".format(self.empty_page))
# Ensure navigate works in our current tab
other_page = self.marionette.absolute_url("test.html")
with self.marionette.using_context("content"):
self.marionette.navigate(other_page)
self.assertEqual(self.marionette.get_url(), other_page)
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
self.marionette.switch_to_window(new_tab)
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
def test_window_handles_after_opening_new_window(self):
def open_with_link():
with self.marionette.using_context("content"):
link = self.marionette.find_element(By.ID, "new-window")
link.click()
# We open a new window but are actually interested in the new tab
new_tab = self.open_tab(trigger=open_with_link)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
# Check that the new tab has the correct page loaded
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
with self.marionette.using_context("content"):
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
lambda mn: mn.get_url() == self.empty_page,
message="{} did not load after opening a new tab".format(self.empty_page))
# Ensure navigate works in our current window
other_page = self.marionette.absolute_url("test.html")
with self.marionette.using_context("content"):
self.marionette.navigate(other_page)
self.assertEqual(self.marionette.get_url(), other_page)
# Close the opened window and carry on in our original tab.
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
def test_window_handles_after_closing_original_tab(self):
def open_with_link():
with self.marionette.using_context("content"):
link = self.marionette.find_element(By.ID, "new-tab")
link.click()
new_tab = self.open_tab(trigger=open_with_link)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
with self.marionette.using_context("content"):
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
lambda mn: mn.get_url() == self.empty_page,
message="{} did not load after opening a new tab".format(self.empty_page))
def test_window_handles_no_switch(self):
"""Regression test for bug 1294456.
This test is testing the case where Marionette attempts to send a
command to a window handle when the browser has opened and selected
a new tab. Before bug 1294456 landed, the Marionette driver was getting
confused about which window handle the client cared about, and assumed
it was the window handle for the newly opened and selected tab.
This caused Marionette to think that the browser needed to do a remoteness
flip in the e10s case, since the tab opened by menu_newNavigatorTab is
about:newtab (which is currently non-remote). This meant that commands
sent to what should have been the original window handle would be
queued and never sent, since the remoteness flip in the new tab was
never going to happen.
"""
def open_with_menu():
menu_new_tab = self.marionette.find_element(By.ID, 'menu_newNavigatorTab')
menu_new_tab.click()
new_tab = self.open_tab(trigger=open_with_menu)
# We still have the default tab set as our window handle. This
# get_url command should be sent immediately, and not be forever-queued.
with self.marionette.using_context("content"):
self.assertEqual(self.marionette.get_url(), self.test_page)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)

View file

@ -0,0 +1,96 @@
# 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_harness import MarionetteTestCase, WindowManagerMixin
class TestWindowHandles(WindowManagerMixin, MarionetteTestCase):
def setUp(self):
super(TestWindowHandles, self).setUp()
self.empty_page = self.marionette.absolute_url("empty.html")
self.test_page = self.marionette.absolute_url("windowHandles.html")
self.marionette.navigate(self.test_page)
def tearDown(self):
self.close_all_tabs()
super(TestWindowHandles, self).tearDown()
def test_window_handles_after_opening_new_tab(self):
def open_with_link():
link = self.marionette.find_element(By.ID, "new-tab")
link.click()
new_tab = self.open_tab(trigger=open_with_link)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
lambda mn: mn.get_url() == self.empty_page,
message="{} did not load after opening a new tab".format(self.empty_page))
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertEqual(self.marionette.get_url(), self.test_page)
self.marionette.switch_to_window(new_tab)
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
def test_window_handles_after_opening_new_window(self):
def open_with_link():
link = self.marionette.find_element(By.ID, "new-window")
link.click()
# We open a new window but are actually interested in the new tab
new_tab = self.open_tab(trigger=open_with_link)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
# Check that the new tab has the correct page loaded
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
Wait(self.marionette, self.marionette.timeout.page_load).until(
lambda _: self.marionette.get_url() == self.empty_page,
message="The expected page '{}' has not been loaded".format(self.empty_page))
# Ensure navigate works in our current window
other_page = self.marionette.absolute_url("test.html")
self.marionette.navigate(other_page)
self.assertEqual(self.marionette.get_url(), other_page)
# Close the opened window and carry on in our original tab.
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(self.start_tab)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.assertEqual(self.marionette.get_url(), self.test_page)
def test_window_handles_after_closing_original_tab(self):
def open_with_link():
link = self.marionette.find_element(By.ID, "new-tab")
link.click()
new_tab = self.open_tab(trigger=open_with_link)
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs) + 1)
self.assertEqual(self.marionette.current_window_handle, self.start_tab)
self.marionette.close()
self.assertEqual(len(self.marionette.window_handles), len(self.start_tabs))
self.marionette.switch_to_window(new_tab)
self.assertEqual(self.marionette.current_window_handle, new_tab)
Wait(self.marionette, self.marionette.timeout.page_load).until(
lambda _: self.marionette.get_url() == self.empty_page,
message="The expected page '{}' has not been loaded".format(self.empty_page))

View file

@ -0,0 +1,42 @@
#Copyright 2007-2009 WebDriver committers
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from marionette_driver.errors import InvalidArgumentException
from marionette_harness import MarionetteTestCase
class TestWindowPosition(MarionetteTestCase):
def test_get_types(self):
position = self.marionette.get_window_position()
self.assertTrue(isinstance(position["x"], int))
self.assertTrue(isinstance(position["y"], int))
def test_set_types(self):
for x, y in (["a", "b"], [1.2, 3.4], [True, False], [[], []], [{}, {}]):
with self.assertRaises(InvalidArgumentException):
self.marionette.set_window_position(x, y)
def test_out_of_bounds_arguments(self):
with self.assertRaises(InvalidArgumentException):
self.marionette.set_window_position(-1, 0)
with self.assertRaises(InvalidArgumentException):
self.marionette.set_window_position(0, -1)
def test_move(self):
old_position = self.marionette.get_window_position()
new_position = {"x": old_position["x"] + 10, "y": old_position["y"] + 10}
self.marionette.set_window_position(new_position["x"], new_position["y"])
self.assertNotEqual(old_position['x'], new_position["x"])
self.assertNotEqual(old_position['y'], new_position["y"])

View file

@ -0,0 +1,12 @@
# 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_harness import MarionetteTestCase
class TestTitle(MarionetteTestCase):
def test_get_html_title(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
self.assertEqual('Marionette Test', self.marionette.title)

View file

@ -0,0 +1,26 @@
# 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_harness import MarionetteTestCase
class TestTitleChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_get_chrome_title(self):
title = self.marionette.execute_script("return window.document.documentElement.getAttribute('title');")
self.assertEqual(title, self.marionette.title)
self.assertEqual('Title Test', self.marionette.title)

View file

@ -0,0 +1,27 @@
# 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_harness import MarionetteTestCase
class TestWindowTypeChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_get_window_type(self):
window_type = self.marionette.execute_script("return window.document.documentElement.getAttribute('windowtype');")
self.assertEqual(window_type, self.marionette.get_window_type())
self.assertEqual('Test Type', self.marionette.get_window_type())

View file

@ -0,0 +1,66 @@
# 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.decorators import using_context
from marionette_driver.errors import MarionetteException
from marionette_harness import MarionetteTestCase
class TestSetContext(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
# shortcuts to improve readability of these tests
self.chrome = self.marionette.CONTEXT_CHROME
self.content = self.marionette.CONTEXT_CONTENT
test_url = self.marionette.absolute_url("empty.html")
self.marionette.navigate(test_url)
self.marionette.set_context(self.content)
self.assertEquals(self.get_context(), self.content)
def get_context(self):
return self.marionette._send_message("getContext", key="value")
def test_set_different_context_using_with_block(self):
with self.marionette.using_context(self.chrome):
self.assertEquals(self.get_context(), self.chrome)
self.assertEquals(self.get_context(), self.content)
def test_set_same_context_using_with_block(self):
with self.marionette.using_context(self.content):
self.assertEquals(self.get_context(), self.content)
self.assertEquals(self.get_context(), self.content)
def test_nested_with_blocks(self):
with self.marionette.using_context(self.chrome):
self.assertEquals(self.get_context(), self.chrome)
with self.marionette.using_context(self.content):
self.assertEquals(self.get_context(), self.content)
self.assertEquals(self.get_context(), self.chrome)
self.assertEquals(self.get_context(), self.content)
def test_set_scope_while_in_with_block(self):
with self.marionette.using_context(self.chrome):
self.assertEquals(self.get_context(), self.chrome)
self.marionette.set_context(self.content)
self.assertEquals(self.get_context(), self.content)
self.assertEquals(self.get_context(), self.content)
def test_exception_raised_while_in_with_block_is_propagated(self):
with self.assertRaises(MarionetteException):
with self.marionette.using_context(self.chrome):
raise MarionetteException
self.assertEquals(self.get_context(), self.content)
def test_with_using_context_decorator(self):
@using_context('content')
def inner_content(m):
self.assertEquals(self.get_context(), 'content')
@using_context('chrome')
def inner_chrome(m):
self.assertEquals(self.get_context(), 'chrome')
inner_content(self.marionette)
inner_chrome(self.marionette)

View file

@ -0,0 +1,132 @@
[test_marionette.py]
[test_geckoinstance.py]
[test_data_driven.py]
[test_session.py]
[test_capabilities.py]
[test_accessibility.py]
[test_expectedfail.py]
expected = fail
[test_import_script.py]
[test_click.py]
[test_click_chrome.py]
skip-if = appname == 'fennec'
[test_checkbox.py]
[test_checkbox_chrome.py]
skip-if = appname == 'fennec'
[test_elementsize.py]
[test_elementsize_chrome.py]
skip-if = appname == 'fennec'
[test_position.py]
[test_rendered_element.py]
[test_chrome_element_css.py]
skip-if = appname == 'fennec'
[test_element_state.py]
[test_element_state_chrome.py]
skip-if = appname == 'fennec'
[test_text.py]
[test_text_chrome.py]
skip-if = true # "Bug 896046"
[test_clearing.py]
[test_typing.py]
[test_log.py]
[test_about_pages.py]
[test_execute_async_script.py]
[test_execute_script.py]
[test_simpletest_fail.js]
[test_element_retrieval.py]
[test_findelement_chrome.py]
skip-if = appname == 'fennec'
[test_navigation.py]
[test_timeouts.py]
[test_single_finger_desktop.py]
skip-if = appname == 'fennec' || os == "win" # Bug 1025040
[test_simpletest_pass.js]
[test_simpletest_sanity.py]
[test_simpletest_chrome.js]
[test_simpletest_timeout.js]
[test_anonymous_content.py]
skip-if = appname == 'fennec'
[test_switch_frame.py]
skip-if = os == "win" # Bug 1078237
[test_switch_frame_chrome.py]
skip-if = appname == 'fennec'
[test_switch_remote_frame.py]
skip-if = appname == 'fennec'
[test_switch_window_chrome.py]
skip-if = appname == 'fennec'
[test_switch_window_content.py]
[test_pagesource.py]
[test_pagesource_chrome.py]
skip-if = appname == 'fennec'
[test_visibility.py]
[test_window_handles_chrome.py]
skip-if = appname == 'fennec'
[test_window_handles_content.py]
[test_window_close_chrome.py]
skip-if = appname == 'fennec'
[test_window_close_content.py]
[test_window_position.py]
skip-if = appname == 'fennec'
[test_screenshot.py]
[test_cookies.py]
[test_window_title.py]
[test_window_title_chrome.py]
skip-if = appname == 'fennec'
[test_window_type.py]
skip-if = appname == 'fennec'
[test_implicit_waits.py]
[test_wait.py]
[test_expected.py]
[test_date_time_value.py]
[test_getactiveframe_oop.py]
skip-if = true # Bug 925688
[test_chrome_async_finish.js]
[test_screen_orientation.py]
[test_errors.py]
[test_execute_isolate.py]
[test_click_scrolling.py]
[test_profile_management.py]
skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921 and bug 1322993
[test_quit_restart.py]
skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921 and bug 1322993
[test_set_window_size.py]
skip-if = os == "linux" || appname == 'fennec' # Bug 1085717
[test_with_using_context.py]
[test_modal_dialogs.py]
skip-if = appname == 'fennec' # Bug 1325738
[test_key_actions.py]
[test_mouse_action.py]
skip-if = appname == 'fennec'
[test_teardown_context_preserved.py]
[test_file_upload.py]
skip-if = appname == 'fennec' || os == "win" # http://bugs.python.org/issue14574
[test_execute_sandboxes.py]
[test_using_permissions.py]
[test_prefs.py]
[test_shadow_dom.py]
[test_chrome.py]
skip-if = appname == 'fennec'
[test_addons.py]
skip-if = appname == 'fennec' # Bug 1330598
[test_select.py]
[test_crash.py]
skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921 and bug 1322993
[test_localization.py]