[IMP] phantomtest helper
bzr revid: al@openerp.com-20140209223917-vruzjvl0mtsqoo87
This commit is contained in:
parent
e6ac29ee43
commit
1f67b2165c
|
@ -1,11 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
import openerp
|
import openerp
|
||||||
from openerp.tests import common
|
|
||||||
|
|
||||||
class test_phantom(common.HttpCase):
|
class test_phantom(openerp.tests.HttpCase):
|
||||||
|
def test_phantom(self):
|
||||||
def test_01_dummy(self):
|
fname, _ = os.path.splitext(__file__)
|
||||||
self.phantomjs(openerp.modules.module.get_module_resource('base','tests','test_phantom_dummy.js'))
|
for i in glob.glob('%s*.js' % fname):
|
||||||
|
self.phantomjs(openerp.modules.module.get_module_resource('base','tests', i))
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
console.log('{ "event": "success", "message": "Phantomjs success"}');
|
|
||||||
// For a failure:
|
|
||||||
// console.log('{ "event": "failure", "message": "The test failed" }');
|
|
||||||
phantom.exit();
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
console.log("hello from test_phantom_hello.js");
|
||||||
|
console.log("ok");
|
||||||
|
// For a failure use:
|
||||||
|
//console.log("error");
|
||||||
|
phantom.exit();
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Load helper
|
||||||
|
phantom.injectJs(phantom.args[0]);
|
||||||
|
|
||||||
|
pt = new PhantomTest();
|
||||||
|
pt.run("/", "console.log('ok')", "console");
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Load helper
|
||||||
|
phantom.injectJs(phantom.args[0]);
|
||||||
|
|
||||||
|
pt = new PhantomTest();
|
||||||
|
pt.run_admin("/", "console.log('ok')", "console");
|
||||||
|
|
|
@ -845,7 +845,7 @@ def load_test_file_py(test_file):
|
||||||
result = unittest2.TextTestRunner(verbosity=2, stream=openerp.modules.module.TestStream()).run(suite)
|
result = unittest2.TextTestRunner(verbosity=2, stream=openerp.modules.module.TestStream()).run(suite)
|
||||||
if not result.wasSuccessful():
|
if not result.wasSuccessful():
|
||||||
r = False
|
r = False
|
||||||
_logger.error('module %s: at least one error occurred in a test', module_name)
|
_logger.error('%s: at least one error occurred in a test', test_file)
|
||||||
|
|
||||||
def preload_registries(dbnames):
|
def preload_registries(dbnames):
|
||||||
""" Preload a registries, possibly run a test file."""
|
""" Preload a registries, possibly run a test file."""
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
import common
|
||||||
|
from common import *
|
|
@ -5,20 +5,18 @@ helpers and classes to write tests.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import select
|
import select
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest2
|
import unittest2
|
||||||
import uuid
|
import uuid
|
||||||
import xmlrpclib
|
import xmlrpclib
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import openerp
|
import openerp
|
||||||
# backward compatbility
|
|
||||||
common = sys.modules['openerp.tests.common'] = sys.modules['openerp.tests']
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -140,15 +138,12 @@ class HttpCase(SingleTransactionCase):
|
||||||
def phantomjs(self, jsfile, timeout=30, options=None):
|
def phantomjs(self, jsfile, timeout=30, options=None):
|
||||||
""" Phantomjs Test protocol.
|
""" Phantomjs Test protocol.
|
||||||
|
|
||||||
Use console.log in phantomjs to output test results evrey line must be
|
Use console.log in phantomjs to output test results:
|
||||||
a one line JSON message using the following format:
|
|
||||||
|
|
||||||
- for a success: { "event": "success", "message": "Log message" }
|
- for a success: console.log("ok")
|
||||||
- for an error: { "event": "error", "message": "Short error description" }
|
- for an error: console.log("error")
|
||||||
|
|
||||||
if a non json parsable line is received the helper will raise an
|
Other lines are relayed to the test log.
|
||||||
exception, the output buffer will be printed and phantom will be
|
|
||||||
killed
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
@ -156,38 +151,35 @@ class HttpCase(SingleTransactionCase):
|
||||||
'timeout' : timeout,
|
'timeout' : timeout,
|
||||||
'port': PORT,
|
'port': PORT,
|
||||||
'db': DB,
|
'db': DB,
|
||||||
'user': ADMIN_USER,
|
'login': ADMIN_USER,
|
||||||
'password': ADMIN_PASSWORD,
|
'password': ADMIN_PASSWORD,
|
||||||
'session_id': self.session_id,
|
'session_id': self.session_id,
|
||||||
}
|
}
|
||||||
if options:
|
if options:
|
||||||
self.options.update(options)
|
self.options.update(options)
|
||||||
|
|
||||||
self.ignore_filters = [
|
phantomtest = os.path.join(os.path.dirname(__file__), 'phantomtest.js')
|
||||||
# Ignore phantomjs warnings
|
|
||||||
"*** WARNING:",
|
|
||||||
# Fixes an issue with PhantomJS 1.9.2 on OS X 10.9 (Mavericks)
|
|
||||||
# cf. https://github.com/ariya/phantomjs/issues/11418
|
|
||||||
"CoreText performance note",
|
|
||||||
]
|
|
||||||
|
|
||||||
cmd = ['phantomjs', jsfile, json.dumps(self.options)]
|
# phantom.args[0] == phantomtest path
|
||||||
|
# phantom.args[1] == options
|
||||||
|
cmd = ['phantomjs', jsfile, phantomtest, json.dumps(self.options)]
|
||||||
_logger.info('executing %s', cmd)
|
_logger.info('executing %s', cmd)
|
||||||
try:
|
try:
|
||||||
phantom = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
phantom = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
except OSError:
|
except OSError:
|
||||||
_logger.info("phantomjs not found, test %s skipped", jsfile)
|
_logger.info("phantomjs not found, test %s skipped", jsfile)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
buf = ''
|
buf = ''
|
||||||
while 1:
|
while 1:
|
||||||
|
# timeout
|
||||||
if time.time() > t0 + self.timeout:
|
if time.time() > t0 + self.timeout:
|
||||||
raise Exception("Phantom js timeout (%ss)" % self.timeout)
|
raise Exception("phantomjs test timeout (%ss)" % self.timeout)
|
||||||
|
|
||||||
|
# read a byte
|
||||||
ready, _, _ = select.select([phantom.stdout], [], [], 0.5)
|
ready, _, _ = select.select([phantom.stdout], [], [], 0.5)
|
||||||
if ready:
|
if ready:
|
||||||
s = phantom.stdout.read(4096)
|
s = phantom.stdout.read(1)
|
||||||
if s:
|
if s:
|
||||||
buf += s
|
buf += s
|
||||||
else:
|
else:
|
||||||
|
@ -196,20 +188,12 @@ class HttpCase(SingleTransactionCase):
|
||||||
# process lines
|
# process lines
|
||||||
if '\n' in buf:
|
if '\n' in buf:
|
||||||
line, buf = buf.split('\n', 1)
|
line, buf = buf.split('\n', 1)
|
||||||
if line not in self.ignore_filters:
|
_logger.info("phantomjs: %s", line)
|
||||||
try:
|
if line == "ok":
|
||||||
line_json = json.loads(line)
|
_logger.info("phantomjs test successful")
|
||||||
if line_json.get('event') == 'success':
|
return
|
||||||
_logger.info(line_json.get('message','ok'))
|
if line == "error":
|
||||||
continue
|
raise Exception("phantomjs test failed")
|
||||||
elif line_json.get('event') == 'error':
|
|
||||||
err = line_json.get('message','error')
|
|
||||||
_logger.info(err)
|
|
||||||
else:
|
|
||||||
err = line + buf
|
|
||||||
except ValueError:
|
|
||||||
err = line + buf
|
|
||||||
raise Exception(err)
|
|
||||||
finally:
|
finally:
|
||||||
# kill phantomjs if phantom.exit() wasn't called in the test
|
# kill phantomjs if phantom.exit() wasn't called in the test
|
||||||
if phantom.poll() is None:
|
if phantom.poll() is None:
|
|
@ -0,0 +1,118 @@
|
||||||
|
// Phantomjs openerp helper
|
||||||
|
|
||||||
|
function waitFor (ready, callback, timeout, timeoutMessageCallback) {
|
||||||
|
timeout = timeout || 10000;
|
||||||
|
var start = new Date().getTime();
|
||||||
|
var condition = ready();
|
||||||
|
var interval = setInterval(function() {
|
||||||
|
if ((new Date().getTime() - start < timeout) && !condition ) {
|
||||||
|
condition = ready();
|
||||||
|
} else {
|
||||||
|
if(!condition) {
|
||||||
|
var message = timeoutMessageCallback ? timeoutMessageCallback() : "Timeout after "+timeout+" ms";
|
||||||
|
console.log(message);
|
||||||
|
console.log("Waiting for " + ready);
|
||||||
|
console.log("error");
|
||||||
|
phantom.exit(1);
|
||||||
|
} else {
|
||||||
|
clearInterval(interval);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PhantomTest() {
|
||||||
|
var self = this;
|
||||||
|
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';
|
||||||
|
this.origin += this.options.port ? ':' + this.options.port : '';
|
||||||
|
|
||||||
|
// ----------------------------------------------------
|
||||||
|
// test reporting
|
||||||
|
// ----------------------------------------------------
|
||||||
|
this.error = function(message) {
|
||||||
|
console.log(message);
|
||||||
|
console.log("error");
|
||||||
|
phantom.exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------
|
||||||
|
// configure page
|
||||||
|
// ----------------------------------------------------
|
||||||
|
this.page = require('webpage').create();
|
||||||
|
this.page.viewportSize = { width: 1366, height: 768 };
|
||||||
|
this.page.addCookie({
|
||||||
|
'domain': 'localhost',
|
||||||
|
'name': 'session_id',
|
||||||
|
'value': this.options.session_id,
|
||||||
|
});
|
||||||
|
this.page.onError = function(message, trace) {
|
||||||
|
self.error(message + " " + trace);
|
||||||
|
};
|
||||||
|
this.page.onAlert = function(message) {
|
||||||
|
self.error(message);
|
||||||
|
};
|
||||||
|
this.page.onConsoleMessage = function(message) {
|
||||||
|
console.log(message);
|
||||||
|
};
|
||||||
|
this.page.onLoadFinished = function(status) {
|
||||||
|
if (status === "success") {
|
||||||
|
for (var k in self.inject) {
|
||||||
|
if(!page.injectJs(self.inject[k])) {
|
||||||
|
self.error("Can't inject " + self.inject[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setTimeout(function () {
|
||||||
|
self.page.evaluate(function () {
|
||||||
|
var message = ("Timeout\nhref: " + window.location.href
|
||||||
|
+ "\nreferrer: " + document.referrer
|
||||||
|
+ "\n\n" + document.body.innerHTML).replace(/[^a-z0-9\s~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, "*");
|
||||||
|
self.error(message);
|
||||||
|
});
|
||||||
|
}, self.timeout);
|
||||||
|
|
||||||
|
// ----------------------------------------------------
|
||||||
|
// run test
|
||||||
|
// ----------------------------------------------------
|
||||||
|
this.run = function(url_path, code, ready) {
|
||||||
|
var url = self.origin + url_path;
|
||||||
|
self.page.open(url, function(status) {
|
||||||
|
if (status !== 'success') {
|
||||||
|
self.error("failed to load " + url)
|
||||||
|
} else {
|
||||||
|
console.log('loaded', url, status);
|
||||||
|
// process ready
|
||||||
|
waitFor(function() {
|
||||||
|
return self.page.evaluate(function (ready) {
|
||||||
|
var r = false;
|
||||||
|
try {
|
||||||
|
r = !!eval(ready);
|
||||||
|
} catch(ex) {
|
||||||
|
console.log("waiting for page " + ready)
|
||||||
|
};
|
||||||
|
return r;
|
||||||
|
}, ready);
|
||||||
|
// run test
|
||||||
|
}, function() {
|
||||||
|
self.page.evaluate(function (code) { return eval(code); }, code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim:et:
|
Loading…
Reference in New Issue