From odoo/tests/

def phantom_js(self, url_path, code, ready="window", login=None, timeout=60, **kw):
    """ Test js code running in the browser
    - optionnally log as 'login'
    - load page given by url_path
    - wait for ready object to be available
    - eval(code) inside the page
    To signal success test do:
    To signal failure do:
    If neither are done before timeout test fails.


  • odoo first loads url_path as user login (e.g. 'admin', 'demo' etc.) or as non-authed user

  • then waits for ready condition, i.e. when some js variable (e.g. window) become truthy

  • then executes js code

  • then wait for one of condition:

    • someone prints console.log('ok') – test passed

    • someone prints console.log('error') – test failed

    • timeout seconds are passed – test failed


Example from mail_sent:

# -*- coding: utf-8 -*-
import odoo.tests

class TestUi(odoo.tests.HttpCase):

    def test_01_mail_sent(self):
        # wait till page loaded and then click and wait again
        code = """
            setTimeout(function () {
                setTimeout(function () {console.log('ok');}, 3000);
            }, 1000);
        link = '/web#action=%s' % self.ref('mail.mail_channel_action_client_chat')
        self.phantom_js(link, code, "['mail_sent.sent'].is_ready", login="demo")

In this test:

  • odoo first loads /web#action=... page

  • then waits for['mail_sent.sent'].is_ready

    •['mail_sent.sent'] is similar to require('mail_sent.sent')

    • is_ready is a variable in sent.js

  • then executes js code:

    setTimeout(function () {
        setTimeout(function () {console.log('ok');}, 3000);
    }, 1000);

    which clicks on Sent menu and gives to the page 3 seconds to load it.

    This code neither throws errors (e.g. via throw new Error('Some error description') nor log console.log('error'), but you can add ones to your code to catch failed cases you need.

  • then if everything is ok, odoo get message console.log('ok')