1import pytest
2
3from tests.support.asserts import assert_error, assert_success
4
5
6def get_element_attribute(session, element, attr):
7    return session.transport.send(
8        "GET", "session/{session_id}/element/{element_id}/attribute/{attr}".format(
9            session_id=session.session_id,
10            element_id=element,
11            attr=attr))
12
13
14def test_no_top_browsing_context(session, closed_window):
15    original_handle, element = closed_window
16    response = get_element_attribute(session, element.id, "id")
17    assert_error(response, "no such window")
18    response = get_element_attribute(session, "foo", "id")
19    assert_error(response, "no such window")
20    session.window_handle = original_handle
21    response = get_element_attribute(session, element.id, "id")
22    assert_error(response, "no such element")
23
24
25def test_no_browsing_context(session, closed_frame):
26    response = get_element_attribute(session, "foo", "id")
27    assert_error(response, "no such window")
28
29
30def test_element_not_found(session):
31    # 13.2 Step 3
32    result = get_element_attribute(session, "foo", "id")
33    assert_error(result, "no such element")
34
35
36def test_element_stale(session, inline):
37    session.url = inline("<input id=foo>")
38    element = session.find.css("input", all=False)
39    session.refresh()
40    result = get_element_attribute(session, element.id, "id")
41    assert_error(result, "stale element reference")
42
43
44def test_normal(session, inline):
45    # 13.2 Step 5
46    session.url = inline("<input type=checkbox>")
47    element = session.find.css("input", all=False)
48    result = get_element_attribute(session, element.id, "input")
49    assert_success(result, None)
50
51    # Check we are not returning the property which will have a different value
52    assert session.execute_script("return document.querySelector('input').checked") is False
53    element.click()
54    assert session.execute_script("return document.querySelector('input').checked") is True
55    result = get_element_attribute(session, element.id, "input")
56    assert_success(result, None)
57
58
59@pytest.mark.parametrize("tag,attrs", [
60    ("audio", ["autoplay", "controls", "loop", "muted"]),
61    ("button", ["autofocus", "disabled", "formnovalidate"]),
62    ("details", ["open"]),
63    ("dialog", ["open"]),
64    ("fieldset", ["disabled"]),
65    ("form", ["novalidate"]),
66    ("iframe", ["allowfullscreen"]),
67    ("img", ["ismap"]),
68    ("input", [
69        "autofocus", "checked", "disabled", "formnovalidate", "multiple", "readonly", "required"
70    ]),
71    ("menuitem", ["checked", "default", "disabled"]),
72    ("ol", ["reversed"]),
73    ("optgroup", ["disabled"]),
74    ("option", ["disabled", "selected"]),
75    ("script", ["async", "defer"]),
76    ("select", ["autofocus", "disabled", "multiple", "required"]),
77    ("textarea", ["autofocus", "disabled", "readonly", "required"]),
78    ("track", ["default"]),
79    ("video", ["autoplay", "controls", "loop", "muted"])
80])
81def test_boolean_attribute(session, inline, tag, attrs):
82    for attr in attrs:
83        session.url = inline("<{0} {1}>".format(tag, attr))
84        element = session.find.css(tag, all=False)
85        result = get_element_attribute(session, element.id, attr)
86        assert_success(result, "true")
87
88
89def test_global_boolean_attributes(session, inline):
90    session.url = inline("<p hidden>foo")
91    element = session.find.css("p", all=False)
92    result = get_element_attribute(session, element.id, "hidden")
93
94    assert_success(result, "true")
95
96    session.url = inline("<p>foo")
97    element = session.find.css("p", all=False)
98    result = get_element_attribute(session, element.id, "hidden")
99    assert_success(result, None)
100
101    session.url = inline("<p itemscope>foo")
102    element = session.find.css("p", all=False)
103    result = get_element_attribute(session, element.id, "itemscope")
104
105    assert_success(result, "true")
106
107    session.url = inline("<p>foo")
108    element = session.find.css("p", all=False)
109    result = get_element_attribute(session, element.id, "itemscope")
110    assert_success(result, None)
111
112
113@pytest.mark.parametrize("is_relative", [True, False], ids=["relative", "absolute"])
114def test_anchor_href(session, inline, url, is_relative):
115    href = "/foo.html" if is_relative else url("/foo.html")
116
117    session.url = inline("<a href='{}'>foo</a>".format(href))
118    element = session.find.css("a", all=False)
119
120    response = get_element_attribute(session, element.id, "href")
121    assert_success(response, href)
122