mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
JS Browser: Support for AJAX form submission
This commit is contained in:
parent
70ff56c1b2
commit
f9dabe9140
@ -130,6 +130,7 @@ class NetworkAccessManager(QNetworkAccessManager): # {{{
|
||||
|
||||
def __init__(self, log, use_disk_cache=True, parent=None):
|
||||
QNetworkAccessManager.__init__(self, parent)
|
||||
self.reply_count = 0
|
||||
self.log = log
|
||||
if use_disk_cache:
|
||||
self.cache = QNetworkDiskCache(self)
|
||||
@ -170,6 +171,7 @@ class NetworkAccessManager(QNetworkAccessManager): # {{{
|
||||
|
||||
def on_finished(self, reply):
|
||||
reply_url = unicode(reply.url().toString())
|
||||
self.reply_count += 1
|
||||
|
||||
if reply.error():
|
||||
self.log.warn("Reply error: %s - %d (%s)" %
|
||||
@ -286,6 +288,17 @@ class Browser(QObject, FormsMixin):
|
||||
|
||||
return lw.loaded_ok
|
||||
|
||||
def _wait_for_replies(self, reply_count, timeout):
|
||||
final_time = time.time() + timeout
|
||||
loop = QEventLoop(self)
|
||||
while (time.time() < final_time and self.nam.reply_count <
|
||||
reply_count):
|
||||
loop.processEvents()
|
||||
time.sleep(0.1)
|
||||
if self.nam.reply_count < reply_count:
|
||||
raise Timeout('Waiting for replies took longer than %d seconds' %
|
||||
timeout)
|
||||
|
||||
def visit(self, url, timeout=30.0):
|
||||
'''
|
||||
Open the page specified in URL and wait for it to complete loading.
|
||||
@ -310,6 +323,7 @@ class Browser(QObject, FormsMixin):
|
||||
:para ajax_replies: Number of replies to wait for after clicking a link
|
||||
that triggers some AJAX interaction
|
||||
'''
|
||||
initial_count = self.nam.reply_count
|
||||
js = '''
|
||||
var e = document.createEvent('MouseEvents');
|
||||
e.initEvent( 'click', true, true );
|
||||
@ -317,7 +331,8 @@ class Browser(QObject, FormsMixin):
|
||||
'''
|
||||
qwe.evaluateJavaScript(js)
|
||||
if ajax_replies > 0:
|
||||
raise NotImplementedError('AJAX clicking not implemented')
|
||||
reply_count = initial_count + ajax_replies
|
||||
self._wait_for_replies(reply_count, timeout)
|
||||
elif wait_for_load and not self._wait_for_load(timeout):
|
||||
raise LoadError('Clicking resulted in a failed load')
|
||||
|
||||
|
@ -229,3 +229,15 @@ class FormsMixin(object):
|
||||
self.click(sc.qwe, wait_for_load=wait_for_load,
|
||||
ajax_replies=ajax_replies, timeout=timeout)
|
||||
|
||||
def ajax_submit(self, submit_control_selector=None,
|
||||
num_of_replies=1, timeout=30.0):
|
||||
'''
|
||||
Submit the current form. This method is meant for those forms that
|
||||
use AJAX rather than a plain submit. It will block until the specified
|
||||
number of responses are returned from the server after the submit
|
||||
button is clicked.
|
||||
'''
|
||||
self.submit(submit_control_selector=submit_control_selector,
|
||||
wait_for_load=False, ajax_replies=num_of_replies,
|
||||
timeout=timeout)
|
||||
|
||||
|
@ -23,6 +23,24 @@ class Server(object):
|
||||
return '''
|
||||
<html>
|
||||
<head><title>JS Browser test</title></head>
|
||||
<script type="text/javascript" src="jquery"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#ajax_test').submit(function() {
|
||||
var val = $('#ajax_test input[name="text"]').val();
|
||||
$.ajax({
|
||||
dataType: "html",
|
||||
url: "/controls_test",
|
||||
data: {"text":val},
|
||||
success: function(data) {
|
||||
$('#ajax_test input[name="text"]').val(data);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<body>
|
||||
<form id="controls_test" method="post" action="controls_test">
|
||||
<h3>Test controls</h3>
|
||||
@ -40,6 +58,12 @@ class Server(object):
|
||||
<div><label>Simple Text:</label><input type="text" name="text" value="Image Test" /></div>
|
||||
<input type="image" src="button_image" alt="Submit" />
|
||||
</form>
|
||||
<form id="ajax_test" method="post" action="controls_test">
|
||||
<h3>Test AJAX submit</h3>
|
||||
<div><label>Simple Text:</label><input type="text" name="text" value="AJAX Test" /></div>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
@ -55,6 +79,12 @@ class Server(object):
|
||||
cherrypy.response.headers['Content-Type'] = 'image/png'
|
||||
return I('next.png', data=True)
|
||||
|
||||
@cherrypy.expose
|
||||
def jquery(self):
|
||||
cherrypy.response.headers['Content-Type'] = 'text/javascript'
|
||||
return P('content_server/jquery.js', data=True)
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
@ -121,6 +151,15 @@ class Test(unittest.TestCase):
|
||||
self.browser.submit()
|
||||
self.assertEqual(self.server.form_data['text'], 'Image Test')
|
||||
|
||||
def test_ajax_submit(self):
|
||||
'Test AJAX based form submission'
|
||||
self.assertEqual(self.browser.visit('http://127.0.0.1:%d'%self.port),
|
||||
True)
|
||||
f = self.browser.select_form('#ajax_test')
|
||||
f['text'] = 'Changed'
|
||||
self.browser.ajax_submit()
|
||||
self.assertEqual(self.server.form_data['text'], 'Changed')
|
||||
|
||||
def tests():
|
||||
return unittest.TestLoader().loadTestsFromTestCase(Test)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user