Skip to content

Commit

Permalink
Merge r225076 - Unreviewed. Update W3C WebDriver imported tests.
Browse files Browse the repository at this point in the history
* imported/w3c/importer.json:
* imported/w3c/tools/webdriver/webdriver/client.py:
* imported/w3c/tools/webdriver/webdriver/error.py:
* imported/w3c/tools/webdriver/webdriver/protocol.py: Added.
* imported/w3c/tools/webdriver/webdriver/transport.py:
* imported/w3c/tools/wptrunner/MANIFEST.in:
* imported/w3c/tools/wptrunner/requirements_firefox.txt:
* imported/w3c/tools/wptrunner/requirements_opera.txt: Added.
* imported/w3c/tools/wptrunner/wptrunner/browsers/__init__.py:
* imported/w3c/tools/wptrunner/wptrunner/browsers/edge.py:
* imported/w3c/tools/wptrunner/wptrunner/browsers/firefox.py:
* imported/w3c/tools/wptrunner/wptrunner/browsers/opera.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/environment.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/base.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/executoredge.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/executors/executormarionette.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/executoropera.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/executors/executorselenium.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/pytestrunner/runner.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/testharness_webdriver.js:
* imported/w3c/tools/wptrunner/wptrunner/executors/testharness_webdriver_resume.js: Added.
* imported/w3c/tools/wptrunner/wptrunner/stability.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/testdriver-extra.js: Added.
* imported/w3c/tools/wptrunner/wptrunner/testloader.py:
* imported/w3c/tools/wptrunner/wptrunner/testrunner.py:
* imported/w3c/tools/wptrunner/wptrunner/update/state.py:
* imported/w3c/tools/wptrunner/wptrunner/update/sync.py:
* imported/w3c/tools/wptrunner/wptrunner/webdriver_server.py:
* imported/w3c/tools/wptrunner/wptrunner/wptcommandline.py:
* imported/w3c/tools/wptrunner/wptrunner/wptlogging.py:
* imported/w3c/tools/wptrunner/wptrunner/wptrunner.py:
* imported/w3c/tools/wptrunner/wptrunner/wpttest.py:
* imported/w3c/webdriver/tests/actions/conftest.py:
* imported/w3c/webdriver/tests/actions/key.py:
* imported/w3c/webdriver/tests/actions/key_shortcuts.py: Added.
* imported/w3c/webdriver/tests/actions/modifier_click.py: Added.
* imported/w3c/webdriver/tests/actions/mouse.py:
* imported/w3c/webdriver/tests/actions/sequence.py:
* imported/w3c/webdriver/tests/actions/special_keys.py:
* imported/w3c/webdriver/tests/actions/support/keys.py:
* imported/w3c/webdriver/tests/actions/support/test_actions_wdspec.html:
* imported/w3c/webdriver/tests/cookies/add_cookie.py:
* imported/w3c/webdriver/tests/cookies/get_named_cookie.py:
* imported/w3c/webdriver/tests/element_click/stale.py: Added.
* imported/w3c/webdriver/tests/element_retrieval/get_active_element.py:
* imported/w3c/webdriver/tests/interaction/element_clear.py: Added.
* imported/w3c/webdriver/tests/navigation/get_title.py:
* imported/w3c/webdriver/tests/retrieval/find_element.py:
* imported/w3c/webdriver/tests/retrieval/find_element_from_element.py:
* imported/w3c/webdriver/tests/retrieval/find_element_from_elements.py:
* imported/w3c/webdriver/tests/retrieval/find_elements.py:
* imported/w3c/webdriver/tests/sessions/new_session/support/__init__.py:
* imported/w3c/webdriver/tests/state/get_element_attribute.py:
* imported/w3c/webdriver/tests/state/get_element_property.py:
* imported/w3c/webdriver/tests/state/get_element_tag_name.py:
* imported/w3c/webdriver/tests/state/is_element_selected.py:
* imported/w3c/webdriver/tests/support/asserts.py:
* imported/w3c/webdriver/tests/user_prompts/send_alert_text.py: Added.
  • Loading branch information
carlosgcampos committed Dec 18, 2017
1 parent 86f9713 commit 2e9f508
Show file tree
Hide file tree
Showing 59 changed files with 2,039 additions and 493 deletions.
63 changes: 63 additions & 0 deletions WebDriverTests/ChangeLog
@@ -1,3 +1,66 @@
2017-11-21 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/webdriver/webdriver/protocol.py: Added.
* imported/w3c/tools/webdriver/webdriver/transport.py:
* imported/w3c/tools/wptrunner/MANIFEST.in:
* imported/w3c/tools/wptrunner/requirements_firefox.txt:
* imported/w3c/tools/wptrunner/requirements_opera.txt: Added.
* imported/w3c/tools/wptrunner/wptrunner/browsers/__init__.py:
* imported/w3c/tools/wptrunner/wptrunner/browsers/edge.py:
* imported/w3c/tools/wptrunner/wptrunner/browsers/firefox.py:
* imported/w3c/tools/wptrunner/wptrunner/browsers/opera.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/environment.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/base.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/executoredge.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/executors/executormarionette.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/executoropera.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/executors/executorselenium.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/pytestrunner/runner.py:
* imported/w3c/tools/wptrunner/wptrunner/executors/testharness_webdriver.js:
* imported/w3c/tools/wptrunner/wptrunner/executors/testharness_webdriver_resume.js: Added.
* imported/w3c/tools/wptrunner/wptrunner/stability.py: Added.
* imported/w3c/tools/wptrunner/wptrunner/testdriver-extra.js: Added.
* imported/w3c/tools/wptrunner/wptrunner/testloader.py:
* imported/w3c/tools/wptrunner/wptrunner/testrunner.py:
* imported/w3c/tools/wptrunner/wptrunner/update/state.py:
* imported/w3c/tools/wptrunner/wptrunner/update/sync.py:
* imported/w3c/tools/wptrunner/wptrunner/webdriver_server.py:
* imported/w3c/tools/wptrunner/wptrunner/wptcommandline.py:
* imported/w3c/tools/wptrunner/wptrunner/wptlogging.py:
* imported/w3c/tools/wptrunner/wptrunner/wptrunner.py:
* imported/w3c/tools/wptrunner/wptrunner/wpttest.py:
* imported/w3c/webdriver/tests/actions/conftest.py:
* imported/w3c/webdriver/tests/actions/key.py:
* imported/w3c/webdriver/tests/actions/key_shortcuts.py: Added.
* imported/w3c/webdriver/tests/actions/modifier_click.py: Added.
* imported/w3c/webdriver/tests/actions/mouse.py:
* imported/w3c/webdriver/tests/actions/sequence.py:
* imported/w3c/webdriver/tests/actions/special_keys.py:
* imported/w3c/webdriver/tests/actions/support/keys.py:
* imported/w3c/webdriver/tests/actions/support/test_actions_wdspec.html:
* imported/w3c/webdriver/tests/cookies/add_cookie.py:
* imported/w3c/webdriver/tests/cookies/get_named_cookie.py:
* imported/w3c/webdriver/tests/element_click/stale.py: Added.
* imported/w3c/webdriver/tests/element_retrieval/get_active_element.py:
* imported/w3c/webdriver/tests/interaction/element_clear.py: Added.
* imported/w3c/webdriver/tests/navigation/get_title.py:
* imported/w3c/webdriver/tests/retrieval/find_element.py:
* imported/w3c/webdriver/tests/retrieval/find_element_from_element.py:
* imported/w3c/webdriver/tests/retrieval/find_element_from_elements.py:
* imported/w3c/webdriver/tests/retrieval/find_elements.py:
* imported/w3c/webdriver/tests/sessions/new_session/support/__init__.py:
* imported/w3c/webdriver/tests/state/get_element_attribute.py:
* imported/w3c/webdriver/tests/state/get_element_property.py:
* imported/w3c/webdriver/tests/state/get_element_tag_name.py:
* imported/w3c/webdriver/tests/state/is_element_selected.py:
* imported/w3c/webdriver/tests/support/asserts.py:
* imported/w3c/webdriver/tests/user_prompts/send_alert_text.py: Added.

2017-09-21 Carlos Garcia Campos <cgarcia@igalia.com>

WebDriver: Add support to import and run W3C tests
Expand Down
2 changes: 1 addition & 1 deletion WebDriverTests/imported/w3c/importer.json
@@ -1,6 +1,6 @@
{
"repository": "https://github.com/w3c/web-platform-tests.git",
"revision": "09c7045152fc66f9ffe8328ba0ebda20a7e1fe90",
"revision": "448984b0e1c5bad4af20abeaf84eb8b5e8e81478",
"paths_to_import": [
"tools/pytest",
"tools/webdriver",
Expand Down
115 changes: 69 additions & 46 deletions WebDriverTests/imported/w3c/tools/webdriver/webdriver/client.py
@@ -1,15 +1,13 @@
import json
import urlparse

import error
import protocol
import transport

from mozlog import get_default_logger

logger = get_default_logger()

element_key = "element-6066-11e4-a52e-4f735466cecf"


def command(func):
def inner(self, *args, **kwargs):
Expand Down Expand Up @@ -147,7 +145,7 @@ def pointer_move(self, x, y, duration=None, origin=None):
if duration is not None:
action["duration"] = duration
if origin is not None:
action["origin"] = origin if isinstance(origin, basestring) else origin.json()
action["origin"] = origin
self._actions.append(action)
return self

Expand Down Expand Up @@ -299,18 +297,9 @@ def css(self, selector, all=True):

def _find_element(self, strategy, selector, all):
route = "elements" if all else "element"

body = {"using": strategy,
"value": selector}

data = self.session.send_session_command("POST", route, body)

if all:
rv = [self.session._element(item) for item in data]
else:
rv = self.session._element(data)

return rv
return self.session.send_session_command("POST", route, body)


class Cookies(object):
Expand Down Expand Up @@ -356,8 +345,13 @@ def text(self, value):


class Session(object):
def __init__(self, host, port, url_prefix="/", capabilities=None,
timeout=None, extension=None):
def __init__(self,
host,
port,
url_prefix="/",
capabilities=None,
timeout=None,
extension=None):
self.transport = transport.HTTPWireProtocol(
host, port, url_prefix, timeout=timeout)
self.capabilities = capabilities
Expand All @@ -375,6 +369,10 @@ def __init__(self, host, port, url_prefix="/", capabilities=None,
self.alert = UserPrompt(self)
self.actions = Actions(self)

def __eq__(self, other):
return (self.session_id is not None and isinstance(other, Session) and
self.session_id == other.session_id)

def __enter__(self):
self.start()
return self
Expand Down Expand Up @@ -422,22 +420,36 @@ def send_command(self, method, url, body=None):
:param body: Optional body of the HTTP request.
:return: `None` if the HTTP response body was empty, otherwise
the result of parsing the body as JSON.
the `value` field returned after parsing the response
body as JSON.
:raises ValueError: If the response body does not contain a
`value` key.
:raises error.WebDriverException: If the remote end returns
an error.
"""
response = self.transport.send(method, url, body)
response = self.transport.send(
method, url, body,
encoder=protocol.Encoder, decoder=protocol.Decoder,
session=self)

if response.status != 200:
raise error.from_response(response)

if "value" in response.body:
value = response.body["value"]
"""
Edge does not yet return the w3c session ID.
We want the tests to run in Edge anyway to help with REC.
In order to run the tests in Edge, we need to hack around
bug:
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14641972
"""
if url == "session" and method == "POST" and "sessionId" in response.body and "sessionId" not in value:
value["sessionId"] = response.body["sessionId"]
else:
raise error.UnknownErrorException("No 'value' key in response body:\n%s" %
json.dumps(response.body))

if response.status != 200:
cls = error.get(value.get("error"))
raise cls(value.get("message"))
raise ValueError("Expected 'value' key in response body:\n"
"%s" % response)

return value

Expand Down Expand Up @@ -512,10 +524,7 @@ def switch_frame(self, frame):
body = None
else:
url = "frame"
if isinstance(frame, Element):
body = {"id": frame.json()}
else:
body = {"id": frame}
body = {"id": frame}

return self.send_session_command("POST", url, body)

Expand All @@ -531,16 +540,7 @@ def handles(self):
@property
@command
def active_element(self):
data = self.send_session_command("GET", "element/active")
if data is not None:
return self._element(data)

def _element(self, data):
elem_id = data[element_key]
assert elem_id
if elem_id in self._element_cache:
return self._element_cache[elem_id]
return Element(self, elem_id)
return self.send_session_command("GET", "element/active")

@command
def cookies(self, name=None):
Expand Down Expand Up @@ -603,26 +603,49 @@ def screenshot(self):


class Element(object):
def __init__(self, session, id):
self.session = session
"""
Representation of a web element.
A web element is an abstraction used to identify an element when
it is transported via the protocol, between remote- and local ends.
"""
identifier = "element-6066-11e4-a52e-4f735466cecf"

def __init__(self, id, session):
"""
Construct a new web element representation.
:param id: Web element UUID which must be unique across
all browsing contexts.
:param session: Current ``webdriver.Session``.
"""
self.id = id
self.session = session

assert id not in self.session._element_cache
self.session._element_cache[self.id] = self

def __eq__(self, other):
return (isinstance(other, Element) and self.id == other.id and
self.session == other.session)

@classmethod
def from_json(cls, json, session):
assert Element.identifier in json
uuid = json[Element.identifier]
if uuid in session._element_cache:
return session._element_cache[uuid]
return cls(uuid, session)

def send_element_command(self, method, uri, body=None):
url = "element/%s/%s" % (self.id, uri)
return self.session.send_session_command(method, url, body)

def json(self):
return {element_key: self.id}

@command
def find_element(self, strategy, selector):
body = {"using": strategy,
"value": selector}

elem = self.send_element_command("POST", "element", body)
return self.session._element(elem)
return self.send_element_command("POST", "element", body)

@command
def click(self):
Expand Down
54 changes: 49 additions & 5 deletions WebDriverTests/imported/w3c/tools/webdriver/webdriver/error.py
@@ -1,10 +1,25 @@
import collections
import json


class WebDriverException(Exception):
http_status = None
status_code = None

def __init__(self, message, stacktrace=None):
super(WebDriverException, self)
self.stacktrace = stacktrace

def __repr__(self):
return "<%s http_status=%d>" % (self.__class__.__name__, self.http_status)

def __str__(self):
return ("%s (%d)\n"
"\n"
"Remote-end stacktrace:\n"
"\n"
"%s" % (self.status_code, self.http_status, self.stacktrace))


class ElementNotSelectableException(WebDriverException):
http_status = 400
Expand Down Expand Up @@ -38,7 +53,7 @@ class InvalidElementCoordinatesException(WebDriverException):

class InvalidElementStateException(WebDriverException):
http_status = 400
status_code = "invalid cookie domain"
status_code = "invalid element state"


class InvalidSelectorException(WebDriverException):
Expand Down Expand Up @@ -92,7 +107,7 @@ class SessionNotCreatedException(WebDriverException):


class StaleElementReferenceException(WebDriverException):
http_status = 400
http_status = 404
status_code = "stale element reference"


Expand Down Expand Up @@ -131,11 +146,40 @@ class UnsupportedOperationException(WebDriverException):
status_code = "unsupported operation"


def get(status_code):
"""Gets exception from `status_code`, falling back to
def from_response(response):
"""
Unmarshals an error from a ``Response``'s `body`, failing
if not all three required `error`, `message`, and `stacktrace`
fields are given. Defaults to ``WebDriverException`` if `error`
is unknown.
"""
if response.status == 200:
raise UnknownErrorException(
"Response is not an error:\n"
"%s" % json.dumps(response.body))

if "value" in response.body:
value = response.body["value"]
else:
raise UnknownErrorException(
"Expected 'value' key in response body:\n"
"%s" % json.dumps(response.body))

# all fields must exist, but stacktrace can be an empty string
code = value["error"]
message = value["message"]
stack = value["stacktrace"] or None

cls = get(code)
return cls(message, stacktrace=stack)


def get(error_code):
"""
Gets exception from `error_code`, falling back to
``WebDriverException`` if it is not found.
"""
return _errors.get(status_code, WebDriverException)
return _errors.get(error_code, WebDriverException)


_errors = collections.defaultdict()
Expand Down

0 comments on commit 2e9f508

Please sign in to comment.