[IMP] phantomjs testing add an easy phantom_js helper
self.phantom_js(<page_to_load>, <code_to_run>, <global_object_to_wait>, **options) example: self.phantom_js("/", "openerp.module.mytest()", "openerp.module.mytest"); console.log('ok') or console.log('error') should be used to signal success or failure. Other console.log's will be passed to the test logger. bzr revid: al@openerp.com-20140210004517-jc2cobc31qshxchm
This commit is contained in:
parent
8f29812b0f
commit
1f78dfb76d
|
@ -1,14 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import glob
|
||||
|
||||
import openerp
|
||||
|
||||
fname, _ = os.path.splitext(__file__)
|
||||
|
||||
class TestUi(openerp.tests.HttpCase):
|
||||
def test(self):
|
||||
for i in glob.glob('%s*.js' % fname):
|
||||
self.phantomjs(i)
|
||||
def test_js(self):
|
||||
self.phantom_js('/',"console.log('ok')","console", login=None)
|
||||
|
||||
def test_jsfile(self):
|
||||
self.phantom_jsfile(os.path.join(os.path.dirname(__file__), 'test_ui_hello.js'))
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
// Load helper
|
||||
phantom.injectJs(phantom.args[0]);
|
||||
|
||||
pt = new PhantomTest();
|
||||
pt.run("/", "console.log('ok')", "console");
|
||||
|
|
@ -112,7 +112,7 @@ class SingleTransactionCase(BaseCase):
|
|||
cls.cr.close()
|
||||
|
||||
|
||||
class HttpCase(SingleTransactionCase):
|
||||
class HttpCase(TransactionCase):
|
||||
""" Transactionnal HTTP TestCase with a phantomjs helper.
|
||||
"""
|
||||
|
||||
|
@ -124,18 +124,16 @@ class HttpCase(SingleTransactionCase):
|
|||
self.xmlrpc_db = xmlrpclib.ServerProxy(url_8 + 'db')
|
||||
self.xmlrpc_object = xmlrpclib.ServerProxy(url_8 + 'object')
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(HttpCase, cls).setUpClass()
|
||||
cls.session_id = uuid.uuid4().hex
|
||||
HTTP_SESSION[cls.session_id] = cls.cr
|
||||
def setUp(self):
|
||||
super(HttpCase, self).setUp()
|
||||
self.session_id = uuid.uuid4().hex
|
||||
HTTP_SESSION[self.session_id] = self.cr
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del HTTP_SESSION[cls.session_id]
|
||||
super(HttpCase, cls).tearDownClass()
|
||||
def tearDown(self):
|
||||
del HTTP_SESSION[self.session_id]
|
||||
super(HttpCase, self).tearDown()
|
||||
|
||||
def phantomjs(self, jsfile, timeout=30, options=None):
|
||||
def phantom_poll(self, phantom, timeout):
|
||||
""" Phantomjs Test protocol.
|
||||
|
||||
Use console.log in phantomjs to output test results:
|
||||
|
@ -146,8 +144,77 @@ class HttpCase(SingleTransactionCase):
|
|||
Other lines are relayed to the test log.
|
||||
|
||||
"""
|
||||
self.timeout = timeout
|
||||
self.options = {
|
||||
t0 = time.time()
|
||||
buf = ''
|
||||
while 1:
|
||||
# timeout
|
||||
if time.time() > t0 + timeout:
|
||||
raise Exception("phantomjs test timeout (%ss)" % timeout)
|
||||
|
||||
# read a byte
|
||||
ready, _, _ = select.select([phantom.stdout], [], [], 0.5)
|
||||
if ready:
|
||||
s = phantom.stdout.read(1)
|
||||
if s:
|
||||
buf += s
|
||||
else:
|
||||
break
|
||||
|
||||
# process lines
|
||||
if '\n' in buf:
|
||||
line, buf = buf.split('\n', 1)
|
||||
_logger.info("phantomjs: %s", line)
|
||||
if line == "ok":
|
||||
_logger.info("phantomjs test successful")
|
||||
return
|
||||
if line == "error":
|
||||
raise Exception("phantomjs test failed")
|
||||
|
||||
def phantom_run(self, cmd, timeout):
|
||||
_logger.info('executing %s', cmd)
|
||||
try:
|
||||
phantom = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
except OSError:
|
||||
_logger.info("phantomjs not found, test %s skipped", jsfile)
|
||||
try:
|
||||
self.phantom_poll(phantom, timeout)
|
||||
finally:
|
||||
# kill phantomjs if phantom.exit() wasn't called in the test
|
||||
if phantom.poll() is None:
|
||||
phantom.terminate()
|
||||
|
||||
def phantom_jsfile(self, jsfile, timeout=30, **kw):
|
||||
options = {
|
||||
'timeout' : timeout,
|
||||
'port': PORT,
|
||||
'db': DB,
|
||||
'session_id': self.session_id,
|
||||
}
|
||||
options.update(kw)
|
||||
phantomtest = os.path.join(os.path.dirname(__file__), 'phantomtest.js')
|
||||
# phantom.args[0] == phantomtest path
|
||||
# phantom.args[1] == options
|
||||
cmd = ['phantomjs', jsfile, phantomtest, json.dumps(options)]
|
||||
self.phantom_run(cmd, timeout)
|
||||
|
||||
def phantom_js(self, url_path, code, ready="window", timeout=30, **kw):
|
||||
""" Test js code running in the browser
|
||||
- load page given by url_path
|
||||
- wait for ready object to be available
|
||||
- eval(code) inside the page
|
||||
|
||||
To signal success test do:
|
||||
console.log('ok')
|
||||
|
||||
To signal failure do:
|
||||
console.log('error')
|
||||
|
||||
If neither are done before timeout test fails.
|
||||
"""
|
||||
options = {
|
||||
'url_path': url_path,
|
||||
'code': code,
|
||||
'ready': ready,
|
||||
'timeout' : timeout,
|
||||
'port': PORT,
|
||||
'db': DB,
|
||||
|
@ -155,49 +222,10 @@ class HttpCase(SingleTransactionCase):
|
|||
'password': ADMIN_PASSWORD,
|
||||
'session_id': self.session_id,
|
||||
}
|
||||
if options:
|
||||
self.options.update(options)
|
||||
|
||||
options.update(kw)
|
||||
phantomtest = os.path.join(os.path.dirname(__file__), 'phantomtest.js')
|
||||
|
||||
# phantom.args[0] == phantomtest path
|
||||
# phantom.args[1] == options
|
||||
cmd = ['phantomjs', jsfile, phantomtest, json.dumps(self.options)]
|
||||
_logger.info('executing %s', cmd)
|
||||
try:
|
||||
phantom = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
except OSError:
|
||||
_logger.info("phantomjs not found, test %s skipped", jsfile)
|
||||
try:
|
||||
t0 = time.time()
|
||||
buf = ''
|
||||
while 1:
|
||||
# timeout
|
||||
if time.time() > t0 + self.timeout:
|
||||
raise Exception("phantomjs test timeout (%ss)" % self.timeout)
|
||||
|
||||
# read a byte
|
||||
ready, _, _ = select.select([phantom.stdout], [], [], 0.5)
|
||||
if ready:
|
||||
s = phantom.stdout.read(1)
|
||||
if s:
|
||||
buf += s
|
||||
else:
|
||||
break
|
||||
|
||||
# process lines
|
||||
if '\n' in buf:
|
||||
line, buf = buf.split('\n', 1)
|
||||
_logger.info("phantomjs: %s", line)
|
||||
if line == "ok":
|
||||
_logger.info("phantomjs test successful")
|
||||
return
|
||||
if line == "error":
|
||||
raise Exception("phantomjs test failed")
|
||||
finally:
|
||||
# kill phantomjs if phantom.exit() wasn't called in the test
|
||||
if phantom.poll() is None:
|
||||
phantom.terminate()
|
||||
cmd = ['phantomjs', phantomtest, json.dumps(options)]
|
||||
self.phantom_run(cmd, timeout)
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -24,7 +24,11 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) {
|
|||
|
||||
function PhantomTest() {
|
||||
var self = this;
|
||||
this.options = JSON.parse(phantom.args[1]);
|
||||
if(phantom.args.length === 1) {
|
||||
this.options = JSON.parse(phantom.args[0]);
|
||||
} else {
|
||||
this.options = JSON.parse(phantom.args[1]);
|
||||
}
|
||||
this.inject = [];
|
||||
this.timeout = this.options.timeout ? Math.round(parseFloat(this.options.timeout)*1000 - 5000) : 10000;
|
||||
this.origin = 'http://localhost';
|
||||
|
@ -80,6 +84,14 @@ function PhantomTest() {
|
|||
// run test
|
||||
// ----------------------------------------------------
|
||||
this.run = function(url_path, code, ready) {
|
||||
if(self.options.login) {
|
||||
qp = [];
|
||||
qp.push('db=' + self.options.db);
|
||||
qp.push('login=' + self.options.login);
|
||||
qp.push('key=' + self.options.password);
|
||||
qp.push('redirect=' + encodeURIComponent(url_path));
|
||||
var url_path = "/web/login?" + qp.join('&');
|
||||
}
|
||||
var url = self.origin + url_path;
|
||||
self.page.open(url, function(status) {
|
||||
if (status !== 'success') {
|
||||
|
@ -104,15 +116,12 @@ function PhantomTest() {
|
|||
}
|
||||
});
|
||||
};
|
||||
this.run_admin = function(url_path, code, ready) {
|
||||
qp = [];
|
||||
qp.push('db=' + self.options.db);
|
||||
qp.push('login=' + self.options.login);
|
||||
qp.push('key=' + self.options.password);
|
||||
qp.push('redirect=' + encodeURIComponent(url_path));
|
||||
var url_path2 = "/web/login?" + qp.join('&');
|
||||
return self.run(url_path2, code, ready);
|
||||
};
|
||||
}
|
||||
|
||||
// js mode or jsfile mode
|
||||
if(phantom.args.length === 1) {
|
||||
pt = new PhantomTest();
|
||||
pt.run(pt.options.url_path, pt.options.code, pt.options.ready);
|
||||
}
|
||||
|
||||
// vim:et:
|
||||
|
|
Loading…
Reference in New Issue