From eb23f30c7e3bcb1fa19c9a9f9d0291d802abe462 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 6 Aug 2014 17:22:03 +0200 Subject: [PATCH] [IMP] tour: add a tour to click on all menu items, sub menu items, need action, and views --- addons/web/static/src/js/tour.js | 84 +++++-- addons/web/static/test/menu.js | 295 +++++++++++++++++++++++ addons/web/views/webclient_templates.xml | 1 + 3 files changed, 363 insertions(+), 17 deletions(-) create mode 100644 addons/web/static/test/menu.js diff --git a/addons/web/static/src/js/tour.js b/addons/web/static/src/js/tour.js index fec189e06f5..0a8ffe7d7ee 100644 --- a/addons/web/static/src/js/tour.js +++ b/addons/web/static/src/js/tour.js @@ -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 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") { diff --git a/addons/web/static/test/menu.js b/addons/web/static/test/menu.js new file mode 100644 index 00000000000..3f0bd8f1891 --- /dev/null +++ b/addons/web/static/test/menu.js @@ -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'); + }, + } + ] + }); + +}()); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index bdb1ed5c162..06c1938bc75 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -23,6 +23,7 @@ +