JS Tour

Tours are used to demonstrate module capabilities step by step with popup windows. It may be launched automatically or manually.

Creating Tour

10.0+

Example from website_sale module:

odoo.define('website_sale.tour', function (require) {
'use strict';

var tour = require("web_tour.tour");
var base = require("web_editor.base");

var options = {
    test: true,
    url: '/shop',
    wait_for: base.ready()
}

var tour_name = 'shop_buy_product';
tour.register(tour_name, options,
    [
        {
            content: "search ipod",
            trigger: 'form input[name="search"]',
            run: "text ipod",
        },
        {
            content: "search ipod",
            trigger: 'form:has(input[name="search"]) .oe_search_button',
        },
        {
            content: "select ipod",
            trigger: '.oe_product_cart a:contains("iPod")',
        },
        {
            content: "select ipod 32GB",
            extra_trigger: '#product_detail',
            trigger: 'label:contains(32 GB) input',
        },
        {
            content: "click on add to cart",
            extra_trigger: 'label:contains(32 GB) input:propChecked',
            trigger: '#product_detail form[action^="/shop/cart/update"] .btn',
        },
        /* ... */
    ]
);

});

Each step may have following attrubutes:

  • content – name or title of the step
  • trigger (mandatory) – where to place tip. In js tests: where to click
  • extra_trigger – when this becomes visible, the tip is appeared. In js tests: when to click
  • position – how to show tip (left, rigth, top, bottom), default right
  • width – width in px of the tip when opened, default 270
  • run – what to do when tour runs automatically (e.g. in tests)
    • 'text SOMETEXT' – writes value in trigger element
    • 'click'
    • 'drag_and_drop TO_SELECTOR'
    • 'auto' – auto action (click or text)
    • function: (actions) { ... } – actions is instance of RunningTourActionHelper – see tour_manager.js for its methods.
  • auto – step is skipped in non-auto running

Options (second argument of tour.register):

  • test – only for tests
  • url – open link before running the tour
  • wait_for – wait for deffered object before running the script
  • skip_enabled – adds Skip button in tips

More documentation:

8.0, 9.0

Tour is a simple JS file with some determined structure. Example:

{
    id: 'mails_count_tour',
    name: _t("Mails count Tour"),
    mode: 'test',
    path: '/web#id=3&model=res.partner',
    steps: [
        {
            title:     _t("Mails count tutorial"),
            content:   _t("Let's see how mails count work."),
            popover:   { next: _t("Start Tutorial"), end: _t("Skip") },
        },
        {
            title:     _t("New fields"),
            content:   _t("Here is new fields with mails counters. Press one of it."),
            element:   '.mails_to',
        },
        {
            waitNot:   '.mails_to:visible',
            title:     _t("Send message from here"),
            placement: 'left',
            content:   _t("Now you can see corresponding mails. You can send mail to this partner right from here. Press <em>'Send a mesage'</em>."),
            element:   '.oe_mail_wall .oe_msg.oe_msg_composer_compact>div>.oe_compose_post',
        },
    ]
}

What you do here is describing steps that got to be proceeded by user or phantom (phantomjs).

In odoo 8 tour defines this way:

(function () {
'use strict';
var _t = openerp._t;
openerp.Tour.register({ ...

In odoo 9 tour defines that way:

odoo.define('account.tour_bank_statement_reconciliation', function(require) {
'use strict';
var core = require('web.core');
var Tour = require('web.Tour');
var _t = core._t;
Tour.register({ ...

Important details:

  • id - need to call this tour
  • path - from this path tour will be started in test mode

Next step occurs when all conditions are satisfied and popup window will appear near (chose position in placement) element specified in element. Element must contain css selector of corresponding node. Conditions may be:

  • waitFor - this step will not start if waitFor node absent.
  • waitNot - this step will not start if waitNot node exists.
  • wait - just wait some amount of milliseconds before next step.
  • element - similar to waitFor, but element must be visible
  • closed window - if popup window have close button it must be closed before next step.

Opened popup window (from previous step) will close automatically and new window (next step) will be shown.

Inject JS Tour file on page:

<template id="res_partner_mails_count_assets_backend" name="res_partner_mails_count_assets_backend" inherit_id="web.assets_backend">
    <xpath expr="." position="inside">
        <script src="/res_partner_mails_count/static/src/js/res_partner_mails_count_tour.js" type="text/javascript"></script>
    </xpath>
</template>

Some docs is here (begin from 10 slide): http://www.slideshare.net/openobject/how-to-develop-automated-tests Also checkout here: https://github.com/odoo/odoo/blob/9.0/addons/web/static/src/js/tour.js

You can launch tour by entering in browser address like this mydatabase/web#/tutorial.mails_count_tour=true where after tutorial. is id of your tour.

Manual launching

10.0+

  • activate developer mode.
  • Click Bug icon (between chat icon and Username at top right-hand corner)
    • click Start tour
  • Click Play button – it starts tour in auto mode

To run test-only tours (or to run tours in auto mode but with some delay) do as following:

  • open browser console (F12 in Chrome)

  • Type in console:

    odoo.__DEBUG__.services['web_tour.tour'].run('TOUR_NAME', 1000); // 1000 is delay in ms before auto action
    

Launch Tour after installation

10.0+

TODO

8.0, 9.0

To run tour after module installation do next steps.

  • Create ToDo
  • Create Action

ToDo is some queued web actions that may call Action like this:

<record id="base.open_menu" model="ir.actions.todo">
    <field name="action_id" ref="action_website_tutorial"/>
    <field name="state">open</field>
</record>

Action is like this:

<record id="res_partner_mails_count_tutorial" model="ir.actions.act_url">
    <field name="name">res_partner_mails_count Tutorial</field>
    <field name="url">/web#id=3&amp;model=res.partner&amp;/#tutorial_extra.mails_count_tour=true</field>
    <field name="target">self</field>
</record>

Here tutorial_extra.**mails_count_tour** is tour id.

Use eval to compute some python code if needed:

<field name="url" eval="'/web?debug=1&amp;res_partner_mails_count=tutorial#id='+str(ref('base.partner_root'))+'&amp;view_type=form&amp;model=res.partner&amp;/#tutorial_extra.mails_count_tour=true'"/>