[英]selenium button click not triggering inline javascript event handler
My HTML looks like below我的 HTML 如下所示
<div class="container">
<div class="jumbotron">
<h1 id="survey-title" class="display-5 text-capitalize">Your favourite candidate</h1>
<hr class="my-4">
<div class="card-body">
<h5 id="question-title" class="card-title">What is your name?</h5>
<form id="question_form" action="/survey/takesurvey/1/2" method="post" class="form">
<input type="hidden" name="csrfmiddlewaretoken" value="ELBWYGZRxRuI7CoZ2xkmgCJ3f9JweFMM4Ew1pQbgSE3BLb38VStPJEbHvsyiBEFg">
<div class="form-group"><input type="text" name="response" value="asdfasdfas" maxlength="400" class="form-control" title="" id="id_response"></div>
</form>
</div>
<a id="btn-previous" href="javascript:history.back()" class="btn btn-primary ">Previous</a>
<a id="btn-next" href="/survey/takesurvey/finish/1" class="btn btn-primary">Next</a>
</div>
</div>
Notice the href
on previous button注意上一个按钮上的
href
<a id="btn-previous" href="javascript:history.back()" class="btn btn-primary ">Previous</a>
Clicking next will submit form and go to "next" page, again clicking "previous" should come back and preserve the input value in previous page.单击下一步将提交表单并转到“下一页”,再次单击“上一页”应返回并保留上一页的输入值。 I am using following code to test this behavior, The following code is working only when I put
sleep(1)
line in between finding the element and clicking.我正在使用以下代码来测试此行为,以下代码仅在我将
sleep(1)
行置于查找元素和单击之间时才有效。 Else the page is not going back (url not changing)否则页面不会返回(网址不变)
cur_url = self.browser.current_url
self.browser.find_element_by_id('btn-next').click()
wait(lambda: self.assertNotEqual(self.browser.current_url, cur_url))
btn_previous = self.browser.find_element_by_id('btn-previous')
## This code is not working without the sleep below. Which I suspect
## has to do with javascript event handler (which is inline in html) not being loaded.
## Is there better way to check that the button is ready to be clicked
sleep(1)
btn_previous.click()
You can use WebDriverWait
with element_to_be_clickable
condition.您可以将
WebDriverWait
与element_to_be_clickable
条件一起使用。 Check here also.也请检查这里。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(self.browser, 5).until(EC.element_to_be_clickable((By.ID, "btn-previous"))).click()
You can try wait for JavaScript:您可以尝试等待 JavaScript:
WebDriverWait(self.browser, 20).until(lambda d: d.execute_script(
'return (document.readyState == "complete" || document.readyState == "interactive")'))
# or without interactive
WebDriverWait(self.browser, 20).until(lambda d: d.execute_script(
'return document.readyState == "complete"'))
This is not the desired solution but a workaround the worked for me for now.这不是理想的解决方案,而是目前对我有用的解决方法。
My functions for wait我的等待功能
from time import sleep
from functools import wraps
from selenium.common.exceptions import NoSuchElementException
def wrap_in_wait(func, retires=5):
@wraps(func)
def wrapper(*args, **kwargs):
return wait(func, *args, retires=retires, **kwargs)
return wrapper
def wait(func, *args, retires=10, exceptions=[AssertionError, NoSuchElementException], **kwargs):
for i in range(retires):
try:
return func(*args, **kwargs)
except Exception as e:
print('retry', i)
if type(e) not in exceptions:
raise e
if i == retires-1:
raise e
sleep(0.5 + i*.2)
Test function with Work around solution使用变通解决方案测试功能
def test_question_form_is_loaded_with_existing_answer(self):
'''Test question form pre-loads'''
self.browser.get(self.live_server_url + self.url)
inp = self.browser.find_element_by_css_selector("input#id_response")
inp.send_keys("This is my answer")
self.browser.find_element_by_id('btn-next').click()
@wrap_in_wait
def click_previous_button():
btn_previous = self.browser.find_element_by_id('btn-previous')
btn_previous.click()
inp = self.browser.find_element_by_css_selector("input#id_response")
self.assertEqual(inp.get_attribute('value'), "This is my answer")
click_previous_button()
This solution retries click_previous_button
for 10 times if it raises AssertionError or NoSuchElementException
exception.如果它引发
AssertionError or NoSuchElementException
异常,此解决方案将重试click_previous_button
10 次。 It is working on 2nd try.它正在进行第二次尝试。
But I am still not sure why javascript event is not triggered even when the button is clickable and if there is direct way to test when javascript is ready但我仍然不确定为什么即使按钮可点击也不会触发 javascript 事件,以及是否有直接的方法来测试 javascript 何时准备就绪
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.