Bug 1081139 - Document Marionette's wait and expected modules. r=ahal
--- a/testing/marionette/client/docs/conf.py
+++ b/testing/marionette/client/docs/conf.py
@@ -119,17 +119,17 @@ html_theme = 'default'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+#html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
--- a/testing/marionette/client/docs/index.rst
+++ b/testing/marionette/client/docs/index.rst
@@ -95,111 +95,148 @@ Please visit, our `Marionette Tests`_ se
.. automodule:: marionette
Marionette Objects
------------------
.. autoclass:: Marionette
Session Management
-``````````````````
+^^^^^^^^^^^^^^^^^^
.. automethod:: Marionette.start_session
.. automethod:: Marionette.delete_session
.. autoattribute:: Marionette.session_capabilities
.. automethod:: Marionette.get_cookie
.. automethod:: Marionette.get_cookies
.. automethod:: Marionette.add_cookie
.. automethod:: Marionette.delete_all_cookies
Context Management
-``````````````````
+^^^^^^^^^^^^^^^^^^
.. autoattribute:: Marionette.current_window_handle
.. autoattribute:: Marionette.window_handles
.. automethod:: Marionette.set_context
.. automethod:: Marionette.switch_to_frame
.. automethod:: Marionette.switch_to_window
.. automethod:: Marionette.get_active_frame
.. automethod:: Marionette.close
Navigation Methods
-``````````````````
+^^^^^^^^^^^^^^^^^^
.. autoattribute:: Marionette.title
.. automethod:: Marionette.navigate
.. automethod:: Marionette.get_url
.. automethod:: Marionette.go_back
.. automethod:: Marionette.go_forward
.. automethod:: Marionette.refresh
.. automethod:: Marionette.absolute_url
.. automethod:: Marionette.get_window_type
DOM Element Methods
-```````````````````
+^^^^^^^^^^^^^^^^^^^
.. automethod:: Marionette.set_search_timeout
.. automethod:: Marionette.find_element
.. automethod:: Marionette.find_elements
Script Execution
-````````````````
+^^^^^^^^^^^^^^^^
.. automethod:: Marionette.execute_script
.. automethod:: Marionette.execute_async_script
.. automethod:: Marionette.set_script_timeout
Debugging
-`````````
+^^^^^^^^^
.. autoattribute:: Marionette.page_source
.. automethod:: Marionette.log
.. automethod:: Marionette.get_logs
.. automethod:: Marionette.screenshot
Querying and Modifying Document Content
---------------------------------------
.. autoclass:: HTMLElement
-
.. autoattribute:: HTMLElement.text
.. autoattribute:: HTMLElement.location
.. autoattribute:: HTMLElement.size
.. autoattribute:: HTMLElement.tag_name
.. automethod:: HTMLElement.send_keys
.. automethod:: HTMLElement.clear
.. automethod:: HTMLElement.click
.. automethod:: HTMLElement.is_selected
.. automethod:: HTMLElement.is_enabled
.. automethod:: HTMLElement.is_displayed
.. automethod:: HTMLElement.value_of_css_property
.. autoclass:: DateTimeValue
-
.. autoattribute:: DateTimeValue.date
.. autoattribute:: DateTimeValue.time
Action Objects
--------------
Action Sequences
-````````````````
+^^^^^^^^^^^^^^^^
.. autoclass:: Actions
-
.. automethod:: Actions.press
.. automethod:: Actions.release
.. automethod:: Actions.move
.. automethod:: Actions.move_by_offset
.. automethod:: Actions.wait
.. automethod:: Actions.cancel
.. automethod:: Actions.long_press
.. automethod:: Actions.flick
.. automethod:: Actions.tap
.. automethod:: Actions.double_tap
.. automethod:: Actions.perform
Multi-action Sequences
-``````````````````````
+^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: MultiActions
-
.. automethod:: MultiActions.add
.. automethod:: MultiActions.perform
+Explicit Waiting and Expected Conditions
+----------------------------------------
+
+Waits are used to pause program execution
+until a given condition is true.
+This is a useful technique to employ
+when documents load new content or change
+after ``Document.readyState``'s value changes to "complete".
+
+Because Marionette returns control to the user
+when the document is completely loaded,
+any subsequent interaction with elements
+are subject to manual synchronisation.
+The reason for this is that Marionette
+does not keep a direct representation of the DOM,
+but instead exposes a way for the user to
+query the browser's DOM state.
+
+The `Wait` helper class provided by Marionette
+avoids some of the caveats of ``time.sleep(n)``,
+which sets the condition to an exact time period to wait.
+It will return immediately
+once the provided condition evaluates to true.
+
+In addition to writing your own custom conditions
+you can combine `Wait`
+with a number of ready-made expected conditions
+that are listed below.
+
+Waits
+^^^^^
+.. autoclass:: marionette.wait.Wait
+ :members:
+ :special-members:
+.. autoattribute marionette.wait.DEFAULT_TIMEOUT
+.. autoattribute marionette.wait.DEFAULT_INTERVAL
+
+Expected Conditions
+^^^^^^^^^^^^^^^^^^^
+.. automodule:: marionette.expected
+ :members:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
--- a/testing/marionette/client/marionette/expected.py
+++ b/testing/marionette/client/marionette/expected.py
@@ -14,21 +14,21 @@ of times until they are either successfu
"""
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:
+ supplying a locator::
el = Wait(marionette).until(expected.element_present(By.ID, "foo"))
- Or by using a function/lambda returning an element:
+ 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
"""
@@ -41,21 +41,21 @@ class element_present(object):
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:
+ supplying a locator::
r = Wait(marionette).until(expected.element_not_present(By.ID, "foo"))
- Or by using a function/lambda returning an element:
+ 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
"""
@@ -67,17 +67,17 @@ class element_not_present(element_presen
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:
+ 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
@@ -96,21 +96,21 @@ class element_stale(object):
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:
+ 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:
+ 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
"""
@@ -123,21 +123,21 @@ class elements_present(object):
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:
+ 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:
+ 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
"""
@@ -209,17 +209,17 @@ class element_selected(object):
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
+ :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)
--- a/testing/marionette/client/marionette/wait.py
+++ b/testing/marionette/client/marionette/wait.py
@@ -30,17 +30,17 @@ class Wait(object):
def __init__(self, marionette, timeout=None,
interval=DEFAULT_INTERVAL, ignored_exceptions=None,
clock=None):
"""Configure the Wait instance to have a custom timeout, interval, and
list of ignored exceptions. Optionally a different time
implementation than the one provided by the standard library
(time) can also be provided.
- Sample usage:
+ Sample usage::
# Wait 30 seconds for window to open, checking for its presence once
# every 5 seconds.
wait = Wait(marionette, timeout=30, interval=5,
ignored_exceptions=errors.NoSuchWindowException)
window = wait.until(lambda m: m.switch_to_window(42))
:param marionette: The input value to be provided to