[IMP] tour: add a tour to click on all menu items, sub menu items, need action, and views

This commit is contained in:
Christophe Matthieu
2014-08-06 17:22:03 +02:00
parent d71a21bfdb
commit eb23f30c7e
3 changed files with 363 additions and 17 deletions
+67 -17
View File
@@ -329,18 +329,22 @@ var Tour = {
}
console.log(message);
},
logError: function (step, message, all) {
var state = Tour.getState();
message += '\ntour: ' + state.id
+ (step ? '\nstep: ' + step.id + ": '" + (step._title || step.title) + "'" : '' )
+ (all ? '\nhref: ' + window.location.href : '' )
+ (all ? '\nreferrer: ' + document.referrer : '' )
+ (step ? '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) : '' )
+ (step ? '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) : '' )
+ (step ? '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) : '' );
+ (all ? "\nlocalStorage: " + JSON.stringify(localStorage) : '' )
+ (all ? '\n\n' + $("body").html() : '' );
Tour.log(message, true);
},
error: function (step, message) {
var state = Tour.getState();
message += '\n tour: ' + state.id
+ (step ? '\n step: ' + step.id + ": '" + (step._title || step.title) + "'" : '' )
+ '\n href: ' + window.location.href
+ '\n referrer: ' + document.referrer
+ (step ? '\n element: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) : '' )
+ (step ? '\n waitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) : '' )
+ (step ? '\n waitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) : '' )
+ "\n localStorage: " + JSON.stringify(localStorage)
+ '\n\n' + $("body").html();
Tour.log(message, true);
Tour.logError(step, "Error: " + message, true);
Tour.endTour();
},
lists: function () {
@@ -403,7 +407,7 @@ var Tour = {
var state = Tour.getState();
var time = new Date().getTime();
var timer;
var next = state.tour.steps[state.step.id+1];
var next = state.step.next ? Tour.search_step(state.step.next) : state.tour.steps[state.step.id+1];
var overlaps = state.mode === "test" ? Tour.errorDelay : 0;
window.onbeforeunload = function () {
@@ -418,20 +422,65 @@ var Tour = {
clearTimeout(Tour.timer);
if (Tour.check(next)) {
clearTimeout(Tour.currentTimer);
// use an other timeout for cke dom loading
Tour.saveState(state.id, state.mode, state.step.id, 0);
setTimeout(function () {
if (state.step.onend && Tour._goto(state.step.onend())) return;
Tour.nextStep(next);
}, Tour.defaultDelay);
return;
} else if (!overlaps || new Date().getTime() - time < overlaps) {
Tour.timer = setTimeout(checkNext, Tour.defaultDelay);
} else {
return Tour.error(next, "Can't reach the next step");
return;
} else if(next.onerror) {
Tour.logError(next, "Error: Can't reach the next step (call next step onerror)", false);
var id = next.onerror();
if (id) {
if (Tour._goto(id)) return;
if (id === true) {
Tour.nextStep(next);
return;
}
}
}
Tour.error(next, "Can't reach the next step");
return;
}
setTimeout(checkNext, 0);
},
search_step: function (id_or_title) {
var state = Tour.getState();
if (id_or_title !== undefined) {
if (isNaN(id_or_title)) {
for (var k=0; k<state.tour.steps.length; k++) {
if (state.tour.steps[k].title === id_or_title || state.tour.steps[k]._title === id_or_title) {
return state.tour.steps[k];
}
}
} else {
return state.tour.steps[id_or_title];
}
}
return undefined;
},
_goto: function (id_or_title) {
var state = Tour.getState();
if (!state) return true;
if (id_or_title === undefined) return false;
var step = Tour.search_step(id_or_title);
Tour.saveState(state.id, state.mode, step.id, 0);
Tour.nextStep(Tour.getState().step);
return true;
},
nextStep: function (step) {
var state = Tour.getState();
@@ -440,7 +489,7 @@ var Tour = {
}
step = step || state.step;
var next = state.tour.steps[step.id+1];
var next = state.step.next ? Tour.search_step(state.step.next) : state.tour.steps[step.id+1];
if (state.mode === "test" && state.number > 3) {
return Tour.error(next, "Cycling. Can't reach the next step");
@@ -448,14 +497,15 @@ var Tour = {
Tour.saveState(state.id, state.mode, step.id, state.number);
if (step.id !== state.step_id) {
if (state.number === 1) {
Tour.log("Tour '"+state.id+"' Step: '" + (step._title || step.title) + "' (" + (new Date().getTime() - this.time) + "ms)");
}
Tour.autoTogglePopover(true);
if (step.onload) {
step.onload();
// onload a step you can fallback to an other step
if (step.onload && Tour._goto(step.onload())) {
return;
}
if (state.mode === "test") {
+295
View File
@@ -0,0 +1,295 @@
(function () {
'use strict';
function openmenu () {
setTimeout(function () {
$(".collapse:not(.in)").addClass("in");
$(".dropdown:not(.open)").addClass("open");
},3000);
}
openerp.Tour.register({
id: 'test_menu',
name: "Test all menu items",
path: '/web',
mode: 'test',
steps: [
{
title: "begin test",
onload: function () {
localStorage.setItem('active_step', 0);
localStorage.setItem('menu_tested', "[]");
},
},
// log as admin
{
title: "log on as admin",
element: ".oe_login_form button",
onload: function () {
$('input[name="login"], input[name="password"]').val("admin");
},
},
{
title: "load web admin",
waitFor: ".oe_view_manager_body",
onload: function () {
localStorage.setItem('active_step', (+localStorage.getItem('active_step'))+1 );
openmenu();
},
},
{
title: "click on Settings",
element: '.oe_application_menu_placeholder a[data-menu]:contains(Settings)',
waitNot: '.oe_loading:visible, button.oe_form_button:contains(Apply).already_tested',
},
// add technical features to admin user
{
title: "click on User form Admin",
element: '.oe_secondary_menu a:visible:contains(Users)',
waitNot: ".oe_loading:visible",
},
{
title: "click on Admin",
element: '.oe_list_field_cell:contains(Admin)',
},
{
waitFor: '.oe_breadcrumb_item:contains(Admin)',
waitNot: ".oe_loading:visible",
},
{
title: "click on Edit button",
element: 'button.oe_form_button_edit',
},
{
title: "click on Technical Features",
element: 'td:contains(Technical Features) + td input:not(:disabled):visible',
onend: function () {
$('td:contains(Technical Features) + td input:not(:disabled):visible').attr("checked", true);
},
},
{
title: "click on Save User",
waitFor: 'td:contains(Technical Features) + td input:checked:not(:disabled):visible',
element: 'button.oe_form_button_save',
},
// add technical features to demo user
{
title: "click on User",
element: '.oe_secondary_menu a:visible:contains(Users)',
waitFor: 'td:contains(Technical Features) + td input:disabled:visible',
},
{
title: "click on Demo",
element: '.oe_list_field_cell:contains(Demo)',
},
{
waitFor: '.oe_breadcrumb_item:contains(Demo)',
waitNot: ".oe_loading:visible",
},
{
title: "click on Edit button",
element: 'button.oe_form_button_edit',
},
{
title: "click on Technical Features",
element: 'td:contains(Technical Features) + td input:not(:disabled):visible',
onend: function () {
$('td:contains(Technical Features) + td input:not(:disabled):visible').attr("checked", true);
if (localStorage.getItem('active_step') === "2") {
$('input').attr("checked", true);
$('.oe_view_manager_body td:contains(Portal) + td input:visible').attr("checked", null);
$('.oe_view_manager_body td:contains(Public) + td input:visible').attr("checked", null);
$('select').each(function () {
$('option:last', this).attr('selected', true);
});
}
},
},
{
title: "click on Save User",
waitFor: 'td:contains(Technical Features) + td input:checked:not(:disabled):visible',
element: 'button.oe_form_button_save',
onload: function () {
openmenu();
},
},
// log out
{
title: "log out amdin",
waitFor: 'td:contains(Technical Features) + td input:disabled:visible',
element: 'a[data-menu="logout"]',
},
// log as demo
{
title: "log on as demo user",
element: ".oe_login_form button",
onload: function () {
$('input[name="login"], input[name="password"]').val("demo");
},
},
{
title: "load web demo",
waitFor: ".oe_view_manager_body",
onload: function () {
openmenu();
},
next: "check",
},
// click all menu items
{
title: "Click on top menu",
element: '.oe_application_menu_placeholder a[data-menu]:not([data-action-model="ir.actions.act_url"]):not(.already_tested):first',
onload: function () {
var $menu = $(this.element);
console.log("Tour 'test_menu' click on: '"+$menu.text().replace(/^\s+|\s+$/g, '')+"'");
},
onend: function () {
$(this.element).addClass('already_tested');
$('.oe_secondary_submenu').show();
},
next: "check"
},
{
title: "Click on sub menu",
element: '.oe_secondary_menu a:not(.oe_menu_toggler):visible:not(.already_tested):first',
onload: function () {
var $menu = $(this.element);
console.log("Tour 'test_menu' click on: '"+$menu.find('span:first').text().replace(/^\s+|\s+$/g, '')+"'");
},
onend: function () {
$(this.element).addClass('already_tested');
},
next: "check"
},
{
title: "Click on need action",
element: '.oe_secondary_menu a:not(.oe_menu_toggler) div.badge:visible:not(.already_tested):first',
onload: function () {
var $menu = $(this.element);
console.log("Tour 'test_menu' click on need action: '"+$menu.parent().find('span:first').text().replace(/^\s+|\s+$/g, '')+"'");
},
onend: function () {
$(this.element).addClass('already_tested');
},
next: "check"
},
{
title: "Click on switch view",
element: '.oe_view_manager_switch li a:not(.already_tested):first',
onload: function () {
var $menu = $(this.element);
console.log("Tour 'test_menu' click on switch view: '"+$menu.data('original-title')+"'");
},
onend: function () {
$(this.element).addClass('already_tested');
},
next: "check"
},
{
title: "check",
waitNot: "body:has("+
".oe_view_manager_body > *:visible:not(:empty).already_loaded:not(.oe_searchview_drawer_container), "+
".oe_form_sheetbg.already_loaded"+
"):not(:has(.modal))",
wait: 100,
onerror: function () {
return "Select next action";
}
},
{
title: "add class already tested",
waitNot: "body.oe_wait",
onload: function () {
var tested = JSON.parse(localStorage.getItem('menu_tested') || "[]");
$('.oe_application_menu_placeholder li.active [data-menu]').addClass('already_tested');
var $menu = $('.oe_secondary_menus_container li.active [data-action-model]');
var model = $menu.data('action-model');
var id = $menu.data('action-id');
var key = '.oe_secondary_menus_container li [data-action-model="'+model+'"][data-action-id="'+id+'"]';
if (tested.indexOf(key) === -1) {
tested.push(key);
}
var type = $('.oe_view_manager_switch li.active [data-view-type]').data('view-type');
var key = 'body:has(.oe_secondary_menus_container li.active [data-action-model="' + model + '"][data-action-id="' + id + '"]) '+
'.oe_view_manager_switch li [data-view-type="'+type+'"]';
if (tested.indexOf(key) === -1) {
tested.push(key);
}
localStorage.setItem('menu_tested', JSON.stringify(tested));
$(tested.join(",")).addClass('already_tested');
$(".oe_view_manager_body > *:visible:not(:empty), .oe_form_sheet").addClass("already_loaded");
$('.oe_view_manager_switch li.active a').addClass('already_tested');
},
wait: 250, // delay to remove wrong-positive
onerror: function () {
return "Select next action";
}
},
{
title: "Select next action",
onload: function () {
if ($(".oe_error_detail").size()) {
console.log("Tour 'test_menu' has detected an error.");
}
if ($(".oe_dialog_warning").size()) {
console.log("Tour 'test_menu' has detected a warning.");
}
$('.modal').modal('hide').remove();
var steps = ["Click on switch view", "Click on sub menu", "Click on need action", "Click on top menu"];
for (var k in steps) {
var step = openerp.Tour.search_step(steps[k]);
if($(step.element).size()) {
return step.id;
}
}
openmenu();
},
},
// log out and re try
{
title: "log out",
element: 'a[data-menu="logout"]',
onend: function () {
if (localStorage.getItem('active_step') == "1") {
return "log on as admin";
}
},
},
{
title: "finish",
waitFor: "form.oe_login_form",
onload: function () {
localStorage.removeItem('active_step');
localStorage.removeItem('menu_tested');
},
}
]
});
}());
+1
View File
@@ -23,6 +23,7 @@
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
<script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script>
<script type="text/javascript" src="/web/static/src/js/tour.js"></script>
<script type="text/javascript" src="/web/static/test/menu.js"></script>
<link rel="stylesheet" href="/web/static/lib/fontawesome/css/font-awesome.css"/>
</template>