Source code for webtest_casperjs
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
__doc__ = '''Allow to run an external process to test your application'''
from webtest import app as testapp
from webtest.http import StopableWSGIServer
from contextlib import contextmanager
from six import binary_type
import subprocess
import logging
import tempfile
import shutil
import time
import sys
import os
log = logging.getLogger('nose.casperjs')
stderr = sys.stderr
[docs]class TestApp(testapp.TestApp):
"""Run the test application in a separate thread to allow to access it via
http"""
def __init__(self, app=None, url=None, timeout=30000,
extra_environ=None, relative_to=None, **kwargs):
super(TestApp, self).__init__(app, relative_to=relative_to)
self.server = StopableWSGIServer.create(app)
self.server.wait()
self.application_url = self.server.application_url
os.environ['APPLICATION_URL'] = self.application_url
self.extra_environ = extra_environ or {}
self.timeout = timeout
self.test_app = self
def get_binary(self, name):
for path in (os.getcwd(), '/usr/local', '/usr', '/opt'):
filename = os.path.join(path, 'bin', name)
if os.path.isfile(filename):
return filename
[docs] def close(self):
"""Close WSGI server if needed"""
if self.server:
self.server.shutdown()
@contextmanager
[docs]def casperjs(test_app, timeout=60):
"""A context manager to run a test with a :class:`webtest.ext.TestApp`"""
app = TestApp(test_app.app)
binary = app.get_binary('casperjs')
tempdir = tempfile.mkdtemp(prefix='casperjs')
def run(script, *args):
dirname = os.path.dirname(sys._getframe(1).f_code.co_filename)
log = os.path.join(tempdir, os.path.basename(script) + '.log')
script = os.path.join(dirname, script)
if binary:
stdout = open(log, 'ab+')
cmd = [binary, 'test'] + list(args) + [script]
p = subprocess.Popen(cmd,
stdout=stdout,
stderr=subprocess.PIPE)
end = time.time() + timeout
while time.time() < end:
ret = p.poll()
if ret is not None:
end = time.time() + 100
break
time.sleep(.3)
if time.time() < end:
try:
p.kill()
except OSError:
pass
if os.path.isfile(log):
with open(log) as fd:
output = fd.read()
if isinstance(output, binary_type):
output = output.decode('utf8', 'replace')
if p.returncode != 0:
print(output)
raise AssertionError(
'Failure while running %s' % ' '.join(cmd))
try:
yield run
finally:
shutil.rmtree(tempdir)
app.close()