Files
odoo_source/addons/web/static/tests/helpers/cleanup.js
T
Aaron Bohy 25690c2879 [FIX] web: fix documents tests failing randomly
Since commit [1], several tests from the "documents" addon failed
randomly, because there were leftovers in the DOM at the end of
the tests. Those leftovers were the many2one dropdowns. Since v12,
we whitelist jQuery autocomplete dropdowns in the leftover check.
However, since [1], the many2one autocomplete has an additionnal
className, and it thus didn't match the element in the whitelist
anymore. Note that we duplicated the entry in the whitelist
because we need both (there are several types of autocomplete
dropdowns in the "documents" view).

[1] 84715436d87bb05b421bc9ccaacda67d07571690

closes odoo/odoo#77861

Related: odoo/enterprise#21460
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
2021-10-05 15:41:15 +00:00

106 lines
3.6 KiB
JavaScript

/** @odoo-module **/
// -----------------------------------------------------------------------------
// Cleanup
// -----------------------------------------------------------------------------
const cleanups = [];
/**
* Register a cleanup callback that will be executed whenever the current test
* is done.
*
* - the cleanups will be executed in reverse order
* - they will be executed even if the test fails/crashes
*
* @param {Function} callback
*/
export function registerCleanup(callback) {
cleanups.push(callback);
}
QUnit.on("OdooAfterTestHook", (info) => {
if (QUnit.config.debug) {
return;
}
let cleanup;
// note that this calls the cleanup callbacks in reverse order!
while ((cleanup = cleanups.pop())) {
try {
cleanup(info);
} catch (error) {
console.error(error);
}
}
});
// -----------------------------------------------------------------------------
// Check leftovers
// -----------------------------------------------------------------------------
/**
* List of elements tolerated in the body after a test. The property "keep"
* prevents the element from being removed (typically: qunit suite elements).
*/
const validElements = [
// always in the body:
{ tagName: "DIV", attr: "id", value: "qunit", keep: true },
{ tagName: "DIV", attr: "id", value: "qunit-fixture", keep: true },
// shouldn't be in the body after a test but are tolerated:
{ tagName: "SCRIPT", attr: "id", value: "" },
{ tagName: "DIV", attr: "class", value: "o_notification_manager" },
{ tagName: "DIV", attr: "class", value: "tooltip fade bs-tooltip-auto" },
{ tagName: "DIV", attr: "class", value: "tooltip fade bs-tooltip-auto show" },
{ tagName: "SPAN", attr: "class", value: "select2-hidden-accessible" },
// Due to a Document Kanban bug (already present in 12.0)
{ tagName: "DIV", attr: "class", value: "ui-helper-hidden-accessible" },
{
tagName: "UL",
attr: "class",
value: "ui-menu ui-widget ui-widget-content ui-autocomplete ui-front",
},
{
tagName: "UL",
attr: "class",
value: "ui-menu ui-widget ui-widget-content ui-autocomplete dropdown-menu ui-front", // many2ones
},
];
/**
* After each test, we check that there is no leftover in the DOM.
*
* Note: this event is not QUnit standard, we added it for this specific use case.
* As a payload, an object with keys 'moduleName' and 'testName' is provided. It
* is used to indicate the test that left elements in the DOM, when it happens.
*/
QUnit.on("OdooAfterTestHook", function (info) {
if (QUnit.config.debug) {
return;
}
const failed = info.testReport.getStatus() === "failed";
const toRemove = [];
// check for leftover elements in the body
for (const bodyChild of document.body.children) {
const tolerated = validElements.find(
(e) => e.tagName === bodyChild.tagName && bodyChild.getAttribute(e.attr) === e.value
);
if (!failed && !tolerated) {
QUnit.pushFailure(`Body still contains undesirable elements:\n${bodyChild.outerHTML}`);
}
if (!tolerated || !tolerated.keep) {
toRemove.push(bodyChild);
}
}
// cleanup leftovers in #qunit-fixture
const qunitFixture = document.getElementById("qunit-fixture");
if (qunitFixture.children.length) {
toRemove.push(...qunitFixture.children);
}
// remove unwanted elements if not in debug
for (const el of toRemove) {
el.remove();
}
document.body.classList.remove("modal-open");
});