diff --git a/src/calibre/web/jsbrowser/browser.py b/src/calibre/web/jsbrowser/browser.py index 5d569a3fac..c4341171ea 100644 --- a/src/calibre/web/jsbrowser/browser.py +++ b/src/calibre/web/jsbrowser/browser.py @@ -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') diff --git a/src/calibre/web/jsbrowser/forms.py b/src/calibre/web/jsbrowser/forms.py index 8a837a1fc2..64c652716c 100644 --- a/src/calibre/web/jsbrowser/forms.py +++ b/src/calibre/web/jsbrowser/forms.py @@ -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) + diff --git a/src/calibre/web/jsbrowser/test.py b/src/calibre/web/jsbrowser/test.py index fbafad3f0c..3c9b98fbcf 100644 --- a/src/calibre/web/jsbrowser/test.py +++ b/src/calibre/web/jsbrowser/test.py @@ -23,6 +23,24 @@ class Server(object): return '''