summaryrefslogtreecommitdiff
path: root/crocoite
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2018-04-14 10:45:22 +0200
committerLars-Dominik Braun <lars@6xq.net>2018-04-14 10:47:03 +0200
commit45ddbd8f74aa624cdb0714db88e133bf4f92e702 (patch)
treeafe1d3a4c9398d7353ce701e6fe7289311e5e4e5 /crocoite
parenta947333da221d8a8f74c1971f1a09fe21ccfebcf (diff)
downloadcrocoite-45ddbd8f74aa624cdb0714db88e133bf4f92e702.tar.gz
crocoite-45ddbd8f74aa624cdb0714db88e133bf4f92e702.tar.bz2
crocoite-45ddbd8f74aa624cdb0714db88e133bf4f92e702.zip
Handle JavaScript dialogs
alert, confirm and prompt and beforeunload
Diffstat (limited to 'crocoite')
-rw-r--r--crocoite/browser.py39
1 files changed, 37 insertions, 2 deletions
diff --git a/crocoite/browser.py b/crocoite/browser.py
index 79845a9..260e061 100644
--- a/crocoite/browser.py
+++ b/crocoite/browser.py
@@ -114,6 +114,7 @@ class SiteLoader:
tab.Network.loadingFailed = self._loadingFailed
tab.Log.entryAdded = self._entryAdded
#tab.Page.loadEventFired = loadEventFired
+ tab.Page.javascriptDialogOpening = self._javascriptDialogOpening
# start the tab
tab.start()
@@ -168,6 +169,7 @@ class SiteLoader:
tab.Network.loadingFinished = None
tab.Network.loadingFailed = None
tab.Page.loadEventFired = None
+ tab.Page.javascriptDialogOpening = None
tab.Log.entryAdded = None
def __exit__ (self, exc_type, exc_value, traceback):
@@ -257,6 +259,18 @@ class SiteLoader:
'error': logging.ERROR}[entry['level']]
self.logger.log (level, 'console: {}: {}'.format (entry['source'], entry['text']), extra={'raw': entry})
+ def _javascriptDialogOpening (self, **kwargs):
+ t = kwargs.get ('type')
+ if t in {'alert', 'confirm', 'prompt'}:
+ self.logger.info ('javascript opened a dialog: {}, {}, canceling'.format (t, kwargs.get ('message')))
+ self.tab.Page.handleJavaScriptDialog (accept=False)
+ elif t == 'beforeunload':
+ # we must accept this one, otherwise the page will not unload/close
+ self.logger.info ('javascript opened a dialog: {}, {}, procceeding'.format (t, kwargs.get ('message')))
+ self.tab.Page.handleJavaScriptDialog (accept=True)
+ else:
+ self.logger.warning ('unknown javascript dialog type {}'.format (t))
+
class AccountingSiteLoader (SiteLoader):
"""
SiteLoader that keeps basic statistics about retrieved pages.
@@ -359,6 +373,7 @@ class TestHTTPRequestHandler (BaseHTTPRequestHandler):
# 1×1 pixel PNG
imageTestData = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDAT\x08\x1dc\xf8\x0f\x00\x01\x01\x01\x006_g\x80\x00\x00\x00\x00IEND\xaeB`\x82'
htmlTestData = '<html><body><img src="/image"><img src="/nonexistent"></body></html>'
+ alertData = '<html><body><script>window.addEventListener("beforeunload", function (e) { e.returnValue = "bye?"; return e.returnValue; }); alert("stopping here"); if (confirm("are you sure?") || prompt ("42?")) { window.location = "/nonexistent"; }</script><img src="/image"></body></html>'
def do_GET(self):
path = self.path
@@ -400,6 +415,11 @@ class TestHTTPRequestHandler (BaseHTTPRequestHandler):
self.send_header ('Content-Type', 'text/html; charset=utf-8')
self.end_headers ()
self.wfile.write (self.htmlTestData.encode ('utf-8'))
+ elif path == '/alert':
+ self.send_response (200)
+ self.send_header ('Content-Type', 'text/html; charset=utf-8')
+ self.end_headers ()
+ self.wfile.write (self.alertData.encode ('utf-8'))
else:
self.send_response (404)
self.end_headers ()
@@ -435,8 +455,8 @@ class TestSiteLoader (unittest.TestCase):
return TestSiteLoaderAdapter (self.browser, '{}{}'.format (self.baseurl, path))
def assertUrls (self, l, expect):
- urls = sorted (map (lambda x: urlsplit (x.url).path, l.finished))
- expect = sorted (expect)
+ urls = set (map (lambda x: urlsplit (x.url).path, l.finished))
+ expect = set (expect)
self.assertEqual (urls, expect)
def test_wait (self):
@@ -521,6 +541,21 @@ class TestSiteLoader (unittest.TestCase):
else:
self.fail ('unknown url')
+ def test_alert (self):
+ with self.buildAdapter ('alert') as l:
+ l.start ()
+ l.waitIdle ()
+ self.assertUrls (l, ['/alert', '/image'])
+ for item in l.finished:
+ if item.url.endswith ('/alert'):
+ self.assertEqual (item.response['status'], 200)
+ self.assertEqual (item.body, TestHTTPRequestHandler.alertData.encode ('utf-8'))
+ elif item.url.endswith ('/image'):
+ self.assertEqual (item.response['status'], 200)
+ self.assertEqual (item.body, TestHTTPRequestHandler.imageTestData)
+ else:
+ self.fail ('unknown url')
+
def tearDown (self):
self.service.__exit__ (None, None, None)
self.server.terminate ()