}
console.log(message);
},
- error: function (step, message) {
+ logError: function (step, message, all) {
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();
+ 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();
+ Tour.logError(step, "Error: " + message, true);
Tour.endTour();
},
lists: function () {
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 () {
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();
}
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");
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") {
--- /dev/null
+(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');
+ },
+ }
+ ]
+ });
+
+}());