+2017-11-28 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Update W3C WebDriver imported tests.
+
+ * imported/w3c/importer.json:
+ * imported/w3c/tools/webdriver/webdriver/client.py:
+ * imported/w3c/tools/webdriver/webdriver/error.py:
+ * imported/w3c/tools/wptrunner/docs/conf.py:
+ * imported/w3c/tools/wptrunner/wptrunner/browsers/ie.py:
+ * imported/w3c/tools/wptrunner/wptrunner/executors/base.py:
+ * imported/w3c/tools/wptrunner/wptrunner/executors/pytestrunner/runner.py:
+ * imported/w3c/tools/wptrunner/wptrunner/stability.py:
+ * imported/w3c/tools/wptrunner/wptrunner/testdriver-vendor.js: Added.
+ * imported/w3c/tools/wptrunner/wptrunner/update/sync.py:
+ * imported/w3c/tools/wptrunner/wptrunner/wptcommandline.py:
+ * imported/w3c/webdriver/interface/interface.html:
+ * imported/w3c/webdriver/tests/document_handling/page_source.py: Added.
+ * imported/w3c/webdriver/tests/element_click/bubbling.py: Added.
+ * imported/w3c/webdriver/tests/element_retrieval/get_active_element.py:
+ * imported/w3c/webdriver/tests/execute_async_script/user_prompts.py: Added.
+ * imported/w3c/webdriver/tests/execute_script/user_prompts.py: Added.
+ * imported/w3c/webdriver/tests/sessions/status.py: Added.
+ * imported/w3c/webdriver/tests/status.py: Removed.
+ * imported/w3c/webdriver/tests/support/fixtures.py:
+ * imported/w3c/webdriver/tests/support/wait.py:
+ * imported/w3c/webdriver/tests/user_prompts/accept_alert.py:
+ * imported/w3c/webdriver/tests/user_prompts/dismiss_alert.py:
+ * imported/w3c/webdriver/tests/user_prompts/get_alert_text.py:
+ * imported/w3c/webdriver/tests/user_prompts/send_alert_text.py:
+
2017-11-28 Carlos Garcia Campos <cgarcia@igalia.com>
WebDriver: add timeout option to run-webdriver-tests script
{
"repository": "https://github.com/w3c/web-platform-tests.git",
- "revision": "448984b0e1c5bad4af20abeaf84eb8b5e8e81478",
+ "revision": "2b50389ee72d89dd0be12bc6ca54a6e95c98d163",
"paths_to_import": [
"tools/pytest",
"tools/webdriver",
def title(self):
return self.send_session_command("GET", "title")
+ @property
+ @command
+ def source(self):
+ return self.send_session_command("GET", "source")
+
@property
@command
def window_handle(self):
self.stacktrace = stacktrace
def __repr__(self):
- return "<%s http_status=%d>" % (self.__class__.__name__, self.http_status)
+ return "<%s http_status=%s>" % (self.__class__.__name__, self.http_status)
def __str__(self):
- return ("%s (%d)\n"
+ return ("%s (%s)\n"
"\n"
"Remote-end stacktrace:\n"
"\n"
"%s" % (self.status_code, self.http_status, self.stacktrace))
+class ElementClickInterceptedException(WebDriverException):
+ http_status = 400
+ status_code = "element click intercepted"
+
+
class ElementNotSelectableException(WebDriverException):
http_status = 400
status_code = "element not selectable"
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('http://docs.python.org/', None),
- 'mozlog': ('http://mozbase.readthedocs.org/en/latest/', None)}
+ 'mozlog': ('https://firefox-source-docs.mozilla.org/', None)}
ieOptions = {}
ieOptions["requireWindowFocus"] = True
capabilities = {}
- capabilities["browserName"] = "internet explorer"
- capabilities["platformName"] = "windows"
capabilities["se:ieOptions"] = ieOptions
executor_kwargs = base_executor_kwargs(test_type, server_config,
cache_manager, **kwargs)
return (test.result_cls(*data), [])
def do_wdspec(self, session_config, path, timeout):
- harness_result = ("OK", None)
- subtest_results = pytestrunner.run(path,
- self.server_config,
- session_config,
- timeout=timeout)
- return (harness_result, subtest_results)
+ return pytestrunner.run(path,
+ self.server_config,
+ session_config,
+ timeout=timeout)
def do_delayed_imports(self):
global pytestrunner
-"""Provides interface to deal with pytest.
+"""
+Provides interface to deal with pytest.
Usage::
def run(path, server_config, session_config, timeout=0):
- """Run Python test at ``path`` in pytest. The provided ``session``
+ """
+ Run Python test at ``path`` in pytest. The provided ``session``
is exposed as a fixture available in the scope of the test functions.
:param path: Path to the test file.
:param timeout: Duration before interrupting potentially hanging
tests. If 0, there is no timeout.
- :returns: List of subtest results, which are tuples of (test id,
- status, message, stacktrace).
+ :returns: (<harness result>, [<subtest result>, ...]),
+ where <subtest result> is (test id, status, message, stacktrace).
"""
-
if pytest is None:
do_delayed_imports()
- recorder = SubtestResultRecorder()
-
os.environ["WD_HOST"] = session_config["host"]
os.environ["WD_PORT"] = str(session_config["port"])
os.environ["WD_CAPABILITIES"] = json.dumps(session_config["capabilities"])
os.environ["WD_SERVER_CONFIG"] = json.dumps(server_config)
- plugins = [recorder]
-
- # TODO(ato): Deal with timeouts
+ harness = HarnessResultRecorder()
+ subtests = SubtestResultRecorder()
with TemporaryDirectory() as cache:
- pytest.main(["--strict", # turn warnings into errors
- "--verbose", # show each individual subtest
- "--capture", "no", # enable stdout/stderr from tests
- "--basetemp", cache, # temporary directory
- "--showlocals", # display contents of variables in local scope
- "-p", "no:mozlog", # use the WPT result recorder
- "-p", "no:cacheprovider", # disable state preservation across invocations
- path],
- plugins=plugins)
-
- return recorder.results
+ try:
+ pytest.main(["--strict", # turn warnings into errors
+ "--verbose", # show each individual subtest
+ "--capture", "no", # enable stdout/stderr from tests
+ "--basetemp", cache, # temporary directory
+ "--showlocals", # display contents of variables in local scope
+ "-p", "no:mozlog", # use the WPT result recorder
+ "-p", "no:cacheprovider", # disable state preservation across invocations
+ path],
+ plugins=[harness, subtests])
+ except Exception as e:
+ harness.outcome = ("ERROR", str(e))
+
+ return (harness.outcome, subtests.results)
+
+
+class HarnessResultRecorder(object):
+ outcomes = {
+ "failed": "ERROR",
+ "passed": "OK",
+ "skipped": "SKIP",
+ }
+
+ def __init__(self):
+ # we are ok unless told otherwise
+ self.outcome = ("OK", None)
+
+ def pytest_collectreport(self, report):
+ harness_result = self.outcomes[report.outcome]
+ self.outcome = (harness_result, None)
class SubtestResultRecorder(object):
import copy
import functools
import imp
+import io
import os
-import sys
from collections import OrderedDict, defaultdict
from datetime import datetime
from mozlog import reader
-from mozlog.formatters import JSONFormatter, TbplFormatter
-from mozlog.handlers import BaseHandler, LogLevelFilter, StreamHandler
+from mozlog.formatters import JSONFormatter
+from mozlog.handlers import BaseHandler, StreamHandler, LogLevelFilter
here = os.path.dirname(__file__)
localpaths = imp.load_source("localpaths", os.path.abspath(os.path.join(here, os.pardir, os.pardir, "localpaths.py")))
def is_inconsistent(results_dict, iterations):
"""Return whether or not a single test is inconsistent."""
+ if 'SKIP' in results_dict:
+ return False
return len(results_dict) > 1 or sum(results_dict.values()) != iterations
kwargs["pause_after_test"] = False
kwargs.update(kwargs_extras)
- handler = LogActionFilter(
- LogLevelFilter(
- StreamHandler(
- sys.stdout,
- TbplFormatter()
- ),
- "WARNING"),
- ["log", "process_output"])
+ def wrap_handler(x):
+ x = LogLevelFilter(x, "WARNING")
+ if not kwargs["verify_log_full"]:
+ x = LogActionFilter(x, ["log", "process_output"])
+ return x
- # There is a public API for this in the next mozlog
initial_handlers = logger._state.handlers
- logger._state.handlers = []
+ logger._state.handlers = [wrap_handler(handler)
+ for handler in initial_handlers]
- with open("raw.log", "wb") as log:
- # Setup logging for wptrunner that keeps process output and
- # warning+ level logs only
- logger.add_handler(handler)
- logger.add_handler(StreamHandler(log, JSONFormatter()))
+ log = io.BytesIO()
+ # Setup logging for wptrunner that keeps process output and
+ # warning+ level logs only
+ logger.add_handler(StreamHandler(log, JSONFormatter()))
- wptrunner.run_tests(**kwargs)
+ wptrunner.run_tests(**kwargs)
logger._state.handlers = initial_handlers
+ logger._state.running_tests = set()
+ logger._state.suite_started = False
- with open("raw.log", "rb") as log:
- results, inconsistent = process_results(log, iterations)
+ log.seek(0)
+ results, inconsistent = process_results(log, iterations)
return results, inconsistent, iterations
--- /dev/null
+// This file intentionally left blank
shutil.copy2(source_path, dest_path)
for source, destination in [("testharness_runner.html", ""),
- ("testharnessreport.js", "resources/"),
("testdriver-vendor.js", "resources/")]:
source_path = os.path.join(here, os.pardir, source)
dest_path = os.path.join(dest, destination, os.path.split(source)[1])
mode_group.add_argument("--verify", action="store_true",
default=False,
help="Run a stability check on the selected tests")
+ mode_group.add_argument("--verify-log-full", action="store_true",
+ default=False,
+ help="Output per-iteration test results when running verify")
test_selection_group = parser.add_argument_group("Test Selection")
test_selection_group.add_argument("--test-types", action="store",
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
+<script src=/resources/WebIDLParser.js></script>
+<script src=/resources/idlharness.js></script>
+<script type=text/plain class=untested>
+[Exposed=Window]
+interface Navigator {
+ // objects implementing this interface also implement the interfaces given below
+};
+</script>
+<script type=text/plain>
+Navigator implements NavigatorAutomationInformation;
+
+[NoInterfaceObject,
+ Exposed=(Window)]
+interface NavigatorAutomationInformation {
+ readonly attribute boolean webdriver;
+ // always returns true
+};
+</script>
<script>
+"use strict";
-test(function() {
- if ("webdriver" in navigator) {
- var descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(navigator), "webdriver");
- assert_true(descriptor !== undefined);
- assert_true(descriptor.configurable);
- assert_true(descriptor.enumerable);
- assert_true(descriptor.set === undefined);
- assert_true(navigator.webdriver);
- } else {
- assert_true(navigator.webdriver === undefined);
- }
-}, "Test that the navigator.webdriver descriptor has expected properties or doesn't exist at all");
+if ("webdriver" in navigator) {
+ test(() => assert_true(navigator.webdriver), "navigator.webdriver is always true");
+ var idlArray = new IdlArray();
+ [].forEach.call(document.querySelectorAll("script[type=text\\/plain]"), function(node) {
+ if (node.className == "untested") {
+ idlArray.add_untested_idls(node.textContent);
+ } else {
+ idlArray.add_idls(node.textContent);
+ }
+ });
+ idlArray.test();
+} else {
+ done();
+}
</script>
-</body>
-</html>
--- /dev/null
+import pytest
+
+from tests.support.inline import inline
+
+
+# 15.1.3 "Let source be the result returned from the outerHTML IDL attribute
+# of the document element"
+def test_source_matches_outer_html(session):
+ session.url = inline("<html><head><title>Cheese</title><body>Peas")
+ expected_source = session.execute_script(
+ "return document.documentElement.outerHTML")
+
+ assert session.source == expected_source
+
--- /dev/null
+from tests.support.asserts import assert_success
+from tests.support.inline import inline
+
+
+def click(session, element):
+ return session.transport.send(
+ "POST", "/session/{session_id}/element/{element_id}/click".format(
+ session_id=session.session_id,
+ element_id=element.id))
+
+
+def test_click_event_bubbles_to_parents(session):
+ session.url = inline("""
+ <style>
+ body * {
+ margin: 10px;
+ padding: 10px;
+ border: 1px solid blue;
+ }
+ </style>
+
+ <div id=three>THREE
+ <div id=two>TWO
+ <div id=one>ONE</div>
+ </div>
+ </div>
+
+ <script>
+ window.clicks = [];
+
+ for (let level of document.querySelectorAll("div")) {
+ level.addEventListener("click", ({currentTarget}) => {
+ window.clicks.push(currentTarget);
+ });
+ }
+ </script>
+ """)
+ three, two, one = session.find.css("div")
+ one.click()
+
+ clicks = session.execute_script("return window.clicks")
+ assert one in clicks
+ assert two in clicks
+ assert three in clicks
+
+
+def test_spin_event_loop(session):
+ """
+ Wait until the user agent event loop has spun enough times to
+ process the DOM events generated by clicking.
+ """
+ session.url = inline("""
+ <style>
+ body * {
+ margin: 10px;
+ padding: 10px;
+ border: 1px solid blue;
+ }
+ </style>
+
+ <div id=three>THREE
+ <div id=two>TWO
+ <div id=one>ONE</div>
+ </div>
+ </div>
+
+ <script>
+ window.delayedClicks = [];
+
+ for (let level of document.querySelectorAll("div")) {
+ level.addEventListener("click", ({currentTarget}) => {
+ setTimeout(() => window.delayedClicks.push(currentTarget), 100);
+ });
+ }
+ </script>
+ """)
+ three, two, one = session.find.css("div")
+ one.click()
+
+ delayed_clicks = session.execute_script("return window.delayedClicks")
+ assert one in delayed_clicks
+ assert two in delayed_clicks
+ assert three in delayed_clicks
+
+
+def test_element_disappears_during_click(session):
+ """
+ When an element in the event bubbling order disappears (its CSS
+ display style is set to "none") during a click, Gecko and Blink
+ exhibit different behaviour. Whilst Chrome fires a "click"
+ DOM event on <body>, Firefox does not.
+
+ A WebDriver implementation may choose to wait for this event to let
+ the event loops spin enough times to let click events propagate,
+ so this is a corner case test that Firefox does not hang indefinitely.
+ """
+ session.url = inline("""
+ <style>
+ #over,
+ #under {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ width: 100px;
+ height: 100px;
+ }
+
+ #over {
+ background: blue;
+ opacity: .5;
+ }
+ #under {
+ background: yellow;
+ }
+
+ #log {
+ margin-top: 120px;
+ }
+ </style>
+
+ <body id="body">
+ <div id=under></div>
+ <div id=over></div>
+
+ <div id=log></div>
+ </body>
+
+ <script>
+ let under = document.querySelector("#under");
+ let over = document.querySelector("#over");
+ let body = document.querySelector("body");
+ let log = document.querySelector("#log");
+
+ function logEvent({type, target, currentTarget}) {
+ log.innerHTML += "<p></p>";
+ log.lastElementChild.textContent = `${type} in ${target.id} (handled by ${currentTarget.id})`;
+ }
+
+ for (let ev of ["click", "mousedown", "mouseup"]) {
+ under.addEventListener(ev, logEvent);
+ over.addEventListener(ev, logEvent);
+ body.addEventListener(ev, logEvent);
+ }
+
+ over.addEventListener("mousedown", () => over.style.display = "none");
+ </script>
+ """)
+ over = session.find.css("#over", all=False)
+
+ # should not time out
+ response = click(session, over)
+ assert_success(response)
from tests.support.fixtures import create_dialog
from tests.support.inline import inline
+
def read_global(session, name):
return session.execute_script("return %s;" % name)
+
def get_active_element(session):
return session.transport.send("GET", "session/%s/element/active" % session.session_id)
assert_is_active_element(session, response)
-def test_sucess_without_body(session):
+def test_missing_document_element(session):
session.url = inline("<body></body>")
session.execute_script("""
if (document.body.remove) {
}""")
response = get_active_element(session)
- assert_is_active_element(session, response)
+ assert_error(response, "no such element")
--- /dev/null
+import pytest
+
+from webdriver import error
+
+
+# 15.2 Executing Script
+
+def test_handle_prompt_accept(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "accept"})}})
+ session.execute_async_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.accept()
+
+
+def test_handle_prompt_dismiss(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "dismiss"})}})
+ session.execute_async_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.dismiss()
+
+
+def test_handle_prompt_dismiss_and_notify(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "dismiss and notify"})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_async_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.dismiss()
+
+
+def test_handle_prompt_accept_and_notify(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "accept and notify"})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_async_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.accept()
+
+
+def test_handle_prompt_ignore(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "ignore"})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_async_script("window.alert('Hello');")
+ session.alert.dismiss()
+
+
+def test_handle_prompt_default(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_async_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.dismiss()
+
+
+def test_handle_prompt_twice(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "accept"})}})
+ session.execute_async_script("window.alert('Hello');window.alert('Bye');")
+ # The first alert has been accepted by the user prompt handler, the second one remains.
+ # FIXME: this is how browsers currently work, but the spec should clarify if this is the
+ # expected behavior, see https://github.com/w3c/webdriver/issues/1153.
+ assert session.alert.text == "Bye"
+ session.alert.dismiss()
--- /dev/null
+import pytest
+
+from webdriver import error
+
+
+# 15.2 Executing Script
+
+def test_handle_prompt_accept(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "accept"})}})
+ session.execute_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.accept()
+
+
+def test_handle_prompt_dismiss(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "dismiss"})}})
+ session.execute_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.dismiss()
+
+
+def test_handle_prompt_dismiss_and_notify(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "dismiss and notify"})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.dismiss()
+
+
+def test_handle_prompt_accept_and_notify(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "accept and notify"})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.accept()
+
+
+def test_handle_prompt_ignore(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "ignore"})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_script("window.alert('Hello');")
+ session.alert.dismiss()
+
+
+def test_handle_prompt_default(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({})}})
+ with pytest.raises(error.UnexpectedAlertOpenException):
+ session.execute_script("window.alert('Hello');")
+ with pytest.raises(error.NoSuchAlertException):
+ session.alert.dismiss()
+
+
+def test_handle_prompt_twice(new_session, add_browser_capabilites):
+ _, session = new_session({"capabilities": {"alwaysMatch": add_browser_capabilites({"unhandledPromptBehavior": "accept"})}})
+ session.execute_script("window.alert('Hello');window.alert('Bye');")
+ # The first alert has been accepted by the user prompt handler, the second one remains.
+ # FIXME: this is how browsers currently work, but the spec should clarify if this is the
+ # expected behavior, see https://github.com/w3c/webdriver/issues/1153.
+ assert session.alert.text == "Bye"
+ session.alert.dismiss()
--- /dev/null
+import pytest
+import json
+
+
+def test_get_status_no_session(http):
+ with http.get("/status") as response:
+ # GET /status should never return an error
+ assert response.status == 200
+
+ # parse JSON response and unwrap 'value' property
+ parsed_obj = json.loads(response.read().decode('utf-8'))
+ value = parsed_obj["value"]
+
+ # Let body be a new JSON Object with the following properties:
+ # "ready"
+ # The remote end's readiness state.
+ assert value["ready"] in [True, False]
+ # "message"
+ # An implementation-defined string explaining the remote end's
+ # readiness state.
+ assert isinstance(value["message"], basestring)
+
+
+def test_status_with_session_running_on_endpoint_node(new_session):
+ # For an endpoint node, the maximum number of active
+ # sessions is 1: https://www.w3.org/TR/webdriver/#dfn-maximum-active-sessions
+ # A session is open, so we expect `ready` to be False
+ # 8.3 step 1.
+
+ _, session = new_session("{}") # we don't care what we're using
+ value = session.send_command("GET", "status")
+
+ assert value["ready"] == False
+ assert "message" in value
+
+ session.end()
+
+ # Active session count is 0, meaning that the
+ # readiness state of the server should be True
+ # 8.3 step 1. Again
+ value = session.send_command("GET", "status")
+
+ assert value["ready"] == True
+ assert "message" in value
+
+++ /dev/null
-import pytest
-import json
-
-
-def test_get_status_no_session(http):
- with http.get("/status") as response:
- # GET /status should never return an error
- assert response.status == 200
-
- # parse JSON response and unwrap 'value' property
- parsed_obj = json.loads(response.read().decode('utf-8'))
- value = parsed_obj["value"]
-
- # Let body be a new JSON Object with the following properties:
- # "ready"
- # The remote end's readiness state.
- assert value["ready"] in [True, False]
- # "message"
- # An implementation-defined string explaining the remote end's
- # readiness state.
- assert isinstance(value["message"], basestring)
from tests.support.asserts import assert_error
from tests.support.http_request import HTTPRequest
+from tests.support.wait import wait
from tests.support import merge_dictionaries
default_host = "http://127.0.0.1"
session.send_session_command("POST",
"execute/async",
{"script": spawn, "args": []})
+ wait(session,
+ lambda s: s.send_session_command("GET", "alert/text") == text,
+ "modal has not appeared",
+ timeout=15,
+ ignored_exceptions=webdriver.NoSuchAlertException)
return create_dialog
+
def clear_all_cookies(session):
"""Removes all cookies associated with the current active document"""
session.transport.send("DELETE", "session/%s/cookie" % session.session_id)
-
+import sys
import time
+
class TimeoutException(Exception):
pass
-def wait(session, condition, message, interval=0.1, timeout=5):
+def wait(session, condition, message,
+ interval=0.1, timeout=5, ignored_exceptions=Exception):
""" Poll a condition until it's true or the timeout ellapses.
:param session: WebDriver session to use with `condition`
:param message: failure description to display in case the timeout is reached
:param interval: seconds between each call to `condition`. Default: 0.1
:param timeout: seconds until we stop polling. Default: 5
+ :param ignored_exceptions: Exceptions that are expected and can be ignored.
+ Default: Exception
"""
start = time.time()
while not (time.time() >= end):
next_step = time.time() + interval
- success = condition(session)
+ try:
+ success = condition(session)
+ except ignored_exceptions:
+ last_exc = sys.exc_info()[0]
+ success = False
next_interval = max(next_step - time.time(), 0)
if not success:
time.sleep(next_interval)
continue
return success
+
+ print "Last exception encountered was {}".format(last_exc)
raise TimeoutException("Timed out after %d seconds: %s" % (timeout, message))
from tests.support.asserts import assert_error, assert_success
+from tests.support.inline import inline
def accept_alert(session):
def test_accept_alert(session):
# 18.2 step 3
- session.execute_script("window.alert(\"Hello\");")
+ session.url = inline("<script>window.alert('Hello');</script>")
response = accept_alert(session)
assert_success(response)
def test_accept_confirm(session):
# 18.2 step 3
- session.execute_script("window.result = window.confirm(\"Hello\");")
+ session.url = inline("<script>window.result = window.confirm('Hello');</script>")
response = accept_alert(session)
assert_success(response)
assert session.execute_script("return window.result") is True
def test_accept_prompt(session):
# 18.2 step 3
- session.execute_script("window.result = window.prompt(\"Enter Your Name: \", \"Federer\");")
+ session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Federer');</script>")
response = accept_alert(session)
assert_success(response)
assert session.execute_script("return window.result") == "Federer"
from tests.support.asserts import assert_error, assert_success
+from tests.support.inline import inline
def dismiss_alert(session):
def test_dismiss_alert(session):
# 18.1 step 3
- session.execute_script("window.alert(\"Hello\");")
+ session.url = inline("<script>window.alert('Hello');</script>")
response = dismiss_alert(session)
assert_success(response)
def test_dismiss_confirm(session):
# 18.1 step 3
- session.execute_script("window.result = window.confirm(\"Hello\");")
+ session.url = inline("<script>window.result = window.confirm('Hello');</script>")
response = dismiss_alert(session)
assert_success(response)
assert session.execute_script("return window.result;") is False
def test_dismiss_prompt(session):
# 18.1 step 3
- session.execute_script("window.result = window.prompt(\"Enter Your Name: \", \"Federer\");")
+ session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Federer');</script>")
response = dismiss_alert(session)
assert_success(response)
assert session.execute_script("return window.result") is None
from tests.support.asserts import assert_error, assert_success
+from tests.support.inline import inline
def get_dialog_text(session):
def test_get_alert_text(session):
# 18.3 step 3
- session.execute_script("window.alert(\"Hello\");")
+ session.url = inline("<script>window.alert('Hello');</script>")
response = get_dialog_text(session)
assert_success(response)
assert isinstance(response.body, dict)
def test_get_confirm_text(session):
# 18.3 step 3
- session.execute_script("window.confirm(\"Hello\");")
+ session.url = inline("<script>window.confirm('Hello');</script>")
response = get_dialog_text(session)
assert_success(response)
assert isinstance(response.body, dict)
def test_get_prompt_text(session):
# 18.3 step 3
- session.execute_script("window.prompt(\"Enter Your Name: \", \"Federer\");")
+ session.url = inline("<script>window.prompt('Enter Your Name: ', 'Federer');</script>")
response = get_dialog_text(session)
assert_success(response)
assert isinstance(response.body, dict)
import pytest
from tests.support.asserts import assert_error, assert_success
+from tests.support.inline import inline
def send_alert_text(session, body=None):
return session.transport.send("POST", "session/{session_id}/alert/text"
@pytest.mark.parametrize("text", [None, {}, [], 42, True])
def test_invalid_input(session, text):
# 18.4 step 2
- session.execute_script("window.result = window.prompt(\"Enter Your Name: \", \"Name\");")
+ session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Name');</script>")
response = send_alert_text(session, {"text": text})
assert_error(response, "invalid argument")
def test_alert_element_not_interactable(session):
# 18.4 step 5
- session.execute_script("window.alert(\"Hello\");")
+ session.url = inline("<script>window.alert('Hello');</script>")
body = {"text": "Federer"}
response = send_alert_text(session, body)
assert_error(response, "element not interactable")
def test_confirm_element_not_interactable(session):
# 18.4 step 5
- session.execute_script("window.confirm(\"Hello\");")
+ session.url = inline("<script>window.confirm('Hello');</script>")
body = {"text": "Federer"}
response = send_alert_text(session, body)
assert_error(response, "element not interactable")
def test_send_alert_text(session):
# 18.4 step 6
- session.execute_script("window.result = window.prompt(\"Enter Your Name: \", \"Name\");")
+ session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Name');</script>")
body = {"text": "Federer"}
send_response = send_alert_text(session, body)
assert_success(send_response)
def test_send_alert_text_with_whitespace(session):
# 18.4 step 6
- session.execute_script("window.result = window.prompt(\"Enter Your Name: \", \"Name\");")
+ session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Name');</script>")
body = {"text": " Fed erer "}
send_response = send_alert_text(session, body)
assert_success(send_response)