From 427bc242fb819a6ccfbd0b778c30c1cede9e15ad Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:00:08 +0200 Subject: [PATCH 01/10] [IMP] point_of_sale: convert tours to use web_tour.tour --- addons/point_of_sale/static/src/js/tests.js | 79 ++++++++++----------- addons/point_of_sale/tests/test_frontend.py | 4 +- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/addons/point_of_sale/static/src/js/tests.js b/addons/point_of_sale/static/src/js/tests.js index e73a5b8eed8..0c578088b20 100644 --- a/addons/point_of_sale/static/src/js/tests.js +++ b/addons/point_of_sale/static/src/js/tests.js @@ -1,15 +1,16 @@ odoo.define('point_of_sale.Tour', function (require) { "use strict"; - var Tour = require('web.Tour'); + var tour = require("web_tour.tour"); function add_product_to_order(product_name) { return [{ - title: 'buy ' + product_name, - element: '.product-list .product-name:contains("' + product_name + '")', + content: 'buy ' + product_name, + trigger: '.product-list .product-name:contains("' + product_name + '")', }, { - title: 'the ' + product_name + ' have been added to the order', - waitFor: '.order .product-name:contains("' + product_name + '")', + content: 'the ' + product_name + ' have been added to the order', + trigger: '.order .product-name:contains("' + product_name + '")', + run: function () {}, // it's a check }]; } @@ -18,8 +19,8 @@ odoo.define('point_of_sale.Tour', function (require) { for (i = 0; i < amount_str.length; ++i) { current_char = amount_str[i]; steps.push({ - title: 'press ' + current_char + ' on payment keypad', - element: keypad_selector + ' .input-button:contains("' + current_char + '"):visible' + content: 'press ' + current_char + ' on payment keypad', + trigger: keypad_selector + ' .input-button:contains("' + current_char + '"):visible' }); } @@ -36,43 +37,44 @@ odoo.define('point_of_sale.Tour', function (require) { function verify_order_total(total_str) { return [{ - title: 'order total contains ' + total_str, - waitFor: '.order .total .value:contains("' + total_str + '")', + content: 'order total contains ' + total_str, + trigger: '.order .total .value:contains("' + total_str + '")', + run: function () {}, // it's a check }]; } function goto_payment_screen_and_select_payment_method() { return [{ - title: "go to payment screen", - element: '.button.pay', + content: "go to payment screen", + trigger: '.button.pay', }, { - title: "pay with cash", - element: '.paymentmethod:contains("Cash")', + content: "pay with cash", + trigger: '.paymentmethod:contains("Cash")', }]; } function finish_order() { return [{ - title: "validate the order", - element: '.button.next:visible', + content: "validate the order", + trigger: '.button.next:visible', }, { - title: "verify that the order is being sent to the backend", - waitFor: ".js_connecting:visible", + content: "verify that the order is being sent to the backend", + trigger: ".js_connecting:visible", + run: function () {}, // it's a check }, { - title: "verify that the order has been succesfully sent to the backend", - waitFor: ".js_connected:visible", + content: "verify that the order has been succesfully sent to the backend", + trigger: ".js_connected:visible", + run: function () {}, // it's a check }, { - title: "next order", - element: '.button.next:visible', + content: "next order", + trigger: '.button.next:visible', }]; } var steps = [{ - title: 'wait for loading screen', - waitFor: '.loader' - }, { - title: 'waiting for loading to finish', - waitFor: '.loader:hidden', + content: 'waiting for loading to finish', + trigger: '.o_main_content:has(.loader:hidden)', + run: function () {}, // it's a check }]; steps = steps.concat(add_product_to_order('Peaches')); @@ -84,11 +86,13 @@ odoo.define('point_of_sale.Tour', function (require) { steps = steps.concat(generate_payment_screen_keypad_steps("12.20")); steps = steps.concat([{ - title: "verify tendered", - waitFor: '.col-tendered:contains("12.20")', + content: "verify tendered", + trigger: '.col-tendered:contains("12.20")', + run: function () {}, // it's a check }, { - title: "verify change", - waitFor: '.col-change:contains("2.00")', + content: "verify change", + trigger: '.col-change:contains("2.00")', + run: function () {}, // it's a check }]); steps = steps.concat(finish_order()); @@ -102,18 +106,13 @@ odoo.define('point_of_sale.Tour', function (require) { steps = steps.concat(finish_order()); steps = steps.concat([{ - title: "close the Point of Sale frontend", - element: ".header-button", + content: "close the Point of Sale frontend", + trigger: ".header-button", }, { - title: "confirm closing the frontend", - element: ".header-button", + content: "confirm closing the frontend", + trigger: ".header-button", }]); - Tour.register({ - id: 'pos_basic_order', - name: 'Complete a basic order trough the Front-End', - path: '/pos/web', - steps: steps, - }); + tour.register('pos_basic_order', { test: true, url: '/pos/web' }, steps); }); diff --git a/addons/point_of_sale/tests/test_frontend.py b/addons/point_of_sale/tests/test_frontend.py index 885b5af6d80..60f8fa19398 100644 --- a/addons/point_of_sale/tests/test_frontend.py +++ b/addons/point_of_sale/tests/test_frontend.py @@ -58,8 +58,8 @@ class TestUi(odoo.tests.HttpCase): cr.release() self.phantom_js("/pos/web", - "odoo.__DEBUG__.services['web.Tour'].run('pos_basic_order', 'test')", - "odoo.__DEBUG__.services['web.Tour'].tours.pos_basic_order", + "odoo.__DEBUG__.services['web_tour.tour'].run('pos_basic_order')", + "odoo.__DEBUG__.services['web_tour.tour'].tours.pos_basic_order.ready", login="admin") for order in env['pos.order'].search([]): From 4ba425583ea19433866f634b5fbc4cc5ad1b471f Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:01:03 +0200 Subject: [PATCH 02/10] [IMP] survey: convert tours to use web_tour.tour --- .../survey/static/src/js/tour_test_survey.js | 207 +++++++++--------- addons/survey/tests/test_survey_ui.py | 11 +- 2 files changed, 107 insertions(+), 111 deletions(-) diff --git a/addons/survey/static/src/js/tour_test_survey.js b/addons/survey/static/src/js/tour_test_survey.js index a3ee49244fc..e459336679a 100644 --- a/addons/survey/static/src/js/tour_test_survey.js +++ b/addons/survey/static/src/js/tour_test_survey.js @@ -1,198 +1,193 @@ odoo.define('survey.tour_test_survey', function (require) { 'use strict'; -var Core = require('web.core'); -var Tour = require('web.Tour'); -var _t = Core._t; + +var tour = require('web_tour.tour'); -Tour.register({ - id: 'test_survey', - name: _t("try to create and fill survey"), - path: '/survey/start/user-feedback-form-1/phantom', - mode: 'test', - steps: [ +tour.register('test_survey', { test: true, url: '/survey/start/user-feedback-form-1/phantom' }, + [ // Page-1 { - title: "Clicking on Start Survey", - element: 'a.btn.btn-primary.btn-lg:contains("Start Survey")', + content: "Clicking on Start Survey", + trigger: 'a.btn.btn-primary.btn-lg:contains("Start Survey")', }, // Question: Where do you develop your new features? { - title: "Selecting answer 'Yes, I use a version < 7.0'", - element: 'select[name="1_1_1"]', - sampleText:'1', + content: "Selecting answer 'Yes, I use a version < 7.0'", + trigger: 'select[name="1_1_1"]', + run: 'text 1', }, // Question: Which modules are you using/testing? { - title: "Ticking answer 'Sales Management'", - element: 'input[name="1_1_2_5"][value="5"]', - sampleText:'5', + content: "Ticking answer 'Sales Management'", + trigger: 'input[name="1_1_2_5"][value="5"]', + run: 'text 5', }, { - title: "Clicking on Next Page", - element: 'button[value="next"]', + content: "Clicking on Next Page", + trigger: 'button[value="next"]', }, // Page-2 // Question: What do you think about the documentation available on doc.odoo.com? { - title: "For 'It is up-to-date' checking 'Totally disagree'", - element: 'input[name="1_2_3_15"][value="11"]', - sampleText:'11', + content: "For 'It is up-to-date' checking 'Totally disagree'", + trigger: 'input[name="1_2_3_15"][value="11"]', + run: 'text 11', }, { - title: "For 'It helps in the beginning' ckecking 'Disagree'", - element: 'input[name="1_2_3_16"][value="12"]', - sampleText:'12', + content: "For 'It helps in the beginning' ckecking 'Disagree'", + trigger: 'input[name="1_2_3_16"][value="12"]', + run: 'text 12', }, { - title: "For 'I use the contextual help in Odoo' checking 'Agree'", - element: 'input[name="1_2_3_17"][value="13"]', - sampleText:'13', + content: "For 'I use the contextual help in Odoo' checking 'Agree'", + trigger: 'input[name="1_2_3_17"][value="13"]', + run: 'text 13', }, { - title: "For 'It is complete' checking 'Totally disagree'", - element: 'input[name="1_2_3_18"][value="11"]', - sampleText:'11', + content: "For 'It is complete' checking 'Totally disagree'", + trigger: 'input[name="1_2_3_18"][value="11"]', + run: 'text 11', }, { - title: "For 'It is clear' checking 'Disagree'", - element: 'input[name="1_2_3_19"][value="12"]', - sampleText:'12', + content: "For 'It is clear' checking 'Disagree'", + trigger: 'input[name="1_2_3_19"][value="12"]', + run: 'text 12', }, // Question: What do you think about the process views of Odoo, available in the web client ? { - title: "For 'They help new users to understand Odoo' checking 'Totally disagree'", - element: 'input[name="1_2_4_24"][value="20"]', - sampleText:'20', + content: "For 'They help new users to understand Odoo' checking 'Totally disagree'", + trigger: 'input[name="1_2_4_24"][value="20"]', + run: 'text 20', }, { - title: "For 'They are clean and correct' checking 'Totally disagree'", - element: 'input[name="1_2_4_25"][value="20"]', - sampleText:'20', + content: "For 'They are clean and correct' checking 'Totally disagree'", + trigger: 'input[name="1_2_4_25"][value="20"]', + run: 'text 20', }, { - title: "For 'They are useful on a daily usage' checking 'Totally disagree'", - element: 'input[name="1_2_4_26"][value="20"]', - sampleText:'20', + content: "For 'They are useful on a daily usage' checking 'Totally disagree'", + trigger: 'input[name="1_2_4_26"][value="20"]', + run: 'text 20', }, { - title: "For 'A process is defined for all enterprise flows' checking 'Disagree'", - element: 'input[name="1_2_4_27"][value="21"]', - sampleText:'21', + content: "For 'A process is defined for all enterprise flows' checking 'Disagree'", + trigger: 'input[name="1_2_4_27"][value="21"]', + run: 'text 21', }, { - title: "For 'It's easy to find the process you need' checking 'Agree'", - element: 'input[name="1_2_4_28"][value="22"]', - sampleText:'22', + content: "For 'It's easy to find the process you need' checking 'Agree'", + trigger: 'input[name="1_2_4_28"][value="22"]', + run: 'text 22', }, // Question: Do you have suggestions on how to improve the process view? { - title: "Writing answer", - element: 'textarea[name="1_2_5"]', - sampleText:'I do not want to provide any suggestions.', + content: "Writing answer", + trigger: 'textarea[name="1_2_5"]', + run: 'text I do not want to provide any suggestions.', }, // Question: What do you think about the structure of the menus? { - title: "Checking 'It can be improved'", - element: 'input[name="1_2_6_30"][value="30"]', - sampleText:'30', + content: "Checking 'It can be improved'", + trigger: 'input[name="1_2_6_30"][value="30"]', + run: 'text 30', }, // Question: What do you think about the groups of users? { - title: "For 'The security rules defined on groups are useful' checking 'Agree'", - element: 'input[name="1_2_7_36"][value="32"]', - sampleText:'32', + content: "For 'The security rules defined on groups are useful' checking 'Agree'", + trigger: 'input[name="1_2_7_36"][value="32"]', + run: 'text 32', }, { - title: "For 'Those security rules are standard and can be used out-of-the-box in most cases' checking 'Totally agree'", - element: 'input[name="1_2_7_37"][value="35"]', - sampleText:'35', + content: "For 'Those security rules are standard and can be used out-of-the-box in most cases' checking 'Totally agree'", + trigger: 'input[name="1_2_7_37"][value="35"]', + run: 'text 35', }, { - title: "For 'The 'Usability/Extended View' group helps in daily work' checking 'Totally agree'", - element: 'input[name="1_2_7_38"][value="35"]', - sampleText:'35', + content: "For 'The 'Usability/Extended View' group helps in daily work' checking 'Totally agree'", + trigger: 'input[name="1_2_7_38"][value="35"]', + run: 'text 35', }, { - title: "For 'The 'Usability/Extended View' group hides only optional fields' checking 'Totally agree'", - element: 'input[name="1_2_7_39"][value="33"]', - sampleText:'33', + content: "For 'The 'Usability/Extended View' group hides only optional fields' checking 'Totally agree'", + trigger: 'input[name="1_2_7_39"][value="33"]', + run: 'text 33', }, { - title: "For 'The groups set on menu items are relevant' checking 'Totally disagree'", - element: 'input[name="1_2_7_40"][value="32"]', - sampleText:'32', + content: "For 'The groups set on menu items are relevant' checking 'Totally disagree'", + trigger: 'input[name="1_2_7_40"][value="32"]', + run: 'text 32', }, // Question: What do you think about the structure of the menus? { - title: "Checking 'There are too few groups defined, security isn't accurate enough'", - element: 'input[name="1_2_8"][value="42"]', - sampleText:'42', + content: "Checking 'There are too few groups defined, security isn't accurate enough'", + trigger: 'input[name="1_2_8"][value="42"]', + run: 'text 42', }, // Question: What do you think about configuration wizards? { - title: "For 'Descriptions and help tooltips are clear enough' checking 'Agree'", - element: 'input[name="1_2_9_48"][value="46"]', - sampleText:'46', + content: "For 'Descriptions and help tooltips are clear enough' checking 'Agree'", + trigger: 'input[name="1_2_9_48"][value="46"]', + run: 'text 46', }, { - title: "For 'Configuration wizard exists for each important setting' checking 'Agree'", - element: 'input[name="1_2_9_49"][value="46"]', - sampleText:'46', + content: "For 'Configuration wizard exists for each important setting' checking 'Agree'", + trigger: 'input[name="1_2_9_49"][value="46"]', + run: 'text 46', }, { - title: "For 'Extra modules proposed are relevant' checking 'Totally agree'", - element: 'input[name="1_2_9_50"][value="47"]', - sampleText:'47', + content: "For 'Extra modules proposed are relevant' checking 'Totally agree'", + trigger: 'input[name="1_2_9_50"][value="47"]', + run: 'text 47', }, { - title: "For 'Running the configuration wizards is a good way to spare time' checking 'Totally disagree'", - element: 'input[name="1_2_9_51"][value="44"]', - sampleText:'44', + content: "For 'Running the configuration wizards is a good way to spare time' checking 'Totally disagree'", + trigger: 'input[name="1_2_9_51"][value="44"]', + run: 'text 44', }, { - title: "Clicking on Next Page", - element: 'button[value="next"]', + content: "Clicking on Next Page", + trigger: 'button[value="next"]', }, // Page-3 // Question: How do you contribute or plan to contribute to Odoo? { - title: "Checking 'I would like to contribute but I don not know how?'", - element: 'input[name="1_3_10_53"][value="53"]', - sampleText:'53', + content: "Checking 'I would like to contribute but I don not know how?'", + trigger: 'input[name="1_3_10_53"][value="53"]', + run: 'text 53', }, // Question: Do you have a proposition to help people to contribute? { - title: "Writing answer", - element: 'textarea[name="1_3_11"]', - sampleText:'No. I do not have any proposition to help people to contribute.', + content: "Writing answer", + trigger: 'textarea[name="1_3_11"]', + run: 'text No. I do not have any proposition to help people to contribute.', }, // Question: Do you have a proposition to attract new contributors? { - title: "Writing answer", - element: 'textarea[name="1_3_12"]', - sampleText:'No. I do not have any proposition to Attract new contributors.', + content: "Writing answer", + trigger: 'textarea[name="1_3_12"]', + run: 'text No. I do not have any proposition to Attract new contributors.', }, { - title: "Clicking on Next Page", - element: 'button[value="next"]', + content: "Clicking on Next Page", + trigger: 'button[value="next"]', }, // Page-4 // Question: Where do you develop your new features? { - title: "Checking 'I host them on my own website'", - element: 'input[name="1_4_13_59"][value="59"]', - sampleText:'59', + content: "Checking 'I host them on my own website'", + trigger: 'input[name="1_4_13_59"][value="59"]', + run: 'text 59', }, { - title: "Finish Survey", - element: 'button[value="finish"]', + content: "Finish Survey", + trigger: 'button[value="finish"]', }, { - title: "Thank you", - element: 'h1:contains("Thank you!")', + content: "Thank you", + trigger: 'h1:contains("Thank you!")', } ] -}); +); }); diff --git a/addons/survey/tests/test_survey_ui.py b/addons/survey/tests/test_survey_ui.py index bea83b1ea7e..8c1b4616eb0 100644 --- a/addons/survey/tests/test_survey_ui.py +++ b/addons/survey/tests/test_survey_ui.py @@ -2,15 +2,16 @@ import odoo.tests # Part of Odoo. See LICENSE file for full copyright and licensing details. -@odoo.tests.common.at_install(False) -@odoo.tests.common.post_install(True) class TestUi(odoo.tests.HttpCase): + post_install = True + at_install = False + def test_01_admin_survey_tour(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('test_survey', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.test_survey", login="admin") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('test_survey')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_survey.ready", login="admin") def test_02_demo_survey_tour(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('test_survey', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.test_survey", login="demo") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('test_survey')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_survey.ready", login="demo") def test_03_public_survey_tour(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('test_survey', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.test_survey") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('test_survey')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_survey.ready") From 0f8f68dfa75ea077fb8e5aaff0e11ea99b446303 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:01:16 +0200 Subject: [PATCH 03/10] [IMP] web_editor: convert tours to use web_tour.tour --- addons/web_editor/static/src/js/tour.rte.js | 714 +++++++++----------- addons/web_editor/tests/test_ui.py | 4 +- 2 files changed, 324 insertions(+), 394 deletions(-) diff --git a/addons/web_editor/static/src/js/tour.rte.js b/addons/web_editor/static/src/js/tour.rte.js index 1e0093f80c0..0575e2f858e 100644 --- a/addons/web_editor/static/src/js/tour.rte.js +++ b/addons/web_editor/static/src/js/tour.rte.js @@ -1,398 +1,328 @@ odoo.define('web_editor.tour', function (require) { -'use strict'; + "use strict"; -var core = require('web.core'); -var Tour = require('web.Tour'); -var base = require('web_editor.base'); -var snippet_editor = require('web_editor.snippet.editor'); + var tour = require("web_tour.tour"); + var base = require("web_editor.base"); + var snippet_editor = require('web_editor.snippet.editor'); -var _t = core._t; + var click_event = function (el, type) { + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent(type, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, el); + el.dispatchEvent(evt); + }; -base.ready().done(function () { - -var click_event = function (el, type) { - var evt = document.createEvent("MouseEvents"); - evt.initMouseEvent(type, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, el); - el.dispatchEvent(evt); -}; - -Tour.register({ - id: 'rte', - name: "Test RTE", - mode: 'test', - path: '/web_editor/field/html?debug&callback=FieldTextHtml_0&enable_editor=1&datarecord=%7B%7D', - steps: [ - { - title: "Change html for this test", - onload: function () { - var html = '\n'+ - '
\n'+ - '
\n'+ - '
\n'+ - '
\n'+ - '

Batnae municipium in Anthemusia

\n'+ - '

Batnae municipium in Anthemusia conditum Macedonum manu priscorum ab Euphrate flumine brevi spatio disparatur, refertum mercatoribus opulentis, ubi annua sollemnitate prope Septembris initium mensis ad.

\n'+ - '

Quam quidem partem accusationis admiratus sum et moleste tuli potissimum esse Atratino datam. Neque enim decebat neque aetas.

\n'+ - '

Et hanc quidem praeter oppida multa duae civitates exornant Seleucia opus Seleuci regis, et Claudiopolis quam deduxit coloniam Claudius Caesar. Isaura enim antehac nimium potens, olim subversa ut rebellatrix.

'+ - '

Harum trium sententiarum nulli prorsus assentior.

\n'+ - '
\n'+ - '
\n'+ - ' Odoo text and image block\n'+ - '
\n'+ - '
\n'+ - '
\n'; - $("#editable_area").html(html); - } - }, - { - element: '#editable_area > section .row > div:first', - title: "simulate triple click and change text bg-color", - onload: function () { - var $el = $(this.element); - var $h1 = $('h1', $el); - $.summernote.core.range.create($h1[0].firstChild, 0, $('p', $el)[0], 0).select(); - click_event($h1[0], 'mouseup'); - } - }, - { - waitFor: '#editable_area > section .row > div:first', - element: '.note-popover button[data-event="color"]:visible', - title: "change text bg-color after triple click", - }, - { - waitFor: '#editable_area > section .row > div:first:not(:has(p font)) h1 font', - element: '.note-color button.dropdown-toggle:visible', - title: "change selection to change text color", - onload: function () { - var $el = $('#editable_area > section .row > div:first:not(:has(p font)) h1 font'); - $.summernote.core.range.create($el[0].firstChild, 5, $el[0].firstChild, 10).select(); - click_event($el[0], 'mouseup'); - } - }, - { - element: ".dropdown-menu:visible .btn-group:last .note-color-row:eq(1) button[data-event=foreColor]:first", - title: "change text color", - }, - { - waitFor: '#editable_area > section .row > div:first h1 font:eq(2)', - element: '.note-color button.dropdown-toggle:visible', - title: "change selection to change text bg-color again", - onload: function () { - var $el = $('#editable_area > section .row > div:first h1 font:eq(2)'); - $.summernote.core.range.create($el.prev()[0].firstChild, 3, $el[0].firstChild, 10).select(); - click_event($el.prev()[0], 'mouseup'); - } - }, - { - element: ".dropdown-menu:visible .btn-group:first .note-color-row:eq(0) button[data-event=backColor]:first", - title: "change text backColor again", - }, - { - waitFor: '#editable_area > section .row > div:first h1 font:eq(4)', - element: '.note-color button.dropdown-toggle:visible:first', - title: "change selection (h1 and p) to change text color with class", - onload: function () { - var $el = $('#editable_area > section .row > div:first h1 font:eq(4)'); - $.summernote.core.range.create($el.prev()[0].firstChild, 3, $el.parent("h1").next("p")[0].firstChild, 30).select(); - click_event($el.prev()[0], 'mouseup'); - } - }, - { - waitFor: ".dropdown-menu:visible", - element: ".dropdown-menu:visible .btn-group:last .note-color-row:eq(0) button[data-event=foreColor]:first", - title: "change text foreColor again", - }, - { - waitFor: '#editable_area > section .row > div:first p font', - element: '.o_editable.note-editable.o_dirty', - title: "delete selection", - keydown: 46 // delete - }, - { - waitFor: '#editable_area > section .row > div:first:not(:has(p font)) h1', - element: '.o_editable.note-editable.o_dirty', - title: "clean and delete (backspace) an other selection", - onload: function () { - var $el = $(this.waitFor); - $.summernote.core.range.createFromNode($el.next("p")[0]).clean(); - $.summernote.core.range.create($el.find('font:containsExact(ici)')[0].firstChild, 1, $el.next().next()[0].firstChild, 5).select(); - click_event($el.find('font:last')[0], 'mouseup'); - }, - keydown: 8 // backspace - }, - { - waitFor: '#editable_area > section .row > div:first:has( font:last:containsExact(i) ):has( p:first:containsRegex(/^uam/) ) h1', - element: '.o_editable.note-editable.o_dirty', - title: "delete an other selection", - onload: function () { - var $el = $(this.waitFor); - $.summernote.core.range.create($el.find('font:first')[0].firstChild, 3, $el.next("p")[0].childNodes[2], 8).select(); - click_event($el.find('font:first')[0], 'mouseup'); - }, - keydown: 46 - }, - { - waitFor: '#editable_area > section .row > div:first:has( font:last:containsExact(Bat) )', - element: '.note-image-popover button[data-event="undo"]', - title: "undo", - }, - { - waitFor: '#editable_area > section .row > div:first:has( font:last:containsExact(i) )', - element: '.note-air-popover button[data-event="undo"]', - title: "undo again", - }, - { - waitFor: '#editable_area > section .row > div:first:not(:has(p font)) h1', - element: '.o_editable.note-editable.o_dirty', - title: "delete (backspace) after undo", - keydown: 8 // backspace - }, - { - waitFor: '#editable_area > section .row > div:first:has( font:last:containsExact(i) ):has( p:first:containsRegex(/^uam/) )', - element: '#editable_area > section .row > div:first img[style*="25%"]', - title: "click on image", - }, - { - element: '.note-image-popover:visible button[data-event="resize"][data-value="0.5"]', - title: "Click on resize half", - }, - { - waitFor: '#editable_area > section .row > div:first img[style*="50%"]', - element: '.note-image-popover:visible button[data-event="showImageDialog"]', - title: "Click on edit picture", - }, - { - waitFor: '.modal #editor-media-image', - element: '.modal a[data-toggle="tab"]:contains(Pictogram)', - title: "Click on pictogram tab", - }, - { - element: '#editor-media-icon.active span.fa:first', - title: "select a pictogram", - }, - { - waitFor: '#editor-media-icon.active span.o_selected', - element: '.modal button.o_save_button', - title: "save pictogram", - }, - { - element: '.note-image-popover button[data-event="resizefa"][data-value="3"]', - title: "select a size for the pictogram", - }, - { - waitFor: '#wrapwrap span.fa-3x', - element: '.note-image-popover:visible button[data-event="floatMe"][data-value="right"]', - title: "click on float right", - }, - { - waitFor: '#editable_area > section .row > div:first span.fa.pull-right', - element: '.note-image-popover:visible button[data-event="showLinkDialog"]', - title: "click on create link", - }, - { - waitFor: '.modal a#link-preview:containsRegex(/^]+><\\/span>$/) > span.fa.fa-3x.pull-right', - element: '.modal .dropdown:has(.link-style) a[data-toggle="dropdown"]', - title: "click on color style", - }, - { - element: '.modal .dropdown ul label.btn-success', - title: "choose success style", - }, - // { - // waitFor: '.modal a#link-preview.btn:containsRegex(/^]+><\\/span>$/)', - // element: '.modal .select2-container.url-source a.select2-choice', - // title: "click to choose an internal page", - // }, - // { - // element: '.select2-drop:visible .select2-search input', - // title: "search 'contact'", - // sampleText: "contact", - // }, - // { - // element: '.select2-drop:visible .select2-results .select2-result div:contains(/page/)', - // title: "select /page/contactus", - // }, - { - // waitNot: '.select2-drop:visible', - element: '#link-text', - title: "change text label", - sampleText: "ABC[IMG] DEF", - }, - { - waitFor: '.modal a#link-preview.btn', - element: '#link-external', - sampleText: "http://www.odoo.com", - title: "insert a link url", - }, - { - waitFor: '.modal a#link-preview.btn:containsRegex(/^ABC]+><\\/span> DEF$/)', - element: '.modal button.o_save_button', - title: "save link", - }, - { - waitNot: '#link-preview', - waitFor: 'a.btn[href^="http://"]:has(span.fa.fa-3x.pull-right)', - element: '#editable_area > section .row > div:last img', - title: "click on other picture", - }, - { - waitFor: '#editable_area > section .row > div:first span.fa.pull-right', - element: '.note-image-popover:visible button[data-event="showLinkDialog"]', - title: "click on create link again", - }, - { - waitFor: '.modal a#link-preview:containsRegex(/^]+>$/)', - element: '.modal .dropdown:has(.link-style) a[data-toggle="dropdown"]', - title: "click on color style again", - }, - { - element: '.modal .dropdown ul label.btn-success', - title: "choose success style", - }, - { - waitFor: '.modal a#link-preview.btn', - element: '#link-external', - sampleText: "test@test.test", - title: "insert an email", - }, - { - waitFor: '.modal a#link-preview.btn[href="mailto:test@test.test"]', - element: '.modal button.o_save_button', - title: "save link", - }, - { - waitNot: '#link-preview', - waitFor: '#editable_area > section .row > div:eq(1) > a > img', - element: '#editable_area > section .row > div:first p:eq(2)', - title: "triple enter then double backspace", - keydown: [66, 13, 66, 13, 13, 8, 8], // B enter B enter enter backspace backspace - onload: function () { - var p = $(this.element)[0].firstChild; - $.summernote.core.range.create(p, p.textContent.length, p, p.textContent.length).select(); - click_event(p, 'mouseup'); - }, - }, - { - waitNot: '#editable_area > section .row > div:first p:eq(4), #editable_area > section .row > div:eq(3)', - waitFor: '#editable_area > section .row > div:first p:eq(3)', - title: "add ul content", - onload: function () { - var $el = $('#editable_area > section .row > div:first'); - var html = '
    '+ - '\n
  • Batnae municipium.

  • '+ - '\n
  • Seleucia praeter.
  • '+ - '\n
  • Et hanc quidem.

  • '+ - '\n
'; - $el.append(html); - var node = $el.find('ul li p:last')[0].firstChild; - $.summernote.core.range.create(node, 6).select(); - click_event(node, 'mouseup'); - } - }, - { - waitFor: '#editable_area > section .row > div:first ul li p:first', - element: '.note-air-popover .note-style button.dropdown-toggle', - title: "click on style dropdown", - }, - { - element: '.note-air-popover .note-style ul:visible a[data-value="h3"]', - title: "select h3", - onload: function () { - var node = $('#editable_area > section .row > div:first ul li p:last')[0].firstChild; - $.summernote.core.range.create(node, 0).select(); - click_event(node, 'mouseup'); - } - }, - { - element: '#editable_area > section .row > div:first > ul > li > h3', - title: "double tabulation", - keydown: [9, 9] // tabulation - }, - { - waitFor: '#editable_area > section .row > div:first ul > li > ul > li > ul > li > h3', - element: '.note-air-popover button[data-event="insertOrderedList"]', - title: "click on order list", - }, - { - waitFor: '#editable_area > section .row > div:first ul > li > ul > li > ol > li > h3', - element: '#editable_area > section .row > div:first ul li > p:last', - title: "enter in ul", - keydown: [66, 13], // enter - onload: function () { - $(this.element)[0].firstChild.textContent += ""; - $.summernote.core.range.create($(this.element)[0].firstChild, 7).select(); - click_event($(this.element)[0], 'mouseup'); - } - }, - { - element: '#editable_area > section .row > div:first ul li > p:eq(1):containsRegex(/^municipium./)', - title: "backspace in list", - keydown: 8 - }, - { - waitFor: '#editable_area > section .row > div:first ul li p:eq(1)', - title: "end", - }, - ] -}); - - -Tour.register({ - id: 'rte_inline', - name: "Test RTE Inline", - mode: 'test', - path: '/web_editor/field/html/inline?callback=FieldTextHtml_0&enable_editor=1&datarecord=%7B%7D', - steps: [ - { - title: "Change html for this test", - onload: function () { - var $el = $(this.element); - var html = '\n'+ - '
\n'+ - ' \n'+ - ' \n'+ - ' \n'+ - ' \n'+ - ' \n'+ - ' \n'+ - ' \n'+ - '
\n'+ - ' Your Logo\n'+ - ' \n'+ - ' \n'+ - ' \n'+ - '
\n'+ - '
'; - $("#editable_area").html(html); - } - }, - { - title: "call clean for save", - element: '#wrapwrap table', - onload: function () { - snippet_editor.instance.clean_for_save(); - } - }, - { - waitFor: '#wrapwrap img:first[width][height][style*="-radius"][style*="1px"][style*="padding"]', - title: "check the image style", - }, - { - waitFor: '#wrapwrap img:eq(1)[src^="/web_editor/font_to_img/"][src$="/rgb(51,122,183)/28"]', - title: "check the font image src", - }, - { - waitFor: '#wrapwrap img:eq(1)[height]:not([class*="fa"])', - title: "check the font class to css", - }, - { - waitFor: '#wrapwrap img:eq(2)[style*="float: right"]', - title: "check the second font class to css", - }, - ] -}); - - -}); + tour.register("rte", { + url: '/web_editor/field/html?callback=FieldTextHtml_0&enable_editor=1&datarecord=%7B%7D', + test: true, + wait_for: base.ready(), + }, [{ + content: "Change html for this test", + trigger: "#editable_area", + run: function () { + var html = '\n'+ + '
\n'+ + '
\n'+ + '
\n'+ + '
\n'+ + '

Batnae municipium in Anthemusia

\n'+ + '

Batnae municipium in Anthemusia conditum Macedonum manu priscorum ab Euphrate flumine brevi spatio disparatur, refertum mercatoribus opulentis, ubi annua sollemnitate prope Septembris initium mensis ad.

\n'+ + '

Quam quidem partem accusationis admiratus sum et moleste tuli potissimum esse Atratino datam. Neque enim decebat neque aetas.

\n'+ + '

Et hanc quidem praeter oppida multa duae civitates exornant Seleucia opus Seleuci regis, et Claudiopolis quam deduxit coloniam Claudius Caesar. Isaura enim antehac nimium potens, olim subversa ut rebellatrix.

'+ + '

Harum trium sententiarum nulli prorsus assentior.

\n'+ + '
\n'+ + '
\n'+ + ' Odoo text and image block\n'+ + '
\n'+ + '
\n'+ + '
\n'; + this.$anchor.html(html); + } + }, { + content: "simulate triple click and change text bg-color", + trigger: '#editable_area > section .row > div:first', + run: function () { + var $h1 = $('h1', this.$anchor); + $.summernote.core.range.create($h1[0].firstChild, 0, $('p', this.$anchor)[0], 0).select(); + click_event($h1[0], 'mouseup'); + } + }, { + content: "change text bg-color after triple click", + trigger: '.note-popover button[data-event="color"]', + extra_trigger: '#editable_area > section .row > div:first', + }, { + content: "change selection to change text color", + trigger: '#editable_area > section .row > div:first:not(:has(p font)) h1 font', + run: function () { + $.summernote.core.range.create(this.$anchor[0].firstChild, 5, this.$anchor[0].firstChild, 10).select(); + click_event(this.$anchor[0], 'mouseup'); + } + }, { + content: "open color dropdown", + trigger: ".note-color button.dropdown-toggle", + }, { + content: "change text color", + trigger: "button[data-event=foreColor]:first", + }, { + content: "change selection to change text bg-color again", + trigger: '#editable_area > section .row > div:first h1 font:eq(2)', + run: function () { + $.summernote.core.range.create(this.$anchor.prev()[0].firstChild, 3, this.$anchor[0].firstChild, 10).select(); + click_event(this.$anchor.prev()[0], 'mouseup'); + } + }, { + content: "open color dropdown", + trigger: ".note-color button.dropdown-toggle", + }, { + content: "change text backColor again", + trigger: "button[data-event=backColor]:visible:first", + }, { + content: "change selection (h1 and p) to change text color with class", + trigger: '#editable_area > section .row > div:first h1 font:eq(4)', + run: function () { + $.summernote.core.range.create(this.$anchor.prev()[0].firstChild, 3, this.$anchor.parent("h1").next("p")[0].firstChild, 30).select(); + click_event(this.$anchor.prev()[0], 'mouseup'); + } + }, { + content: "open color dropdown", + trigger: ".note-color button.dropdown-toggle", + }, { + content: "change text color again", + trigger: "button[data-event=foreColor]:visible:eq(3)", + }, { + content: "delete selection", + trigger: '.o_editable.note-editable.o_dirty', + extra_trigger: '#editable_area > section .row > div:first p font', + run: "keydown 46", // delete + }, { + content: "create an other selection to delete", + trigger: '#editable_area > section .row > div:first:not(:has(p font)) h1', + extra_trigger: '.o_editable.note-editable.o_dirty', + run: function () { + $.summernote.core.range.createFromNode(this.$anchor.next("p")[0]).clean(); + $.summernote.core.range.create(this.$anchor.find('font:containsExact(ici)')[0].firstChild, 1, this.$anchor.next().next()[0].firstChild, 5).select(); + click_event(this.$anchor.find('font:last')[0], 'mouseup'); + }, + }, { + content: "clean and delete (backspace) an other selection", + trigger: '#editable_area > section .row > div:first:not(:has(p font)) h1', + run: "keydown 8", // backspace + }, { + content: "an other selection", + trigger: '#editable_area > section .row > div:first:has( font:last:containsExact(i) ):has( p:first:containsRegex(/^uam/) ) h1', + extra_trigger: '.o_editable.note-editable.o_dirty', + run: function () { + $.summernote.core.range.create(this.$anchor.find('font:first')[0].firstChild, 3, this.$anchor.next("p")[0].childNodes[2], 8).select(); + click_event(this.$anchor.find('font:first')[0], 'mouseup'); + }, + }, { + content: "delete an other selection", + trigger: '#editable_area > section .row > div:first:has( font:last:containsExact(i) ):has( p:first:containsRegex(/^uam/) ) h1', + run: "keydown 46", + }, { + content: "undo", + trigger: '.note-image-popover button[data-event="undo"]', + extra_trigger: '#editable_area > section .row > div:first:has( font:last:containsExact(Bat) )', + }, { + content: "undo again", + trigger: '.note-air-popover button[data-event="undo"]', + extra_trigger: '#editable_area > section .row > div:first:has( font:last:containsExact(i) )', + }, { + content: "delete (backspace) after undo", + trigger: '.o_editable.note-editable.o_dirty', + extra_trigger: '#editable_area > section .row > div:first:not(:has(p font)) h1', + run: "keydown 8", // backspace + }, { + content: "click on image", + trigger: '#editable_area > section .row > div:first img[style*="25%"]', + extra_trigger: '#editable_area > section .row > div:first:has( font:last:containsExact(i) ):has( p:first:containsRegex(/^uam/) )', + }, { + content: "Click on resize half", + trigger: '.note-image-popover:visible button[data-event="resize"][data-value="0.5"]', + }, { + content: "Click on edit picture", + trigger: '.note-image-popover:visible button[data-event="showImageDialog"]', + extra_trigger: '#editable_area > section .row > div:first img[style*="50%"]', + }, { + content: "Click on pictogram tab", + trigger: 'a[data-toggle="tab"]:contains(Pictogram)', + extra_trigger: '#editor-media-image', + }, { + content: "select a pictogram", + trigger: '#editor-media-icon.active span.fa:first', + }, { + content: "save pictogram", + trigger: 'button.o_save_button', + extra_trigger: '#editor-media-icon.active span.o_selected', + }, { + content: "select a size for the pictogram", + trigger: '.note-image-popover button[data-event="resizefa"][data-value="3"]', + }, { + content: "click on float right", + trigger: '.note-image-popover:visible button[data-event="floatMe"][data-value="right"]', + extra_trigger: '#wrapwrap span.fa-3x', + }, { + content: "click on create link", + trigger: '.note-image-popover:visible button[data-event="showLinkDialog"]', + extra_trigger: '#editable_area > section .row > div:first span.fa.pull-right', + }, { + content: "click on color style", + trigger: '.dropdown:has(.link-style) a[data-toggle="dropdown"]', + extra_trigger: 'a#link-preview:containsRegex(/^]+><\\/span>$/) > span.fa.fa-3x.pull-right', + }, { + content: "choose success style", + trigger: '.dropdown ul label.btn-success', + }, { + content: "insert a link url", + trigger: '#link-external', + extra_trigger: 'a#link-preview.btn', + run: "text http://www.odoo.com", + }, { + content: "change text label", + trigger: '#link-text', + run: "text ABC[IMG] DEF", + }, { + content: "save link", + trigger: 'button.o_save_button', + extra_trigger: 'a#link-preview.btn:containsRegex(/^ABC]+><\\/span> DEF$/)', + }, { + content: "click on other picture", + trigger: '#editable_area > section .row > div:last img', + extra_trigger: 'body:not(:has(#link-preview)) a.btn[href^="http://"]:has(span.fa.fa-3x.pull-right)', + }, { + content: "click on create link again", + trigger: '.note-image-popover:visible button[data-event="showLinkDialog"]', + extra_trigger: '#editable_area > section .row > div:first span.fa.pull-right', + }, { + content: "click on color style again", + trigger: '.dropdown:has(label.btn-success) a[data-toggle="dropdown"]', + extra_trigger: 'a#link-preview:containsRegex(/^]+>$/) img', + }, { + content: "choose success style", + trigger: '.dropdown ul label.btn-success', + }, { + content: "insert an email", + trigger: '#link-external', + extra_trigger: 'a#link-preview.btn', + run: "text test@test.test", + }, { + content: "save link", + trigger: 'button.o_save_button', + extra_trigger: 'a#link-preview.btn[href="mailto:test@test.test"]', + }, { + content: "select for triple enter then double backspace", + trigger: '#editable_area > section .row > div:first p:eq(2)', + extra_trigger: 'body:not(:has(#link-preview)) #editable_area > section .row > div:eq(1) > a > img', + run: function () { + var p = this.$anchor[0].firstChild; + $.summernote.core.range.create(p, p.textContent.length, p, p.textContent.length).select(); + click_event(p, 'mouseup'); + }, + }, { + content: "triple enter then double backspace", + trigger: '#editable_area > section .row > div:first p:eq(2)', + run: "keydown 66,13,66,13,13,8,8", // B enter B enter enter backspace backspace + }, { + content: "add ul content", + trigger: '#editable_area > section .row > div:first', + extra_trigger: 'body:not(:has(#editable_area > section .row > div:first p:eq(4), #editable_area > section .row > div:eq(3))) #editable_area > section .row > div:first p:eq(3)', + run: function () { + var html = '
    '+ + '\n
  • Batnae municipium.

  • '+ + '\n
  • Seleucia praeter.
  • '+ + '\n
  • Et hanc quidem.

  • '+ + '\n
'; + this.$anchor.append(html); + var node = this.$anchor.find('ul li p:last')[0].firstChild; + $.summernote.core.range.create(node, 6).select(); + click_event(node, 'mouseup'); + } + }, { + content: "click on style dropdown", + trigger: '.note-air-popover .note-style button.dropdown-toggle', + extra_trigger: '#editable_area > section .row > div:first ul li p:first', + }, { + content: "select h3", + trigger: '.note-air-popover .note-style ul:visible a[data-value="h3"]', + }, { + content: "select h3", + trigger: '#editable_area > section .row > div:first > ul > li > h3', + run: function () { + var node = this.$anchor[0].firstChild; + $.summernote.core.range.create(node, 0).select(); + click_event(node, 'mouseup'); + } + }, { + content: "double tabulation", + trigger: '#editable_area > section .row > div:first > ul > li > h3', + run: "keydown 9,9", // tabulation + }, { + content: "click on order list", + trigger: '.note-air-popover button[data-event="insertOrderedList"]', + extra_trigger: '#editable_area > section .row > div:first ul > li > ul > li > ul > li > h3', + }, { + content: "select for enter in ul", + trigger: '#editable_area > section .row > div:first ul li > p:last', + run: function () { + this.$anchor[0].firstChild.textContent += ""; + $.summernote.core.range.create(this.$anchor[0].firstChild, 7).select(); + click_event(this.$anchor[0], 'mouseup'); + } + }, { + content: "enter in ul", + trigger: '#editable_area > section .row > div:first ul li > p:last', + run: "keydown 66,13", // enter + }, { + trigger: '#editable_area > section .row > div:first ul li > p:eq(1):containsRegex(/^municipium./)', + content: "backspace in list", + run: "keydown 8", + }, { + content: "end", + trigger: '#editable_area > section .row > div:first ul li p:eq(0):containsRegex(/^Batnae Bmunicipium.$/)', + }]); + tour.register('rte_inline', { + url: '/web_editor/field/html/inline?callback=FieldTextHtml_0&enable_editor=1&datarecord=%7B%7D', + test: true, + wait_for: base.ready(), + }, [{ + content: "Change html for this test", + trigger: "#editable_area", + run: function () { + var html = '\n'+ + '
\n'+ + ' \n'+ + ' \n'+ + ' \n'+ + ' \n'+ + ' \n'+ + ' \n'+ + ' \n'+ + '
\n'+ + ' Your Logo\n'+ + ' \n'+ + ' \n'+ + ' \n'+ + '
\n'+ + '
'; + this.$anchor.html(html); + } + }, { + content: "call clean for save", + trigger: '#wrapwrap table', + run: function () { + snippet_editor.instance.clean_for_save(); + } + }, { + content: "check the image style", + trigger: '#wrapwrap img:first[width][height][style*="-radius"][style*="1px"][style*="padding"]', + }, { + content: "check the font image src", + trigger: '#wrapwrap img:eq(1)[src^="/web_editor/font_to_img/"][src$="/rgb(51,122,183)/28"]', + }, { + content: "check the font class to css", + trigger: '#wrapwrap img:eq(1)[height]:not([class*="fa"])', + }, { + content: "check the second font class to css", + trigger: '#wrapwrap img:eq(2)[style*="float: right"]', + }]); }); diff --git a/addons/web_editor/tests/test_ui.py b/addons/web_editor/tests/test_ui.py index 22736ce7d3e..3a05da5acc9 100644 --- a/addons/web_editor/tests/test_ui.py +++ b/addons/web_editor/tests/test_ui.py @@ -11,7 +11,7 @@ class TestUi(odoo.tests.HttpCase): at_install = False def test_01_admin_rte(self): - self.phantom_js("/web", "odoo.__DEBUG__.services['web.Tour'].run('rte', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.rte", login='admin') + self.phantom_js("/web", "odoo.__DEBUG__.services['web_tour.tour'].run('rte')", "odoo.__DEBUG__.services['web_tour.tour'].tours.rte.ready", login='admin') def test_02_admin_rte_inline(self): - self.phantom_js("/web", "odoo.__DEBUG__.services['web.Tour'].run('rte_inline', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.rte", login='admin') + self.phantom_js("/web", "odoo.__DEBUG__.services['web_tour.tour'].run('rte_inline')", "odoo.__DEBUG__.services['web_tour.tour'].tours.rte_inline.ready", login='admin') From ea1c061e11c4d83f456564dab3afcb15ce626156 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Fri, 26 Aug 2016 11:00:11 +0200 Subject: [PATCH 04/10] [IMP] website: convert tours to use web_tour.tour --- .../website/static/src/js/website.tour.rte.js | 299 ++++++++---------- addons/website/tests/test_ui.py | 11 +- 2 files changed, 140 insertions(+), 170 deletions(-) diff --git a/addons/website/static/src/js/website.tour.rte.js b/addons/website/static/src/js/website.tour.rte.js index c6ceb88a6bd..3026e4c86b2 100644 --- a/addons/website/static/src/js/website.tour.rte.js +++ b/addons/website/static/src/js/website.tour.rte.js @@ -1,190 +1,155 @@ odoo.define('website.tour.rte', function (require) { 'use strict'; -var Tour = require('web.Tour'); +var tour = require("web_tour.tour"); var local_storage = require('web.local_storage'); -Tour.register({ - id: 'rte_translator', - name: "Test translator", - mode: 'test', - steps: [ +tour.register('rte_translator', { test: true }, + [ { - title: "click on Add a language", - element: '.js_language_selector a:has(i.fa)', - }, - { - title: "select french", - element: '.modal select[name="lang"]', - sampleText: '"fr_BE"', - }, - { - title: "load french", - waitFor: '.modal select[name="lang"]:propValueContains(fr_BE)', - element: '.modal .modal-footer button:first', - }, - { - title: "go to english version", - waitFor: 'html[lang*="fr"]', - element: '.js_language_selector a[data-lang="en_US"]', - onload: function () { - local_storage.removeItem('website_translator_nodialog'); - } - }, - { - waitFor: 'a[data-action="edit"]', - title: "Open new page menu", - element: '#oe_main_menu_navbar a[data-action=new_page]', - }, - { - title: "click on new page", - element: '.modal a[data-action="new_page"]', - }, - { - title: "insert page name", - element: '#editor_new_page input[type="text"]', - sampleText: 'rte_translator', - }, - { - title: "create page", - waitFor: 'input[type="text"]:propValue(rte_translator)', - element: '.modal:has(#editor_new_page) button.btn-continue', - }, - { - title: "drop a snippet", - snippet: '#snippet_structure .oe_snippet:eq(1)', - }, - { - title: "change content", - waitFor: '.oe_overlay_options .oe_options:visible', - onload: function () { + content: "click on Add a language", + trigger: '.js_language_selector a:has(i.fa)', + }, { + content: "select french", + trigger: 'select[name="lang"]', + run: 'text "fr_BE"', + }, { + content: "load french", + trigger: '.modal-footer button:first', + extra_trigger: '.modal select[name="lang"]:propValueContains(fr_BE)', + }, { + content: "go to english version", + trigger: '.js_language_selector a[data-lang="en_US"]', + extra_trigger: 'html[lang*="fr"]', + }, { + content: "Open new page menu", + trigger: '#oe_main_menu_navbar a[data-action=new_page]', + extra_trigger: 'a[data-action="edit"]', + }, { + content: "click on new page", + trigger: 'a[data-action="new_page"]', + }, { + content: "insert page name", + trigger: '#editor_new_page input[type="text"]', + run: 'text rte_translator', + }, { + content: "create page", + trigger: 'button.btn-continue', + extra_trigger: 'input[type="text"]:propValue(rte_translator)', + }, { + content: "drop a snippet", + trigger: "#snippet_structure .oe_snippet:eq(1) .oe_snippet_thumbnail", + run: 'drag_and_drop', + }, { + content: "change content", + trigger: '.oe_overlay_options .oe_options:visible', + run: function () { $("#wrap p:first").replaceWith('

Write one or two paragraphs describing your product or\ services. To be successful your content needs to be\ useful to your readers.

\

<b></b> is an HTML tag & is empty

'); $("#wrap img").attr("title", "test translate image title"); } - }, - { - title: "save", - waitFor: '#wrap p:first b', - element: 'button[data-action=save]', - }, - { - title: "click on french version", - waitFor: 'html[lang*="en"]', - waitNot: 'button[data-action=save]', - element: '.js_language_selector a[data-lang="fr_BE"]', - }, - { - title: "translate", - waitNot: '#wrap p span', - element: '.o_menu_systray a[data-action="translate"]', - }, - { - title: "check if translation is activate", - waitFor: '[data-oe-translation-id]', - }, - { - title: "close modal", - element: '.modal button[data-action="activate"]', - }, - { - title: "translate text", - element: '#wrap p font:first', - sampleText: 'translated french text', - onload: function () { - $(this.element).closest('[data-oe-translation-id]').addClass('o_dirty').trigger('keyup'); + }, { + content: "save", + trigger: 'button[data-action=save]', + extra_trigger: '#wrap p:first b', + }, { + content: "click on french version", + trigger: '.js_language_selector a[data-lang="fr_BE"]', + extra_trigger: 'html[lang*="en"]:not(:has(button[data-action=save]))', + }, { + content: "translate", + trigger: 'html:not(:has(#wrap p span)) .o_menu_systray a[data-action="translate"]', + }, { + content: "close modal", + trigger: 'button[data-action="activate"]', + }, { + content: "check if translation is activate", + trigger: '[data-oe-translation-id]', + }, { + content: "translate text", + trigger: '#wrap p font:first', + run: function (action_helper) { + action_helper.text('translated french text'); + this.$anchor.trigger('keydown'); }, - }, - { - title: "click on input", - waitFor: '#wrap .o_dirty font:first:contains(translated french text)', - element: 'input:first', - }, - { - title: "translate text with special char", - onload: function () { - $('#wrap input + p').find(':last').prepend('<{translated}>') - .closest('[data-oe-translation-id]').addClass('o_dirty').trigger('keyup'); + }, { + content: "translate text with special char", + trigger: '#wrap input + p span:first', + run: function (action_helper) { + action_helper.click(); + this.$anchor.prepend('<{translated}>').trigger('keydown'); }, - }, - { - title: "translate placeholder", - element: '.modal input:first', - sampleText: 'test french placeholder', - }, - { - title: "close modal", - waitFor: '.modal input:propValue(test french placeholder)', - element: '.modal button', - }, - { - title: "close modal", - waitNot: '.modal:visible', - element: 'button[data-action=save]', - }, - { - title: "check: content is translated", - waitNot: 'button[data-action=save]', - waitFor: '#wrap p font:first:contains(translated french text)', - }, - { - title: "check: content with special char is translated", - waitFor: "#wrap input + p:contains(<{translated}> is an HTML\xa0tag & )", - }, - { - title: "check: placeholder translation", - waitFor: 'input[placeholder="test french placeholder"]', - }, - { - title: "return to english version", - waitFor: 'html[lang*="fr"]', - waitNot: '#wrap p span', - element: '.js_language_selector a[data-lang="en_US"]', - }, - { - title: "edit english version", - waitNot: '#wrap p font:first:containsExact(paragraphs describing)', - element: 'a[data-action=edit]', - }, - { - title: "select text", - waitFor: 'button[data-action=save]', - element: '#wrap p', - onload: function () { - var el = $(this.element)[0]; + }, { + content: "click on input", + trigger: 'input:first', + extra_trigger: '#wrap .o_dirty font:first:contains(translated french text)', + run: 'click', + }, { + content: "translate placeholder", + trigger: 'input:first', + run: 'text test french placeholder', + }, { + content: "close modal", + trigger: 'button.o_save_button', + extra_trigger: '.modal input:propValue(test french placeholder)', + }, { + content: "save translation", + trigger: 'button[data-action=save]', + }, { + content: "check: content is translated", + trigger: '#wrap p font:first:contains(translated french text)', + run: function () {}, // it's a check + }, { + content: "check: content with special char is translated", + trigger: "#wrap input + p:contains(<{translated}> is an HTML\xa0tag & )", + run: function () {}, // it's a check + + }, { + content: "check: placeholder translation", + trigger: 'input[placeholder="test french placeholder"]', + run: function () {}, // it's a check + }, { + content: "return to english version", + trigger: '.js_language_selector a[data-lang="en_US"]', + extra_trigger: 'html[lang*="fr"]:not(:has(#wrap p span))', + }, { + content: "edit english version", + trigger: 'a[data-action=edit]', + extra_trigger: 'body:not(:has(#wrap p font:first:containsExact(paragraphs describing)))', + }, { + content: "select text", + extra_trigger: 'button[data-action=save]', + trigger: '#wrap p', + run: function (action_helper) { + action_helper.click(); + var el = this.$anchor[0]; var evt = document.createEvent("MouseEvents"); $.summernote.core.range.create(el.childNodes[2], 6, el.childNodes[2], 13).select(); evt.initMouseEvent('mouseup', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, el); el.dispatchEvent(evt); }, - }, - { - title: "underline", - element: '.note-air-popover button[data-event="underline"]', - }, - { - title: "save new change", - waitFor: '#wrap p u', - element: 'button[data-action=save]', - }, - { - title: "return in french", - waitFor: 'html[lang*="en"]', - waitNot: 'button[data-action=save]', - element: 'html[lang="en-US"] .js_language_selector a[data-lang="fr_BE"]', - }, - { - title: "check bis: content is translated", - waitNot: 'button[data-action=save]', - waitFor: '#wrap p font:first:contains(translated french text)', - }, - { - title: "check bis: placeholder translation", - waitFor: 'input[placeholder="test french placeholder"]', + }, { + content: "underline", + trigger: '.note-air-popover button[data-event="underline"]', + }, { + content: "save new change", + trigger: 'button[data-action=save]', + extra_trigger: '#wrap p u', + }, { + content: "return in french", + trigger: 'html[lang="en-US"] .js_language_selector a[data-lang="fr_BE"]', + extra_trigger: 'html[lang*="en"]:not(:has(button[data-action=save]))', + }, { + content: "check bis: content is translated", + trigger: '#wrap p font:first:contains(translated french text)', + extra_trigger: 'body:not(:has(button[data-action=save]))', + }, { + content: "check bis: placeholder translation", + trigger: 'input[placeholder="test french placeholder"]', }, ] -}); +); }); diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py index a249b7c14a7..9ba72151013 100644 --- a/addons/website/tests/test_ui.py +++ b/addons/website/tests/test_ui.py @@ -5,8 +5,16 @@ import odoo import odoo.tests +class TestUiTranslate(odoo.tests.HttpCase): + def test_admin_tour_rte_translator(self): + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('rte_translator')", "odoo.__DEBUG__.services['web_tour.tour'].tours.rte_translator.ready", login='admin', timeout=120) + + class TestUi(odoo.tests.HttpCase): + post_install = True + at_install = False + def test_01_public_homepage(self): self.phantom_js("/", "console.log('ok')", "'website.snippets.animation' in odoo.__DEBUG__.services") @@ -15,6 +23,3 @@ class TestUi(odoo.tests.HttpCase): def test_03_admin_tour_banner(self): self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('banner')", "odoo.__DEBUG__.services['web_tour.tour'].tours.banner.ready", login='admin') - - def test_03_admin_tour_rte_translator(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('rte_translator', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.rte_translator", login='admin') From 21e26f6009e1831da1256d85252b4eb3473d5768 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:02:02 +0200 Subject: [PATCH 05/10] [IMP] website_crm: convert tours to use web_tour.tour --- .../static/src/js/website_crm_tour.js | 88 ++++++++----------- addons/website_crm/tests/test_website_crm.py | 2 +- 2 files changed, 37 insertions(+), 53 deletions(-) diff --git a/addons/website_crm/static/src/js/website_crm_tour.js b/addons/website_crm/static/src/js/website_crm_tour.js index 576d5e6c6c9..114478b76cf 100644 --- a/addons/website_crm/static/src/js/website_crm_tour.js +++ b/addons/website_crm/static/src/js/website_crm_tour.js @@ -1,60 +1,44 @@ odoo.define('website_crm.tour', function(require) { 'use strict'; + var tour = require('web_tour.tour'); var base = require('web_editor.base'); - var core = require('web.core'); - var Tour = require('web.Tour'); - var Model = require('web.Model'); - var Session = require('web.Session'); - base.ready().done(function () { - Tour.register({ - id: 'website_crm_tour', - name: "Test the contact us form", - path: '/page/contactus', - mode: 'test', - steps: [ - { - title: "Complete name", - element: "input[name=contact_name]", - sampleText: "John Smith", - }, - { - title: "Complete phone number", - element: "input[name=phone]", - sampleText: "118.218" - }, - { - title: "Complete Email", - element: "input[name=email_from]", - sampleText: "john@smith.com" - }, - { - title: "Complete Company", - element: "input[name=partner_name]", - sampleText: "Odoo S.A." - }, - { - title: "Complete Subject", - element: "input[name=name]", - sampleText: "Useless message" - }, - { - title: "Complete Subject", - element: "textarea[name=description]", - sampleText: "### TOUR DATA ###" - }, - { - title: "Send the form", - element: ".o_website_form_send" - }, - { - title: "Check we were redirected to the success page", - waitFor: "#wrap:has(h1:contains('Thanks')):has(div.alert-success)" - } - ] - }); - }); + tour.register('website_crm_tour', { + test: true, + url: '/page/contactus', + wait_for: base.ready(), + }, [{ + content: "Complete name", + trigger: "input[name=contact_name]", + run: "text John Smith", + }, { + content: "Complete phone number", + trigger: "input[name=phone]", + run: "text 118.218" + }, { + content: "Complete Email", + trigger: "input[name=email_from]", + run: "text john@smith.com" + }, { + content: "Complete Company", + trigger: "input[name=partner_name]", + run: "text Odoo S.A." + }, { + content: "Complete Subject", + trigger: "input[name=name]", + run: "text Useless message" + }, { + content: "Complete Subject", + trigger: "textarea[name=description]", + run: "text ### TOUR DATA ###" + }, { + content: "Send the form", + trigger: ".o_website_form_send" + }, { + content: "Check we were redirected to the success page", + trigger: "#wrap:has(h1:contains('Thanks')):has(div.alert-success)" + }]); return {}; }); diff --git a/addons/website_crm/tests/test_website_crm.py b/addons/website_crm/tests/test_website_crm.py index 3d1c85856a8..0ac1bfa6ecf 100644 --- a/addons/website_crm/tests/test_website_crm.py +++ b/addons/website_crm/tests/test_website_crm.py @@ -10,7 +10,7 @@ import odoo.tests class TestWebsiteCrm(odoo.tests.HttpCase): def test_tour(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('website_crm_tour', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.website_crm_tour") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('website_crm_tour')", "odoo.__DEBUG__.services['web_tour.tour'].tours.website_crm_tour.ready") # need environment using the test cursor as it's not committed cr = self.registry.cursor() From 3fe48f7f495f07b151f21936da5c8185343f36f5 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:02:46 +0200 Subject: [PATCH 06/10] [IMP] website_event_sale: convert tours to use web_tour.tour --- .../static/src/js/website.tour.event_sale.js | 174 +++++++++--------- addons/website_event_sale/tests/test_ui.py | 10 +- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/addons/website_event_sale/static/src/js/website.tour.event_sale.js b/addons/website_event_sale/static/src/js/website.tour.event_sale.js index 26dacb79ed9..25b27c69ca2 100644 --- a/addons/website_event_sale/static/src/js/website.tour.event_sale.js +++ b/addons/website_event_sale/static/src/js/website.tour.event_sale.js @@ -1,95 +1,93 @@ odoo.define('website_event_sale.tour', function (require) { 'use strict'; -var Tour = require('web.Tour'); -var base = require('web_editor.base'); -var website = require('website.website'); +var tour = require('web_tour.tour'); -base.ready().done(function () { - Tour.register({ - id: 'event_buy_tickets', - name: "Buy tickets for the Conference on Business Apps", - path: '/event', - mode: 'test', - steps: [ - { - title: "Go to the `Events` page", - element: 'a[href*="/event"]:contains("Conference on Business Apps"):first', +tour.register('event_buy_tickets', { test: true, url: '/event' }, + [ + { + content: "Go to the `Events` page", + trigger: 'a[href*="/event"]:contains("Conference on Business Apps"):first', + }, + { + content: "Select 1 unit of `Standard` ticket type", + extra_trigger: '#wrap:not(:has(a[href*="/event"]:contains("Conference on Business Apps")))', + trigger: 'select:eq(0)', + run: 'text 1', + }, + { + content: "Select 2 units of `VIP` ticket type", + extra_trigger: 'select:eq(0):has(option:contains(1):propSelected)', + trigger: 'select:eq(1)', + run: 'text 2', + }, + { + content: "Click on `Order Now` button", + extra_trigger: 'select:eq(1):has(option:contains(2):propSelected)', + trigger: '.btn-primary:contains("Order Now")', + }, + { + content: "Fill attendees details", + trigger: 'form[id="attendee_registration"] .btn:contains("Continue")', + run: function () { + $("input[name='1-name']").val("Att1"); + $("input[name='1-phone']").val("111 111"); + $("input[name='1-email']").val("att1@example.com"); + $("input[name='2-name']").val("Att2"); + $("input[name='2-phone']").val("222 222"); + $("input[name='2-email']").val("att2@example.com"); + $("input[name='3-name']").val("Att3"); + $("input[name='3-phone']").val("333 333"); + $("input[name='3-email']").val("att3@example.com"); }, - { - title: "Select 1 unit of `Standard` ticket type", - waitNot: 'a[href*="/event"]:contains("Conference on Business Apps")', - element: 'select:eq(0)', - sampleText: '1', - }, - { - title: "Select 2 units of `VIP` ticket type", - waitFor: 'select:eq(0) option:contains(1):propSelected', - element: 'select:eq(1)', - sampleText: '2', - }, - { - title: "Click on `Order Now` button", - waitFor: 'select:eq(1) option:contains(2):propSelected', - element: '.btn-primary:contains("Order Now")', - }, - { - title: "Fill attendees details", - waitFor: 'form[id="attendee_registration"] .btn:contains("Continue")', - autoComplete: function (tour) { - $("input[name='1-name']").val("Att1"); - $("input[name='1-phone']").val("111 111"); - $("input[name='1-email']").val("att1@example.com"); - $("input[name='2-name']").val("Att2"); - $("input[name='2-phone']").val("222 222"); - $("input[name='2-email']").val("att2@example.com"); - $("input[name='3-name']").val("Att3"); - $("input[name='3-phone']").val("333 333"); - $("input[name='3-email']").val("att3@example.com"); - }, - }, - { - title: "Validate attendees details", - waitFor: "input[name='1-name'], input[name='2-name'], input[name='3-name']", - element: '.modal button:contains("Continue")', - }, - { - title: "Check that the cart contains exactly 3 elements", - element: 'a:has(.my_cart_quantity:containsExact(3))', - }, - { - title: "Modify the cart to add 1 unit of `VIP` ticket type", - waitFor: "#cart_products:contains(Standard):contains(VIP)", - element: "#cart_products tr:contains(VIP) .fa-plus", - }, - { - title: "Now click on `Process Checkout`", - waitFor: 'a:has(.my_cart_quantity):contains(4)', - element: '.btn-primary:contains("Process Checkout")' - }, - { - title: "Complete the checkout", - element: 'a[href="/shop/confirm_order"]:contains("Confirm")', - }, - { - title: "Check that the subtotal is 5,500.00", - element: '#order_total_untaxed .oe_currency_value:contains("5,500.00")', - }, - { - title: "Select `Wire Transfer` payment method", - element: '#payment_method label:has(img[title="Wire Transfer"]) input', - }, - { - title: "Pay", - waitFor: '#payment_method label:has(input:checked):has(img[title="Wire Transfer"])', - element: '.oe_sale_acquirer_button .btn[type="submit"]:visible', - }, - { - title: "Last step", - waitFor: '.oe_website_sale:contains("Thank you for your order")', - } - ] - }); -}); + }, + { + content: "Validate attendees details", + extra_trigger: "input[name='1-name'], input[name='2-name'], input[name='3-name']", + trigger: 'button:contains("Continue")', + }, + { + content: "Check that the cart contains exactly 3 triggers", + trigger: 'a:has(.my_cart_quantity:containsExact(3))', + run: function () {}, // it's a check + }, + { + content: "go to cart", + trigger: 'a:contains(Return to Cart)', + }, + { + content: "Modify the cart to add 1 unit of `VIP` ticket type", + extra_trigger: "#cart_products:contains(Standard):contains(VIP)", + trigger: "#cart_products tr:contains(VIP) .fa-plus", + }, + { + content: "Now click on `Process Checkout`", + extra_trigger: 'a:has(.my_cart_quantity):contains(4)', + trigger: '.btn-primary:contains("Process Checkout")' + }, + { + content: "Complete the checkout", + trigger: 'a[href="/shop/confirm_order"]:contains("Confirm")', + }, + { + content: "Check that the subtotal is 5,500.00", + trigger: '#order_total_untaxed .oe_currency_value:contains("5,500.00")', + run: function () {}, // it's a check + }, + { + content: "Select `Wire Transfer` payment method", + trigger: '#payment_method label:contains(Wire Transfer) input', + }, + { + content: "Pay", + extra_trigger: '#payment_method label:contains(Wire Transfer) input:checked', + trigger: '.oe_sale_acquirer_button .btn[type="submit"]:visible', + }, + { + content: "Last step", + trigger: '.oe_website_sale:contains("Thank you for your order")', + } + ] +); }); diff --git a/addons/website_event_sale/tests/test_ui.py b/addons/website_event_sale/tests/test_ui.py index cad7ae99040..193521db8d8 100644 --- a/addons/website_event_sale/tests/test_ui.py +++ b/addons/website_event_sale/tests/test_ui.py @@ -1,13 +1,15 @@ import odoo.tests -@odoo.tests.common.at_install(False) -@odoo.tests.common.post_install(True) class TestUi(odoo.tests.HttpCase): + + post_install = True + at_install = False + def test_admin(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('event_buy_tickets', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.event_buy_tickets", login="admin") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('event_buy_tickets')", "odoo.__DEBUG__.services['web_tour.tour'].tours.event_buy_tickets.ready", login="admin") def test_demo(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('event_buy_tickets', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.event_buy_tickets", login="demo") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('event_buy_tickets')", "odoo.__DEBUG__.services['web_tour.tour'].tours.event_buy_tickets.ready", login="demo") # TO DO - add public test with new address when convert to web.tour format. From d39fbea9ad5d8dc130171488297312a27cd347aa Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:03:05 +0200 Subject: [PATCH 07/10] [IMP] website_forum: convert tours to use web_tour.tour --- .../src/js/website_tour_forum_question.js | 136 +++++++----------- .../website_forum/tests/test_forum_process.py | 9 +- 2 files changed, 56 insertions(+), 89 deletions(-) diff --git a/addons/website_forum/static/src/js/website_tour_forum_question.js b/addons/website_forum/static/src/js/website_tour_forum_question.js index fe12a1a244c..34c0737cc8b 100644 --- a/addons/website_forum/static/src/js/website_tour_forum_question.js +++ b/addons/website_forum/static/src/js/website_tour_forum_question.js @@ -1,89 +1,55 @@ odoo.define('website_forum.tour_forum_question', function (require) { -'use strict'; + 'use strict'; -var Tour = require('web.Tour'); + var tour = require("web_tour.tour"); + var base = require("web_editor.base"); -Tour.register({ - id: 'forum_question', - name: "try to create question", - path: '/forum/help-1', - mode: 'test', - steps: [ - { - title: "Ask a Question", - element: '.btn-block a:first', - placement: 'left', - content: "Ask the question in this forum by clicking on the button.", - }, - { - title: "Question Title", - element: 'input[name=post_name]', - sampleText:'First Question Title', - placement: 'top', - content: "Give your question title.", - }, - { - title: "Question", - waitNot: "input[name=post_name]:propValue('')", - element: '.note-editable p', - sampleText: 'First Question', - placement: 'top', - content: "Put your question here.", - }, - { - title: "Give Tag", - waitFor: '.note-editable:not(:has(br))', - element: '.select2-choices', - sampleText:'Tag', - placement: 'top', - content: "Insert tags related to your question.", - }, - { - title: "Post Question", - waitNot: "input[id=s2id_autogen2]:propValue('')", - element: 'button:contains("Post Your Question")', - placement: 'bottom', - content: "Click to post your question.", - }, - { - title: "New Question Created", - waitFor: 'body:has(".fa-star")', - content: "This page contain new created question.", - popover: { next: "Continue" }, - }, - { - title: "Answer", - element: '.note-editable p', - sampleText: 'First Answer', - placement: 'top', - content: "Put your answer here.", - }, - { - title: "Post Answer", - waitFor: '.note-editable:not(:has(br))', - element: 'button:contains("Post Answer")', - placement: 'bottom', - content: "Click to post your answer.", - }, - { - title: "Answer Posted", - waitFor: 'body:has(".fa-check-circle")', - content: "This page contain new created question and its answer.", - popover: { next: "Continue" }, - }, - { - title: "Accept Answer", - element: 'a[data-karma="20"]:first', - placement: 'right', - content: "Click here to accept this answer.", - }, - { - title: "Congratulations", - waitFor: 'body:has(".oe_answer_true")', - content: "Congratulations! You just created and post your first question and answer.", - popover: { next: "Close Tutorial" }, - }, - ] + tour.register('forum_question', { + test: true, + url: '/forum/help-1', + wait_for: base.ready(), + }, [{ + content: "Ask the question in this forum by clicking on the button.", + trigger: '.btn-block a:first', + }, { + content: "Give your question content.", + trigger: 'input[name=post_name]', + run: 'text First Question Title', + }, { + content: "Put your question here.", + extra_trigger: "#wrap:not(:has(input[name=post_name]:propValue('')))", + trigger: '.note-editable p', + run: 'text First Question', + }, { + content: "Insert tags related to your question.", + extra_trigger: '.note-editable:not(:has(br))', + trigger: '.select2-choices', + run: 'text Tag', + }, { + content: "Click to post your question.", + extra_trigger: "#wrap:not(:has(input[id=s2id_autogen2]:propValue('')))", + trigger: 'button:contains("Post Your Question")', + }, { + content: "This page contain new created question.", + extra_trigger: '#wrap:has(".fa-star")', + trigger: 'button[data-dismiss="modal"]', + }, { + content: "Put your answer here.", + trigger: '.note-editable p', + run: 'text First Answer', + }, { + content: "Click to post your answer.", + extra_trigger: '.note-editable:not(:has(br))', + trigger: 'button:contains("Post Answer")', + }, { + content: "This page contain new created question and its answer.", + extra_trigger: '#wrap:has(".fa-check-circle")', + trigger: 'button[data-dismiss="modal"]', + }, { + content: "Click here to accept this answer.", + trigger: 'a[data-karma="20"]:first', + }, { + content: "Congratulations! You just created and post your first question and answer.", + trigger: '#wrap:has(".oe_answer_true")', + }]); }); - -}); \ No newline at end of file diff --git a/addons/website_forum/tests/test_forum_process.py b/addons/website_forum/tests/test_forum_process.py index a81140c6cd3..2f23ebae67e 100644 --- a/addons/website_forum/tests/test_forum_process.py +++ b/addons/website_forum/tests/test_forum_process.py @@ -2,10 +2,11 @@ import odoo.tests - -@odoo.tests.common.at_install(False) -@odoo.tests.common.post_install(True) class TestUi(odoo.tests.HttpCase): + + post_install = True + at_install = False + def test_01_admin_forum_tour(self): self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('question')", "odoo.__DEBUG__.services['web_tour.tour'].tours.question.ready", login="admin") @@ -15,4 +16,4 @@ class TestUi(odoo.tests.HttpCase): forum = env.ref('website_forum.forum_help') demo = env.ref('base.user_demo') demo.karma = forum.karma_post + 1 - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('forum_question', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.forum_question", login="demo") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('forum_question')", "odoo.__DEBUG__.services['web_tour.tour'].tours.forum_question.ready", login="demo") From 48fccec1f232f1725fa082f0ef8d0e05183d1f2b Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:03:30 +0200 Subject: [PATCH 08/10] [IMP] website_hr_recruitment: convert tours to use web_tour.tour --- .../src/js/website_hr_recruitment_tour.js | 71 ++++++++----------- .../tests/test_website_hr_recruitment.py | 2 +- 2 files changed, 29 insertions(+), 44 deletions(-) diff --git a/addons/website_hr_recruitment/static/src/js/website_hr_recruitment_tour.js b/addons/website_hr_recruitment/static/src/js/website_hr_recruitment_tour.js index a85d7760034..aedbdca8445 100644 --- a/addons/website_hr_recruitment/static/src/js/website_hr_recruitment_tour.js +++ b/addons/website_hr_recruitment/static/src/js/website_hr_recruitment_tour.js @@ -2,50 +2,35 @@ odoo.define('website_hr_recruitment.tour', function(require) { 'use strict'; var base = require('web_editor.base'); - var core = require('web.core'); - var Tour = require('web.Tour'); - var Model = require('web.Model'); - var Session = require('web.Session'); + var tour = require("web_tour.tour"); - base.ready().done(function () { - Tour.register({ - id: 'website_hr_recruitment_tour', - name: "Test the hr applicants form", - path: '/jobs/apply/3', - mode: 'test', - steps: [ - { - title: "Complete name", - element: "input[name=partner_name]", - sampleText: "John Smith" - }, - { - title: "Complete Email", - element: "input[name=email_from]", - sampleText: "john@smith.com" - }, - { - title: "Complete phone number", - element: "input[name=partner_phone]", - sampleText: "118.218" - }, - { - title: "Complete Subject", - element: "textarea[name=description]", - sampleText: "### HR RECRUITMENT TEST DATA ###" - }, - // TODO: Upload a file ? - { - title: "Send the form", - element: ".o_website_form_send" - }, - { - title: "Check the form is submited without errors", - waitFor: ".oe_structure:has(h1:contains('Thank you!'))" - } - ] - }); - }); + tour.register('website_hr_recruitment_tour', { + test: true, + url: '/jobs/apply/3', + wait_for: base.ready(), + }, [{ + content: "Complete name", + trigger: "input[name=partner_name]", + run: "text John Smith" + }, { + content: "Complete Email", + trigger: "input[name=email_from]", + run: "text john@smith.com" + }, { + content: "Complete phone number", + trigger: "input[name=partner_phone]", + run: "text 118.218" + }, { + content: "Complete Subject", + trigger: "textarea[name=description]", + run: "text ### HR RECRUITMENT TEST DATA ###" + }, { // TODO: Upload a file ? + content: "Send the form", + trigger: ".o_website_form_send" + }, { + content: "Check the form is submited without errors", + trigger: ".oe_structure:has(h1:contains('Thank you!'))" + }]); return {}; }); diff --git a/addons/website_hr_recruitment/tests/test_website_hr_recruitment.py b/addons/website_hr_recruitment/tests/test_website_hr_recruitment.py index a84aee1ebaa..db68b4811d6 100644 --- a/addons/website_hr_recruitment/tests/test_website_hr_recruitment.py +++ b/addons/website_hr_recruitment/tests/test_website_hr_recruitment.py @@ -8,7 +8,7 @@ import odoo.tests @odoo.tests.common.post_install(True) class TestWebsiteHrRecruitmentForm(odoo.tests.HttpCase): def test_tour(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('website_hr_recruitment_tour', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.website_hr_recruitment_tour") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('website_hr_recruitment_tour')", "odoo.__DEBUG__.services['web_tour.tour'].tours.website_hr_recruitment_tour.ready") # get test cursor to read from same transaction browser is writing to cr = self.registry.cursor() From dff1b6cc03d71627d6c1b66cddd2e60ced47bb86 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:03:46 +0200 Subject: [PATCH 09/10] [IMP] website_sale: convert tours to use web_tour.tour --- .../static/src/js/website_sale_tour_buy.js | 92 +++++++++---------- .../website_sale/tests/test_sale_process.py | 4 +- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/addons/website_sale/static/src/js/website_sale_tour_buy.js b/addons/website_sale/static/src/js/website_sale_tour_buy.js index 03bcfe02921..c5a3b8abb31 100644 --- a/addons/website_sale/static/src/js/website_sale_tour_buy.js +++ b/addons/website_sale/static/src/js/website_sale_tour_buy.js @@ -1,80 +1,78 @@ odoo.define('website_sale.tour', function (require) { 'use strict'; -var Tour = require('web.Tour'); +var tour = require("web_tour.tour"); -Tour.register({ - id: 'shop_buy_product', - name: "Try to buy products", - path: '/shop', - mode: 'test', - steps: [ +tour.register('shop_buy_product', { test: true, url: '/shop' }, + [ { - title: "search ipod", - element: 'form:has(input[name="search"]) a.a-submit', - onload: function() { - $('input[name="search"]').val("ipod"); - } + content: "search ipod", + trigger: 'form input[name="search"]', + run: "text ipod", }, { - title: "select ipod", - element: '.oe_product_cart a:contains("iPod")', + content: "search ipod", + trigger: 'form:has(input[name="search"]) .oe_search_button', }, { - title: "select ipod 32GB", - waitFor: '#product_detail', - element: 'label:contains(32 GB) input', + content: "select ipod", + trigger: '.oe_product_cart a:contains("iPod")', }, { - title: "click on add to cart", - waitFor: 'label:contains(32 GB) input:propChecked', - element: '#product_detail form[action^="/shop/cart/update"] .btn', + content: "select ipod 32GB", + extra_trigger: '#product_detail', + trigger: 'label:contains(32 GB) input', }, { - title: "add suggested", - waitNot: '#cart_products:contains("[A8767] Apple In-Ear Headphones")', - element: '.oe_cart a:contains("Add to Cart")', + content: "click on add to cart", + extra_trigger: 'label:contains(32 GB) input:propChecked', + trigger: '#product_detail form[action^="/shop/cart/update"] .btn', }, { - title: "add one more iPod", - waitFor: '.my_cart_quantity:contains(2)', - element: '#cart_products tr:contains("32 GB") a.js_add_cart_json:eq(1)', + content: "add suggested", + extra_trigger: '#wrap:not(:has(#cart_products:contains("[A8767] Apple In-Ear Headphones")))', + trigger: '.oe_cart:has(tr:contains("32 GB")) a:contains("Add to Cart")', }, { - title: "remove Headphones", - waitFor: '#cart_products tr:contains("32 GB") input.js_quantity:propValue(2)', - element: '#cart_products tr:contains("Apple In-Ear Headphones") a.js_add_cart_json:first', + content: "add one more iPod", + extra_trigger: '.my_cart_quantity:contains(2)', + trigger: '#cart_products tr:contains("32 GB") a.js_add_cart_json:eq(1)', }, { - title: "set one iPod", - waitNot: '#cart_products tr:contains("Apple In-Ear Headphones")', - element: '#cart_products input.js_quantity', - sampleText: '1', + content: "remove Headphones", + extra_trigger: '#cart_products tr:contains("32 GB") input.js_quantity:propValue(2)', + trigger: '#cart_products tr:contains("Apple In-Ear Headphones") a.js_add_cart_json:first', }, { - title: "go to checkout", - waitFor: '#cart_products input.js_quantity:propValue(1)', - element: 'a[href="/shop/checkout"]', + content: "set one iPod", + extra_trigger: '#wrap:not(:has(#cart_products tr:contains("Apple In-Ear Headphones")))', + trigger: '#cart_products input.js_quantity', + run: 'text 1', }, { - title: "Confirm checkout", - waitFor: "div.all_shipping .panel", - element: 'a[href="/shop/confirm_order"]', + content: "go to checkout", + extra_trigger: '#cart_products input.js_quantity:propValue(1)', + trigger: 'a[href="/shop/checkout"]', }, { - title: "select payment", - element: '#payment_method label:has(img[title="Wire Transfer"]) input', + content: "Confirm checkout", + extra_trigger: "div.all_shipping .panel", + trigger: 'a[href="/shop/confirm_order"]', }, { - title: "Pay Now", - waitFor: '#payment_method label:has(input:checked):has(img[title="Wire Transfer"])', - element: '.oe_sale_acquirer_button .btn[type="submit"]:visible', + content: "select payment", + trigger: '#payment_method label:contains("Wire Transfer") input', }, { - title: "finish", - waitFor: '.oe_website_sale:contains("Thank you for your order")', + content: "Pay Now", + extra_trigger: '#payment_method label:contains("Wire Transfer") input:checked', + trigger: '.oe_sale_acquirer_button .btn[type="submit"]:visible', + }, + { + content: "finish", + trigger: '.oe_website_sale:contains("Thank you for your order")', } ] -}); +); }); diff --git a/addons/website_sale/tests/test_sale_process.py b/addons/website_sale/tests/test_sale_process.py index 767cc4bbb9c..fab3e63b559 100644 --- a/addons/website_sale/tests/test_sale_process.py +++ b/addons/website_sale/tests/test_sale_process.py @@ -10,9 +10,9 @@ class TestUi(odoo.tests.HttpCase): self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('shop')", "odoo.__DEBUG__.services['web_tour.tour'].tours.shop.ready", login="admin") def test_02_admin_checkout(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('shop_buy_product', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.shop_buy_product", login="admin") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('shop_buy_product')", "odoo.__DEBUG__.services['web_tour.tour'].tours.shop_buy_product.ready", login="admin") def test_03_demo_checkout(self): - self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('shop_buy_product', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.shop_buy_product", login="demo") + self.phantom_js("/", "odoo.__DEBUG__.services['web_tour.tour'].run('shop_buy_product')", "odoo.__DEBUG__.services['web_tour.tour'].tours.shop_buy_product.ready", login="demo") # TO DO - add public test with new address when convert to web.tour format. From c41e85ae120a94116b8a2a0c35e27bfa38975d3f Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 25 Aug 2016 15:04:06 +0200 Subject: [PATCH 10/10] [IMP] website_sale_options: convert tours to use web_tour.tour --- .../static/src/js/website_sale.test.js | 107 +++++++++--------- .../tests/test_customize.py | 9 +- 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/addons/website_sale_options/static/src/js/website_sale.test.js b/addons/website_sale_options/static/src/js/website_sale.test.js index a4a6bb267a3..947d30079ba 100644 --- a/addons/website_sale_options/static/src/js/website_sale.test.js +++ b/addons/website_sale_options/static/src/js/website_sale.test.js @@ -1,101 +1,98 @@ odoo.define('website_sale.test', function (require) { 'use strict'; -var core = require('web.core'); -var Tour = require('web.Tour'); +require("website_sale.tour"); +var tour = require("web_tour.tour"); -var _t = core._t; - -var steps = Tour.tours.shop_buy_product.steps; +var steps = tour.tours.shop_buy_product.steps; for (var k=0; k