summaryrefslogtreecommitdiff
path: root/crocoite/browser.py
diff options
context:
space:
mode:
Diffstat (limited to 'crocoite/browser.py')
-rw-r--r--crocoite/browser.py162
1 files changed, 0 insertions, 162 deletions
diff --git a/crocoite/browser.py b/crocoite/browser.py
index f583c9b..3b9f7ab 100644
--- a/crocoite/browser.py
+++ b/crocoite/browser.py
@@ -25,7 +25,6 @@ Chrome browser interactions.
import logging
from urllib.parse import urlsplit
from base64 import b64decode
-from http.server import BaseHTTPRequestHandler
from collections import deque
from threading import Event
@@ -397,164 +396,3 @@ class NullService:
def __exit__ (self, *exc):
pass
-### tests ###
-
-import unittest, time
-from operator import itemgetter
-
-class TestItem (Item):
- """ This should be as close to Item as possible """
-
- __slots__ = ('bodySend', '_body')
- base = 'http://localhost:8000/'
-
- def __init__ (self, path, status, headers, bodyReceive, bodySend=None):
- super ().__init__ (tab=None)
- self.chromeResponse = {'response': {'headers': headers, 'status': status, 'url': self.base + path}}
- self._body = bodyReceive, False
- self.bodySend = bodyReceive if not bodySend else bodySend
-
- @property
- def body (self):
- return self._body
-
-testItems = [
- TestItem ('binary', 200, {'Content-Type': 'application/octet-stream'}, b'\x00\x01\x02'),
- TestItem ('attachment', 200,
- {'Content-Type': 'text/plain; charset=utf-8',
- 'Content-Disposition': 'attachment; filename="attachment.txt"',
- },
- 'This is a simple text file with umlauts. ÄÖU.'.encode ('utf8')),
- TestItem ('encoding/utf8', 200, {'Content-Type': 'text/plain; charset=utf-8'},
- 'This is a test, äöü μνψκ ¥¥¥¿ýý¡'.encode ('utf8')),
- TestItem ('encoding/iso88591', 200, {'Content-Type': 'text/plain; charset=ISO-8859-1'},
- 'This is a test, äöü.'.encode ('utf8'),
- 'This is a test, äöü.'.encode ('ISO-8859-1')),
- TestItem ('encoding/latin1', 200, {'Content-Type': 'text/plain; charset=latin1'},
- 'This is a test, äöü.'.encode ('utf8'),
- 'This is a test, äöü.'.encode ('latin1')),
- TestItem ('image', 200, {'Content-Type': 'image/png'},
- # 1×1 png image
- 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'),
- TestItem ('empty', 200, {}, b''),
- TestItem ('redirect/301/empty', 301, {'Location': '/empty'}, b''),
- TestItem ('redirect/301/redirect/301/empty', 301, {'Location': '/redirect/301/empty'}, b''),
- TestItem ('nonexistent', 404, {}, b''),
- TestItem ('html', 200, {'Content-Type': 'html'},
- '<html><body><img src="/image"><img src="/nonexistent"></body></html>'.encode ('utf8')),
- TestItem ('html/alert', 200, {'Content-Type': 'html'},
- '<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>'.encode ('utf8')),
- ]
-testItemMap = dict ([(item.parsedUrl.path, item) for item in testItems])
-
-class TestHTTPRequestHandler (BaseHTTPRequestHandler):
- def do_GET(self):
- item = testItemMap.get (self.path)
- if item:
- self.send_response (item.response['status'])
- for k, v in item.response['headers'].items ():
- self.send_header (k, v)
- body = item.bodySend
- self.send_header ('Content-Length', len (body))
- self.end_headers()
- self.wfile.write (body)
- return
-
- def log_message (self, format, *args):
- pass
-
-def startServer ():
- import http.server
- PORT = 8000
- httpd = http.server.HTTPServer (("localhost", PORT), TestHTTPRequestHandler)
- httpd.serve_forever()
-
-class TestSiteLoader (unittest.TestCase):
- __slots__ = ('server', 'baseurl', 'service', 'browser')
-
- def setUp (self):
- from multiprocessing import Process
- self.server = Process (target=startServer)
- self.server.start ()
- self.baseurl = 'http://localhost:8000'
- self.service = ChromeService ()
- self.browser = self.service.__enter__ ()
-
- def buildAdapter (self, path):
- self.assertTrue (path.startswith ('/'))
- return SiteLoader (self.browser, '{}{}'.format (self.baseurl, path))
-
- def assertItems (self, l, items):
- items = dict ([(i.parsedUrl.path, i) for i in items])
- timeout = 5
- while True:
- if not l.notify.wait (timeout) and len (items) > 0:
- self.fail ('timeout')
- if len (l.queue) > 0:
- item = l.queue.popleft ()
- if isinstance (item, Exception):
- raise item
- self.assertIsNot (item.chromeResponse, None, msg='url={}'.format (item.request['url']))
- golden = items.pop (item.parsedUrl.path)
- if not golden:
- self.fail ('url {} not supposed to be fetched'.format (item.url))
- self.assertEqual (item.body[0], golden.body[0], msg='body for url={}'.format (item.request['url']))
- self.assertEqual (item.response['status'], golden.response['status'])
- for k, v in golden.responseHeaders:
- actual = list (map (itemgetter (1), filter (lambda x: x[0] == k, item.responseHeaders)))
- self.assertIn (v, actual)
-
- # check queue at least once
- if not items:
- break
-
- def assertLiteralItem (self, item, deps=[]):
- with self.buildAdapter (item.parsedUrl.path) as l:
- l.start ()
- self.assertItems (l, [item] + deps)
-
- def test_empty (self):
- self.assertLiteralItem (testItemMap['/empty'])
-
- def test_redirect (self):
- self.assertLiteralItem (testItemMap['/redirect/301/empty'], [testItemMap['/empty']])
- # chained redirects
- self.assertLiteralItem (testItemMap['/redirect/301/redirect/301/empty'], [testItemMap['/redirect/301/empty'], testItemMap['/empty']])
-
- def test_encoding (self):
- """ Text responses are transformed to UTF-8. Make sure this works
- correctly. """
- for item in {testItemMap['/encoding/utf8'], testItemMap['/encoding/latin1'], testItemMap['/encoding/iso88591']}:
- self.assertLiteralItem (item)
-
- def test_binary (self):
- """ Browser should ignore content it cannot display (i.e. octet-stream) """
- with self.buildAdapter ('/binary') as l:
- l.start ()
- self.assertItems (l, [])
-
- def test_image (self):
- """ Images should be displayed inline """
- self.assertLiteralItem (testItemMap['/image'])
-
- def test_attachment (self):
- """ And downloads won’t work in headless mode, even if it’s just a text file """
- with self.buildAdapter ('/attachment') as l:
- l.start ()
- self.assertItems (l, [])
-
- def test_html (self):
- self.assertLiteralItem (testItemMap['/html'], [testItemMap['/image'], testItemMap['/nonexistent']])
- # make sure alerts are dismissed correctly (image won’t load otherwise)
- self.assertLiteralItem (testItemMap['/html/alert'], [testItemMap['/image']])
-
- def tearDown (self):
- self.service.__exit__ (None, None, None)
- self.server.terminate ()
- self.server.join ()
-
-if __name__ == '__main__':
- import sys
- if sys.argv[1] == 'server':
- startServer ()
-