[FIX] website: tour, test and test_runner

bzr revid: chm@openerp.com-20140206140746-jmeyx8q9qxv7sz1j
This commit is contained in:
Christophe Matthieu 2014-02-06 15:07:46 +01:00
parent 0677fda79e
commit e8964f896c
18 changed files with 365 additions and 166 deletions

View File

@ -1,40 +0,0 @@
var tests = {};
var droptest = function () {
var errors = [];
for (var snippet_id in tests) {
if (!tests[snippet_id]['activated'] || !tests[snippet_id]['dropped']){
console.log("Can't dropped or activated snippet: " + snippet_id);
}
}
if (errors.length) {
console.log(tests);
throw new Error("Can't dropped or activated at least one snippet");
}
$("#oe_snippets").off('snippet-activated snippet-dropped');
};
var droptesttime = setTimeout(droptest,0);
$("#oe_snippets").off('snippet-activated snippet-dropped')
.on('snippet-activated', function (event, dom) {
tests[$(dom).data('src-snippet-id')]['activated'] = true;
clearTimeout(droptesttime);
droptesttime = setTimeout(droptest,0);
})
.on('snippet-dropped', function (event, dom, src_snipped_id) {
tests[$(dom).data('src-snippet-id')]['dropped'] = true;
clearTimeout(droptesttime);
droptesttime = setTimeout(droptest,0);
});
var $thumbnails = $('#oe_snippets div.oe_snippet[data-snippet-id] .oe_snippet_thumbnail');
$thumbnails.each(function () {
var $thumbnail = $(this);
tests[$thumbnail.parent().data('snippet-id')] = {};
var position = $thumbnail.position();
$thumbnail.trigger( $.Event( "mousedown", { which: 1, pageX: position.left, pageY: position.top } ) );
$thumbnail.trigger( $.Event( "mousemove", { which: 1, pageX: position.left+100, pageY: position.top+100 } ) );
$first_drop = $(".oe_drop_zone").first();
position = $first_drop.position();
$first_drop.trigger( $.Event( "mouseup", { which: 1, pageX: position.left+20, pageY: position.top+20 } ) );
clearTimeout(droptesttime);
droptesttime = setTimeout(droptest,0);
});

View File

@ -4,6 +4,7 @@
var website = openerp.website;
website.add_template_file('/website/static/src/xml/website.tour.xml');
if (website.EditorBar)
website.EditorBar.include({
tours: [],
start: function () {
@ -17,31 +18,11 @@ website.EditorBar.include({
});
menu.append($menuItem);
});
this.waitRTEReady = false;
this.on('rte:called', this, function () {self.waitRTEReady = true; });
this.on('rte:ready', this, function () {self.waitRTEReady = false;});
var res = this._super();
website.Tour.waitReady.call(this, this.testRunning);
return res;
return this._super();
},
registerTour: function (tour) {
website.Tour.add(tour);
this.tours.push(tour);
},
testRunning: function () {
if (this.waitRTEReady) {
this.on('rte:ready', this, function () {
website.Tour.each(function () {
this.running();
});
});
} else {
website.Tour.each(function () {
this.running();
});
}
}
});
@ -78,23 +59,12 @@ $.ajaxSetup({
}
});
website.Tour = openerp.Class.extend({
steps: [],
defaultDelay: 50, //ms
defaultOverLaps: 5000, //ms
localStorage: window.localStorage,
init: function (url) {
this.tour = new Tour({
name: this.id,
storage: this.tourStorage,
keyboard: false,
template: this.popover(),
onHide: function () {
window.scrollTo(0, 0);
}
});
this.registerSteps();
},
init: function () {},
run: function (automatic) {
this.reset();
@ -143,14 +113,11 @@ website.Tour = openerp.Class.extend({
},
_running: function () {
var stepId = this.localStorage.getItem("tour-"+this.id+"-test");
var automatic = !!this.localStorage.getItem("tour-"+this.id+"-test-automatic");
if (stepId != null) {
if (!this.check(this.step(stepId))) {
var step = this.next(stepId);
stepId = step ? step.stepId : stepId;
}
this.nextStep(stepId, automatic ? this.autoNextStep : null, automatic ? 5000 : null);
this.automatic = !!this.localStorage.getItem("tour-"+this.id+"-test-automatic");
this.registerTour();
this.nextStep(stepId, this.automatic ? this.autoNextStep : null, this.automatic ? this.defaultOverLaps : null);
}
},
@ -187,6 +154,18 @@ website.Tour = openerp.Class.extend({
}
},
registerTour: function () {
this.tour = new Tour({
name: this.id,
storage: this.tourStorage,
keyboard: false,
template: this.popover(),
onHide: function () {
window.scrollTo(0, 0);
}
});
this.registerSteps();
},
registerSteps: function () {
for (var index=0, len=this.steps.length; index<len; index++) {
var step = this.steps[index];
@ -199,8 +178,8 @@ website.Tour = openerp.Class.extend({
step.waitFor = '.oe_overlay_options .oe_options:visible';
}
step._title = step.title;
step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title });
step._title = step._title || step.title;
step.title = this.popoverTitle({ title: step._title });
if (!step.element) step.orphan = true;
if (step.snippet) {
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
@ -219,8 +198,21 @@ website.Tour = openerp.Class.extend({
this.tour.addSteps(this.steps);
},
popoverTitle: function (options) {
try {
return openerp.qweb.render('website.tour_popover_title', options);
} catch (e) {
if (!this.automatic) throw e;
return options.title;
}
},
popover: function (options) {
return openerp.qweb.render('website.tour_popover', options);
try {
return openerp.qweb.render('website.tour_popover', options);
} catch (e) {
if (!this.automatic) throw e;
return "";
}
},
timer: null,
@ -268,7 +260,12 @@ website.Tour = openerp.Class.extend({
self.timer = setTimeout(checkNext, self.defaultDelay);
} else {
self.reset();
throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'");
throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'"
+ '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden")))
+ '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size())
+ '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size())
+ '\n\n' + $("body").html()
);
}
}
checkNext();
@ -291,7 +288,7 @@ website.Tour = openerp.Class.extend({
$(".popover.tour").remove();
// go to step in bootstrap tour
this.tour.goto(index);
if (step.callback) step.callback();
if (step.onload) step.onload();
next = steps.shift();
break;
}
@ -358,7 +355,10 @@ website.Tour = openerp.Class.extend({
} else if (step.sampleText) {
$element.trigger($.Event("keydown", { srcElement: $element }));
if ($element.is("select") || $element.is("input") ) {
if ($element.is("input") ) {
$element.val(step.sampleText);
} if ($element.is("select")) {
$element.find("[value='"+step.sampleText+"'], option:contains('"+step.sampleText+"')").attr("selected", true);
$element.val(step.sampleText);
} else {
$element.html(step.sampleText);
@ -404,7 +404,10 @@ website.Tour.busy = false;
website.Tour.add = function (tour) {
website.Tour.waitReady(function () {
tour = tour.id ? tour : new tour();
website.Tour.tours[tour.id] = tour;
if (!website.Tour.tours[tour.id]) {
website.Tour.tours[tour.id] = tour;
tour.running();
}
});
};
website.Tour.get = function (id) {
@ -435,18 +438,20 @@ website.Tour.waitReady = function (callback) {
});
};
website.Tour.run_test = function (id) {
website.Tour.get(id).run(true);
website.Tour.waitReady(function () {
if (!website.Tour.is_busy()) {
website.Tour.tours[id].run(true);
}
});
};
website.Tour.is_busy = function () {
for (var k in this.localStorage) {
if (!k.indexOf("tour-")) {
return true;
return k;
}
}
return website.Tour.busy;
};
}());

View File

@ -0,0 +1,27 @@
(function () {
var scripts = [];
if (typeof openerp === "undefined") {
scripts.push("/web/static/lib/qweb/qweb2.js");
scripts.push("/web/static/lib/qweb/openerpframework.js");
}
if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file)
scripts.push("/website/static/src/js/website.js");
if (typeof openerp === "undefined" || !openerp.website.Tour)
scripts.push("/website/static/src/js/website.tour.js");
if (typeof Tour === "undefined") {
scripts.push("/website/static/lib/bootstrap-tour/bootstrap-tour.js");
}
for (var i in scripts) {
if (typeof jQuery === "undefined") {
throw new Error("jQuery not found.\nhref: " + window.location.href + "\n\n" + document.body.innerHTML);
}
jQuery.ajax({
async: false,
type: 'GET',
data: null,
url: scripts[i],
dataType: "script",
error: function (a,b,e) {throw e;}
});
}
})();

View File

@ -58,7 +58,6 @@ class WebsiteUiSuite(unittest.TestSuite):
return iter([self])
def run(self, result):
return
# clean slate
if sql_db._Pool is not None:
sql_db._Pool.close_all(sql_db.dsn(tools.config['db_name']))
@ -79,18 +78,21 @@ class WebsiteUiSuite(unittest.TestSuite):
del result._exc_info_to_string
def _run(self, result):
self._test = WebsiteUiTest(self._testfile)
self._test = WebsiteUiTest("%s (as %s)" %
(self._testfile, self._options.get('user') or "Anonymous" if 'user' in self._options else "admin" ))
start_time = time.time()
last_check_time = time.time()
self._options['timeout'] = self._timeout
self._options['port'] = tools.config.get('xmlrpc_port', 80)
self._options['db'] = tools.config.get('db_name', '')
self._options['user'] = 'admin'
self._options['password'] = tools.config.get('admin_passwd', 'admin')
if 'user' not in self._options:
self._options['user'] = 'admin'
self._options['password'] = tools.config.get('admin_passwd', 'admin')
phantom = subprocess.Popen([
'phantomjs',
#'--debug=true',
self._testfile,
json.dumps(self._options)
], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

View File

@ -19,7 +19,7 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) {
}, 100);
}
function run (test) {
function run (test, onload, inject) {
var options = JSON.parse(phantom.args);
var timeout = options.timeout ? Math.round(parseFloat(options.timeout)*1000) : 60000;
@ -56,6 +56,18 @@ function run (test) {
};
page.onConsoleMessage = function(message) {
console.log(message);
try {
var result = JSON.parse(message);
if (result.event === 'success') {
phantom.exit(0);
} else if (result.event === 'console') {
return;
} else {
phantom.exit(1);
}
} catch (exception) {
phantom.exit(1);
}
};
page.onCallback = function(data) {
@ -63,6 +75,22 @@ function run (test) {
test(page, timeout);
}
};
page.onLoadFinished = function(status) {
if (status === "success") {
if (inject) {
if (!inject instanceof Array) {
inject = [inject];
}
for (var k in inject) {
if(!page.injectJs(inject[k])) {
console.log("Can't inject "+inject[k]);
phantom.exit(1);
}
}
}
if (onload) onload(page, timeout);
}
};
var maxRetries = 10;
var retryDelay = 1000; // ms
@ -87,7 +115,32 @@ function run (test) {
});
}
function run_test (testname, options) {
options = options || {};
run(
function start (page, timeout) {
page.evaluate(function () { localStorage.clear(); });
},
function onload (page, timeout) {
waitFor(function clientReady () {
return page.evaluate(function () {
return window.$
&& window.openerp
&& window.openerp.website
&& window.openerp.website.Tour;
});
}, function executeTest () {
page.evaluate(function (testname) {
window.openerp.website.Tour.run_test(testname);
}, testname);
}, timeout);
},
options.inject || null
);
}
module.exports = {
waitFor: waitFor,
run: run
run: run,
run_test: run_test
}

View File

@ -290,6 +290,12 @@
</xpath>
</template>
<template id="debugger" inherit_option_id="website.layout" name="Debugger &amp; Tests">
<xpath expr='//t[@name="layout_head"]' position="after">
<script type="text/javascript" src="/website/static/src/js/website.tour.test.js"></script>
</xpath>
</template>
<template id="login_layout" inherit_id="web.login_layout" name="Website Login Layout">
<xpath expr="t" position="replace">
<t t-call="website.layout">

View File

@ -1,17 +1,3 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
var waitFor = testRunner.waitFor;
testRunner.run(function blogTest (page, timeout) {
page.evaluate(function () { localStorage.clear(); });
waitFor(function clientReady () {
return page.evaluate(function () {
return window.$ && window.openerp && window.openerp.website
&& window.openerp.website.Tour;
});
}, function executeTest () {
page.evaluate(function () {
window.openerp.website.Tour.run_test('blog');
});
}, timeout);
});
testRunner.run_test('blog');

View File

@ -1,17 +1,3 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
var waitFor = testRunner.waitFor;
testRunner.run(function eventTest (page, timeout) {
page.evaluate(function () { localStorage.clear(); });
waitFor(function clientReady () {
return page.evaluate(function () {
return window.$ && window.openerp && window.openerp.website
&& window.openerp.website.Tour;
});
}, function executeTest () {
page.evaluate(function () {
window.openerp.website.Tour.get('event').run(true);
});
}, timeout);
});
testRunner.run_test('event');

View File

@ -0,0 +1,80 @@
(function () {
'use strict';
var website = openerp.website;
website.Tour.EventSaleTest = website.Tour.extend({
id: 'event_buy_tickets',
name: "Try to buy tickets for event",
path: '/event',
testPath: '/(event|shop)',
init: function () {
var self = this;
self.steps = [
{
title: "select event",
element: 'a[href*="/event"]:contains("Open Days in Los Angeles")',
},
{
title: "go to register page",
waitNot: 'a[href*="/event"]:contains("Functional Webinar")',
onload: function () {
// use onload if website_event_track is installed
if (!$('form:contains("Ticket Type")').size()) {
window.location.href = $('a[href*="/event"][href*="/register"]').attr("href");
}
},
},
{
title: "select 2 Standard tickets",
element: 'select[name="ticket-1"]',
sampleText: '2',
},
{
title: "select 3 VIP tickets",
waitFor: 'select[name="ticket-1"] option:contains(2):selected',
element: 'select[name="ticket-2"]',
sampleText: '3',
},
{
title: "Order Now",
waitFor: 'select[name="ticket-2"] option:contains(3):selected',
element: 'button.btn-primary:contains("Order Now")',
},
{
title: "Complete checkout",
waitFor: '#top_menu .my_cart_quantity:contains(5)',
element: 'form[action="/shop/confirm_order/"] button',
onload: function (tour) {
if ($("input[name='name']").val() === "")
$("input[name='name']").val("website_sale-test-shoptest");
if ($("input[name='email']").val() === "")
$("input[name='email']").val("website_event_sale_test_shoptest@websiteeventsaletest.optenerp.com");
$("input[name='phone']").val("123");
$("input[name='street']").val("123");
$("input[name='city']").val("123");
$("input[name='zip']").val("123");
$("select[name='country_id']").val("21");
},
},
{
title: "select payment",
element: '#payment_method label:has(img[title="transfer"]) input',
},
{
title: "Pay Now",
waitFor: '#payment_method label:has(input:checked):has(img[title="transfer"])',
element: '.oe_sale_acquirer_button button[name="submit"]:visible',
},
{
title: "finish",
waitFor: '.oe_website_sale:contains("Thank you for your order")',
}
];
return this._super();
},
});
// for test without editor bar
website.Tour.add(website.Tour.EventSaleTest);
}());

View File

@ -0,0 +1 @@
import test_ui

View File

@ -0,0 +1,10 @@
import openerp.addons.website.tests.test_ui as test_ui
def load_tests(loader, base, _):
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_event_sale_test.js'),
{'redirect': '/page/website.homepage'}))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_event_sale_test.js'),
{'redirect': '/page/website.homepage', 'user': 'demo', 'password': 'demo'}))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_event_sale_test.js'),
{'path': '/', 'user': None}))
return base

View File

@ -0,0 +1,7 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
testRunner.run_test('event_buy_tickets', {
"inject": [
"./../../../website/static/src/js/website.tour.test.js",
"./../../../website_event_sale/static/src/js/website.tour.event_sale.js"]
});

View File

@ -0,0 +1,95 @@
(function () {
'use strict';
var website = openerp.website;
website.Tour.ShopTest = website.Tour.extend({
id: 'shop_buy_product',
name: "Try to buy products",
path: '/shop',
testPath: '/shop',
init: function () {
var self = this;
self.steps = [
{
title: "select ipod",
element: '.oe_product_cart a:contains("iPod")',
},
{
title: "select ipod 32Go",
element: 'input[name="product_id"]:not([checked])',
},
{
title: "click on add to cart",
waitFor: 'input[name="product_id"]:eq(1)[checked]',
element: 'form[action="/shop/add_cart/"] button',
},
{
title: "add suggested",
element: 'form[action="/shop/add_cart/"] button.btn-link:contains("Add to Cart")',
},
{
title: "add one more iPod",
waitFor: '.my_cart_quantity:contains(2)',
element: '#mycart_products tr:contains("iPod: 32 Gb") a.js_add_cart_json:eq(1)',
},
{
title: "remove Headphones",
waitFor: '#mycart_products tr:contains("iPod: 32 Gb") input.js_quantity[value=2]',
element: '#mycart_products tr:contains("Apple In-Ear Headphones") a.js_add_cart_json:first',
},
{
title: "set one iPod",
waitNot: '#mycart_products tr:contains("Apple In-Ear Headphones")',
element: '#mycart_products input.js_quantity',
sampleText: '1',
},
{
title: "go to checkout",
waitFor: '#mycart_products input.js_quantity[value=1]',
element: 'a[href="/shop/checkout/"]',
},
{
title: "test with input error",
element: 'form[action="/shop/confirm_order/"] button',
onload: function (tour) {
$("input[name='phone']").val("");
},
},
{
title: "test without input error",
waitFor: 'form[action="/shop/confirm_order/"] .has-error',
element: 'form[action="/shop/confirm_order/"] button',
onload: function (tour) {
if ($("input[name='name']").val() === "")
$("input[name='name']").val("website_sale-test-shoptest");
if ($("input[name='email']").val() === "")
$("input[name='email']").val("website_sale_test_shoptest@websitesaletest.optenerp.com");
$("input[name='phone']").val("123");
$("input[name='street']").val("123");
$("input[name='city']").val("123");
$("input[name='zip']").val("123");
$("select[name='country_id']").val("21");
},
},
{
title: "select payment",
element: '#payment_method label:has(img[title="transfer"]) input',
},
{
title: "Pay Now",
waitFor: '#payment_method label:has(input:checked):has(img[title="transfer"])',
element: '.oe_sale_acquirer_button button[name="submit"]:visible',
},
{
title: "finish",
waitFor: '.oe_website_sale:contains("Thank you for your order")',
}
];
return this._super();
},
});
// for test without editor bar
website.Tour.add(website.Tour.ShopTest);
}());

View File

@ -26,11 +26,12 @@ $(document).ready(function () {
if (isNaN(value)) value = 0;
openerp.jsonRpc("/shop/set_cart_json/", 'call', {'order_line_id': $input.data('id'), 'set_number': value})
.then(function (data) {
if (!data) {
location.reload();
return;
}
set_my_cart_quantity(data[1]);
$input.val(data[0]);
if (!data[0]) {
location.reload();
}
});
});

View File

@ -1,8 +1,12 @@
import openerp.addons.website.tests.test_ui as test_ui
def load_tests(loader, base, _):
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-add_product-test.js'),
{'redirect': '/page/website.homepage'}))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
{ 'action': 'website.action_website_homepage' }))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test-2.js'),
{ 'action': 'website.action_website_homepage' }))
{'redirect': '/page/website.homepage'}))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
{'redirect': '/page/website.homepage', 'user': 'demo', 'password': 'demo'}))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
{'path': '/', 'user': None}))
return base

View File

@ -0,0 +1,3 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
testRunner.run_test('shop');

View File

@ -1,17 +0,0 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
var waitFor = testRunner.waitFor;
testRunner.run(function websiteSaleTest (page, timeout) {
page.evaluate(function () { localStorage.clear(); });
waitFor(function clientReady () {
return page.evaluate(function () {
return window.$ && window.openerp && window.openerp.website
&& window.openerp.website.Tour;
});
}, function executeTest () {
page.evaluate(function () {
window.openerp.website.Tour.run_test('shop');
});
}, timeout);
});

View File

@ -1,17 +1,7 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
var waitFor = testRunner.waitFor;
testRunner.run(function websiteSaleTest (page, timeout) {
page.evaluate(function () { localStorage.clear(); });
waitFor(function clientReady () {
return page.evaluate(function () {
return window.$ && window.openerp && window.openerp.website
&& window.openerp.website.Tour;
});
}, function executeTest () {
page.evaluate(function () {
window.openerp.website.Tour.run_test('shop_buy_product');
});
}, timeout);
});
testRunner.run_test('shop_buy_product', {
"inject": [
"./../../../website/static/src/js/website.tour.test.js",
"./../../../website_sale/static/src/js/website.tour.sale.js"]
});