From 7329b5dc78d25083c666d3fe255c591d67d3fc40 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Tue, 27 Jul 2021 15:52:25 +0000 Subject: [PATCH] [ADD] test_website_modules: new website test module The goal of this module is to be able to write tests that run and test the `website` module business code with all the website modules installed (like website_blog, website_sale etc). This is, among other things, useful to test the configurator behavior. Testing the configurator inside the `website` module would require the tour to install modules, which is against our testing suite policy. Such tests end up in `@standalone` testing suite, run only in nightly, meaning anyone can break stuff without knowing. Such tests are way, way less efficient. Community: https://github.com/odoo/odoo/pull/71993 Enterprise: https://github.com/odoo/enterprise/pull/18930 task-2518565 --- addons/test_website_modules/__manifest__.py | 29 +++++ .../static/tests/tours/configurator_flow.js | 104 ++++++++++++++++++ addons/test_website_modules/tests/__init__.py | 4 + .../tests/test_configurator.py | 50 +++++++++ 4 files changed, 187 insertions(+) create mode 100644 addons/test_website_modules/__manifest__.py create mode 100644 addons/test_website_modules/static/tests/tours/configurator_flow.js create mode 100644 addons/test_website_modules/tests/__init__.py create mode 100644 addons/test_website_modules/tests/test_configurator.py diff --git a/addons/test_website_modules/__manifest__.py b/addons/test_website_modules/__manifest__.py new file mode 100644 index 00000000000..d6771d3781d --- /dev/null +++ b/addons/test_website_modules/__manifest__.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Website Modules Test', + 'version': '1.0', + 'category': 'Hidden', + 'sequence': 9876, + 'description': """This module contains tests related to website modules. +It allows to test website business code when another website module is +installed.""", + 'depends': [ + 'theme_default', + 'website', + 'website_blog', + 'website_event_sale', + 'website_slides', + ], + 'data': [ + ], + 'installable': True, + 'application': False, + 'assets': { + 'web.assets_tests': [ + 'test_website_modules/static/tests/**/*', + ], + }, + 'license': 'LGPL-3', +} diff --git a/addons/test_website_modules/static/tests/tours/configurator_flow.js b/addons/test_website_modules/static/tests/tours/configurator_flow.js new file mode 100644 index 00000000000..ea4529a0927 --- /dev/null +++ b/addons/test_website_modules/static/tests/tours/configurator_flow.js @@ -0,0 +1,104 @@ +odoo.define('test_website_modules.tour.configurator_flow', function (require) { +'use strict'; + +const tour = require('web_tour.tour'); + +tour.register('configurator_flow', { + test: true, + url: '/web#action=website.action_website_configuration', +}, +[ + { + content: "click on create new website", + trigger: 'button[name="action_website_create_new"]', + }, { + content: "insert website name", + trigger: 'input[name="name"]', + run: 'text Website Test', + }, { + content: "validate the website creation modal", + trigger: 'button.btn-primary', + }, + // Configurator first screen + { + content: "click next", + trigger: 'button.o_configurator_show', + }, + // Description screen + { + content: "select a website type", + trigger: 'a.o_change_website_type', + }, { + content: "insert a website industry", + trigger: '.o_configurator_industry input', + run: 'text ab', + }, { + content: "select a website industry from the autocomplete", + trigger: '.o_configurator_industry ul li a', + }, { + content: "select an objective", + trigger: '.o_configurator_purpose_dd a', + }, { + content: "choose from the objective list", + trigger: 'a.o_change_website_purpose', + }, + // Palette screen + { + content: "chose a palette card", + trigger: '.palette_card', + }, + // Features screen + { + content: "select Pricing", + trigger: '.card:contains("Pricing")', + }, { + content: "Events should be selected (module already installed)", + extra_trigger: '.card.border-success:contains("Pricing")', + trigger: '.card.card_installed:contains("Events")', + run: function () {}, // it's a check + }, { + content: "Slides should be selected (module already installed)", + trigger: '.card.card_installed:contains("eLearning")', + run: function () {}, // it's a check + }, { + content: "Success Stories (Blog) and News (Blog) should be selected (module already installed)", + extra_trigger: '.card.card_installed:contains("Success Stories")', + trigger: '.card.card_installed:contains("News")', + run: function () {}, // it's a check + }, { + content: "Click on build my website", + trigger: 'button.btn-primary', + }, { + content: "Loader should be shown", + trigger: '.o_theme_install_loader_container', + run: function () {}, // it's a check + }, { + content: "Wait untill the configurator is finished", + trigger: 'body.editor_started', + timeout: 30000, + }, { + content: "exit edit mode", + trigger: '.o_we_website_top_actions button.btn-primary:contains("Save")', + }, { + content: "check menu and footer links are correct", + trigger: '#oe_main_menu_navbar', // edit mode left and landed on regular frontend + run: function () { + for (const menu of ['Home', 'Events', 'Courses', 'Pricing', 'News', 'Success Stories', 'Contact us']) { + if (!$(`#top_menu a:contains(${menu})`).length) { + console.error(`Missing ${menu} menu. It should have been created by the configurator.`); + } + } + for (const url of ['/', '/event', '/slides', '/pricing', '/blog/', '/blog/', '/contactus']) { + if (!$(`#top_menu a[href^='${url}'`).length) { + console.error(`Missing ${url} menu URL. It should have been created by the configurator.`); + } + } + for (const link of ['Privacy Policy', 'Contact us']) { + if (!$(`#footer ul a:contains(${link})`).length) { + console.error(`Missing ${link} footer link. It should have been created by the configurator.`); + } + } + }, + }, +]); +}); diff --git a/addons/test_website_modules/tests/__init__.py b/addons/test_website_modules/tests/__init__.py new file mode 100644 index 00000000000..458e74d12ca --- /dev/null +++ b/addons/test_website_modules/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_configurator diff --git a/addons/test_website_modules/tests/test_configurator.py b/addons/test_website_modules/tests/test_configurator.py new file mode 100644 index 00000000000..525e71faec6 --- /dev/null +++ b/addons/test_website_modules/tests/test_configurator.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from unittest.mock import patch + +import odoo.tests +from odoo.addons.iap.tools.iap_tools import iap_jsonrpc_mocked + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestConfigurator(odoo.tests.HttpCase): + + def _theme_upgrade_upstream(self): + # patch to prevent module install/upgrade during tests + pass + + def setUp(self): + super().setUp() + + def iap_jsonrpc_mocked_configurator(*args, **kwargs): + endpoint = args[0] + if endpoint.endswith('/api/website/1/configurator/industries'): + return {"industries": [ + {"id": 1, "label": "abbey"}, + {"id": 2, "label": "aboriginal and torres strait islander organisation"}, + {"id": 3, "label": "aboriginal art gallery"}, + {"id": 4, "label": "abortion clinic"}, + {"id": 5, "label": "abrasives supplier"}, + {"id": 6, "label": "abundant life church"}]} + elif '/api/website/1/configurator/recommended_themes' in endpoint: + return [] + elif '/api/website/1/configurator/custom_resources/' in endpoint: + return { + 'pages': { + 'pricing': ['website.s_comparisons'], + 'homepage': ['website.s_cover', 'website.s_text_image', 'website.s_numbers']}, + 'images': []} + + iap_jsonrpc_mocked() + + iap_patch = patch('odoo.addons.iap.tools.iap_tools.iap_jsonrpc', iap_jsonrpc_mocked_configurator) + iap_patch.start() + self.addCleanup(iap_patch.stop) + + patcher = patch('odoo.addons.website.models.ir_module_module.IrModuleModule._theme_upgrade_upstream', wraps=self._theme_upgrade_upstream) + patcher.start() + self.addCleanup(patcher.stop) + + def test_01_configurator_flow(self): + self.start_tour('/web#action=website.action_website_configuration', 'configurator_flow', login="admin")