From 45ddbd8f74aa624cdb0714db88e133bf4f92e702 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sat, 14 Apr 2018 10:45:22 +0200 Subject: Handle JavaScript dialogs alert, confirm and prompt and beforeunload --- crocoite/browser.py | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'crocoite/browser.py') 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 = '' + alertData = '' 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 () -- cgit v1.2.3