diff --git a/addons/html_editor/static/src/main/font/color_plugin.js b/addons/html_editor/static/src/main/font/color_plugin.js
index 0bbf47b67ca7d..a9704117a4d12 100644
--- a/addons/html_editor/static/src/main/font/color_plugin.js
+++ b/addons/html_editor/static/src/main/font/color_plugin.js
@@ -21,8 +21,8 @@ import {
isCSSColor,
RGBA_REGEX,
rgbaToHex,
- COLOR_COMBINATION_CLASSES_REGEX,
} from "@web/core/utils/colors";
+import { COLOR_COMBINATION_CLASSES_REGEX } from "@html_editor/utils/color";
import { ColorSelector } from "./color_selector";
const RGBA_OPACITY = 0.6;
diff --git a/addons/web/static/src/core/color_picker/color_picker.scss b/addons/web/static/src/core/color_picker/color_picker.scss
index 26c802ca0820a..160288d6aaf79 100644
--- a/addons/web/static/src/core/color_picker/color_picker.scss
+++ b/addons/web/static/src/core/color_picker/color_picker.scss
@@ -60,9 +60,12 @@
margin-left: 2px;
}
-.o_font_color_selector .o_color_button.selected {
+.o_font_color_selector {
// todo: check web_editor
- border: 3px solid $o-enterprise-action-color;
+ .o_color_button.selected,
+ .o_custom_gradient_button.selected {
+ border: 3px solid $o-enterprise-action-color !important;
+ }
}
// custom gradients
.custom-gradient-configurator {
diff --git a/addons/web/static/src/core/color_picker/color_picker.xml b/addons/web/static/src/core/color_picker/color_picker.xml
index 7b5531831bea6..fda79a5ea2c16 100644
--- a/addons/web/static/src/core/color_picker/color_picker.xml
+++ b/addons/web/static/src/core/color_picker/color_picker.xml
@@ -114,11 +114,11 @@
-
+
-
+
diff --git a/addons/web/static/src/core/color_picker/gradient_picker/gradient_picker.xml b/addons/web/static/src/core/color_picker/gradient_picker/gradient_picker.xml
index 059d1d8cae989..e5fe66f77a2c4 100644
--- a/addons/web/static/src/core/color_picker/gradient_picker/gradient_picker.xml
+++ b/addons/web/static/src/core/color_picker/gradient_picker/gradient_picker.xml
@@ -91,6 +91,7 @@
diff --git a/addons/website/static/tests/tours/snippet_background_edition.js b/addons/website/static/tests/tours/snippet_background_edition.js
index 476ee34344b2a..d2c6c0b0149a1 100644
--- a/addons/website/static/tests/tours/snippet_background_edition.js
+++ b/addons/website/static/tests/tours/snippet_background_edition.js
@@ -16,20 +16,29 @@ const snippets = [
groupName: "Content",
},
];
+const backgroundColors = [
+ {
+ code: "200",
+ hex: "#e9ecef"
+ },
+ {
+ code: "800",
+ hex: "#343a40"
+ },
+]
const gradients = [
'linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
'linear-gradient(135deg, rgb(255, 222, 202) 0%, rgb(202, 115, 69) 100%)',
];
function typeToName(xType) {
- return xType === 'cc' ? 'color combinations' : xType === 'bg' ? 'background colors' : 'gradients';
+ return xType === "cc" ? "Theme" : xType === "bg" ? "Custom" : "Gradient";
}
function switchTo(type, _name) {
- const target = type === 'cc' ? 'color-combinations' : type === 'bg' ? 'custom-colors' : 'gradients';
const name = _name || typeToName(type);
return {
- trigger: `.o_we_colorpicker_switch_pane_btn[data-target="${target}"]`,
+ trigger: `.o_font_color_selector .btn-tab:contains("${name}")`,
content: `Switch to ${name}`,
run: "click",
};
@@ -41,8 +50,8 @@ function addCheck(steps, checkX, checkNoX, xType, noSwitch = false) {
}
const name = typeToName(xType);
- const selectorCheckX = checkX && `.o_we_color_btn[data-color="${checkX}"].selected`;
- const selectorCheckNoX = checkNoX && `.o_we_color_btn[data-color="${checkNoX}"]:not(.selected)`;
+ const selectorCheckX = checkX && `[data-color="${checkX}"].selected`;
+ const selectorCheckNoX = checkNoX && `[data-color="${checkNoX}"]:not(.selected)`;
const step = {
trigger: selectorCheckX || selectorCheckNoX,
content: `The correct ${name} is marked as selected`,
@@ -76,7 +85,11 @@ function checkAndUpdateBackgroundColor({
if (changeType) {
steps.push(switchTo(changeType));
- steps.push(changeOption('ColoredLevelBackground', `.o_we_color_btn[data-color="${change}"]`, 'background color', 'top', true));
+ steps.push({
+ content: "Change background color",
+ trigger: `.o_popover [data-color="${change}"]`,
+ run: "click"
+ })
steps.push({
trigger: finalSelector,
content: "The selected colors have been applied (CC AND (BG or GRADIENT))",
@@ -89,10 +102,7 @@ function checkAndUpdateBackgroundColor({
}
function updateAndCheckCustomGradient({updateStep, checkGradient}) {
- const steps = [updateStep, {
- trigger: `:iframe #wrapwrap section.${snippets[0].id}.o_cc1`,
- content: 'Color combination 1 still selected',
- }];
+ const steps = [ updateStep ];
addCheck(steps, checkGradient, checkGradient !== gradients[0] && gradients[0], 'gradient', true);
return steps;
}
@@ -106,11 +116,7 @@ registerWebsitePreviewTour('snippet_background_edition', {
...clickOnSnippet(snippets[0]),
// Set background image and save.
-{
- content: "Click on camera icon",
- trigger: ".snippet-option-ColoredLevelBackground we-button.fa-camera",
- run: "click",
-},
+changeOption("Text - Image", "button[data-action-id='toggleBgImage']"),
{
content: "Click on image",
trigger: ".o_select_media_dialog img[title='test.png']",
@@ -119,114 +125,101 @@ registerWebsitePreviewTour('snippet_background_edition', {
...clickOnSave(),
{
content: "Check that the image is set",
- trigger: `:iframe section.${snippets[0].id} img[data-original-id]`,
+ trigger: `:iframe section.${snippets[0].id}[style*="background-image"]`,
},
...clickOnEditAndWaitEditMode(),
...clickOnSnippet(snippets[0]),
// Remove background image.
-{
- content: "Click on camera icon",
- trigger: ".snippet-option-ColoredLevelBackground we-button.fa-camera",
- run: "click",
-},
+changeOption("Text - Image", "button[data-action-id='toggleBgImage']"),
// Add a color combination
...checkAndUpdateBackgroundColor({
changeType: 'cc',
- change: 3,
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc3:not([class*=bg-]):not([style*="background"])`,
+ change: "o_cc3",
+ finalSelector: `:iframe .${snippets[0].id}.o_cc3:not([class*=bg-]):not([style*="background"])`,
}),
// Change the color combination + Check the previous one was marked as selected
...checkAndUpdateBackgroundColor({
- checkCC: 3,
+ checkCC: "o_cc3",
changeType: 'cc',
- change: 2,
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc2:not(.o_cc3):not([class*=bg-])`,
+ change: "o_cc2",
+ finalSelector: `:iframe .${snippets[0].id}.o_cc2:not(.o_cc3):not([class*=bg-])`,
}),
// Check the color combination was marked as selected + Edit the bg color
...checkAndUpdateBackgroundColor({
- checkCC: 2,
- checkNoCC: 3,
+ checkCC: "o_cc2",
+ checkNoCC: "o_cc3",
changeType: 'bg',
- change: 'black-50',
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc2.bg-black-50`,
+ change: backgroundColors[0].code,
+ finalSelector: `:iframe .${snippets[0].id}.o_cc2.bg-${backgroundColors[0].code}`,
}),
// Check the current color palette selection + Change the bg color
...checkAndUpdateBackgroundColor({
- checkCC: 2,
- checkBg: 'black-50',
+ checkCC: "o_cc2",
+ checkBg: backgroundColors[0].hex,
changeType: 'bg',
- change: '800',
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc2.bg-800:not(.bg-black-50)`,
+ change: backgroundColors[1].code,
+ finalSelector: `:iframe .${snippets[0].id}.o_cc2.bg-${backgroundColors[1].code}:not(.bg-${backgroundColors[0].code})`,
}),
// Check the current color palette selection + Change the color combination
-// again. It should keep the bg color class.
+// again. It should remove the bg color class.
...checkAndUpdateBackgroundColor({
- checkCC: 2,
- checkBg: '800',
- checkNoBg: 'black-50',
+ checkCC: "o_cc2",
+ checkBg: backgroundColors[1].hex,
+ checkNoBg: backgroundColors[0].hex,
changeType: 'cc',
- change: 4,
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc4:not(.o_cc2).bg-800`,
+ change: "o_cc4",
+ finalSelector: `:iframe .${snippets[0].id}.o_cc4:not(.o_cc2):not(.bg-${backgroundColors[1].code})`,
}),
// Check the current color palette status + Replace the bg color by a gradient
+// It should remove the custom color class.
...checkAndUpdateBackgroundColor({
- checkCC: 4,
- checkNoCC: 2,
- checkBg: '800',
+ checkCC: "o_cc4",
+ checkNoCC: "o_cc2",
changeType: 'gradient',
change: gradients[0],
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc4:not(.bg-800)[style*="background-image: ${gradients[0]}"]`,
+ finalSelector: `:iframe .${snippets[0].id}:not(.o_cc4)[style*="background-image: ${gradients[0]}"]`,
}),
// Check the current color palette status + Replace the gradient
...checkAndUpdateBackgroundColor({
- checkCC: 4,
- checkNoBg: '800',
+ checkNoCC: "o_cc4",
checkGradient: gradients[0],
changeType: 'gradient',
change: gradients[1],
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc4[style*="background-image: ${gradients[1]}"]:not([style*="background-image: ${gradients[0]}"])`,
+ finalSelector: `:iframe .${snippets[0].id}[style*="background-image: ${gradients[1]}"]:not([style*="background-image: ${gradients[0]}"])`,
}),
// Check the current color palette selection + Change the color combination
-// again. It should keep the gradient.
+// again. It should remove the gradient.
...checkAndUpdateBackgroundColor({
- checkCC: 4,
checkGradient: gradients[1],
checkNoGradient: gradients[0],
changeType: 'cc',
- change: 1,
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc1:not(.o_cc4)[style*="background-image: ${gradients[1]}"]`,
+ change: "o_cc1",
+ finalSelector: `:iframe .${snippets[0].id}.o_cc1:not([style*="background-image: ${gradients[1]}"])`,
}),
// Final check of the color status in the color palette
...checkAndUpdateBackgroundColor({
- checkCC: 1,
- checkNoCC: 4,
- checkGradient: gradients[1],
+ checkCC: "o_cc1",
+ checkNoGradient: gradients[1],
}),
-// Now, add an image on top of that color combination + gradient
-{
- // Close the palette before selecting a media.
- trigger: '.snippet-option-ColoredLevelBackground we-title',
- content: 'Close palette',
- run: "click",
-},
-changeOption('ColoredLevelBackground', '[data-name="bg_image_toggle_opt"]'),
+// Now, add an image on top of that color combination
+changeOption("Text - Image", "button[data-action-id='toggleBgImage']"),
{
trigger: '.o_existing_attachment_cell img',
content: "Select an image in the media dialog",
run: "click",
},
{
- trigger: `:iframe .${snippets[0].id}.o_cc.o_cc1`,
+ trigger: `:iframe .${snippets[0].id}.o_cc1`,
run: function () {
const parts = weUtils.backgroundImageCssToParts(
getComputedStyle(this.anchor)["background-image"]
@@ -234,25 +227,22 @@ changeOption('ColoredLevelBackground', '[data-name="bg_image_toggle_opt"]'),
if (!parts.url || !parts.url.startsWith('url(')) {
throw new Error('An image should have been added as background.');
}
- if (parts.gradient !== gradients[1]) {
- throw new Error('The gradient should have been kept when adding the background image');
- }
},
},
-// Replace the gradient while there is a background-image
+// Add the gradient while there is a background-image.
+// It should remove the image.
...checkAndUpdateBackgroundColor({
- checkCC: 1,
- checkGradient: gradients[1],
+ checkCC: "o_cc1",
changeType: 'gradient',
change: gradients[0],
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc1:not([style*="${gradients[1]}"])`,
+ finalSelector: `:iframe .${snippets[0].id}:not(.o_cc1):not([style*="${gradients[1]}"])`,
finalRun: function () {
const parts = weUtils.backgroundImageCssToParts(
getComputedStyle(this.anchor)["background-image"]
);
- if (!parts.url || !parts.url.startsWith('url(')) {
- throw new Error('The image should have been kept when changing the gradient');
+ if (parts.url && parts.url.startsWith("url(")) {
+ throw new Error("The image should have been removed when changing the gradien");
}
if (parts.gradient !== gradients[0]) {
throw new Error('The gradient should have been changed');
@@ -263,42 +253,40 @@ changeOption('ColoredLevelBackground', '[data-name="bg_image_toggle_opt"]'),
// Customize gradient
changeBackgroundColor(),
switchTo('gradient'),
+{
+ content: "Click on 'Custom' button to show custom gradient options",
+ trigger: ".o_popover .o_custom_gradient_button",
+ run: "click"
+},
// Avoid navigating across tabs to maintain current editor state
// Step colors
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker .o_custom_gradient_scale',
+ trigger: ".o_popover .gradient-preview",
content: 'Add step',
- run() {
- // TODO: use run: "click", instead
- this.anchor.click();
- }
+ run: "click"
},
- checkGradient: 'linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
+ checkGradient: "linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(139, 160, 237) 50%, rgb(75, 225, 236) 100%)",
}),
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker .o_slider_multi input.active',
+ trigger: ".o_popover .gradient-colors input.active",
content: 'Move step',
- run(helpers) {
- this.anchor.value = 45;
- helpers.click();
- },
+ run: "range 45"
},
- checkGradient: 'linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(203, 94, 238) 45%, rgb(75, 225, 236) 100%)',
+ checkGradient: "linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(139, 160, 237) 45%, rgb(75, 225, 236) 100%)",
}),
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker .o_color_picker_inputs .o_hex_div input',
+ trigger: ".o_popover .o_color_picker_inputs .o_hex_div input",
content: 'Pick step color',
- // TODO: remove && click
- run: "edit #FF0000 && click .o_color_picker_inputs",
+ run: "edit #FF0000"
},
checkGradient: 'linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(255, 0, 0) 45%, rgb(75, 225, 236) 100%)',
}),
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker .o_remove_color',
+ trigger: ".o_popover .gradient-color-bin a",
content: 'Delete step',
run: 'click',
},
@@ -307,7 +295,7 @@ switchTo('gradient'),
// Linear
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker input[data-name="angle"]',
+ trigger: ".o_popover input[name='angle']",
content: 'Change angle',
run: "edit 50 && click .o_color_picker_inputs",
},
@@ -316,88 +304,64 @@ switchTo('gradient'),
// Radial
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker we-button[data-gradient-type="radial-gradient"]',
+ trigger: ".o_popover button:contains('Radial')",
content: 'Switch to Radial',
run: 'click',
},
- checkGradient: 'radial-gradient(circle farthest-side at 25% 25%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
+ checkGradient: "radial-gradient(circle closest-side at 25% 25%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)",
}),
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker input[data-name="positionX"]',
+ trigger: ".o_popover input[name='positionX']",
content: 'Change X position',
run: "edit 33 && click .o_color_picker_inputs",
},
- checkGradient: 'radial-gradient(circle farthest-side at 33% 25%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
+ checkGradient: "radial-gradient(circle closest-side at 33% 25%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)",
}),
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker input[data-name="positionY"]',
+ trigger: ".o_popover input[name='positionY']",
content: 'Change Y position',
run: "edit 75 && click .o_color_picker_inputs",
},
- checkGradient: 'radial-gradient(circle farthest-side at 33% 75%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
+ checkGradient: "radial-gradient(circle closest-side at 33% 75%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)",
}),
...updateAndCheckCustomGradient({
updateStep: {
- trigger: '.colorpicker we-button[data-gradient-size="closest-side"]',
+ trigger: ".o_popover button[title='Extend to the farthest side']",
content: 'Change color spread size',
run: 'click',
},
- checkGradient: 'radial-gradient(circle closest-side at 33% 75%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)',
+ checkGradient: "radial-gradient(circle farthest-side at 33% 75%, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%)",
}),
// Revert to predefined gradient
{
- trigger: `.o_we_color_btn[data-color="${gradients[0]}"]`,
+ trigger: `.o_colorpicker_sections button[data-color="${gradients[0]}"]`,
content: `Revert to predefiend gradient ${gradients[0]}`,
run: 'click',
},
-// Replace the gradient by a bg color
+// Replace the gradient by a bg color. It should remove the gradient.
...checkAndUpdateBackgroundColor({
- checkCC: 1,
checkGradient: gradients[0],
- checkNoGradient: gradients[1],
changeType: 'bg',
- change: 'black-75',
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc1.bg-black-75[style^="background-image: url("]:not([style*="${gradients[0]}"])`
+ change: backgroundColors[1].code,
+ finalSelector: `:iframe .${snippets[0].id}.bg-${backgroundColors[1].code}:not([style*="background-image: ${gradients[0]}"])`
}),
// Re-add a gradient
...checkAndUpdateBackgroundColor({
- checkCC: 1,
- checkBg: 'black-75',
+ checkBg: backgroundColors[1].hex,
checkNoGradient: gradients[0],
changeType: 'gradient',
change: gradients[1],
- finalSelector: `:iframe .${snippets[0].id}.o_cc.o_cc1:not(.bg-black-75)`,
- finalRun() {
- const parts = weUtils.backgroundImageCssToParts(
- getComputedStyle(this.anchor)["background-image"]
- );
- if (!parts.url || !parts.url.startsWith('url(')) {
- throw new Error('The image should have been kept when re-adding the gradient');
- }
- if (parts.gradient !== gradients[1]) {
- throw new Error('The gradient should have been re-added');
- }
- },
+ finalSelector: `:iframe .${snippets[0].id}[style*="background-image: ${gradients[1]}"]:not(.bg-${backgroundColors[1].code})`,
}),
-// Final check of color selection and removing the image
-...checkAndUpdateBackgroundColor({
- checkCC: 1,
- checkNoBg: 'black-75',
- checkGradient: gradients[1],
-}),
-changeOption('ColoredLevelBackground', '[data-name="bg_image_toggle_opt"]', 'image toggle', 'top', true),
-{
- trigger: `:iframe .${snippets[0].id}.o_cc.o_cc1[style*="background-image: ${gradients[1]}"]`,
-},
-
-// Now removing all colors via the 'None' button (note: colorpicker still opened)
+// Now removing all colors via the 'None' button
+changeBackgroundColor(),
{
- trigger: '.o_colorpicker_reset',
+ trigger: ".o_popover button[title='Reset']",
content: "Click on the None button of the color palette",
run: "click",
},
diff --git a/addons/website/static/tests/tours/snippet_editor_panel_options.js b/addons/website/static/tests/tours/snippet_editor_panel_options.js
index 992e48bc9a938..6c4a1a0e82a09 100644
--- a/addons/website/static/tests/tours/snippet_editor_panel_options.js
+++ b/addons/website/static/tests/tours/snippet_editor_panel_options.js
@@ -1,5 +1,6 @@
import {
changeOption,
+ changeOptionInPopover,
clickOnSave,
insertSnippet,
goBackToBlocks,
@@ -7,19 +8,9 @@ import {
} from '@website/js/tours/tour_utils';
import { browser } from '@web/core/browser/browser';
-registerWebsitePreviewTour('snippet_editor_panel_options', {
- url: '/',
- edition: true,
-}, () => [
-...insertSnippet({
- id: 's_text_image',
- name: 'Text - Image',
- groupName: "Content",
-}),
-// Test keeping the text selection when using the width option.
-{
+const selectParagraphTextInSnippet = (trigger) => ({
content: "Select the first paragraph.",
- trigger: ':iframe .s_text_image p',
+ trigger: trigger,
async run(actions) {
await actions.click();
const range = document.createRange();
@@ -28,45 +19,59 @@ registerWebsitePreviewTour('snippet_editor_panel_options', {
selection.removeAllRanges();
selection.addRange(range);
},
-}, {
- content: "The text toolbar should be visible. The paragraph should be selected.",
- trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container',
+});
+
+const checkIfParagraphSelected = (trigger) => ({
+ content: "Check if the paragraph is selected.",
+ trigger: trigger,
run() {
- const iframeDocument = document.querySelector('.o_iframe').contentDocument;
- const pText = iframeDocument.querySelector('.s_text_image p').textContent;
- const selection = iframeDocument.getSelection().toString();
+ const pText = this.anchor.textContent;
+ const selection = this.anchor.ownerDocument.getSelection().toString();
if (pText !== selection) {
console.error("The paragraph was not correctly selected.");
}
},
-}, {
+});
+
+const checkIfTextToolbarVisible = {
+ content: "Check if the text toolbar is visible",
+ trigger: ".o-we-toolbar",
+};
+
+registerWebsitePreviewTour('snippet_editor_panel_options', {
+ url: '/',
+ edition: true,
+}, () => [
+...insertSnippet({
+ id: 's_text_image',
+ name: 'Text - Image',
+ groupName: "Content",
+}),
+// Test keeping the text selection when using the width option.
+selectParagraphTextInSnippet(":iframe .s_text_image p"),
+checkIfParagraphSelected(":iframe .s_text_image p"),
+checkIfTextToolbarVisible,
+{
content: "Click on the width option.",
- trigger: '[data-select-class="o_container_small"]',
+ trigger: "[data-action-param='o_container_small']",
run: "click",
}, {
content: "The snippet should have the correct class.",
trigger: ':iframe .s_text_image > .o_container_small',
-}, {
- content: "The text toolbar should still be visible, and the text still selected.",
- trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container',
- run() {
- const iframeDocument = document.querySelector('.o_iframe').contentDocument;
- const pText = iframeDocument.querySelector('.s_text_image p').textContent;
- const selection = iframeDocument.getSelection().toString();
- if (pText !== selection) {
- console.error("The paragraph text selection was lost.");
- }
- },
},
+checkIfParagraphSelected(":iframe .s_text_image p"),
// Test the anchor option.
{
content: "Click on the anchor option",
- trigger: '#oe_snippets .snippet-option-anchor we-button',
+ trigger: "[data-container-title='Text - Image'] .oe_snippet_anchor",
async run(helpers) {
// Patch and ignore write on clipboard in tour as we don't have permissions
const oldWriteText = browser.navigator.clipboard.writeText;
browser.navigator.clipboard.writeText = () => { console.info('Copy in clipboard ignored!') };
await helpers.click();
+ // Restore the writeText after a short delay to avoid reverting it
+ // before the plugin function has been completed
+ await new Promise(resolve => setTimeout(resolve, 100));
browser.navigator.clipboard.writeText = oldWriteText;
}
}, {
@@ -81,7 +86,7 @@ registerWebsitePreviewTour('snippet_editor_panel_options', {
console.error('The anchor option should target the frontend');
}
- const iframeDocument = document.querySelector('.o_iframe').contentDocument;
+ const iframeDocument = document.querySelector(".o_iframe_container iframe").contentDocument;
const snippetId = iframeDocument.querySelector('.s_text_image').id;
if (!url || url.indexOf(snippetId) < 0) {
console.error('The anchor option does not target the correct snippet.');
@@ -95,38 +100,11 @@ goBackToBlocks(),
name: 'Text',
groupName: "Text",
}),
+selectParagraphTextInSnippet(":iframe .s_text_block p"),
+checkIfParagraphSelected(":iframe .s_text_block p"),
+checkIfTextToolbarVisible,
+...changeOptionInPopover("Text", "Layout", "[data-action-value='3']"),
{
- content: "Select the first paragraph.",
- trigger: ':iframe .s_text_block p',
- async run(actions) {
- await actions.click();
- const range = document.createRange();
- const selection = this.anchor.ownerDocument.getSelection();
- range.selectNodeContents(this.anchor);
- selection.removeAllRanges();
- selection.addRange(range);
- },
-}, {
- content: "The text toolbar should be visible. The paragraph should be selected.",
- trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container',
- run() {
- const iframeDocument = document.querySelector('.o_iframe').contentDocument;
- const pText = iframeDocument.querySelector('.s_text_block p').textContent;
- const selection = iframeDocument.getSelection().toString();
- if (pText !== selection) {
- console.error("The paragraph was not correctly selected.");
- }
- },
-}, {
- content: "Click on the columns option.",
- trigger: '.snippet-option-layout_column we-select',
- run: "click",
-},
-{
- content: "Change the number of columns.",
- trigger: '.snippet-option-layout_column [data-select-count="3"]',
- run: "click",
-}, {
content: "The snippet should have the correct number of columns.",
trigger: ':iframe .s_text_block .container > .row .col-lg-4:eq(3)',
run() {
@@ -134,92 +112,28 @@ goBackToBlocks(),
console.error("The snippet does not have the correct number of columns");
}
},
-}, {
- content: "The text toolbar should still be visible, and the text still selected.",
- trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container',
- run() {
- const iframeDocument = document.querySelector('.o_iframe').contentDocument;
- const pText = iframeDocument.querySelector('.s_text_block p').textContent;
- const selection = iframeDocument.getSelection().toString();
- if (pText !== selection) {
- console.error("The paragraph text selection was lost.");
- }
- },
},
+checkIfParagraphSelected(":iframe .s_text_block p"),
// Test keeping the text selection when removing all columns of a snippet.
+...changeOptionInPopover("Text", "Layout", "[data-action-value='0']"),
{
- content: "Click on the columns option.",
- trigger: '.snippet-option-layout_column we-select',
- run: "click",
-},
-{
- content: "Change the number of columns.",
- trigger: '.snippet-option-layout_column [data-select-count="0"]',
- run: "click",
-}, {
content: "The snippet should have the correct number of columns.",
trigger: ':iframe .s_text_block .container:not(:has(.row))',
-}, {
- content: "The text toolbar should still be visible, and the text still selected.",
- trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container',
- run() {
- const iframeDocument = document.querySelector('.o_iframe').contentDocument;
- const pText = iframeDocument.querySelector('.s_text_block p').textContent;
- const selection = iframeDocument.getSelection().toString();
- if (pText !== selection) {
- console.error("The paragraph text selection was lost.");
- }
- },
},
+checkIfParagraphSelected(":iframe .s_text_block p"),
// Test keeping the text selection when toggling the grid mode.
-changeOption("layout_column", 'we-button[data-name="grid_mode"]'),
+changeOption("Text", "[data-action-id='setGridLayout']"),
{
content: "The snippet row should have the grid mode class.",
trigger: ":iframe .s_text_block .row.o_grid_mode",
-}, {
- content: "The text toolbar should still be visible, and the text still selected.",
- trigger: "#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container",
- run() {
- const iframeDocument = document.querySelector(".o_iframe").contentDocument;
- const pText = iframeDocument.querySelector(".s_text_block p").textContent;
- const selection = iframeDocument.getSelection().toString();
- if (pText !== selection) {
- console.error("The paragraph text selection was lost.");
- }
- },
},
-// Test keeping the text selection when toggling back the normal mode.
-changeOption("layout_column", 'we-button[data-name="normal_mode"]'),
+checkIfParagraphSelected(":iframe .s_text_block p"),
+// Test keeping the text selection when toggling back the column mode.
+changeOption("Text", "[data-action-id='setColumnLayout']"),
{
content: "The snippet row should not have the grid mode class anymore.",
trigger: ":iframe .s_text_block .row:not(.o_grid_mode)",
-}, {
- content: "The text toolbar should still be visible, and the text still selected.",
- trigger: "#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container",
- run() {
- const iframeDocument = document.querySelector(".o_iframe").contentDocument;
- const pText = iframeDocument.querySelector(".s_text_block p").textContent;
- const selection = iframeDocument.getSelection().toString();
- if (pText !== selection) {
- console.error("The paragraph text selection was lost.");
- }
- },
-},
-// Test close dropdowns if click anywhere outside the dropdown
-{
- content: "Open text style dropdown.",
- trigger: "#style button.dropdown-toggle",
- run: "click",
-}, {
- content: "Check if dropdown opened correctly.",
- trigger: "#style button[data-bs-toggle=dropdown][aria-expanded=true]",
-}, {
- content: "Click on the first paragraph again.",
- trigger: ":iframe .s_text_block p",
- run: "click",
-}, {
- content: "Check if dropdown closed correctly.",
- trigger: "#style button[data-bs-toggle=dropdown][aria-expanded=false]",
},
+checkIfParagraphSelected(":iframe .s_text_block p"),
...clickOnSave(),
]);
diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py
index 48a007d6b0fa2..a69b329035387 100644
--- a/addons/website/tests/test_ui.py
+++ b/addons/website/tests/test_ui.py
@@ -433,7 +433,6 @@ def test_10_website_conditional_visibility(self):
self.start_tour(self.env['website'].get_client_action_url('/'), 'conditional_visibility_4', login='admin')
self.start_tour(self.env['website'].get_client_action_url('/'), 'conditional_visibility_5', login='admin')
- @unittest.skip
def test_11_website_snippet_background_edition(self):
self.env['ir.attachment'].create({
'public': True,
@@ -527,7 +526,6 @@ def test_18_website_snippets_menu_tabs(self):
def test_19_website_page_options(self):
self.start_tour("/odoo", "website_page_options", login="admin")
- @unittest.skip
def test_20_snippet_editor_panel_options(self):
self.start_tour('/@/', 'snippet_editor_panel_options', login='admin')
diff --git a/addons/website/tests/test_website_form_editor.py b/addons/website/tests/test_website_form_editor.py
index b37725cb6fb36..8aeb2d3c51f2c 100644
--- a/addons/website/tests/test_website_form_editor.py
+++ b/addons/website/tests/test_website_form_editor.py
@@ -61,8 +61,6 @@ def test_contactus_form_email_stay_dynamic(self):
def test_website_form_editable_content(self):
self.start_tour('/', 'website_form_editable_content', login="admin")
- # TODO @mysterious-egg: new tour
- @unittest.skip
def test_website_form_special_characters(self):
self.start_tour('/', 'website_form_special_characters', login='admin')
mail = self.env['mail.mail'].search([], order='id desc', limit=1)