Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/test/selenium/webdriver/common/executing_async_javascript_tests.py
1865 views
1
# Licensed to the Software Freedom Conservancy (SFC) under one
2
# or more contributor license agreements. See the NOTICE file
3
# distributed with this work for additional information
4
# regarding copyright ownership. The SFC licenses this file
5
# to you under the Apache License, Version 2.0 (the
6
# "License"); you may not use this file except in compliance
7
# with the License. You may obtain a copy of the License at
8
#
9
# http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing,
12
# software distributed under the License is distributed on an
13
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
# KIND, either express or implied. See the License for the
15
# specific language governing permissions and limitations
16
# under the License.
17
18
import pytest
19
20
from selenium.common.exceptions import TimeoutException, WebDriverException
21
from selenium.webdriver.common.by import By
22
from selenium.webdriver.remote.webelement import WebElement
23
24
25
@pytest.fixture(autouse=True)
26
def reset_timeouts(driver):
27
driver.set_script_timeout(5)
28
yield
29
driver.set_script_timeout(30)
30
31
32
def test_should_not_timeout_if_callback_invoked_immediately(driver, pages):
33
pages.load("ajaxy_page.html")
34
result = driver.execute_async_script("arguments[arguments.length - 1](123);")
35
assert isinstance(result, int)
36
assert 123 == result
37
38
39
def test_should_be_able_to_return_javascript_primitives_from_async_scripts_neither_none_nor_undefined(driver, pages):
40
pages.load("ajaxy_page.html")
41
assert 123 == driver.execute_async_script("arguments[arguments.length - 1](123);")
42
assert "abc" == driver.execute_async_script("arguments[arguments.length - 1]('abc');")
43
assert not bool(driver.execute_async_script("arguments[arguments.length - 1](false);"))
44
assert bool(driver.execute_async_script("arguments[arguments.length - 1](true);"))
45
46
47
def test_should_be_able_to_return_javascript_primitives_from_async_scripts_null_and_undefined(driver, pages):
48
pages.load("ajaxy_page.html")
49
assert driver.execute_async_script("arguments[arguments.length - 1](null)") is None
50
assert driver.execute_async_script("arguments[arguments.length - 1]()") is None
51
52
53
def test_should_be_able_to_return_an_array_literal_from_an_async_script(driver, pages):
54
pages.load("ajaxy_page.html")
55
result = driver.execute_async_script("arguments[arguments.length - 1]([]);")
56
assert "Expected not to be null!", result is not None
57
assert isinstance(result, list)
58
assert len(result) == 0
59
60
61
def test_should_be_able_to_return_an_array_object_from_an_async_script(driver, pages):
62
pages.load("ajaxy_page.html")
63
result = driver.execute_async_script("arguments[arguments.length - 1](new Array());")
64
assert "Expected not to be null!", result is not None
65
assert isinstance(result, list)
66
assert len(result) == 0
67
68
69
def test_should_be_able_to_return_arrays_of_primitives_from_async_scripts(driver, pages):
70
pages.load("ajaxy_page.html")
71
72
result = driver.execute_async_script("arguments[arguments.length - 1]([null, 123, 'abc', true, false]);")
73
74
assert result is not None
75
assert isinstance(result, list)
76
assert not bool(result.pop())
77
assert bool(result.pop())
78
assert "abc" == result.pop()
79
assert 123 == result.pop()
80
assert result.pop() is None
81
assert len(result) == 0
82
83
84
def test_should_be_able_to_return_web_elements_from_async_scripts(driver, pages):
85
pages.load("ajaxy_page.html")
86
87
result = driver.execute_async_script("arguments[arguments.length - 1](document.body);")
88
assert isinstance(result, WebElement)
89
assert "body" == result.tag_name.lower()
90
91
92
@pytest.mark.xfail_safari
93
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4525")
94
def test_should_be_able_to_return_arrays_of_web_elements_from_async_scripts(driver, pages):
95
pages.load("ajaxy_page.html")
96
97
result = driver.execute_async_script("arguments[arguments.length - 1]([document.body, document.body]);")
98
assert result is not None
99
assert isinstance(result, list)
100
101
list_ = result
102
assert 2 == len(list_)
103
assert isinstance(list_[0], WebElement)
104
assert isinstance(list_[1], WebElement)
105
assert "body" == list_[0].tag_name
106
# assert list_[0] == list_[1]
107
108
109
def test_should_timeout_if_script_does_not_invoke_callback(driver, pages):
110
pages.load("ajaxy_page.html")
111
with pytest.raises(TimeoutException):
112
# Script is expected to be async and explicitly callback, so this should timeout.
113
driver.execute_async_script("return 1 + 2;")
114
115
116
def test_should_timeout_if_script_does_not_invoke_callback_with_azero_timeout(driver, pages):
117
pages.load("ajaxy_page.html")
118
with pytest.raises(TimeoutException):
119
driver.execute_async_script("window.setTimeout(function() {}, 0);")
120
121
122
def test_should_not_timeout_if_script_callsback_inside_azero_timeout(driver, pages):
123
pages.load("ajaxy_page.html")
124
driver.execute_async_script(
125
"""var callback = arguments[arguments.length - 1];
126
window.setTimeout(function() { callback(123); }, 0)"""
127
)
128
129
130
def test_should_timeout_if_script_does_not_invoke_callback_with_long_timeout(driver, pages):
131
driver.set_script_timeout(0.5)
132
pages.load("ajaxy_page.html")
133
with pytest.raises(TimeoutException):
134
driver.execute_async_script(
135
"""var callback = arguments[arguments.length - 1];
136
window.setTimeout(callback, 1500);"""
137
)
138
139
140
def test_should_detect_page_loads_while_waiting_on_an_async_script_and_return_an_error(driver, pages):
141
pages.load("ajaxy_page.html")
142
driver.set_script_timeout(0.1)
143
with pytest.raises(WebDriverException):
144
url = pages.url("dynamic.html")
145
driver.execute_async_script(f"window.location = '{url}';")
146
147
148
def test_should_catch_errors_when_executing_initial_script(driver, pages):
149
pages.load("ajaxy_page.html")
150
with pytest.raises(WebDriverException):
151
driver.execute_async_script("throw Error('you should catch this!');")
152
153
154
def test_should_be_able_to_execute_asynchronous_scripts(driver, pages):
155
pages.load("ajaxy_page.html")
156
157
typer = driver.find_element(by=By.NAME, value="typer")
158
typer.send_keys("bob")
159
assert "bob" == typer.get_attribute("value")
160
161
driver.find_element(by=By.ID, value="red").click()
162
driver.find_element(by=By.NAME, value="submit").click()
163
164
assert 1 == len(driver.find_elements(by=By.TAG_NAME, value="div")), (
165
"There should only be 1 DIV at this point, which is used for the butter message"
166
)
167
driver.set_script_timeout(10)
168
text = driver.execute_async_script(
169
"""var callback = arguments[arguments.length - 1];
170
window.registerListener(arguments[arguments.length - 1]);"""
171
)
172
assert "bob" == text
173
assert "" == typer.get_attribute("value")
174
175
assert 2 == len(driver.find_elements(by=By.TAG_NAME, value="div")), (
176
"There should be 1 DIV (for the butter message) + 1 DIV (for the new label)"
177
)
178
179
180
def test_should_be_able_to_pass_multiple_arguments_to_async_scripts(driver, pages):
181
pages.load("ajaxy_page.html")
182
result = driver.execute_async_script(
183
"""
184
arguments[arguments.length - 1](arguments[0] + arguments[1]);""",
185
1,
186
2,
187
)
188
assert 3 == result
189
190
191
# TODO DavidBurns Disabled till Java WebServer is used
192
# def test_should_be_able_to_make_xmlhttp_requests_and_wait_for_the_response(driver, pages):
193
# script = """
194
# var url = arguments[0];
195
# var callback = arguments[arguments.length - 1];
196
# // Adapted from http://www.quirksmode.org/js/xmlhttp.html
197
# var XMLHttpFactories = [
198
# function () return new XMLHttpRequest(),
199
# function () return new ActiveXObject('Msxml2.XMLHTTP'),
200
# function () return new ActiveXObject('Msxml3.XMLHTTP'),
201
# function () return new ActiveXObject('Microsoft.XMLHTTP')
202
# ];
203
# var xhr = false;
204
# while (!xhr && XMLHttpFactories.length)
205
# try{
206
# xhr = XMLHttpFactories.shift().call();
207
# }catch (e)
208
#
209
# if (!xhr) throw Error('unable to create XHR object');
210
# xhr.open('GET', url, true);
211
# xhr.onreadystatechange = function()
212
# if (xhr.readyState == 4) callback(xhr.responseText);
213
#
214
# xhr.send('');""" # empty string to stop firefox 3 from choking
215
#
216
# pages.load("ajaxy_page.html")
217
# driver.set_script_timeout(3)
218
# response = driver.execute_async_script(script, pages.sleepingPage + "?time=2")
219
# htm = "<html><head><title>Done</title></head><body>Slept for 2s</body></html>"
220
# assert response.strip() == htm
221
222