diff --git a/addons/im_livechat/__manifest__.py b/addons/im_livechat/__manifest__.py
index 26fc7955c68..ac4db3b9825 100644
--- a/addons/im_livechat/__manifest__.py
+++ b/addons/im_livechat/__manifest__.py
@@ -132,7 +132,7 @@ Help your customers with this chat, and analyse their feedback.
'im_livechat/static/src/embed/external/**/*',
],
'im_livechat.embed_test_assets': [
- ('include', 'web.assets_backend_tests'),
+ ('include', 'web.assets_backend'),
('include', 'web.tests_assets'),
('remove', 'web/static/tests/mock_server_tests.js'),
('remove', 'im_livechat/static/**'),
diff --git a/addons/mail/static/tests/helpers/test_utils.js b/addons/mail/static/tests/helpers/test_utils.js
index 251621b039e..840053a0594 100644
--- a/addons/mail/static/tests/helpers/test_utils.js
+++ b/addons/mail/static/tests/helpers/test_utils.js
@@ -9,7 +9,7 @@ import { patchBrowserNotification } from "@mail/../tests/helpers/patch_notificat
import { getAdvanceTime } from "@mail/../tests/helpers/time_control";
import { getWebClientReady } from "@mail/../tests/helpers/webclient_setup";
-import { App, EventBus } from "@odoo/owl";
+import { EventBus } from "@odoo/owl";
import { browser } from "@web/core/browser/browser";
import { registry } from "@web/core/registry";
@@ -23,8 +23,6 @@ import {
import { getFixture, patchWithCleanup } from "@web/../tests/helpers/utils";
import { doAction, getActionManagerServerData } from "@web/../tests/webclient/helpers";
-const { afterNextRender } = App;
-
// load emoji data and lamejs once, when the test suite starts.
QUnit.begin(loadEmoji);
QUnit.begin(loadLamejs);
@@ -102,7 +100,7 @@ function getOpenDiscuss(webClient, { context = {}, params = {}, ...props } = {})
id: threadId,
})
);
- return afterNextRender(() => doAction(webClient, actionOpenDiscuss, { props }));
+ await doAction(webClient, actionOpenDiscuss, { props });
};
}
@@ -248,20 +246,16 @@ async function start(param0 = {}) {
param0.serverData = param0.serverData || getActionManagerServerData();
param0.serverData.models = { ...pyEnv.getData(), ...param0.serverData.models };
param0.serverData.views = { ...pyEnv.getViews(), ...param0.serverData.views };
- let webClient;
- await afterNextRender(async () => {
- webClient = await getWebClientReady({ ...param0, messagingBus });
- });
+ const webClient = await getWebClientReady({ ...param0, messagingBus });
if (webClient.env.services.ui.isSmall) {
target.style.width = "100%";
}
const openView = async (action, options) => {
action["type"] = action["type"] || "ir.actions.act_window";
- await afterNextRender(() => doAction(webClient, action, { props: options }));
+ await doAction(webClient, action, { props: options });
};
return {
advanceTime,
- afterNextRender,
env: webClient.env,
insertText,
openDiscuss: getOpenDiscuss(webClient, discuss),
diff --git a/addons/web/__manifest__.py b/addons/web/__manifest__.py
index 533a21923e2..671cd834a9b 100644
--- a/addons/web/__manifest__.py
+++ b/addons/web/__manifest__.py
@@ -447,11 +447,6 @@ This module provides the core of the Odoo Web Client.
('include', 'web.assets_tests'),
'web/static/tests/ignore_missing_deps_stop.js',
],
- # remove this bundle alongside the owl2 compatibility layer
- 'web.assets_backend_tests': [
- ('include', 'web.assets_backend'),
- ('after', 'web/static/src/libs/owl.js', 'web/static/tests/owl2_compatibility_app.js'),
- ],
'web.tests_assets': [
'web/static/tests/patch_translations.js',
'web/static/lib/qunit/qunit-2.9.1.css',
diff --git a/addons/web/static/tests/owl2_compatibility_app.js b/addons/web/static/tests/owl2_compatibility_app.js
deleted file mode 100644
index 01acb1db141..00000000000
--- a/addons/web/static/tests/owl2_compatibility_app.js
+++ /dev/null
@@ -1,99 +0,0 @@
-(function () {
- const App = owl.App;
-
- const stopPromises = [];
- const schedulers = new Set();
-
- function isRunning(scheduler) {
- for (const fiber of scheduler.tasks) {
- if (fiber.node.status !== 2) {
- return true;
- }
- }
- return false;
- }
-
- function hookIntoScheduler(scheduler) {
- const { flush: originalFlush } = scheduler;
- scheduler.flush = function flush() {
- originalFlush.call(this, ...arguments);
- window.requestAnimationFrame(() => {
- if ([...schedulers].every((scheduler) => !isRunning(scheduler))) {
- while (stopPromises.length) {
- stopPromises.pop().resolve();
- }
- }
- });
- };
- }
-
- owl.App = class extends App {
- constructor() {
- super(...arguments);
- this.setup();
- hookIntoScheduler(this.scheduler);
- schedulers.add(this.scheduler);
- }
- destroy() {
- schedulers.delete(this.scheduler);
- super.destroy();
- }
- setup() {}
- };
-
- /**
- * Returns a promise resolved the next time OWL stops rendering.
- *
- * @param {function} func function which, when called, is
- * expected to trigger OWL render(s).
- * @param {number} [timeoutDelay=5000] in ms
- * @returns {Promise}
- */
- owl.App.afterNextRender = async function afterNextRender(func, timeoutDelay = 5000) {
- // Define the potential errors outside of the promise to get a proper
- // trace if they happen.
- const startError = new Error("Timeout: the render didn't start.");
- const stopError = new Error("Timeout: the render didn't stop.");
- // Set up the timeout to reject if no render happens.
- let timeoutNoRender;
-
- const timeoutProm = new Promise((resolve, reject) => {
- timeoutNoRender = setTimeout(() => {
- let error = startError;
- const runningSchedulers = [...schedulers].filter(isRunning);
- if (runningSchedulers.length) {
- error = stopError;
- }
- console.warn(
- error,
- runningSchedulers.map((s) => [...s.tasks].map((f) => [f, f.node.status])),
- runningSchedulers
- );
- reject(error);
- }, timeoutDelay);
- });
- // Set up the promise to resolve if a render happens.
- let resolve;
- const prom = new Promise((res) => {
- resolve = res;
- });
- prom.resolve = resolve;
- stopPromises.push(prom);
- // Start the function expected to trigger a render after the promise
- // has been registered to not miss any potential render.
- const funcRes = func();
- // Make them race (first to resolve/reject wins).
- await Promise.race([prom, timeoutProm]);
- clearTimeout(timeoutNoRender);
- // Wait the end of the function to ensure all potential effects are
- // taken into account during the following verification step.
- await funcRes;
- // Wait one more frame to make sure no new render has been queued.
- await new Promise(function (resolve) {
- setTimeout(() => window.requestAnimationFrame(() => resolve()));
- });
- if ([...schedulers].some(isRunning)) {
- await afterNextRender(() => {}, timeoutDelay);
- }
- };
-})();
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index cfb2b8acf43..00ee3462e85 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -210,7 +210,7 @@
Web Tests
-
+
@@ -229,7 +229,7 @@
-
+