1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
# -*- coding: utf-8 -*-
import threading
import logging
import time
from unittest import TestCase
from wsgiref.simple_server import make_server
from ghost import Ghost
class ServerThread(threading.Thread):
"""Starts given WSGI application.
:param app: The WSGI application to run.
:param port: The port to run on.
"""
def __init__(self, app, port=5000):
self.app = app
self.port = port
super(ServerThread, self).__init__()
def run(self):
self.http_server = make_server('', self.port, self.app)
self.http_server.serve_forever()
def join(self, timeout=None):
if hasattr(self, 'http_server'):
self.http_server.shutdown()
del self.http_server
class BaseGhostTestCase(TestCase):
display = False
wait_timeout = 5
viewport_size = (800, 600)
log_level = logging.DEBUG
def __new__(cls, *args, **kwargs):
"""Creates Ghost instance."""
if not hasattr(cls, 'ghost'):
cls.ghost = Ghost(
log_level=cls.log_level,
defaults=dict(
display=cls.display,
viewport_size=cls.viewport_size,
wait_timeout=cls.wait_timeout,
)
)
return super(BaseGhostTestCase, cls).__new__(cls)
def __call__(self, result=None):
"""Does the required setup, doing it here
means you don't have to call super.setUp
in subclasses.
"""
self._pre_setup()
super(BaseGhostTestCase, self).__call__(result)
self._post_teardown()
def _post_teardown(self):
"""Deletes ghost cookies and hide UI if needed."""
self.session.exit()
def _pre_setup(self):
"""Shows UI if needed.
"""
self.session = self.ghost.start()
if self.display:
self.session.show()
class GhostTestCase(BaseGhostTestCase):
"""TestCase that provides a ghost instance and manage
an HTTPServer running a WSGI application.
"""
server_class = ServerThread
port = 5000
def create_app(self):
"""Returns your WSGI application for testing.
"""
raise NotImplementedError
@classmethod
def tearDownClass(cls):
"""Stops HTTPServer instance."""
cls.server_thread.join()
super(GhostTestCase, cls).tearDownClass()
@classmethod
def setUpClass(cls):
"""Starts HTTPServer instance from WSGI application.
"""
cls.server_thread = cls.server_class(cls.create_app(), cls.port)
cls.server_thread.daemon = True
cls.server_thread.start()
while not hasattr(cls.server_thread, 'http_server'):
time.sleep(0.01)
super(GhostTestCase, cls).setUpClass()
|