Odoo18-Base/addons/website/static/tests/tours/website_no_dirty_page.js
2025-01-06 10:57:38 +07:00

310 lines
11 KiB
JavaScript

/** @odoo-module **/
import { browser } from '@web/core/browser/browser';
import {
clickOnEditAndWaitEditMode,
clickOnSave,
insertSnippet,
registerWebsitePreviewTour,
} from '@website/js/tours/tour_utils';
const makeSteps = (steps = []) => [
...insertSnippet({
id: "s_text_image",
name: "Text - Image",
groupName: "Content",
}), {
content: "Click on Discard",
trigger: '.o_we_website_top_actions [data-action="cancel"]',
run: "click",
}, {
content: "Check that discarding actually warns when there are dirty changes, and cancel",
trigger: ".modal-footer .btn-secondary",
run: "click",
},
...clickOnSave(),
...clickOnEditAndWaitEditMode(),
{
// This makes sure the last step about leaving edit mode at the end of
// this tour makes sense.
content: "Confirm we are in edit mode",
trigger: 'body.editor_has_snippets',
},
...steps,
{
// Makes sure the dirty flag does not happen after a setTimeout or
// something like that.
content: "Click elsewhere and wait for a few ms",
trigger: ":iframe #wrap",
async run(actions) {
// TODO: use actions.click(); instead
this.anchor.click();
await new Promise((resolve) => {
browser.setTimeout(() => {
document.body.classList.add("o_test_delay");
resolve();
}, 999);
});
},
},
{
trigger: "body.o_test_delay",
},
{
content: "Click on Discard",
trigger: '.o_we_website_top_actions [data-action="cancel"]',
run: "click",
}, {
content: "Confirm we are not in edit mode anymore",
trigger: 'body:not(.editor_has_snippets)',
},
];
registerWebsitePreviewTour('website_no_action_no_dirty_page', {
url: '/',
edition: true,
}, () => makeSteps());
registerWebsitePreviewTour('website_no_dirty_page', {
url: '/',
edition: true,
}, () => makeSteps([
{
// This has been known to mark the page as dirty because of the "drag
// the column on image move" feature.
content: "Click on default image",
trigger: ':iframe .s_text_image img',
run: "click",
}, {
content: "Click on default paragraph",
trigger: ':iframe .s_text_image h2 + p.o_default_snippet_text',
run: "click",
}, {
// TODO this should be done in a dedicated test which would be testing
// all default snippet texts behaviors. Will be done in master where a
// task will review this feature.
// TODO also test that applying an editor command removes that class.
content: "Make sure the paragraph still acts as a default paragraph",
trigger: ':iframe .s_text_image h2 + p.o_default_snippet_text',
}, {
content: "Click on button",
trigger: ':iframe .s_text_image .btn',
async run(actions) {
await actions.click();
const el = this.anchor;
const sel = el.ownerDocument.getSelection();
sel.collapse(el, 0);
el.focus();
},
},
]));
registerWebsitePreviewTour(
"website_default_snippet_text",
{
url: "/",
edition: true,
},
() => [
...insertSnippet({
id: "s_text_image",
name: "Text - Image",
groupName: "Content",
}),
...insertSnippet({
id: "s_banner",
name: "Banner",
groupName: "Intro",
}),
{
content: "Click on first paragraph",
trigger: ":iframe .s_text_image p.o_default_snippet_text",
run: "click",
},
{
content: "Select the first word (Write)",
trigger: ":iframe .s_text_image p.o_default_snippet_text",
run() {
const paragraph = this.anchor;
const range = document.createRange();
const text = paragraph.textContent;
const firstWordLength = text.split(" ")[0].length;
range.setStart(paragraph.firstChild, 0);
range.setEnd(paragraph.firstChild, firstWordLength);
const selection = this.anchor.ownerDocument.getSelection();
selection.removeAllRanges();
selection.addRange(range);
},
},
{
content: "Apply bold formatting",
trigger: ".o_we_toolbar_wrapper #bold",
run: "click",
},
{
content: "Check if default_snippet_text class is removed",
trigger: ":iframe .s_text_image p:eq(0)",
run() {
if (this.anchor.classList.contains("o_default_snippet_text")) {
console.error("The class o_default_snippet_text should be removed");
}
},
},
{
content: "Click on second paragraph",
trigger: ":iframe .s_text_image p.o_default_snippet_text",
run: "click",
},
{
content: "The paragraph should be selected",
trigger: ":iframe .s_text_image p:eq(1)",
run() {
const pText = this.anchor.textContent;
const selection = this.anchor.ownerDocument.getSelection();
if (selection.toString() !== pText) {
console.error("The paragraph should be selected");
}
},
},
{
content: "Replace the paragraph by typing something",
trigger: ":iframe .s_text_image p:eq(1)",
run(actions) {
// We must invoke 'trigger' from a jQuery object because
// the 'keyup.snippets_menu' event needs to be dispatched.
// TODO: Replace this event trigger with vanilla JavaScript
// once jQuery is removed from the snippets editor.
$(this.anchor.ownerDocument.body).trigger("keyup.snippets_menu");
actions.editor("Another brick in the wall");
},
},
{
content: "Check if default_snippet_text class is removed",
trigger: ":iframe .s_text_image p:eq(1)",
run() {
if (this.anchor.classList.contains("o_default_snippet_text")) {
console.error("The class o_default_snippet_text should be removed");
}
},
},
{
content: "Re-click on the paragraph",
trigger: ":iframe .s_text_image p:eq(1)",
run: "click",
},
{
content: "The paragraph should not be selected",
trigger: ":iframe .s_text_image p:eq(1)",
run() {
const pText = this.anchor.textContent;
const selection = this.anchor.ownerDocument.getSelection();
if (selection.toString() === pText) {
console.error("The paragraph should not be selected");
}
},
},
{
content: "Click on the paragraph",
trigger: ":iframe .s_banner p.o_default_snippet_text",
run: "click",
},
{
content: "The paragraph should be selected",
trigger: ":iframe .s_banner p.o_default_snippet_text",
run() {
const pText = this.anchor.textContent.trim();
const selectionText = this.anchor.ownerDocument.getSelection().toString().trim();
if (selectionText !== pText) {
console.error("The paragraph should be selected: ", selectionText, pText);
}
},
},
{
content: "Click elsewhere",
trigger: ":iframe .s_banner img",
run: "click",
},
{
content: "Re-click on the paragraph",
trigger: ":iframe .s_banner p.o_default_snippet_text",
run: "click",
},
{
content: "The paragraph should not be selected",
trigger: ":iframe .s_banner p.o_default_snippet_text",
run() {
const pText = this.anchor.textContent.trim();
const selectionText = this.anchor.ownerDocument.getSelection().toString().trim();
if (selectionText === pText) {
console.error("The paragraph should not be selected: ", selectionText, pText);
}
},
},
...clickOnSave(),
...clickOnEditAndWaitEditMode(),
{
content: "Click on the paragraph",
trigger: ":iframe .s_banner p.o_default_snippet_text",
run: "click",
},
{
content: "The paragraph should be re-selected",
trigger: ":iframe .s_banner p.o_default_snippet_text",
run() {
const pText = this.anchor.textContent.trim();
const selectionText = this.anchor.ownerDocument.getSelection().toString().trim();
if (selectionText !== pText) {
console.error("The paragraph should be re-selected: ", selectionText, pText);
}
},
},
]
);
registerWebsitePreviewTour('website_no_dirty_lazy_image', {
url: '/',
edition: true,
}, () => [
...insertSnippet({
id: 's_text_image',
name: 'Text - Image',
groupName: "Content",
}),
{
// Ensure the test keeps testing what it should test (eg if we ever
trigger: ':iframe img.o_lang_flag[loading="lazy"]',
},
{
content: "Replace first paragraph, to insert a new link",
// remove the lazy loading on those language img))
trigger: ':iframe #wrap .s_text_image p',
run: 'editor SomeTestText',
},
{
trigger: ':iframe #wrap .s_text_image p:contains("SomeTestText")',
},
{
content: "Click elsewhere to be sure the editor fully process the new content",
trigger: ':iframe #wrap .s_text_image img',
run: "click",
},
{
trigger: '.o_we_user_value_widget[data-replace-media="true"]',
},
{
content: "Check that there is no more than one dirty flag",
trigger: ':iframe body',
run: function () {
const dirtyCount = this.anchor.querySelectorAll('.o_dirty').length;
if (dirtyCount !== 1) {
console.error(dirtyCount + " dirty flag(s) found");
} else {
this.anchor.querySelector('#wrap').classList.add('o_dirty_as_expected');
}
},
}, {
content: "Check previous step went through correctly about dirty flags",
trigger: ':iframe #wrap.o_dirty_as_expected',
}
]);