mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 948075 - Add expected conditions to Marionette. r=mdas r=dhunt
This commit is contained in:
parent
8e322c8fdc
commit
192cd998cb
265
testing/marionette/client/marionette/expected.py
Normal file
265
testing/marionette/client/marionette/expected.py
Normal file
@ -0,0 +1,265 @@
|
||||
# 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 errors
|
||||
import types
|
||||
|
||||
"""This file provides a set of expected conditions for common use
|
||||
cases when writing Marionette tests.
|
||||
|
||||
The conditions rely on explicit waits that retries conditions a number
|
||||
of times until they are either successfully met, or they time out.
|
||||
|
||||
"""
|
||||
|
||||
class element_present(object):
|
||||
"""Checks that a web element is present in the DOM of the current
|
||||
context. This does not necessarily mean that the element is
|
||||
visible.
|
||||
|
||||
You can select which element to be checked for presence by
|
||||
supplying a locator:
|
||||
|
||||
el = Wait(marionette).until(expected.element_present(By.ID, "foo"))
|
||||
|
||||
Or by using a function/lambda returning an element:
|
||||
|
||||
el = Wait(marionette).until(expected.element_present(lambda m: m.find_element(By.ID, "foo")))
|
||||
|
||||
:param args: locator or function returning web element
|
||||
:returns: the web element once it is located, or False
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
if len(args) == 1 and isinstance(args[0], types.FunctionType):
|
||||
self.locator = args[0]
|
||||
else:
|
||||
self.locator = lambda m: m.find_element(*args)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return _find(marionette, self.locator)
|
||||
|
||||
class element_not_present(element_present):
|
||||
"""Checks that a web element is not present in the DOM of the current
|
||||
context.
|
||||
|
||||
You can select which element to be checked for lack of presence by
|
||||
supplying a locator:
|
||||
|
||||
r = Wait(marionette).until(expected.element_not_present(By.ID, "foo"))
|
||||
|
||||
Or by using a function/lambda returning an element:
|
||||
|
||||
r = Wait(marionette).until(expected.element_present(lambda m: m.find_element(By.ID, "foo")))
|
||||
|
||||
:param args: locator or function returning web element
|
||||
:returns: True if element is not present, or False if it is present
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
super(element_not_present, self).__init__(*args)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return not super(element_not_present, self).__call__(marionette)
|
||||
|
||||
class element_stale(object):
|
||||
"""Check that the given element is no longer attached to DOM of the
|
||||
current context.
|
||||
|
||||
This can be useful for waiting until an element is no longer
|
||||
present.
|
||||
|
||||
Sample usage:
|
||||
|
||||
el = marionette.find_element(By.ID, "foo")
|
||||
# ...
|
||||
Wait(marionette).until(expected.element_stale(el))
|
||||
|
||||
:param element: the element to wait for
|
||||
:returns: False if the element is still attached to the DOM, True
|
||||
otherwise
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
self.el = element
|
||||
|
||||
def __call__(self, marionette):
|
||||
try:
|
||||
# Calling any method forces a staleness check
|
||||
self.el.is_enabled()
|
||||
return False
|
||||
except errors.StaleElementException:
|
||||
return True
|
||||
|
||||
class elements_present(object):
|
||||
"""Checks that web elements are present in the DOM of the current
|
||||
context. This does not necessarily mean that the elements are
|
||||
visible.
|
||||
|
||||
You can select which elements to be checked for presence by
|
||||
supplying a locator:
|
||||
|
||||
els = Wait(marionette).until(expected.elements_present(By.TAG_NAME, "a"))
|
||||
|
||||
Or by using a function/lambda returning a list of elements:
|
||||
|
||||
els = Wait(marionette).until(expected.elements_present(lambda m: m.find_elements(By.TAG_NAME, "a")))
|
||||
|
||||
:param args: locator or function returning a list of web elements
|
||||
:returns: list of web elements once they are located, or False
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
if len(args) == 1 and isinstance(args[0], types.FunctionType):
|
||||
self.locator = args[0]
|
||||
else:
|
||||
self.locator = lambda m: m.find_elements(*args)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return _find(marionette, self.locator)
|
||||
|
||||
class elements_not_present(elements_present):
|
||||
"""Checks that web elements are not present in the DOM of the
|
||||
current context.
|
||||
|
||||
You can select which elements to be checked for not being present
|
||||
by supplying a locator:
|
||||
|
||||
r = Wait(marionette).until(expected.elements_not_present(By.TAG_NAME, "a"))
|
||||
|
||||
Or by using a function/lambda returning a list of elements:
|
||||
|
||||
r = Wait(marionette).until(expected.elements_not_present(lambda m: m.find_elements(By.TAG_NAME, "a")))
|
||||
|
||||
:param args: locator or function returning a list of web elements
|
||||
:returns: True if elements are missing, False if one or more are
|
||||
present
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
super(elements_not_present, self).__init__(*args)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return not super(elements_not_present, self).__call__(marionette)
|
||||
|
||||
class element_displayed(object):
|
||||
"""An expectation for checking that an element is visible.
|
||||
|
||||
Visibility means that the element is not only displayed, but also
|
||||
has a height and width that is greater than 0 pixels.
|
||||
|
||||
Stale elements, meaning elements that have been detached from the
|
||||
DOM of the current context are treated as not being displayed,
|
||||
meaning this expectation is not analogous to the behaviour of
|
||||
calling `is_displayed()` on an `HTMLElement`.
|
||||
|
||||
:param element: the element to perform the visibility check on
|
||||
:returns: True if element is displayed, False if hidden
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
self.el = element
|
||||
|
||||
def __call__(self, marionette):
|
||||
try:
|
||||
return self.el.is_displayed()
|
||||
except errors.StaleElementException:
|
||||
return False
|
||||
|
||||
class element_not_displayed(element_displayed):
|
||||
"""An expectation for checking that an element is not visible.
|
||||
|
||||
Visibility means that the element is not only displayed, but also
|
||||
has a height and width that is greater than 0 pixels.
|
||||
|
||||
Stale elements, meaning elements that have been detached fom the
|
||||
DOM of the current context are treated as not being displayed,
|
||||
meaning this expectation is not analogous to the behaviour of
|
||||
calling `is_displayed()` on an `HTMLElement`.
|
||||
|
||||
:param element: the element to perform the visibility check on
|
||||
:returns: True if element is hidden, False if visible
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
super(element_not_displayed, self).__init__(element)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return not super(element_not_displayed, self).__call__(marionette)
|
||||
|
||||
class element_selected(object):
|
||||
"""An expectation for checking that the given element is selected.
|
||||
|
||||
:param element: the element to be selected
|
||||
:returns: True if element is selected, False otherwise
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
self.el = element
|
||||
|
||||
def __call__(self, marionette):
|
||||
return self.el.is_selected()
|
||||
|
||||
class element_not_selected(element_selected):
|
||||
"""An expectation for checking that the given element is not
|
||||
selected.
|
||||
|
||||
:param element: the element to not be selected
|
||||
:returns True if element is not selected, False if selected
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
super(element_not_selected, self).__init__(element)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return not super(element_not_selected, self).__call__(marionette)
|
||||
|
||||
class element_enabled(object):
|
||||
"""An expectation for checking that the given element is enabled.
|
||||
|
||||
:param element: the element to check if enabled
|
||||
:returns: True if element is enabled, False otherwise
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
self.el = element
|
||||
|
||||
def __call__(self, marionette):
|
||||
return self.el.is_enabled()
|
||||
|
||||
class element_not_enabled(element_enabled):
|
||||
"""An expectation for checking that the given element is disabled.
|
||||
|
||||
:param element: the element to check if disabled
|
||||
:returns: True if element is disabled, False if enabled
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, element):
|
||||
super(element_not_enabled, self).__init__(element)
|
||||
|
||||
def __call__(self, marionette):
|
||||
return not super(element_not_enabled, self).__call__(marionette)
|
||||
|
||||
def _find(marionette, func):
|
||||
el = None
|
||||
|
||||
try:
|
||||
el = func(marionette)
|
||||
except errors.NoSuchElementException:
|
||||
pass
|
||||
|
||||
if el is None:
|
||||
return False
|
||||
return el
|
198
testing/marionette/client/marionette/tests/unit/test_expected.py
Normal file
198
testing/marionette/client/marionette/tests/unit/test_expected.py
Normal 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/.
|
||||
|
||||
import urllib
|
||||
|
||||
import expected
|
||||
import marionette_test
|
||||
|
||||
from by import By
|
||||
|
||||
def inline(doc):
|
||||
return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
|
||||
|
||||
static_element = inline("""<p>foo</p>""")
|
||||
static_elements = static_element + static_element
|
||||
|
||||
remove_element_by_tag_name = \
|
||||
"""var el = document.getElementsByTagName('%s')[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 % "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_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_when_hidden(self):
|
||||
self.marionette.navigate(hidden_element)
|
||||
el = self.marionette.find_element(By.TAG_NAME, "p")
|
||||
hidden = expected.element_displayed(el)(self.marionette)
|
||||
self.assertFalse(hidden)
|
||||
|
||||
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")
|
||||
visible = expected.element_not_displayed(el)(self.marionette)
|
||||
self.assertTrue(visible)
|
||||
|
||||
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_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)
|
@ -93,6 +93,7 @@ b2g = false
|
||||
b2g = false
|
||||
[test_implicit_waits.py]
|
||||
[test_wait.py]
|
||||
[test_expected.py]
|
||||
[test_date_time_value.py]
|
||||
[test_getactiveframe_oop.py]
|
||||
disabled = "Bug 925688"
|
||||
@ -100,4 +101,4 @@ disabled = "Bug 925688"
|
||||
[test_chrome_async_finish.js]
|
||||
[test_screen_orientation.py]
|
||||
browser = false
|
||||
[test_errors.py]
|
||||
[test_errors.py]
|
||||
|
Loading…
Reference in New Issue
Block a user