Previously, when killing the server, the longpolling bus stopped but
didn't start polling again after a few seconds, this was caused by the
fact that ConnectionLostError wasn't treated like a legacy error and
remapped to an object with a message, meaning it didn't trigger
guardedCatch callbacks.
Since ConnectionLostErrors should be handled much the same way as
RPCError when interacting with legacy code this commit simply adds
ConnectionLostError in the same places we already have RPCError during
error handling of legacy errors, but delegates behaviour to the new
lostConnectionHandler when appropriate.
closesodoo/odoo#74530
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
A number of functions from `web.test_utils` have been deprecated at
the module root and should be called through submodules.
Fix a bunch of remaining cases. Also add a few missing `await`s on
`triggerMouseEvent` calls. Don't bother rewriting the imports in
unpacking style as for most updating the imports is unnecessary. Do so
for `field_one2many_tests.js` where we have to rewrite the imports
anyway:
* recursively import controlPanel, createView, mock.patch and
mock.unpatch
* remove the aliasing of controlPanel to cpHelpers
Some services are coupled with a Component. Usually the service
handles the state of the system, and the Component displays or uses it.
To enable the communication between the service and the component
while making it private, the services should add themselves their
Component in the relevant registry, with the proper means of communication
passed in props.
This mechanism relies on c1d49d494e0ae3a94b3943186eb6d1ebd7b98a6e
This commit splits the 'getActionManagerTestConfig' helper into 2:
'setupWebClientServiceRegistry' and 'getActionManagerServerData'.
The first one is now automatically called by the 'createWebClient'
helper, as it properly setups the service registry with all services
required by the WebClient component.
The second one generates a few data (menus, actions, views...) that
can be used in tests. That helper is mainly useful for action tests
(formerly ActionManager tests) in web. With this refactoring, they
are no longer generated for each test in the whole codebase that
spawns a webclient, as before this commit.
closesodoo-dev/odoo#906
Related: odoo-dev/enterprise#161
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit adapts the community codebase to the rewriting of the
/web application in owl.
Co-authored-by: Aaron Bohy <aab@odoo.com>
Co-authored-by: Bruno Boi <boi@odoo.com>
Co-authored-by: Géry Debongnie <ged@odoo.com>
Co-authored-by: Samuel Degueldre <sad@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Co-authored-by: Simon Genin (ges) <ges@odoo.com>
Co-authored-by: Francois (fge) <fge@odoo.com>
Co-authored-by: Michael Mattiello (mcm) <mcm@odoo.com>
Co-authored-by: Julien Mougenot <jum@odoo.com>
Co-authored-by: Lucas Perais (lpe) <lpe@odoo.com>
Co-authored-by: Jorge Pinna Puissant <jpp@odoo.com>
Before this commit, it might happen that, in some situations,
with several tabs opened, the CrossTabBus called the longpolling
route repeatedly, thus slowing down the server, and freezing the
webclient.
The issue was tricky to reproduce. It was a race-condition that
could occur when several tabs performed simultanous calls to
addChannel, while being unloaded or becoming mastertab in the
meantime (e.g. when opening/closing/refreshing several tabs
simultaneously).
This issue has been introduced by [1] which by mistake (probably)
made each tab calling itself the localStorage to update the list
of channels when it was notified that the list of channels in
the localStorage just changed. So if several tabs had a slightly
different list of channels at a given moment (e.g. at startup),
it might happen that they in turn, undo what another tab just
put in the localStorage, and thus produced an infinite loop of
localStorage writes and longpolling request aborts/calls.
The issue could be reproduced with the OCA module [2], which
performs several addChannel at webclient startup.
This commit restores this part of the code as it was initially
written in [3].
Closes#69067
opw~2502799
maybe opw~2451865 as well
[1] https://github.com/odoo/odoo/commit/6448420
[2] https://odoo-community.org/shop/product/web-notify-2670#attr=10773
[3] https://github.com/odoo/odoo/commit/38581f67236377daa767ca2216529a26b8708b00#diff-f6eccad21ae3543606ab8f97b8b097d015412caeaee2bf8cc928eb3ccabac9f5R149closesodoo/odoo#69777
X-original-commit: a52aa41d04330efb81090409ec7fbcbbedaca317
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Use case:
When the server is restarted, the python is updated,
but some users may have an ongoing session in a browser tab
This may lead to code being unsynchronized and ultimately to some
odd bugs.
Purpose:
When we are in such a case, that is, the assets were recomputed
after a update of the code and a restart of the server by the request of another user,
notify connected users that assets have changed.
Then propose them to reload the page.
Known caveats:
- This is not a developer's feature.
Since assets computing is ORM cached, they have limited
opportunities to rebuild. Namely, the feature won't trigger
each time the JS has changed, rather, it will
when JS has changed AND the cache has been reset somehow (e.g. when the server is restarted).
- This not a portal/website feature either, but only in backend.
Business clients won't be notified that the JS has changed.
- While requests debug=assets do trigger a recomputing
of the *components* of bundles, they do not save a bundle
This means that the requests that sends the notification
cannot be debug=assets.
Task 2034462
closesodoo/odoo#39875
Signed-off-by: Mathieu Duckerts-Antoine <Polymorphe57@users.noreply.github.com>
This commit adapts tests following recent changes on the helpers.
The main change is that addMockEnvironment (and all functions using
it) are now async, as they need to wait for services to be started.
This rev. introduces robust helpers to use in the JS tests suite to
interact with DOM and components, and starts using them (almost)
everywhere.
All the helpers are exposed though testUtils.js.
There are 2 kinds of helpers:
1. Assertions
-------------
* assert.containsNone, containsN, containsOnce check that the DOM
(or a specific part of the DOM) contains a `selector`. It
generates a correct error message automatically.
ex: assert.strictEqual(form.$('.o_form_editable'), 1, "msg");
-> assert.containsOnce(form, '.o_form_editable');
* assert.isVisible, isNotVisible check that the DOM has an element
visible or not. They also check that the element is actually in
the DOM (before most tests didn't verify this).
* assert.hasClass, doesNotHaveClass, hasAttrVAlue, check specific
properties of a DOM element, and also validate that it is
applied on a single existing DOM element (before most tests
didn't verify this).
ex: assert.notOk(form.$('button').hasClass('btn-primary'));
-> assert.doesNotHaveClass(form.$('button'), 'btn-primary');
2. Utilities
------------
The goal of the utilities is to centralize the definition of many
standard components and interactions, ensuring that when we
refactor the JS framework, we do not need to change all the tests.
Existing mock utilities (addMockEnvironment, intercept, path,
patchDate, unpatch and fieldsViewGet) are moved to
'testUtils.mock.*'.
Existing DOM utilities are moved to 'testUtils.dom.*'.
New dom utilities are created for opendDatePicker, click,
clickFirst and clickLast. Helper `click` verifies that there is
exactly 1 element visible in the DOM you click on, `clickFirst`
and `clickLast` verify that there are more than one element on the
DOM.
ex: form.$('button').click();
-> testUtils.dom.click(form.$('button'));
New Form utilities: (testUtils.form.*)
clickEdit, clickSave, clickCreate, clickDiscard, all clicks on
the control panel buttons of the form.
`reload` reloads the form data.
New modal, graph, kanban and pivot utils (testUtils.pivot.*,
testUtils.kanban.*, etc.).
New fields utils: (testUtils.fields.*)
* editInput, editSelect: allow to change the value of a field,
using a selector to identify it. They validate that the input
exists and trigger the change event automatically.
* editAndTrigger: allow to modify a field and trigger specific
events after the value change
* many2one (testUtils.fields.many2one.*)
clickOpenDropdown, clickHighlightedItem, clickItem,
searchAndClickItem: use a field name instead of a selector and
do all the complex mechanism to open, filter and highlight
many2one fields.
Joint work with aab, dam, ged, mge, svs and vsc.
Before this commit, chat windows could not be sync'ed
between browser tabs for about 10 to 20 seconds.
This issue is caused by the implementation of the
crosstab longpolling, which uses a master-slave
architecture with a single tab being the master tab.
The master tab is responsible for performing the
longpolling RPC, so that it keeps a single HTTP request
for all Odoo tabs. Other tabs are synchronized through
the local storage.
When the master tab was closed, a new master tab election
must occur. However, this process was taking up to 20 seconds,
due to the tab waiting for their next tick on the local
storage to initiate a new election. The tick for a slave
tab is 10 seconds, and it may jumps a tick in case the master
tab is closed exactly before the tick, hence extending the
duration to 20 seconds.
This commit fixes the problem by ensuring that the tab
election for the longpolling is done right after the master
tab is closed. As a result, a new master tab should follow
right away.
Steps to reproduce:
1. open two tabs.
2. open a chat window in one tab: it opens in both tabs.
3. fold/unfold chat window in one tab: both tab should sync.
4. refresh both tabs.
5. fold/unfold chat window in one tab: both tab should not sync.
6. after 10 or 20 seconds, both tabs should again sync.
Task-ID 1911437
closesodoo/odoo#28925
Revision on bus refactoring: https://github.com/odoo/odoo/commit/6448420c5dd160470e465dee7729d19d8d5e7bab
Before this commit, when a user was disconnected for a very long
time, he would receive lots of chat notifications on his next login.
Here is an example of weird behaviour with this issue:
- User folds and unfolds a chat window 50 times
- User disconnects for more than 50 seconds
- User reconnects
==> the chat window rapidly folds and unfolds itself 50 times!
This issue comes from the fact that after 50 seconds without any
longpolling, the web client ignores the last tracked notification
and sents the ID `-1` to the server.
The web client always provides a notification ID to the server
on a `longpolling/poll`. Usually, the server returns all
notifications of the user with an ID greater than the provided ID.
There is an exception with ID `0`, in which all notifications since
the last connection of the user are returned.
The cause of the issue is a mismatch of the special notification
ID between the server and the web client. For the web client, the
ID `-1` is used for not tracking any notification, whereas the
server uses the ID `0` for this case. As a result, when the server
receives the value `-1`, it returns all notifications having an ID
greater than `-1`. In other words, it returns all notifications
related to this user, even the ones received long time ago!
This commit fixes the issue by enforcing the special notification ID
`0` on both the webclient and server.
Note that this logic is similar to 11.0:
- The webclient uses the ID `-1` most of the time to define 'untracked':
https://github.com/odoo/odoo/blob/11.0/addons/bus/static/src/js/bus.js#L154
- However, it passes the ID `0` to the server:
https://github.com/odoo/odoo/blob/11.0/addons/bus/static/src/js/bus.js#L193
The purpose of this change is to make the code clearer and testable.
In this change, the 'tab_manager' static object was merged with the bus
cross tab.
Cleaning was done to clearly define private and public functions as well
as handlers. The methods are documented and the constants are now defined
on the class. The bus use the service behavior with 'trigger_up'.
'bus.CrossTab' who extend 'bus.Longpolling' are instantiated by the
bus service.
The class is always instantiated with a parent, or root in the case of the website
(im_livechat), to use the ajax and localstorage services. So the behavior, perhaps
logger or redefined by the parents.