[FIX] website: add test for popup and scrollbar

Add test to verify scrollbar behavior for page and popups with or
without backdrop. The expected behavior is that the page scrollbar
should not be present when a modal with a backdrop is open, and that the
page scrollbar should be displayed if the popup does not have a
backdrop, such as a cookie bar. However, if a modal without a backdrop
itself has a scrollbar, the page scrollbar should not be displayed to
prevent the two scrollbars from overlapping, which prevents scrolling of
the popup on Chrome (when clicking on the scrollbar instead of using the
mouse wheel).

In addition to that, this commit includes a test to confirm the proper
functionality of snippet animations when a cookie bar is displayed on
the page. Moreover, it also verifies that the snippet animations perform
correctly within a popup.

During the forward port of this commit (Master branch), the test failed
due to missing braces around 'throttleForAnimation' in the '000.js' file
of 's_popup'. These were directly added in this commit.

task-2983901

closes odoo/odoo#128914

X-original-commit: 4dd462f20ccb29923e5a053e0ed4c08545f82ae7
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Signed-off-by: Benjamin Vray (bvr) <bvr@odoo.com>
This commit is contained in:
Benjamin Vray
2023-07-25 10:35:43 +02:00
parent 286cc97dd4
commit c8a40b9025
4 changed files with 258 additions and 1 deletions
@@ -4,7 +4,7 @@ import config from "web.config";
import publicWidget from "web.public.widget";
import {getCookie, setCookie} from "web.utils.cookies";
import dom from "web.dom";
import throttleForAnimation from "@web/core/utils/timing";
import {throttleForAnimation} from "@web/core/utils/timing";
// TODO In master, export this class too or merge it with PopupWidget
const SharedPopupWidget = publicWidget.Widget.extend({
@@ -0,0 +1,118 @@
/** @odoo-module */
import wTourUtils from "website.tour_utils";
const snippets = [
{
id: "s_popup",
name: "Popup",
},
{
id: "s_media_list",
name: "Media List",
},
{
id: "s_three_columns",
name: "Columns",
},
];
const setOnScrollAnim = function () {
return [
wTourUtils.changeOption("WebsiteAnimate", 'we-select[data-is-animation-type-selection="true"] we-toggler'),
wTourUtils.changeOption("WebsiteAnimate", 'we-button[data-animation-mode="onScroll"]'),
wTourUtils.changeOption("WebsiteAnimate", 'we-select[data-name="animation_effect_opt"] we-toggler'),
wTourUtils.changeOption("WebsiteAnimate", 'we-button[data-name="o_anim_slide_in_opt"]'),
];
};
wTourUtils.registerWebsitePreviewTour("snippet_popup_and_animations", {
test: true,
url: "/",
edition: true,
}, [
wTourUtils.dragNDrop(snippets[1]), // Media List
wTourUtils.dragNDrop(snippets[1]), // Media List
wTourUtils.dragNDrop(snippets[2]), // Columns
wTourUtils.clickOnElement("3rd columns", "iframe .s_three_columns .row > :last-child"),
...setOnScrollAnim(),
{
content: "Open the Cookies Bar.",
trigger: ".o_we_invisible_el_panel .o_we_invisible_entry",
},
{
content: "Scroll to top",
trigger: "iframe #wrapwrap",
extra_trigger: "iframe #website_cookies_bar:not(.d-none)",
run: function () {
const animatedColumnEl = this.$anchor[0].querySelector(".s_three_columns .row > :last-child");
// When the animated element is fully visible, its animation delay
// should be rounded to -1 in the following condition.
if (Math.round(parseFloat(animatedColumnEl.style.animationDelay)) !== -1) {
console.error("The scroll animation in the page did not start properly with the cookies bar open.");
}
this.$anchor[0].scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});
},
},
{
content: "Wait for the page to be scrolled to the top.",
trigger: "iframe .s_three_columns .row > :last-child:not(.o_animating)",
extra_trigger: "iframe header#top:not(.o_header_affixed)",
run: function () {
// If the column has been animated successfully, the animation delay
// should be set to approximately zero when it is not visible.
// The main goal of the following condition is to verify if the
// animation delay is being updated as expected.
if (Math.round(parseFloat(this.$anchor[0].style.animationDelay)) !== 0) {
console.error("The scroll animation in the page did not end properly with the cookies bar open.");
}
},
},
{
content: "Close the Cookies Bar.",
trigger: ".o_we_invisible_el_panel .o_we_invisible_entry",
run: "click",
},
wTourUtils.dragNDrop(snippets[0]), // Popup
wTourUtils.dragNDrop(snippets[1]), // Media List
{
content: "Drag the Columns building block and drop it at the bottom of the popup.",
trigger: '#oe_snippets .oe_snippet[name="Columns"] .oe_snippet_thumbnail:not(.o_we_already_dragging)',
extra_trigger: ".o_website_preview.editor_enable.editor_has_snippets",
run: "drag_and_drop iframe #wrapwrap .modal-content .s_media_list .container > .row > :last-child",
},
wTourUtils.clickOnElement("3rd columns", "iframe .s_popup .s_three_columns .row > :last-child"),
...setOnScrollAnim(),
{
content: "Verify the animation delay of the animated element in the popup at the beginning",
trigger: "iframe .s_popup .modal",
run: function () {
const animatedColumnEl = this.$anchor[0].querySelector(".s_three_columns .row > :last-child");
// When the animated element is fully visible, its animation delay
// should be rounded to -1 in the following condition.
if (Math.round(parseFloat(animatedColumnEl.style.animationDelay)) !== -1) {
console.error("The scroll animation in the modal did not start properly.");
}
this.$anchor[0].closest(".modal").scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});
},
},
{
content: "Wait until the column is no longer animated/visible.",
trigger: "iframe .s_popup .s_three_columns .row > :last-child:not(.o_animating)",
run: function () {
// If the column has been animated successfully, the animation delay
// should be set to approximately zero when it is not visible.
if (Math.round(parseFloat(this.$anchor[0].style.animationDelay)) !== 0) {
console.error("The scroll animation in the modal did not end properly.");
}
},
},
]);
@@ -0,0 +1,133 @@
/** @odoo-module */
import wTourUtils from "website.tour_utils";
const snippets = [
{
id: "s_popup",
name: "Popup",
},
{
id: "s_media_list",
name: "Media List",
},
];
const checkScrollbar = function (hasScrollbar) {
return {
content: `Check that the #wrapwrap ${hasScrollbar ? "has" : "does not have"} a vertical scrollbar.`,
trigger: `iframe ${hasScrollbar ? "body:not(.modal-open)" : "body.modal-open"}`,
run: function () {
const wrapwrapEl = this.$anchor[0].querySelector("#wrapwrap");
const wrapwrapStyle = window.getComputedStyle(wrapwrapEl);
if (!hasScrollbar && (wrapwrapStyle.overflow !== "hidden" || parseFloat(wrapwrapStyle.paddingRight) < 1)) {
console.error("error The #wrapwrap vertical scrollbar should be hidden");
} else if (hasScrollbar && (wrapwrapStyle.overflow === "hidden" || parseFloat(wrapwrapStyle.paddingRight) > 0)) {
console.error("error The #wrapwrap vertical scrollbar should be displayed");
}
},
};
};
const toggleBackdrop = function () {
return wTourUtils.changeOption('SnippetPopup', 'we-button[data-name="popup_backdrop_opt"] we-checkbox', 'backdrop');
};
wTourUtils.registerWebsitePreviewTour("snippet_popup_and_scrollbar", {
test: true,
url: "/",
edition: true,
}, [
wTourUtils.dragNDrop(snippets[1]), // Media List
wTourUtils.dragNDrop(snippets[0]), // Popup
checkScrollbar(false),
{
content: 'Click on the s_popup snippet',
in_modal: false,
trigger: 'iframe .s_popup .modal',
},
toggleBackdrop(), // hide Popup backdrop
checkScrollbar(true),
wTourUtils.goBackToBlocks(),
{
content: "Drag the Media List block and drop it in the popup.",
trigger: "#oe_snippets .oe_snippet:has(> [data-snippet='s_media_list']) .oe_snippet_thumbnail",
run: "drag_and_drop iframe #wrap .s_popup .modal-content.oe_structure",
},
checkScrollbar(false),
{
content: "Select the Media List snippet in the Popup.",
trigger: "iframe #wrap .s_popup .modal-content .s_media_list",
},
{
content: "Remove the Media List snippet in the Popup.",
trigger: "iframe .oe_overlay.oe_active .oe_snippet_remove",
},
checkScrollbar(true),
toggleBackdrop(), // show Popup backdrop
checkScrollbar(false),
{
content: "Close the Popup.",
trigger: ".o_we_invisible_el_panel .o_we_invisible_entry",
},
checkScrollbar(true),
{
content: "Open the Cookies Bar.",
trigger: ".o_we_invisible_el_panel .o_we_invisible_entry:last-child",
},
checkScrollbar(true),
toggleBackdrop(), // show Cookies Bar backdrop
checkScrollbar(false),
toggleBackdrop(), // hide Cookies Bar backdrop
checkScrollbar(true),
{
content: "Open the Popup.",
trigger: ".o_we_invisible_el_panel .o_we_invisible_entry",
},
checkScrollbar(false),
wTourUtils.goBackToBlocks(),
{
content: "Drag the Media List block and drop it in the popup.",
trigger: "#oe_snippets .oe_snippet:has(> [data-snippet='s_media_list']) .oe_snippet_thumbnail",
run: "drag_and_drop iframe #wrap .s_popup .modal-content.oe_structure",
},
checkScrollbar(false),
{
content: 'Click on the s_popup snippet',
in_modal: false,
trigger: 'iframe .s_popup .modal',
},
{
content: "Remove the s_popup snippet",
trigger: ".o_we_customize_panel we-customizeblock-options:contains('Popup') we-button.oe_snippet_remove:first",
in_modal: false,
run: "click",
},
checkScrollbar(true),
wTourUtils.goBackToBlocks(),
{
content: "Drag a Media List snippet and drop it in the Cookies Bar.",
trigger: "#oe_snippets .oe_snippet:has(> [data-snippet='s_media_list']) .oe_snippet_thumbnail",
run: "drag_and_drop iframe #website_cookies_bar .modal-content.oe_structure",
},
{
content: "Select the Media List snippet in the Cookies Bar.",
trigger: "iframe #website_cookies_bar .modal-content .s_media_list",
},
{
content: "Duplicate the Media List snippet",
trigger: ".o_we_customize_panel we-customizeblock-options:contains('Media List') we-button.oe_snippet_clone:first",
in_modal: false,
run: "click",
},
checkScrollbar(false),
{
content: "Remove the first Media List snippet in the Cookies Bar.",
trigger: "iframe .oe_overlay.oe_active .oe_snippet_remove",
},
{
content: "Remove the second Media List snippet in the Cookies Bar.",
trigger: "iframe .oe_overlay.oe_active .oe_snippet_remove",
},
checkScrollbar(true),
]);
+6
View File
@@ -80,3 +80,9 @@ class TestSnippets(HttpCase):
def test_12_snippet_images_wall(self):
self.start_tour('/', 'snippet_images_wall', login='admin')
def test_snippet_popup_with_scrollbar_and_animations(self):
website = self.env.ref('website.default_website')
website.cookies_bar = True
self.start_tour(self.env['website'].get_client_action_url('/'), 'snippet_popup_and_scrollbar', login='admin')
self.start_tour(self.env['website'].get_client_action_url('/'), 'snippet_popup_and_animations', login='admin')