From 264bb780a1e8c197658bc048074ca83a91a0fc57 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Fri, 17 Jul 2015 15:34:39 +0200 Subject: [PATCH] [IMP] web: web modules return readable logs and phantomjs logs boot.js log: * ``Missing dependencies``: These modules do not appear in the page. It is possible that the JavaScript file is not in the page or that the module name is wrong * ``Failed modules``: A javascript error is detected * ``Rejected modules``: The module returns a rejected deferred. It (and its dependent modules) is not loaded. * ``Rejected linked modules``: Modules who depend on a rejected module * ``Non loaded modules``: Modules who depend on a missing or a failed module --- addons/web/static/src/js/boot.js | 56 ++++++++++++++++++----- addons/web/static/src/js/tour.js | 6 +-- addons/web/views/database_manager.html | 1 - addons/web/views/webclient_templates.xml | 1 - addons/web_editor/static/src/js/iframe.js | 4 -- addons/website/static/src/js/website.js | 10 +--- doc/reference/javascript.rst | 17 +++++++ openerp/tests/common.py | 26 +++++++---- 8 files changed, 82 insertions(+), 39 deletions(-) diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index dc4ea5b337c..97e3e121a6f 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -6,9 +6,25 @@ * @name openerp * @namespace openerp * - * Modules can return a deferred the module is mark as loaded only when - * the deferred is resolved, and the service value equal the resolved value. - * The module can be rejected (unloaded) and logged as info. + * Each module can return a deferred. In that case, the module is marked as loaded + * only when the deferred is resolved, and its value is equal to the resolved value. + * The module can be rejected (unloaded). This will be logged in the console as info. + * + * logs: + * Missing dependencies: + * These modules do not appear in the page. It is possible that the + * JavaScript file is not in the page or that the module name is wrong + * Failed modules: + * A javascript error is detected + * Rejected modules: + * The module returns a rejected deferred. It (and its dependent modules) + * is not loaded. + * Rejected linked modules: + * Modules who depend on a rejected module + * Non loaded modules: + * Modules who depend on a missing or a failed module + * Debug: + * Non loaded or failed module informations for debugging */ (function() { @@ -123,10 +139,7 @@ this.process_jobs(jobs, services); }, - init: function () { - odoo.__DEBUG__.remaining_jobs = jobs; - odoo.__DEBUG__.web_client = services['web.web_client']; - + log: function () { if (jobs.length) { var debug_jobs = {}; var rejected = []; @@ -168,10 +181,16 @@ } var missing = odoo.__DEBUG__.get_missing_jobs(); var failed = odoo.__DEBUG__.get_failed_jobs(); - console.error('Warning: Some modules could not be started !'+ - '\nMissing dependencies: ', !missing.length ? null : missing, - '\nFailed modules: ', _.isEmpty(failed) ? null : _.map(failed, function (job) {return job.name;}), - '\nUnloaded modules: ', _.isEmpty(debug_jobs) ? null : debug_jobs); + var unloaded = _.filter(debug_jobs, function (job) { return job.missing; }); + + var log = [(_.isEmpty(failed) ? (_.isEmpty(unloaded) ? 'info' : 'warning' ) : 'error') + ':', 'Some modules could not be started']; + if (missing.length) log.push('\nMissing dependencies: ', missing); + if (!_.isEmpty(failed)) log.push('\nFailed modules: ', _.pluck(failed, 'name')); + if (!_.isEmpty(rejected)) log.push('\nRejected modules: ', rejected); + if (!_.isEmpty(rejected_linked))log.push('\nRejected linked modules:', rejected_linked); + if (!_.isEmpty(unloaded)) log.push('\nNon loaded modules: ', _.pluck(unloaded, 'name')); + if (!_.isEmpty(debug_jobs)) log.push('\nDebug: ', debug_jobs); + console[_.isEmpty(unloaded) ? 'info' : 'error'].apply(console, log); } }, process_jobs: function (jobs, services) { @@ -229,4 +248,19 @@ } }; + // automatically log errors detected when loading modules + var log_when_loaded = function () { + _.delay(function () { + var len = job_deferred.length; + $.when.apply($, job_deferred).then(function () { + if (len === job_deferred.length) { + odoo.log(); + } else { + log_when_loaded(); + } + }); + }, 100); + }; + $(log_when_loaded); + })(); diff --git a/addons/web/static/src/js/tour.js b/addons/web/static/src/js/tour.js index dd74ca42e9e..5f8da21cbc9 100644 --- a/addons/web/static/src/js/tour.js +++ b/addons/web/static/src/js/tour.js @@ -433,7 +433,7 @@ var Tour = { }, error: function (step, message) { var state = Tour.getState(); - Tour.logError(step, "Error: " + message, true); + Tour.logError(step, "error: " + message, true); Tour.endTour(); }, lists: function () { @@ -537,7 +537,7 @@ var Tour = { } else if(next.onerror) { - Tour.logError(next, "Error: Can't reach the next step (call next step onerror)", false); + Tour.logError(next, "error: Can't reach the next step (call next step onerror)", false); var id = next.onerror(); if (id) { if (Tour._goto(id)) return; @@ -756,7 +756,7 @@ $(document).ready(function () { if (Tour.autoRunning) { Tour.running(); } - }, 0); + }, 250); }); return Tour; diff --git a/addons/web/views/database_manager.html b/addons/web/views/database_manager.html index d3ebd84339f..6e05857ea47 100644 --- a/addons/web/views/database_manager.html +++ b/addons/web/views/database_manager.html @@ -108,7 +108,6 @@ web_client.start(); return web_client; }); - odoo.init(); }); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 69899d742db..e08299f69e4 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -254,7 +254,6 @@ web_client.start(); return web_client; }); - odoo.init(); }); diff --git a/addons/web_editor/static/src/js/iframe.js b/addons/web_editor/static/src/js/iframe.js index 553c68b30af..10aa53d353b 100644 --- a/addons/web_editor/static/src/js/iframe.js +++ b/addons/web_editor/static/src/js/iframe.js @@ -72,7 +72,3 @@ translator.Class.include({ }); }); - -$(function () { - _.delay(odoo.init, 500); -}); diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index ddae7891266..9a87c4bbae8 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -221,13 +221,9 @@ ajax.loadXML('/website/static/src/xml/website.xml', qweb); * Cancel the auto run of Tour (test) and launch the tour after tob bar all bind events */ -Tour.autoRunning = false; base.ready().then(function () { data.topBar = new TopBar(); - data.topBar.attachTo($("#oe_main_menu_navbar")) - .then(function () { - setTimeout(Tour.running,0); - }); + data.topBar.attachTo($("#oe_main_menu_navbar")); }); /** @@ -321,7 +317,3 @@ var data = { return data; }); - -$(function () { - _.defer(odoo.init); -}); diff --git a/doc/reference/javascript.rst b/doc/reference/javascript.rst index a41709beb51..d10c72145dd 100644 --- a/doc/reference/javascript.rst +++ b/doc/reference/javascript.rst @@ -755,6 +755,23 @@ properly. Modules are contained in a file, but a file can define several modules (however, it is better to keep them in separate files). +Each module can return a deferred. In that case, the module is marked as loaded +only when the deferred is resolved, and its value is equal to the resolved value. +The module can be rejected (unloaded). This will be logged in the console as info. + +* ``Missing dependencies``: + These modules do not appear in the page. It is possible that the JavaScript + file is not in the page or that the module name is wrong +* ``Failed modules``: + A javascript error is detected +* ``Rejected modules``: + The module returns a rejected deferred. It (and its dependent modules) is not + loaded. +* ``Rejected linked modules``: + Modules who depend on a rejected module +* ``Non loaded modules``: + Modules who depend on a missing or a failed module + Web client structure -------------------- diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 0ae5adafaf6..c591e8c7a68 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -305,19 +305,25 @@ class HttpCase(TransactionCase): line, buf = buf.split('\n', 1) line = str(line) - # relay everything from console.log, even 'ok' or 'error...' lines - _logger.info("phantomjs: %s", line) + if line.startswith("error"): + try: + # when errors occur the execution stack may be sent as a JSON + _logger.error("phantomjs: %s", json.loads(line[6:])) + except ValueError: + line_ = line.split('\n\n') + _logger.error("phantomjs: %s", line_[0]) + # The second part of the log is for debugging + if len(line_) > 1: + _logger.info("phantomjs: \n%s", line.split('\n\n')[1]) + pass + break + elif line.startswith("warning"): + _logger.warn("phantomjs: %s", line) + else: + _logger.info("phantomjs: %s", line) if line == "ok": break - if line.startswith("error"): - line_ = line[6:] - # when error occurs the execution stack may be sent as as JSON - try: - line_ = json.loads(line_) - except ValueError: - pass - self.fail(line_ or "phantomjs test failed") def phantom_run(self, cmd, timeout): _logger.info('phantom_run executing %s', ' '.join(cmd))