Skip to content

Commit 3c526a2

Browse files
committed
[IMP] integration_testing: add information about JS touring
Adding basic information about `How to make a test tour`. task-2742841 closes #1517 X-original-commit: 827270c Signed-off-by: Morgane Demesmaeker <[email protected]>
1 parent 7ebbd34 commit 3c526a2

File tree

2 files changed

+181
-17
lines changed

2 files changed

+181
-17
lines changed

content/developer/reference/backend/testing.rst

Lines changed: 179 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ tests
1414
- Tours (see `Integration Testing`_): tours simulate a real situation. They ensures that the
1515
python and the javascript parts properly talk to each other.
1616

17+
.. _testing/python:
18+
1719
Testing Python code
1820
===================
1921

@@ -28,11 +30,11 @@ e.g.
2830
.. code-block:: text
2931
3032
your_module
31-
|-- ...
32-
`-- tests
33-
|-- __init__.py
34-
|-- test_bar.py
35-
`-- test_foo.py
33+
├── ...
34+
├── tests
35+
| ├── __init__.py
36+
| ├── test_bar.py
37+
| └── test_foo.py
3638
3739
and ``__init__.py`` contains::
3840

@@ -124,7 +126,7 @@ Subclasses of :class:`odoo.tests.common.BaseCase` (usually through
124126
``standard`` and ``at_install`` by default.
125127

126128
Invocation
127-
^^^^^^^^^^
129+
~~~~~~~~~~
128130

129131
:option:`--test-tags <odoo-bin --test-tags>` can be used to select/filter tests
130132
to run on the command-line. It implies :option:`--test-enable <odoo-bin --test-enable>`,
@@ -230,7 +232,7 @@ can be specified at once separated by a `,` like with regular tags.
230232
.. _reference/testing/tags:
231233

232234
Special tags
233-
^^^^^^^^^^^^
235+
~~~~~~~~~~~~
234236

235237
- ``standard``: All Odoo tests that inherit from
236238
:class:`~odoo.tests.common.BaseCase` are implicitly tagged standard.
@@ -248,7 +250,7 @@ Special tags
248250
``-at_install`` when tagging a test class.
249251

250252
Examples
251-
^^^^^^^^
253+
~~~~~~~~
252254

253255
.. important::
254256

@@ -533,15 +535,175 @@ Tips
533535
Integration Testing
534536
===================
535537

536-
Testing Python code and JS code separately is very useful, but it does not prove
537-
that the web client and the server work together. In order to do that, we can
538-
write another kind of test: tours. A tour is a mini scenario of some interesting
539-
business flow. It explains a sequence of steps that should be followed. The
540-
test runner will then create a Chrome headless browser, point it to the proper url
541-
and simulate the click and inputs, according to the scenario.
538+
Testing Python code and JS code separately is very useful, but it does not prove that the web client
539+
and the server work together. In order to do that, we can write another kind of test: tours. A
540+
tour is a mini scenario of some interesting business flow. It explains a sequence of steps that
541+
should be followed. The test runner will then create a PhantomJs browser, point it to the proper
542+
url and simulate the click and inputs, according to the scenario.
543+
544+
Writing a test tour
545+
-------------------
546+
547+
Structure
548+
~~~~~~~~~
549+
550+
To write a test tour for `your_module`, start with creating the required files:
551+
552+
.. code-block:: text
553+
554+
your_module
555+
├── ...
556+
├── static
557+
| └── tests
558+
| └── tours
559+
| └── your_tour.js
560+
├── tests
561+
| ├── __init__.py
562+
| └── test_calling_the_tour.py
563+
└── __manifest__.py
564+
565+
You can then:
566+
567+
- update :file:`__manifest__.py` to add :file:`your_tour.js` in the assets.
568+
569+
.. code-block:: python
570+
571+
'assets': {
572+
'web.assets_tests': [
573+
'your_module/static/tests/tours/your_tour.js',
574+
],
575+
},
576+
577+
- update :file:`__init__.py` in the folder :file:`tests` to import :file:`test_calling_the_tour`.
578+
579+
.. seealso::
580+
- :ref:`Assets Bundle <reference/assets_bundle>`
581+
- :ref:`testing/python`
582+
583+
Javascript
584+
~~~~~~~~~~
585+
586+
#. Setup your tour by registering it.
587+
588+
.. code-block:: javascript
589+
590+
/** @odoo-module **/
591+
import tour from 'web_tour.tour';
592+
tour.register('rental_product_configurator_tour', {
593+
url: '/web', // Here, you can specify any other starting url
594+
test: true,
595+
}, [
596+
// Your sequence of steps
597+
]);
598+
599+
#. Add any step you want.
600+
601+
Every step contains at least a trigger. You can either use the `predefined steps
602+
<https://github.com/odoo/odoo/blob/15.0/addons/web_tour/static/src/js/tour_step_utils.js>`_ or write
603+
your own personalized step.
604+
605+
Here are some example of steps:
606+
607+
.. example::
608+
609+
.. code-block:: javascript
610+
611+
// First step
612+
tour.stepUtils.showAppsMenuItem(),
613+
// Second step
614+
{
615+
trigger: '.o_app[data-menu-xmlid="your_module.maybe_your_module_menu_root"]',
616+
edition: 'community' // Optional
617+
}, {
618+
// Third step
619+
},
620+
621+
.. example::
622+
623+
.. code-block:: javascript
624+
625+
{
626+
trigger: '.js_product:has(strong:contains(Chair floor protection)) .js_add',
627+
extra_trigger: '.oe_advanced_configurator_modal', // This ensure we are in the wizard
628+
},
629+
630+
.. example::
631+
632+
.. code-block:: javascript
633+
634+
{
635+
trigger: 'a:contains("Add a product")',
636+
// Extra-trigger to make sure a line is added before trying to add another one
637+
extra_trigger: '.o_field_many2one[name="product_template_id"] .o_external_button',
638+
},
639+
640+
Here are some possible arguments for your personalized steps:
641+
642+
- **trigger**: selector/element/jQuery you want to trigger
643+
- **extra-trigger**: optional selector/element/jQuery that needs to be present before the next
644+
step begins. This is especially useful when the tour needs to wait for a wizard to open, a
645+
line added to a list view...
646+
- **run**: optional action to run, defaults either to `click` or `text Test` if you are triggering
647+
an input. A multitude of actions are possible. Here are some of them: `click`, `dbclick`,
648+
`tripleclick`, `text Example`, `drag_and_drop selector1 selector2`...
649+
- **edition**: optional,
650+
651+
- If you don't specify an edition, the step will be active in both community and enterprise.
652+
- Sometimes, a step will be different in enterprise or in community. You can then write two
653+
steps, one for the enterprise edition and one for the community one.
654+
- Generally, you want to specify an edition for steps that use the main menu as the main
655+
menus are different in community and enterprise.
656+
- **position**: optional
657+
- **id**: optional
658+
- **auto**: optional
659+
- **in_modal**: optional
660+
661+
.. tip::
662+
Your browser's developer tools are your best tool to find the element your tour needs to use as a
663+
trigger/extra-trigger.
664+
665+
.. seealso::
666+
- `jQuery documentation about find <https://api.jquery.com/find/>`_
667+
668+
Python
669+
~~~~~~
670+
671+
To start a tour from a python test, make the class inherit from
672+
:class:`~odoo.tests.common.HTTPCase`, and call `start_tour`:
673+
674+
.. code-block:: python
675+
676+
def test_your_test(self):
677+
# Optional Setup
678+
self.start_tour("/web", 'your_module.your_tour_name', login="admin")
679+
# Optional verifications
680+
681+
Debugging tips
682+
--------------
683+
684+
Running the tour in debug mode
685+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
686+
687+
First, activate the :doc:`developer mode </applications/general/developer_mode>` with
688+
`?debug=tests`. Then, open your debug menu and click on **Start Tour**. You can now launch your tour
689+
from there with the button `Test`.
690+
691+
You can also add this step in your tour to stop it right where you want it to:
692+
693+
.. code-block:: javascript
694+
695+
{
696+
trigger: "body",
697+
run: () => {debugger}
698+
}
699+
700+
.. caution::
701+
Be aware that when running the tour, any data added to the setup of your python test won't be
702+
present in the tour unless you launched the test calling the tour with a breakpoint.
703+
542704

543705
Screenshots and screencasts during browser_js tests
544-
---------------------------------------------------
706+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
545707

546708
When running tests that use HttpCase.browser_js from the command line, the Chrome
547709
browser is used in headless mode. By default, if a test fails, a PNG screenshot is
@@ -602,7 +764,7 @@ To specify this feature for a given model, the following methods and attributes
602764
on the model to enable database population.
603765

604766
Example model
605-
^^^^^^^^^^^^^
767+
~~~~~~~~~~~~~
606768

607769
.. code-block:: python
608770
@@ -646,7 +808,7 @@ Example model
646808
return records
647809
648810
Population tools
649-
^^^^^^^^^^^^^^^^
811+
~~~~~~~~~~~~~~~~
650812

651813
Multiple population tools are available to easily create
652814
the needed data generators.

content/developer/reference/frontend/assets.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ associated with a checksum, which is injected into the page source. The checksum
4747
is then added to the url, which means that it is possible to safely set the cache
4848
headers to a long period.
4949

50+
.. _reference/assets_bundle:
51+
5052
Bundles
5153
=======
5254

0 commit comments

Comments
 (0)