
/* /base/static/tests/test_ir_model_fields_translation.js */
odoo.define('@base/../tests/test_ir_model_fields_translation',['@web/core/registry','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");function checkLoginColumn(translation){return[stepUtils.showAppsMenuItem(),{content:"Settings",trigger:'a[data-menu-xmlid="base.menu_administration"]',run:'click',},{content:"Open Users & Companies",trigger:'[data-menu-xmlid="base.menu_users"]',run:"click",},{content:"Open Users",trigger:'[data-menu-xmlid="base.menu_action_res_users"]',run:"click",},{content:`Login column should be ${translation}`,trigger:`[data-name="login"] span:contains("${translation}")`,}]}
registry.category("web_tour.tours").add('ir_model_fields_translation_en_tour',{url:'/odoo',steps:()=>checkLoginColumn('Login')});registry.category("web_tour.tours").add('ir_model_fields_translation_en_tour2',{url:'/odoo',steps:()=>checkLoginColumn('Login2')});registry.category("web_tour.tours").add('ir_model_fields_translation_fr_tour',{url:'/odoo',steps:()=>checkLoginColumn('Identifiant')});registry.category("web_tour.tours").add('ir_model_fields_translation_fr_tour2',{url:'/odoo',steps:()=>checkLoginColumn('Identifiant2')});return __exports;});;

/* /web/static/tests/legacy/helpers/cleanup.js */
odoo.define('@web/../tests/legacy/helpers/cleanup',[],function(require){'use strict';let __exports={};const cleanups=[];__exports.registerCleanup=registerCleanup;function registerCleanup(callback){cleanups.push(callback);}
if(window.QUnit){QUnit.on("OdooAfterTestHook",(info)=>{if(QUnit.config.debug){return;}
let cleanup;while((cleanup=cleanups.pop())){try{cleanup(info);}catch(error){console.error(error);}}});const validElements=[{tagName:"DIV",attr:"id",value:"qunit",keep:true},{tagName:"DIV",attr:"id",value:"qunit-fixture",keep:true},{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:"DIV",attr:"class",value:"tooltip tooltip-field-info fade bs-tooltip-auto"},{tagName:"DIV",attr:"class",value:"tooltip tooltip-field-info fade bs-tooltip-auto show",},{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",},];QUnit.on("OdooAfterTestHook",function(info){if(QUnit.config.debug){return;}
const failed=info.testReport.getStatus()==="failed";const toRemove=[];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);}}
const qunitFixture=document.getElementById("qunit-fixture");if(qunitFixture.children.length){toRemove.push(...qunitFixture.children);}
for(const el of toRemove){el.remove();}
document.body.classList.remove("modal-open");});}
return __exports;});odoo.define(`@web/../tests/helpers/cleanup`,['@web/../tests/legacy/helpers/cleanup'],function(require){return require('@web/../tests/legacy/helpers/cleanup');});;

/* /web/static/tests/legacy/helpers/utils.js */
odoo.define('@web/../tests/legacy/helpers/utils',['@web/core/templates','@web/core/browser/browser','@web/core/browser/feature_detection','@web/core/network/download','@web/core/popover/popover','@web/core/utils/concurrency','@web/core/utils/patch','@web/core/utils/ui','@web/core/l10n/translation','@web/../tests/legacy/helpers/cleanup','@odoo/owl'],function(require){'use strict';let __exports={};const{getTemplate}=require("@web/core/templates");const{browser}=require("@web/core/browser/browser");const{isMacOS}=require("@web/core/browser/feature_detection");const{download}=require("@web/core/network/download");const{getPopoverForTarget}=require("@web/core/popover/popover");const{Deferred}=require("@web/core/utils/concurrency");const{patch}=require("@web/core/utils/patch");const{isVisible}=require("@web/core/utils/ui");const{_t}=require("@web/core/l10n/translation");const{registerCleanup}=require("@web/../tests/legacy/helpers/cleanup");const{App,onError,onMounted,onPatched,onRendered,onWillDestroy,onWillPatch,onWillRender,onWillStart,onWillUnmount,onWillUpdateProps,useComponent,}=require("@odoo/owl");__exports.patchDate=patchDate;function patchDate(year,month,day,hours,minutes,seconds,ms=0){var RealDate=window.Date;var actualDate=new RealDate();var fakeDate=new RealDate(year,month,day,hours,minutes,seconds,ms);if(!(luxon.Settings.defaultZone instanceof luxon.FixedOffsetZone)){throw new Error("luxon.Settings.defaultZone must be a FixedOffsetZone");}
const browserOffset=-fakeDate.getTimezoneOffset();const patchedOffset=luxon.Settings.defaultZone.offset();const offsetDiff=patchedOffset-browserOffset;const correctedMinutes=fakeDate.getMinutes()-offsetDiff;fakeDate.setMinutes(correctedMinutes);var timeInterval=actualDate.getTime()-fakeDate.getTime();window.Date=(function(NativeDate){function Date(Y,M,D,h,m,s,ms){var length=arguments.length;let date;if(arguments.length>0){date=length==1&&String(Y)===Y?new NativeDate(Date.parse(Y)):length>=7?new NativeDate(Y,M,D,h,m,s,ms):length>=6?new NativeDate(Y,M,D,h,m,s):length>=5?new NativeDate(Y,M,D,h,m):length>=4?new NativeDate(Y,M,D,h):length>=3?new NativeDate(Y,M,D):length>=2?new NativeDate(Y,M):length>=1?new NativeDate(Y):new NativeDate();date.constructor=Date;return date;}else{date=new NativeDate();var time=date.getTime();time-=timeInterval;date.setTime(time);return date;}}
for(var key in NativeDate){Date[key]=NativeDate[key];}
Date.now=function(){var date=new NativeDate();var time=date.getTime();time-=timeInterval;return time;};Date.UTC=NativeDate.UTC;Date.prototype=NativeDate.prototype;Date.prototype.constructor=Date;Date.parse=NativeDate.parse;return Date;})(Date);registerCleanup(()=>{window.Date=RealDate;});}
__exports.patchTimeZone=patchTimeZone;function patchTimeZone(offset){patchWithCleanup(luxon.Settings,{defaultZone:luxon.FixedOffsetZone.instance(offset)});}
__exports.patchWithCleanup=patchWithCleanup;function patchWithCleanup(obj,patchValue){const unpatch=patch(obj,patchValue);registerCleanup(()=>{unpatch();});}
__exports.getFixture=getFixture;function getFixture(){if(!window.QUnit){return document;}
if(QUnit.config.debug){return document.body;}else{return document.getElementById("qunit-fixture");}}
__exports.nextTick=nextTick;async function nextTick(){await new Promise((resolve)=>window.requestAnimationFrame(resolve));await new Promise((resolve)=>setTimeout(resolve));}
__exports.makeDeferred=makeDeferred;function makeDeferred(){return new Deferred();}
__exports.findElement=findElement;function findElement(el,selector){let target=el;if(selector){const els=el.querySelectorAll(selector);if(els.length===0){throw new Error(`No element found (selector: ${selector})`);}
if(els.length>1){throw new Error(`Found ${els.length} elements, instead of 1 (selector: ${selector})`);}
target=els[0];}
return target;}
const mapBubblingEvent=(args)=>({...args,bubbles:true});const mapNonBubblingEvent=(args)=>({...args,bubbles:false});const mapBubblingPointerEvent=(args={})=>({clientX:args.pageX,clientY:args.pageY,...args,bubbles:true,cancelable:true,view:window,});const mapNonBubblingPointerEvent=(args)=>({...mapBubblingPointerEvent(args),bubbles:false,cancelable:false,});const mapCancelableTouchEvent=(args={})=>({...args,bubbles:true,cancelable:true,composed:true,rotation:0.0,touches:args.touches?[...args.touches.map((e)=>new Touch(e))]:undefined,view:window,zoom:1.0,});const mapNonCancelableTouchEvent=(args)=>({...mapCancelableTouchEvent(args),cancelable:false,});const mapKeyboardEvent=(args)=>({...args,bubbles:true,cancelable:true,});const getEventConstructor=(eventType)=>{switch(eventType){case"auxclick":case"click":case"contextmenu":case"dblclick":case"mousedown":case"mouseup":case"mousemove":case"mouseover":case"mouseout":{return[MouseEvent,mapBubblingPointerEvent];}
case"mouseenter":case"mouseleave":{return[MouseEvent,mapNonBubblingPointerEvent];}
case"pointerdown":case"pointerup":case"pointermove":case"pointerover":case"pointerout":{return[PointerEvent,mapBubblingPointerEvent];}
case"pointerenter":case"pointerleave":{return[PointerEvent,mapNonBubblingPointerEvent];}
case"focusin":{return[FocusEvent,mapBubblingEvent];}
case"focus":case"blur":{return[FocusEvent,mapNonBubblingEvent];}
case"cut":case"copy":case"paste":{return[ClipboardEvent,mapBubblingEvent];}
case"keydown":case"keypress":case"keyup":{return[KeyboardEvent,mapKeyboardEvent];}
case"drag":case"dragend":case"dragenter":case"dragstart":case"dragleave":case"dragover":case"drop":{return[DragEvent,mapBubblingEvent];}
case"input":{return[InputEvent,mapBubblingEvent];}
case"compositionstart":case"compositionend":{return[CompositionEvent,mapBubblingEvent];}
case"scroll":{return[UIEvent,mapNonBubblingEvent];}
case"touchstart":case"touchend":case"touchmove":{return[TouchEvent,mapCancelableTouchEvent];}
case"touchcancel":{return[TouchEvent,mapNonCancelableTouchEvent];}
default:{return[Event,mapBubblingEvent];}}};__exports.triggerEvent=triggerEvent;function triggerEvent(el,selector,eventType,eventInit,options={}){const errors=[];const target=findElement(el,selector);if(typeof eventType!=="string"){errors.push("event type must be a string");}
if(!target){errors.push("cannot find target");}else if(!options.skipVisibilityCheck&&!isVisible(target)){errors.push("target is not visible");}
if(errors.length){throw new Error(`Cannot trigger event${eventType ? `"${eventType}"` : ""}${
                selector ? `(with selector"${selector}")` : ""
            }: ${errors.join(" and ")}`);}
const[Constructor,processParams]=getEventConstructor(eventType);const event=new Constructor(eventType,processParams(eventInit));target.dispatchEvent(event);if(window.QUnit&&QUnit.config.debug){const group=`%c[${event.type.toUpperCase()}]`;console.groupCollapsed(group,"color: #b52c9b");console.log(target,event);console.groupEnd(group,"color: #b52c9b");}
if(options.sync){return event;}else{return nextTick().then(()=>event);}}
__exports.triggerEvents=triggerEvents;function triggerEvents(el,selector,eventDefs,options={}){const events=[...eventDefs].map((eventDef)=>{const[eventType,eventInit]=Array.isArray(eventDef)?eventDef:[eventDef,{}];return triggerEvent(el,selector,eventType,eventInit,options);});if(options.sync){return events;}else{return nextTick().then(()=>events);}}
__exports.triggerScroll=triggerScroll;async function triggerScroll(target,coordinates={left:null,top:null},canPropagate=true){const isScrollable=(target.scrollHeight>target.clientHeight&&target.clientHeight>0)||(target.scrollWidth>target.clientWidth&&target.clientWidth>0);if(!isScrollable&&!canPropagate){return;}
if(isScrollable){const canScrollFrom={left:coordinates.left>target.scrollLeft?target.scrollLeft+target.clientWidth<target.scrollWidth:target.scrollLeft>0,top:coordinates.top>target.scrollTop?target.scrollTop+target.clientHeight<target.scrollHeight:target.scrollTop>0,};const scrollCoordinates={};Object.entries(coordinates).forEach(([key,value])=>{if(value!==null&&canScrollFrom[key]){scrollCoordinates[key]=value;delete coordinates[key];}});target.scrollTo(scrollCoordinates);await triggerEvent(target,null,"scroll");if(!canPropagate||!Object.entries(coordinates).length){return;}}
target.parentElement?triggerScroll(target.parentElement,coordinates):triggerEvent(window,null,"scroll");await nextTick();}
__exports.click=click;function click(el,selector,{mouseEventInit={},skipDisabledCheck=false,skipVisibilityCheck=false}={}){if(!skipDisabledCheck&&el.disabled){throw new Error("Can't click on a disabled button");}
return triggerEvents(el,selector,["pointerdown","mousedown","focus","focusin","pointerup","mouseup",["click",mouseEventInit],],{skipVisibilityCheck});}
__exports.clickCreate=clickCreate;function clickCreate(htmlElement){if(htmlElement.querySelectorAll(".o_control_panel_main_buttons .o_form_button_create").length){return click(htmlElement,".o_control_panel_main_buttons .o_form_button_create");}else if(htmlElement.querySelectorAll(".o_control_panel_main_buttons .o_list_button_create").length){return click(htmlElement,".o_control_panel_main_buttons .o_list_button_create");}else{throw new Error("No edit button found to be clicked.");}}
__exports.clickEdit=clickEdit;function clickEdit(htmlElement){if(htmlElement.querySelectorAll(".o_list_button_edit").length){return click(htmlElement,".o_list_button_edit");}else{throw new Error("No edit button found to be clicked.");}}
__exports.clickSave=clickSave;async function clickSave(htmlElement){if(htmlElement.querySelectorAll(".o_form_status_indicator").length){await mouseEnter(htmlElement,".o_form_status_indicator");}
if(htmlElement.querySelectorAll(".o_form_button_save").length){return click(htmlElement,".o_form_button_save");}
const listSaveButtons=htmlElement.querySelectorAll(".o_list_button_save");if(listSaveButtons.length){return listSaveButtons.length>=2?click(listSaveButtons[1]):click(listSaveButtons[0]);}else{throw new Error("No save button found to be clicked.");}}
__exports.clickDiscard=clickDiscard;async function clickDiscard(htmlElement){if(htmlElement.querySelectorAll(".o_form_status_indicator").length){await mouseEnter(htmlElement,".o_form_status_indicator");}
if(htmlElement.querySelectorAll(".o_form_button_cancel").length){return click(htmlElement,".o_form_button_cancel");}else if($(htmlElement).find(".o_list_button_discard:visible").length){return click($(htmlElement).find(".o_list_button_discard:visible").get(0));}else{throw new Error("No discard button found to be clicked.");}}
__exports.mouseEnter=mouseEnter;async function mouseEnter(el,selector,coordinates){const target=el.querySelector(selector)||el;const atPos=coordinates||{clientX:target.getBoundingClientRect().left+target.getBoundingClientRect().width/2,clientY:target.getBoundingClientRect().top+target.getBoundingClientRect().height/2,};return triggerEvents(target,null,["pointerenter","mouseenter"],atPos);}
__exports.mouseLeave=mouseLeave;async function mouseLeave(el,selector){const target=el.querySelector(selector)||el;return triggerEvents(target,null,["pointerleave","mouseleave"]);}
__exports.editInput=editInput;async function editInput(el,selector,value){const input=findElement(el,selector);if(!(input instanceof HTMLInputElement||input instanceof HTMLTextAreaElement)){throw new Error("Only 'input' and 'textarea' elements can be edited with 'editInput'.");}
if(!["text","textarea","email","search","color","number","file","tel"].includes(input.type)){throw new Error(`Type "${input.type}" not supported by 'editInput'.`);}
const eventOpts={};if(input.type==="file"){const files=Array.isArray(value)?value:[value];const dataTransfer=new DataTransfer();for(const file of files){if(!(file instanceof File)){throw new Error(`File input value should be one or several File objects.`);}
dataTransfer.items.add(file);}
input.files=dataTransfer.files;eventOpts.skipVisibilityCheck=true;}else{input.value=value;}
await triggerEvents(input,null,["input","change"],eventOpts);if(input.type==="file"){await nextTick();await nextTick();}}
__exports.editSelect=editSelect;function editSelect(el,selector,value){const select=findElement(el,selector);if(select.tagName!=="SELECT"){throw new Error("Only select tag can be edited with selectInput.");}
select.value=value;return triggerEvent(select,null,"change");}
__exports.editSelectMenu=editSelectMenu;async function editSelectMenu(el,selector,value){const dropdown=el.querySelector(selector);await click(dropdown.querySelector(".dropdown-toggle"));for(const item of Array.from(el.querySelectorAll(".o_select_menu_menu .dropdown-item"))){if(item.textContent===value){return click(item);}}}
__exports.triggerHotkey=triggerHotkey;async function triggerHotkey(hotkey,addOverlayModParts=false,eventAttrs={}){eventAttrs.key=hotkey.split("+").pop();if(/shift/i.test(hotkey)){eventAttrs.shiftKey=true;}
if(/control/i.test(hotkey)){if(isMacOS()){eventAttrs.metaKey=true;}else{eventAttrs.ctrlKey=true;}}
if(/alt/i.test(hotkey)||addOverlayModParts){if(isMacOS()){eventAttrs.ctrlKey=true;}else{eventAttrs.altKey=true;}}
if(!("bubbles"in eventAttrs)){eventAttrs.bubbles=true;}
const[keydownEvent,keyupEvent]=await triggerEvents(document.activeElement,null,[["keydown",eventAttrs],["keyup",eventAttrs],],{skipVisibilityCheck:true});return{keydownEvent,keyupEvent};}
__exports.mockDownload=mockDownload;function mockDownload(cb){patchWithCleanup(download,{_download:cb});}
const hushConsole=__exports.hushConsole=Object.create(null);for(const propName of Object.keys(window.console)){hushConsole[propName]=()=>{};}
__exports.mockSendBeacon=mockSendBeacon;function mockSendBeacon(mock){patchWithCleanup(navigator,{sendBeacon:(url,blob)=>{return mock(url,blob)!==false;},});}
__exports.mockTimeout=mockTimeout;function mockTimeout(){const timeouts=new Map();let currentTime=0;let id=1;patchWithCleanup(browser,{setTimeout(fn,delay=0){timeouts.set(id,{fn,scheduledFor:delay+currentTime,id});return id++;},clearTimeout(id){timeouts.delete(id);},});return{execRegisteredTimeouts(){for(const{fn}of timeouts.values()){fn();}
timeouts.clear();},async advanceTime(duration){await nextTick();currentTime+=duration;for(const{fn,scheduledFor,id}of timeouts.values()){if(scheduledFor<=currentTime){fn();timeouts.delete(id);}}
await nextTick();},};}
__exports.mockAnimationFrame=mockAnimationFrame;function mockAnimationFrame(){const callbacks=new Map();let currentTime=0;let id=1;patchWithCleanup(browser,{requestAnimationFrame(fn){callbacks.set(id,{fn,scheduledFor:16+currentTime,id});return id++;},cancelAnimationFrame(id){callbacks.delete(id);},performance:{now:()=>currentTime},});return{execRegisteredAnimationFrames(){for(const{fn}of callbacks.values()){fn(currentTime);}
callbacks.clear();},async advanceFrame(count=1){await nextTick();currentTime+=16*count;for(const{fn,scheduledFor,id}of callbacks.values()){if(scheduledFor<=currentTime){fn(currentTime);callbacks.delete(id);}}
await nextTick();},};}
__exports.mount=mount;async function mount(Comp,target,config={}){let{props,env}=config;env=env||{};const configuration={env,getTemplate,test:true,props,};if(env.services&&"localization"in env.services){configuration.translateFn=_t;}
const app=new App(Comp,configuration);registerCleanup(()=>app.destroy());return app.mount(target);}
__exports.destroy=destroy;function destroy(comp){comp.__owl__.app.destroy();}
__exports.findChildren=findChildren;function findChildren(comp,predicate=(e)=>e){const queue=[];[].unshift.apply(queue,Object.values(comp.__owl__.children));while(queue.length>0){const curNode=queue.pop();if(predicate(curNode)){return curNode;}
[].unshift.apply(queue,Object.values(curNode.component.__owl__.children));}}
__exports.useChild=useChild;function useChild(){const node=useComponent().__owl__;const setChild=()=>{const componentNode=Object.values(node.children)[0];node.component.child=componentNode.component;};onMounted(setChild);onPatched(setChild);}
__exports.useLogLifeCycle=useLogLifeCycle;function useLogLifeCycle(logFn,name=""){const component=useComponent();let loggedName=`${component.constructor.name}`;if(name){loggedName=`${component.constructor.name} ${name}`;}
onError(()=>{logFn(`onError ${loggedName}`);});onMounted(()=>{logFn(`onMounted ${loggedName}`);});onPatched(()=>{logFn(`onPatched ${loggedName}`);});onRendered(()=>{logFn(`onRendered ${loggedName}`);});onWillDestroy(()=>{logFn(`onWillDestroy ${loggedName}`);});onWillPatch(()=>{logFn(`onWillPatch ${loggedName}`);});onWillRender(()=>{logFn(`onWillRender ${loggedName}`);});onWillStart(()=>{logFn(`onWillStart ${loggedName}`);});onWillUnmount(()=>{logFn(`onWillUnmount ${loggedName}`);});onWillUpdateProps(()=>{logFn(`onWillUpdateProps ${loggedName}`);});}
function getDifferentParents(n1,n2){const parents=[n2];while(parents[0].parentNode){const parent=parents[0].parentNode;if(parent.contains(n1)){break;}
parents.unshift(parent);}
return parents;}
__exports.dragAndDrop=dragAndDrop;async function dragAndDrop(from,to,position){const{drop}=await drag(from);await drop(to,position);}
__exports.drag=drag;async function drag(from,pointerType="mouse"){const assertIsDragging=(fn,endDrag)=>{return{async[fn.name](...args){if(dragEndReason){throw new Error(`Cannot execute drag helper '${fn.name}': drag sequence has been ended by '${dragEndReason}'.`);}
await fn(...args);if(endDrag){dragEndReason=fn.name;}},}[fn.name];};const cancel=assertIsDragging(async function cancel(){await triggerEvent(window,null,"keydown",{key:"Escape"});},true);const drop=assertIsDragging(async function drop(to,position){if(to){await moveTo(to,position);}
await triggerEvent(target||source,null,"pointerup",targetPosition);},true);const getEl=(selector)=>selector instanceof Element?selector:fixture.querySelector(selector);const getTargetPosition=(position)=>{const tRect=target.getBoundingClientRect();const tPos={clientX:Math.floor(tRect.x),clientY:Math.floor(tRect.y),};if(position&&typeof position==="object"){tPos.clientX+=position.x||0;tPos.clientY+=position.y||0;}else{const positions=typeof position==="string"?position.split("-"):[];if(positions.includes("left")){tPos.clientX-=1;}else if(positions.includes("right")){tPos.clientX+=Math.ceil(tRect.width)+1;}else{tPos.clientX+=Math.floor(tRect.width/2);}
if(positions.includes("top")){tPos.clientY-=1;}else if(positions.includes("bottom")){tPos.clientY+=Math.ceil(tRect.height)+1;}else{tPos.clientY+=Math.floor(tRect.height/2);}}
return tPos;};const moveTo=assertIsDragging(async function moveTo(to,position){target=getEl(to);if(!target){return;}
targetPosition=getTargetPosition(position);await triggerEvent(source,null,"pointermove",{...targetPosition,button:-1});for(const parent of getDifferentParents(source,target)){triggerEvent(parent,null,"pointerenter",targetPosition);}
await nextTick();return dragHelpers;},false);const dragHelpers={cancel,drop,moveTo};const fixture=getFixture();const source=getEl(from instanceof Element?from:fixture.querySelector(from));const sourceRect=source.getBoundingClientRect();let dragEndReason=null;let target;let targetPosition;await triggerEvent(source,null,"pointerdown",{pointerType,clientX:sourceRect.x+sourceRect.width/2,clientY:sourceRect.y+sourceRect.height/2,});return dragHelpers;}
__exports.getDropdownMenu=getDropdownMenu;function getDropdownMenu(target,togglerSelector){if(!(target instanceof HTMLElement)){throw new Error(`getDropdownMenu: target is not an HTMLElement.`);}
let el=togglerSelector instanceof HTMLElement?togglerSelector:target.querySelector(togglerSelector);if(el&&!el.classList.contains("o-dropdown")){el=el.querySelector(".o-dropdown");}
if(!el){throw new Error(`getDropdownMenu: Could not find element "${togglerSelector}".`);}
return getPopoverForTarget(el);}
__exports.clickDropdown=clickDropdown;async function clickDropdown(target,fieldName){const dropdownInput=target.querySelector(`[name='${fieldName}'] .dropdown input`);dropdownInput.focus();await nextTick();await click(dropdownInput);}
__exports.clickOpenedDropdownItem=clickOpenedDropdownItem;async function clickOpenedDropdownItem(target,fieldName,itemContent){const dropdowns=target.querySelectorAll(`[name='${fieldName}'] .dropdown .dropdown-menu`);if(dropdowns.length===0){throw new Error(`No dropdown found for field ${fieldName}`);}else if(dropdowns.length>1){throw new Error(`Found ${dropdowns.length} dropdowns for field ${fieldName}`);}
const dropdownItems=dropdowns[0].querySelectorAll("li");const indexToClick=Array.from(dropdownItems).map((html)=>html.textContent).indexOf(itemContent);if(indexToClick===-1){throw new Error(`The element '${itemContent}' does not exist in the dropdown`);}
await click(dropdownItems[indexToClick]);}
__exports.selectDropdownItem=selectDropdownItem;async function selectDropdownItem(target,fieldName,itemContent){await clickDropdown(target,fieldName);await clickOpenedDropdownItem(target,fieldName,itemContent);}
__exports.getNodesTextContent=getNodesTextContent;function getNodesTextContent(nodes){return Array.from(nodes).map((n)=>n.textContent);}
__exports.clickOpenM2ODropdown=clickOpenM2ODropdown;async function clickOpenM2ODropdown(el,fieldName,selector){const m2oSelector=`${selector || ""} .o_field_many2one[name=${fieldName}] input`;const matches=el.querySelectorAll(m2oSelector);if(matches.length!==1){throw new Error(`cannot open m2o: selector ${selector} has been found ${matches.length} instead of 1`);}
await click(matches[0]);return matches[0];}
__exports.clickM2OHighlightedItem=clickM2OHighlightedItem;async function clickM2OHighlightedItem(el,fieldName,selector){const m2oSelector=`${selector || ""} .o_field_many2one[name=${fieldName}] input`;const matches=el.querySelectorAll(m2oSelector);if(matches.length!==1){throw new Error(`cannot open m2o: selector ${selector} has been found ${matches.length} instead of 1`);}
return click(matches[0].parentElement.querySelector("li"));}
__exports.addRow=addRow;async function addRow(target,selector){await click(target.querySelector(`${selector ? selector : ""} .o_field_x2many_list_row_add a`));}
__exports.removeRow=removeRow;async function removeRow(target,index){await click(target.querySelectorAll(".o_list_record_remove")[index]);}
return __exports;});odoo.define(`@web/../tests/helpers/utils`,['@web/../tests/legacy/helpers/utils'],function(require){return require('@web/../tests/legacy/helpers/utils');});;

/* /web/static/tests/legacy/utils.js */
odoo.define('@web/../tests/legacy/utils',['@web/core/utils/ui','@web/../tests/helpers/cleanup','@web/../tests/helpers/utils'],function(require){'use strict';let __exports={};const{isVisible}=require("@web/core/utils/ui");const{registerCleanup}=require("@web/../tests/helpers/cleanup");const{click:webClick,getFixture,makeDeferred,triggerEvents:webTriggerEvents,}=require("@web/../tests/helpers/utils");function createFakeDataTransfer(files){return{dropEffect:"all",effectAllowed:"all",files,items:[],types:["Files"],};}
__exports.click=click;async function click(selector,options={}){const{shiftKey}=options;delete options.shiftKey;await contains(selector,{click:{shiftKey},...options});}
__exports.dragenterFiles=dragenterFiles;async function dragenterFiles(selector,files,options){await contains(selector,{dragenterFiles:files,...options});}
__exports.dragoverFiles=dragoverFiles;async function dragoverFiles(selector,files,options){await contains(selector,{dragoverFiles:files,...options});}
__exports.dropFiles=dropFiles;async function dropFiles(selector,files,options){await contains(selector,{dropFiles:files,...options});}
__exports.inputFiles=inputFiles;async function inputFiles(selector,files,options){await contains(selector,{inputFiles:files,...options});}
__exports.pasteFiles=pasteFiles;async function pasteFiles(selector,files,options){await contains(selector,{pasteFiles:files,...options});}
__exports.focus=focus;async function focus(selector,options){await contains(selector,{setFocus:true,...options});}
__exports.insertText=insertText;async function insertText(selector,content,options={}){const{replace=false}=options;delete options.replace;await contains(selector,{...options,insertText:{content,replace}});}
__exports.scroll=scroll;async function scroll(selector,scrollTop,options){await contains(selector,{setScroll:scrollTop,...options});}
__exports.triggerEvents=triggerEvents;async function triggerEvents(selector,events,options){await contains(selector,{triggerEvents:events,...options});}
function log(ok,message){if(window.QUnit){QUnit.assert.ok(ok,message);}else{if(ok){console.log(message);}else{console.error(message);}}}
let hasUsedContainsPositively=false;if(window.QUnit){QUnit.testStart(()=>(hasUsedContainsPositively=false));}
class Contains{constructor(selector,options={}){this.selector=selector;this.options=options;this.options.count??=1;this.options.targetParam=this.options.target;this.options.target??=getFixture();let selectorMessage=`${this.options.count} of "${this.selector}"`;if(this.options.visible!==undefined){selectorMessage=`${selectorMessage} ${
                this.options.visible ? "visible" : "invisible"
            }`;}
if(this.options.targetParam){selectorMessage=`${selectorMessage} inside a specific target`;}
if(this.options.parent){selectorMessage=`${selectorMessage} inside a specific parent`;}
if(this.options.contains){selectorMessage=`${selectorMessage} with a specified sub-contains`;}
if(this.options.text!==undefined){selectorMessage=`${selectorMessage} with text "${this.options.text}"`;}
if(this.options.textContent!==undefined){selectorMessage=`${selectorMessage} with textContent "${this.options.textContent}"`;}
if(this.options.value!==undefined){selectorMessage=`${selectorMessage} with value "${this.options.value}"`;}
if(this.options.scroll!==undefined){selectorMessage=`${selectorMessage} with scroll "${this.options.scroll}"`;}
if(this.options.after!==undefined){selectorMessage=`${selectorMessage} after a specified element`;}
if(this.options.before!==undefined){selectorMessage=`${selectorMessage} before a specified element`;}
this.selectorMessage=selectorMessage;if(this.options.contains&&!Array.isArray(this.options.contains[0])){this.options.contains=[this.options.contains];}
if(this.options.count){hasUsedContainsPositively=true;}else if(!hasUsedContainsPositively){throw new Error(`Starting a test with "contains" of count 0 for selector "${this.selector}" is useless because it might immediately resolve. Start the test by checking that an expected element actually exists.`);}
this.successMessage=undefined;this.executeError=undefined;}
run(){this.done=false;this.def=makeDeferred();this.scrollListeners=new Set();this.onScroll=()=>this.runOnce("after scroll");if(!this.runOnce("immediately")){this.timer=setTimeout(()=>this.runOnce("Timeout of 5 seconds",{crashOnFail:true}),5000);this.observer=new MutationObserver((mutations)=>{try{this.runOnce("after mutations");}catch(e){this.def.reject(e);}});this.observer.observe(this.options.target,{attributes:true,childList:true,subtree:true,});registerCleanup(()=>{if(!this.done){this.runOnce("Test ended",{crashOnFail:true});}});}
return this.def;}
runOnce(whenMessage,{crashOnFail=false,executeOnSuccess=true}={}){const res=this.select();if(res?.length===this.options.count||crashOnFail){this.observer?.disconnect();clearTimeout(this.timer);for(const el of this.scrollListeners??[]){el.removeEventListener("scroll",this.onScroll);}
this.done=true;}
if(res?.length===this.options.count){this.successMessage=`Found ${this.selectorMessage} (${whenMessage})`;if(executeOnSuccess){this.executeAction(res[0]);}
return res;}else{this.executeError=()=>{let message=`Failed to find ${this.selectorMessage} (${whenMessage}).`;message=res?`${message} Found ${res.length} instead.`:`${message} Parent not found.`;if(this.parentContains){if(this.parentContains.successMessage){log(true,this.parentContains.successMessage);}else{this.parentContains.executeError();}}
log(false,message);this.def?.reject(new Error(message));for(const childContains of this.childrenContains||[]){if(childContains.successMessage){log(true,childContains.successMessage);}else{childContains.executeError();}}};if(crashOnFail){this.executeError();}}}
executeAction(el){let message=this.successMessage;if(this.options.click){message=`${message} and clicked it`;webClick(el,undefined,{mouseEventInit:this.options.click,skipDisabledCheck:true,skipVisibilityCheck:true,});}
if(this.options.dragenterFiles){message=`${message} and dragentered ${this.options.dragenterFiles.length} file(s)`;const ev=new Event("dragenter",{bubbles:true});Object.defineProperty(ev,"dataTransfer",{value:createFakeDataTransfer(this.options.dragenterFiles),});el.dispatchEvent(ev);}
if(this.options.dragoverFiles){message=`${message} and dragovered ${this.options.dragoverFiles.length} file(s)`;const ev=new Event("dragover",{bubbles:true});Object.defineProperty(ev,"dataTransfer",{value:createFakeDataTransfer(this.options.dragoverFiles),});el.dispatchEvent(ev);}
if(this.options.dropFiles){message=`${message} and dropped ${this.options.dropFiles.length} file(s)`;const ev=new Event("drop",{bubbles:true});Object.defineProperty(ev,"dataTransfer",{value:createFakeDataTransfer(this.options.dropFiles),});el.dispatchEvent(ev);}
if(this.options.inputFiles){message=`${message} and inputted ${this.options.inputFiles.length} file(s)`;const dataTransfer=new window.DataTransfer();for(const file of this.options.inputFiles){dataTransfer.items.add(file);}
el.files=dataTransfer.files;const versionRaw=navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);const chromeVersion=versionRaw?parseInt(versionRaw[2],10):false;if(!chromeVersion||chromeVersion>=73){el.dispatchEvent(new Event("change"));}}
if(this.options.insertText!==undefined){message=`${message} and inserted text "${this.options.insertText.content}" (replace: ${this.options.insertText.replace})`;el.focus();if(this.options.insertText.replace){el.value="";el.dispatchEvent(new window.KeyboardEvent("keydown",{key:"Backspace"}));el.dispatchEvent(new window.KeyboardEvent("keyup",{key:"Backspace"}));el.dispatchEvent(new window.InputEvent("input"));}
for(const char of this.options.insertText.content){el.value+=char;el.dispatchEvent(new window.KeyboardEvent("keydown",{key:char}));el.dispatchEvent(new window.KeyboardEvent("keyup",{key:char}));el.dispatchEvent(new window.InputEvent("input"));}
el.dispatchEvent(new window.InputEvent("change"));}
if(this.options.pasteFiles){message=`${message} and pasted ${this.options.pasteFiles.length} file(s)`;const ev=new Event("paste",{bubbles:true});Object.defineProperty(ev,"clipboardData",{value:createFakeDataTransfer(this.options.pasteFiles),});el.dispatchEvent(ev);}
if(this.options.setFocus){message=`${message} and focused it`;el.focus();}
if(this.options.setScroll!==undefined){message=`${message} and set scroll to "${this.options.setScroll}"`;el.scrollTop=this.options.setScroll==="bottom"?el.scrollHeight:this.options.setScroll;}
if(this.options.triggerEvents){message=`${message} and triggered "${this.options.triggerEvents.join(", ")}" events`;webTriggerEvents(el,null,this.options.triggerEvents,{skipVisibilityCheck:true,});}
if(this.parentContains){log(true,this.parentContains.successMessage);}
log(true,message);for(const childContains of this.childrenContains){log(true,childContains.successMessage);}
this.def?.resolve();}
select(){const target=this.selectParent();if(!target){return;}
const baseRes=[...target.querySelectorAll(this.selector)].map((el)=>(this.options.shadowRoot?el.shadowRoot:el)).filter((el)=>el);this.childrenContains=[];const res=baseRes.filter((el,currentIndex)=>{let condition=(this.options.textContent===undefined||el.textContent.trim()===this.options.textContent)&&(this.options.value===undefined||el.value===this.options.value)&&(this.options.scroll===undefined||(this.options.scroll==="bottom"?Math.abs(el.scrollHeight-el.clientHeight-el.scrollTop)<=1:Math.abs(el.scrollTop-this.options.scroll)<=1));if(condition&&this.options.text!==undefined){if(el.textContent.trim()!==this.options.text&&[...el.querySelectorAll("*")].every((el)=>el.textContent.trim()!==this.options.text)){condition=false;}}
if(condition&&this.options.contains){for(const param of this.options.contains){const childContains=new Contains(param[0],{...param[1],target:el});if(!childContains.runOnce(`as child of el ${currentIndex + 1})`,{executeOnSuccess:false,})){condition=false;}
this.childrenContains.push(childContains);}}
if(condition&&this.options.visible!==undefined){if(isVisible(el)!==this.options.visible){condition=false;}}
if(condition&&this.options.after){const afterContains=new Contains(this.options.after[0],{...this.options.after[1],target,});const afterEl=afterContains.runOnce(`as "after"`,{executeOnSuccess:false,})?.[0];if(!afterEl||!(el.compareDocumentPosition(afterEl)&Node.DOCUMENT_POSITION_PRECEDING)){condition=false;}
this.childrenContains.push(afterContains);}
if(condition&&this.options.before){const beforeContains=new Contains(this.options.before[0],{...this.options.before[1],target,});const beforeEl=beforeContains.runOnce(`as "before"`,{executeOnSuccess:false,})?.[0];if(!beforeEl||!(el.compareDocumentPosition(beforeEl)&Node.DOCUMENT_POSITION_FOLLOWING)){condition=false;}
this.childrenContains.push(beforeContains);}
return condition;});if(this.options.scroll!==undefined&&this.scrollListeners&&baseRes.length===this.options.count&&res.length!==this.options.count){for(const el of baseRes){if(!this.scrollListeners.has(el)){this.scrollListeners.add(el);el.addEventListener("scroll",this.onScroll);}}}
return res;}
selectParent(){if(this.options.parent){this.parentContains=new Contains(this.options.parent[0],{...this.options.parent[1],target:this.options.target,});return this.parentContains.runOnce(`as parent`,{executeOnSuccess:false})?.[0];}
return this.options.target;}}
__exports.contains=contains;async function contains(selector,options){await new Contains(selector,options).run();}
const stepState={expectedSteps:null,deferred:null,timeout:null,currentSteps:[],clear(){clearTimeout(this.timeout);this.timeout=null;this.deferred=null;this.currentSteps=[];this.expectedSteps=null;},check({crashOnFail=false}={}){const success=this.expectedSteps.length===this.currentSteps.length&&this.expectedSteps.every((s,i)=>s===this.currentSteps[i]);if(!success&&!crashOnFail){return;}
QUnit.config.current.assert.verifySteps(this.expectedSteps);if(success){this.deferred.resolve();}else{this.deferred.reject(new Error("Steps do not match."));}
this.clear();},};if(window.QUnit){QUnit.testStart(()=>registerCleanup(()=>{if(stepState.expectedSteps){stepState.check({crashOnFail:true});}else{stepState.clear();}}));}
__exports.step=step;function step(step){stepState.currentSteps.push(step);QUnit.config.current.assert.step(step);if(stepState.expectedSteps){stepState.check();}}
__exports.assertSteps=assertSteps;function assertSteps(steps){if(stepState.expectedSteps){stepState.check({crashOnFail:true});}
stepState.expectedSteps=steps;stepState.deferred=makeDeferred();stepState.timeout=setTimeout(()=>stepState.check({crashOnFail:true}),2000);stepState.check();return stepState.deferred;}
return __exports;});odoo.define(`@web/../tests/utils`,['@web/../tests/legacy/utils'],function(require){return require('@web/../tests/legacy/utils');});;

/* /web/static/tests/tours/user_switch_tour.js */
odoo.define('@web/../tests/tours/user_switch_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");function logout(){return[{content:"check we're logged in",trigger:".o_user_menu .dropdown-toggle",run:"click",},{content:"click the Log out button",trigger:".dropdown-item[data-menu=logout]",run:"click",expectUnloadPage:true,},];}
registry.category("web_tour.tours").add("test_user_switch",{url:"/odoo",steps:()=>[...logout(),{content:"check if the login input is empty",trigger:"input#login:empty",},{content:"check if the password input is empty",trigger:"input#password:empty",},{content:"Should contains the user switch button",trigger:".oe_login_form .o_user_switch_btn",run:"click",},{content:"Click on Marc Demo on the quick login page",trigger:".o_user_switch:not(:has(.list-group-item:nth-child(2))) .list-group-item:contains('Marc Demo')",run:"click",},{content:"Check user choice button to back on the quick login page",trigger:".oe_login_form .o_user_switch_btn",run:"click",},{content:"Display the login form",trigger:".o_user_switch .fa-user-circle-o",run:"click",},{content:"fill the login",trigger:"input#login",run:"edit admin",},{content:"fill the password",trigger:"input#password",run:"edit admin",},{content:"click on login button",trigger:'button:contains("Log in")',run:"click",expectUnloadPage:true,},...logout(),{content:"Check if there is Mitchell Admin in user list selection",trigger:".o_user_switch .list-group-item:nth-child(1):contains('Mitchell Admin')",},{content:"Check if there is Marc Demo in user list selection",trigger:".o_user_switch .list-group-item:nth-child(2):contains('Marc Demo')",},{content:"Choice demo",trigger:".o_user_switch .list-group-item:contains('Marc Demo')",run:"click",},{content:"check the login for demo",trigger:"input#login:value('demo')",},{content:"fill the password",trigger:"input#password",run:"edit demo",},{content:"Check back button to back on the quick login page",trigger:".oe_login_form .o_user_switch_btn",run:"click",},{content:"Check have 2 users",trigger:".o_user_switch .list-group-item:nth-child(2)",},{content:"Click on Mitchell Admin",trigger:".o_user_switch .list-group-item:nth-child(1):contains('Mitchell Admin')",run:"click",},{content:"check the login for admin",trigger:"input#login:value('admin')",},{content:"fill the password",trigger:"input#password",run:"edit admin",},{content:"Check back button to back on the quick login page",trigger:".oe_login_form .o_user_switch_btn",run:"click",},{content:"Display the login form",trigger:".o_user_switch .fa-user-circle-o",run:"click",},{content:"the login form is display",trigger:"form.oe_login_form:not(.d-none)",},{content:"check if the login input is empty",trigger:"input#login:empty",},{content:"check if the password input is empty",trigger:"input#password:empty",},{content:"Back to user switch",trigger:".oe_login_form .o_user_switch_btn",run:"click",},{content:"Remove the admin user from page",trigger:".o_user_switch .d-flex:first-child .fa-times",run:"click",},{content:"only one user is left on quick login",trigger:".o_user_switch:not(:has(.list-group-item:nth-child(2))) .list-group-item:contains('Marc Demo')",},],});return __exports;});;

/* /mail/static/tests/tours/activity_date_format_tour.js */
odoo.define('@mail/../tests/tours/activity_date_format_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("mail_activity_date_format",{steps:()=>[{trigger:"button:contains('Activities')",run:"click",},{trigger:"input[id*='activity_type_id']",run:"click",},{trigger:".dropdown-item:contains('To-Do')",run:"click",},{trigger:"div[name='summary'] input",run:"edit Go Party",},{trigger:"button:contains('Schedule')",run:"click",},{trigger:".o-mail-Activity:contains('Go Party')",run:"click",},{trigger:".o-mail-Activity-info i",run:"click",},{trigger:".o-mail-Activity-details tr:contains('Created') td:contains('01/Jan/24 09:00:00 AM')",},{trigger:".o-mail-Activity-details tr:contains('Due on') td:contains('06/Jan/24')",},],});return __exports;});;

/* /mail/static/tests/tours/discuss_channel_as_guest_tour.js */
odoo.define('@mail/../tests/tours/discuss_channel_as_guest_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("discuss_channel_as_guest_tour.js",{steps:()=>[{content:"Channel secret token has been hidden on welcome page",trigger:".o-mail-WelcomePage",run(){if(!window.location.pathname.startsWith("/discuss/channel")){console.error("Channel secret token is still present in URL.");}},},{content:"Click join",trigger:"button[title='Join Channel']",run:"click",},{content:"Check that we are on channel page",trigger:".o-mail-Thread",},],});return __exports;});;

/* /mail/static/tests/tours/discuss_channel_call_public_tour.js */
odoo.define('@mail/../tests/tours/discuss_channel_call_public_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("discuss_channel_call_public_tour.js",{steps:()=>[{content:"The call does not start on the welcome page",trigger:".o-mail-WelcomePage",async run(){await new Promise((r)=>setTimeout(r,250));const rtcService=odoo.__WOWL_DEBUG__.root.env.services["discuss.rtc"];if(rtcService?.selfSession||rtcService?.state.hasPendingRequest){console.error("The call should not have started.");}},},{content:"Click join",trigger:"button[title='Join Channel']",run:"click",},{content:"Check that the call has started",trigger:".o-discuss-Call",},{content:"Check that current user is in call ('disconnect' button visible)",trigger:"button[title='Disconnect']",},],});return __exports;});;

/* /mail/static/tests/tours/discuss_channel_public_tour.js */
odoo.define('@mail/../tests/tours/discuss_channel_public_tour',['@web/core/registry','@web/../tests/utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{inputFiles}=require("@web/../tests/utils");const messageSelector=".o-mail-Message:has(.o-mail-Message-body:contains('cheese'))";const editedMessageSelector=".o-mail-Message:has(.o-mail-Message-body:contains('vegetables'))";registry.category("web_tour.tours").add("discuss_channel_public_tour.js",{steps:()=>[{trigger:".o-mail-Discuss",},{trigger:".o-mail-Thread",run(){if(!window.location.pathname.startsWith("/discuss/channel")){console.error("Channel secret token is still present in URL.");}
const errors=odoo.loader.findErrors();if(Object.keys(errors).length){console.error("Couldn't load all JS modules.",errors);}
document.body.classList.add("o_discuss_channel_public_modules_loaded");if(document.title!==document.querySelector(".o-mail-Discuss-threadName")?.value){console.error("Tab title should match conversation name.");}},},{trigger:".o_discuss_channel_public_modules_loaded",},{trigger:".o-mail-Composer-input",run:"edit cheese",},{trigger:".o-mail-Composer button[aria-label='Attach files']",async run(){const text=new File(["hello, world"],"text.txt",{type:"text/plain"});await inputFiles(".o-mail-Composer-coreMain .o_input_file",[text]);},},{trigger:".o-mail-AttachmentCard:not(.o-isUploading):contains(text.txt)",},{trigger:".o-mail-Composer button[aria-label='Attach files']",async run(){await inputFiles(".o-mail-Composer-coreMain .o_input_file",[new File([await(await fetch("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2P4v5ThPwAG7wKklwQ/bwAAAABJRU5ErkJggg==")).blob(),],"image.png",{type:"image/png"}),]);},},{trigger:'.o-mail-AttachmentImage:not(.o-isUploading)[title="image.png"]',async run(){const store=odoo.__WOWL_DEBUG__.root.env.services["mail.store"];if(store.self.type==="guest"){const src=this.anchor.querySelector("img").src;const token=store.Attachment.get((src.match("/web/image/([0-9]+)")||[]).at(-1))?.access_token;if(!(token&&src.includes(`access_token=${token}`))){throw new Error("Access token of the attachment isn't correct.");}}},},{trigger:".o-mail-Composer-send:enabled",run:"click",},{trigger:`${messageSelector}[data-persistent]`,},{trigger:`${messageSelector} .o-mail-AttachmentCard:contains("text.txt")`,},{trigger:messageSelector,run:`hover && click ${messageSelector} [title='Add a Reaction']`,},{trigger:".o-EmojiPicker .o-Emoji:contains('🙂')",run:"click",},{trigger:`${messageSelector} .o-mail-MessageReaction:contains('🙂')`,run:"click",},{trigger:`${messageSelector}:not(:has(.o-mail-MessageReaction:contains('🙂')))`,},{trigger:`${messageSelector}`,run:`hover && click ${messageSelector} [title='Expand']`,},{trigger:`.o-mail-Message-moreMenu [title='Edit'], ${messageSelector} [title='Edit']`,run:"click",},{trigger:".o-mail-Message .o-mail-Composer-input",run:"edit vegetables",},{trigger:".o-mail-Message button[aria-label='Attach files']",async run(){const extratxt=new File(["hello 2"],"extra.txt",{type:"text/plain"});await inputFiles(".o-mail-Message .o_input_file",[extratxt]);},},{trigger:".o-mail-Message .o-mail-Composer .o-mail-AttachmentCard:not(.o-isUploading):contains(extra.txt)",},{trigger:".o-mail-Message a:contains(save)",run:"click",},{trigger:editedMessageSelector,},{trigger:`${editedMessageSelector} .o-mail-AttachmentCard:contains("text.txt")`,},{trigger:`${editedMessageSelector} .o-mail-AttachmentCard:contains("extra.txt")`,},{trigger:`${editedMessageSelector} .o-mail-AttachmentCard:contains("extra.txt") .o-mail-AttachmentCard-unlink`,run:"click",},{trigger:".modal:contains(Confirmation) .btn:contains(Ok)",run:"click",},{trigger:`${editedMessageSelector}:not(:has(.o-mail-AttachmentCard:contains("extra.txt")))`,},{trigger:"button[title='Search Messages']",run:"click",},{trigger:".o_searchview_input",run:"edit text.txt",},{trigger:"button[aria-label='Search button']",run:"click",},{trigger:`.o-mail-SearchMessagesPanel ${editedMessageSelector} .o-mail-AttachmentCard:contains("text.txt")`,},],});return __exports;});;

/* /mail/static/tests/tours/discuss_configuration_tour.js */
odoo.define('@mail/../tests/tours/discuss_configuration_tour',['@web/core/registry','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");registry.category("web_tour.tours").add("discuss_configuration_tour",{url:"/odoo",steps:()=>[stepUtils.showAppsMenuItem(),{trigger:'.o_app[data-menu-xmlid="mail.menu_root_discuss"]',run:"click",},{trigger:".o_main_navbar button:contains('Configuration')",run:"click",},{trigger:".dropdown-menu a:contains('Notification')",run:"click",},{trigger:".o-mail-DiscussNotificationSettings label:contains('Mute')",run:"click",},{trigger:"button:contains('All Messages')",run:"click",},{trigger:"button:contains('Mentions Only')",run:"click",},{trigger:"button:contains('Nothing')",run:"click",},{trigger:".modal-header button[aria-label='Close']",run:"click",},{trigger:".o_main_navbar button:contains('Configuration')",run:"click",},{trigger:".dropdown-menu a:contains('Voice & Video')",run:"click",},{trigger:"select[name='inputDevice']",},{trigger:"button:contains('Voice Detection')",run:"click",},{trigger:"label:contains('Voice detection threshold')",},{trigger:"button:contains('Push to Talk')",run:"click",},{trigger:"label:contains('Push-to-talk key')",},{trigger:"label:contains('Delay after releasing push-to-talk')",},{trigger:"input[aria-label='Show video participants only']",},{trigger:"input[aria-label='Blur video background']",run:"click",},{trigger:"label:contains('Background blur intensity')",},{trigger:"label:contains('Edge blur intensity')",},],});return __exports;});;

/* /mail/static/tests/tours/discuss_go_back_to_thread_from_breadcrumbs_tour.js */
odoo.define('@mail/../tests/tours/discuss_go_back_to_thread_from_breadcrumbs_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("discuss_go_back_to_thread_from_breadcrumbs.js",{steps:()=>[{trigger:".o-mail-Discuss-threadName[title='Inbox']"},{trigger:".o-mail-DiscussSidebar-item:contains(Starred)",run:"click"},{trigger:"button[title='View or join channels']",run:"click"},{trigger:".breadcrumb-item:contains(Starred)",run:"click"},{trigger:".o-mail-Discuss-threadName[title='Starred']"},],});return __exports;});;

/* /mail/static/tests/tours/discuss_sidebar_in_public_page_tour.js */
odoo.define('@mail/../tests/tours/discuss_sidebar_in_public_page_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("sidebar_in_public_page_tour",{steps:()=>[{trigger:".o-mail-Discuss-header [title='Channel 1']",},{trigger:".o-mail-DiscussSidebarChannel:contains(Channel 1).o-active",},{trigger:".o-mail-DiscussSidebarChannel:contains(Channel 2)",run:"click",},{trigger:".o-mail-Discuss-header [title='Channel 2']",},{trigger:".o-mail-DiscussSidebarChannel:contains(Channel 2).o-active",run(){history.back();},},{trigger:".o-mail-Discuss-header [title='Channel 1']",},{trigger:".o-mail-DiscussSidebarChannel:contains(Channel 1).o-active",run(){history.forward();},},{trigger:".o-mail-Discuss-header [title='Channel 2']",},{trigger:".o-mail-DiscussSidebarChannel:contains(Channel 2).o-active",},],});return __exports;});;

/* /mail/static/tests/tours/discuss_sub_channel_search_tour.js */
odoo.define('@mail/../tests/tours/discuss_sub_channel_search_tour',['@mail/discuss/core/public_web/sub_channel_list','@odoo/owl','@web/core/registry','@web/core/utils/concurrency','@web/core/utils/patch','@web/core/utils/reactive','@web/../tests/utils'],function(require){'use strict';let __exports={};const{SubChannelList}=require("@mail/discuss/core/public_web/sub_channel_list");const{status}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{Deferred}=require("@web/core/utils/concurrency");const{patch}=require("@web/core/utils/patch");const{effect}=require("@web/core/utils/reactive");const{contains,dragenterFiles,dropFiles,scroll}=require("@web/../tests/utils");let waitForLoadMoreToDisappearDef;registry.category("web_tour.tours").add("test_discuss_sub_channel_search",{steps:()=>[{trigger:"body",run(){patch(SubChannelList.prototype,{setup(){super.setup(...arguments);effect((state)=>{if(status(this)==="destroyed"){return;}
if(!state.isVisible){waitForLoadMoreToDisappearDef?.resolve();}},[this.loadMoreState]);},});},},{trigger:"button[title='Threads']",run:"click",},{trigger:".o-mail-SubChannelList",async run(){for(let i=99;i>69;i--){await contains(".o-mail-SubChannelList-thread",{text:`Sub Channel ${i}`,});await contains(".o-mail-SubChannelList-thread",{count:30});}},},{trigger:".o-mail-ActionPanel:has(.o-mail-SubChannelList) .o_searchview_input",run:"edit Sub Channel 10",},{trigger:".o-mail-ActionPanel:has(.o-mail-SubChannelList) button[aria-label='Search button']",run:"click",},{trigger:".o-mail-SubChannelList-thread:contains(Sub Channel 10)",async run(){await contains(".o-mail-SubChannelList-thread",{count:1});waitForLoadMoreToDisappearDef=new Deferred();},},{trigger:".o_searchview_input",run:"clear",},{trigger:".o-mail-SubChannelList-thread:contains(Sub Channel 99)",async run(){await contains(".o-mail-SubChannelList-thread",{count:31});for(let i=99;i>69;i--){await contains(".o-mail-SubChannelList-thread",{text:`Sub Channel ${i}`,});}
await contains(".o-mail-SubChannelList-thread",{text:`Sub Channel 10`});await waitForLoadMoreToDisappearDef;waitForLoadMoreToDisappearDef=new Deferred();await scroll(".o-mail-ActionPanel:has(.o-mail-SubChannelList)","bottom");},},{trigger:".o-mail-SubChannelList-thread:contains(Sub Channel 40)",async run(){await contains(".o-mail-SubChannelList-thread",{count:61});for(let i=99;i>39;i--){await contains(".o-mail-SubChannelList-thread",{text:`Sub Channel ${i}`,});}
await waitForLoadMoreToDisappearDef;waitForLoadMoreToDisappearDef=new Deferred();await scroll(".o-mail-ActionPanel:has(.o-mail-SubChannelList)","bottom");},},{trigger:".o-mail-SubChannelList-thread:contains(Sub Channel 11)",async run(){await contains(".o-mail-SubChannelList-thread",{count:90});for(let i=99;i>9;i--){await contains(".o-mail-SubChannelList-thread",{text:`Sub Channel ${i}`,});}
await waitForLoadMoreToDisappearDef;await scroll(".o-mail-ActionPanel:has(.o-mail-SubChannelList)","bottom");},},{trigger:".o-mail-SubChannelList-thread:contains(Sub Channel 0)",async run(){await contains(".o-mail-SubChannelList-thread",{count:100});for(let i=99;i>0;i--){await contains(".o-mail-SubChannelList-thread",{text:`Sub Channel ${i}`,});}},},],});registry.category("web_tour.tours").add("create_thread_for_attachment_without_body",{steps:()=>[{content:"Open general channel",trigger:'.o-mail-DiscussSidebarChannel-itemName:contains("general")',run:"click",},{content:"Drop a file",trigger:".o-mail-Discuss-main",async run(){const files=[new File(["hi there"],"file2.txt",{type:"text/plain"})];await dragenterFiles(".o-mail-Discuss-main",files);await dropFiles(".o-Dropzone",files);},},{trigger:'.o-mail-AttachmentCard:not(.o-isUploading):contains("file2.txt")',},{content:"Click on send button",trigger:".o-mail-Composer-send:enabled",run:"click",},{content:"Hover on attachment",trigger:'.o-mail-Message .o-mail-AttachmentCard:contains("file2.txt")',run:"hover",},{content:"Click on expand button",trigger:'.o-mail-Message [title="Expand"]',run:"click",},{content:"Create a new thread",trigger:'.o-dropdown-item:contains("Create Thread")',run:"click",},{content:"Check a new thread is created",trigger:'.o-mail-Discuss:contains("New Thread")',},],});return __exports;});;

/* /mail/static/tests/tours/mail_activity_schedule_from_chatter.js */
odoo.define('@mail/../tests/tours/mail_activity_schedule_from_chatter',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("mail_activity_schedule_from_chatter",{steps:()=>[{trigger:"button:contains('Activities')",run:"click",},{trigger:"input[id*='activity_type_id']",run:"click",},{trigger:".dropdown-item:contains('Call')",run:"click",},{trigger:"input[id*='activity_type_id']:value('Call')",},{trigger:"button:contains('Schedule')",},{trigger:"input[id*='activity_type_id']",run:"click",},{trigger:".dropdown-item:contains('To-Do')",run:"click",},{trigger:"div[name='summary'] input",run:"edit Play Mario Party",},{trigger:"button:contains('Schedule')",run:"click",},{trigger:".o-mail-Activity:contains('Play Mario Party')",run:"click",},{trigger:"button:contains('Activities')",run:"click",},{trigger:"div[name='summary'] input",run:"edit Play Mario Kart",},{trigger:"button:contains('Mark as Done')",run:"click",},{trigger:".o-mail-Message:contains('Play Mario Kart')",},],});return __exports;});;

/* /mail/static/tests/tours/mail_composer_test_tour.js */
odoo.define('@mail/../tests/tours/mail_composer_test_tour',['@web/core/registry','@web/../tests/utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{contains,dragenterFiles,dropFiles,inputFiles}=require("@web/../tests/utils");registry.category("web_tour.tours").add("mail/static/tests/tours/mail_composer_test_tour.js",{steps:()=>[{content:"Wait for the chatter to be fully loaded",trigger:".o-mail-Chatter",async run(){await contains(".o-mail-Message",{count:1});},},{content:"Click on Send Message",trigger:"button:contains(Send message)",run:"click",},{content:"Write something in composer",trigger:".o-mail-Composer-input",run:"edit blahblah @Not && click body",},{content:"Mention a partner",trigger:".o-mail-Composer-suggestion:contains(Not A Demo User)",run:"click",},{content:"Add one file in composer",trigger:".o-mail-Composer button[aria-label='Attach files']",async run(){const files=[new File(["hello, world"],"file1.txt",{type:"text/plain"})];await inputFiles(".o-mail-Composer-coreMain .o_input_file",files);},},{trigger:'.o-mail-AttachmentCard:not(.o-isUploading):contains("file1.txt")',},{content:"Open full composer",trigger:"button[aria-label='Full composer']",run:"click",},{content:"Check composer keeps open after pushing Escape",trigger:".o_mail_composer_form_view",run:"press Escape",},{content:"Check the earlier provided attachment is listed",trigger:".o_field_mail_composer_attachment_list a:contains(file1.txt)",},{content:"Check subject is autofilled",trigger:'[name="subject"] input',run(){const subjectValue=document.querySelector('[name="subject"] input').value;if(subjectValue!=="Jane"){console.error(`Full composer should have "Jane" in subject input (actual: ${subjectValue})`);}},},{content:"Check composer content is kept and contains the user's signature",trigger:'.o_field_html[name="body"]',run(){const bodyContent=document.querySelector('.o_field_html[name="body"]').textContent;if(!bodyContent.replace(/\uFEFF/g,"").includes("blahblah @Not A Demo User")){console.error(`Full composer should contain text from small composer ("blahblah @Not A Demo User") in body input (actual: ${bodyContent})`);}
const mentionLink=document.querySelector('.o_field_html[name="body"] a').textContent;if(!mentionLink.includes("@Not A Demo User")){console.error(`Full composer should contain mention link from small composer ("@Not A Demo User") in body input)`);}
if((bodyContent.match(/--\nErnest/g)||[]).length!==1){console.error("Full composer should contain the user's signature once.");}},},{content:"Trigger channel mention with #",trigger:".odoo-editor-editable",run(){this.anchor.dispatchEvent(new InputEvent("beforeinput",{inputType:"insertText",data:"#",bubbles:true,}));},},{content:"Search for general channel",trigger:".o-mail-MentionList input",run:"edit gen",},{content:"Select channel from suggestion",trigger:".o-mail-Composer-suggestion:contains(general)",run:"click",},{content:"Check channel mention is present in body",trigger:'.o_field_html[name="body"] .o_channel_redirect:contains(general)',},{content:"Drop a file on the full composer",trigger:".o_mail_composer_form_view",async run(){const files=[new File(["hi there"],"file2.txt",{type:"text/plain"})];await dragenterFiles(".o_mail_composer_form_view .o_form_renderer",files);await dropFiles(".o-Dropzone",files);},},{content:"Check the attachment is listed",trigger:".o_field_mail_composer_attachment_list a:contains(file2.txt)",},{content:"Click on the mail template selector",trigger:".mail-composer-template-dropdown-btn",run:"click",},{content:"Check a template is listed",trigger:'.mail-composer-template-dropdown.popover .o-dropdown-item:contains("Test template")',},{content:"Verify admin template is NOT listed",trigger:".mail-composer-template-dropdown.popover",run(){const hasAdminTemplate=[...document.querySelectorAll(".o-dropdown-item")].some((item)=>item.textContent.includes("Test template for admin"));if(hasAdminTemplate){console.error("Template assigned to the admin is visible to a non-assigned user! This should not happen.");}},},{content:"Send message from full composer",trigger:".o_mail_send",run:"click",},{content:"Check message is shown",trigger:'.o-mail-Message-body:contains("blahblah @Not A Demo User")',run:"click",},{content:"Click on envelope to see recipients of message",trigger:'.o-mail-Message:has(.o-mail-Message-body:contains("blahblah @Not A Demo User")) .o-mail-Message-notification',run:"click",},{content:"Check message has correct recipients",trigger:".o-mail-MessageNotificationPopover:contains('Not A Demo User Jane')",},{content:"Check message contains the first attachment",trigger:'.o-mail-Message .o-mail-AttachmentCard:contains("file1.txt")',},{content:"Check message contains the second attachment",trigger:'.o-mail-Message .o-mail-AttachmentCard:contains("file2.txt")',},{content:"Click on Send Message",trigger:"button:contains(Send message)",run:"click",},{content:"Open full composer",trigger:"button[aria-label='Full composer']",run:"click",},{content:"Check that the composer contains the signature",trigger:'.o_field_html[name="body"]',run(){const bodyContent=document.querySelector('.o_field_html[name="body"]').textContent;if((bodyContent.match(/--\nErnest/g)||[]).length!==1){console.log("Full composer should contain the user's signature once.");}},},{content:"Write something in full composer",trigger:".note-editable",run:"editor keep the content",},{content:"Close full composer",trigger:".btn-close",run:"click",},{content:"Click on Send Message",trigger:"button:contains(Send message)",run:"click",},{content:"Check full composer text is kept",trigger:".o-mail-Composer-input",run(){if(this.anchor.value!=="keep the content"){console.error("Composer in chatter should contain full composer text after discarding.");}},},{content:"Open full composer",trigger:"button[aria-label='Full composer']",run:"click",},{content:"Check that the composer doesn't add the user's signature twice",trigger:".note-editable",run(){const bodyContent=document.querySelector('.o_field_html[name="body"]').textContent;if((bodyContent.match(/--\nErnest/g)||[]).length!==0){console.error("The composer should not contain the user's signature.");}},},{content:"Close full composer",trigger:".btn-close",run:"click",},{content:"Click on Send Message",trigger:"button:contains(Send message)",run:"click",},{content:"Send message from chatter",trigger:".o-mail-Composer-send:enabled",run:"click",},{content:"Check message is shown",trigger:'.o-mail-Message-body:contains("keep the content")',},{content:"Click on Send Message",trigger:"button:contains(Send message)",run:"click",},{content:"Write a message",trigger:".o-mail-Composer-input",run:"edit hello world",},{content:"Send message from chatter",trigger:".o-mail-Composer-send:enabled",run:"click",},{content:"Check message is shown",trigger:'.o-mail-Message-body:contains("hello world")',},],});return __exports;});;

/* /mail/static/tests/tours/mail_message_load_order_tour.js */
odoo.define('@mail/../tests/tours/mail_message_load_order_tour',['@web/core/registry','@web/../tests/utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{contains,scroll}=require("@web/../tests/utils");registry.category("web_tour.tours").add("mail_message_load_order_tour",{steps:()=>[{trigger:".o-mail-DiscussSidebarChannel:contains(MyTestChannel)",run:"click",},{trigger:".o-mail-Thread .o-mail-Message",async run(){await contains(".o-mail-Thread .o-mail-Message",{count:30});await contains(".o-mail-Thread",{scroll:"bottom"});},},{trigger:"*[title='Pinned Messages']",run:"click",},{content:"Click on invisible jump (should hover card to be visible)",trigger:".o-mail-MessageCard-jump:not(:visible)",run:"click",},{trigger:".o-mail-Thread .o-mail-Message:first .o-mail-Message-textContent:not(:contains(31))",async run(){await contains(".o-mail-Thread .o-mail-Message",{count:31});await contains(".o-mail-Thread",{scroll:0});const messages=Array.from(document.querySelectorAll(".o-mail-Thread .o-mail-Message-content")).map((el)=>el.innerText);for(let i=0;i<31;i++){if(messages[i]!==(i+1).toString()){throw new Error("Wrong message order after loading around");}}
await scroll(".o-mail-Thread","bottom");},},{trigger:".o-mail-Thread .o-mail-Message .o-mail-Message-textContent:contains(17)",async run(){await contains(".o-mail-Thread .o-mail-Message",{count:60});const messages=Array.from(document.querySelectorAll(".o-mail-Thread .o-mail-Message-content")).map((el)=>el.innerText);for(let i=0;i<60;i++){if(messages[i]!==(i+1).toString()){throw new Error("Wrong message order after loading after");}}},},],});return __exports;});;

/* /mail/static/tests/tours/mail_template_dynamic_placeholder_tour.js */
odoo.define('@mail/../tests/tours/mail_template_dynamic_placeholder_tour',['@web/core/registry','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");registry.category("web_tour.tours").add("mail_template_dynamic_placeholder_tour",{url:"/odoo",steps:()=>[stepUtils.showAppsMenuItem(),{content:'Go into the Setting "app"',trigger:'.o_app[data-menu-xmlid="base.menu_administration"]',run:"click",},{content:"Open email templates",trigger:'button[name="open_mail_templates"]',run:"click",},{content:"Create a new email template",trigger:"button.o_list_button_add",run:"click",},{content:'Insert # inside "Subject" input',trigger:'div[name="subject"] input[type="text"]',run:"edit(no_model_id #)",},{content:'Select "Contact" model',trigger:'div[name="model_id"] input[type="text"]',run:"edit Contact",},{content:"Click on contact",trigger:'div[name="model_id"] .ui-autocomplete .dropdown-item:text(Contact)',run:"click",},{content:"Wait for the drop down to disappear",trigger:'div[name="model_id"] .o-autocomplete:not(:has(.ui-autocomplete))',run:async()=>{await new Promise((r)=>setTimeout(r,200));},},{content:'Retry insert # inside "Subject" input',trigger:'div[name="subject"] input[type="text"]',run:"edit (yes_model_id) && press #",},{content:"Check if the dynamic placeholder popover is opened",trigger:"div.o_model_field_selector_popover",},{content:"filter the dph result",trigger:"div.o_model_field_selector_popover_search input[type='text']",run:"edit name",},{content:"Click on the first entry of the dynamic placeholder",trigger:'div.o_model_field_selector_popover button:contains("Company Name")',run:"click",},{content:"Enter a default value",trigger:'div.o_model_field_selector_popover .o_model_field_selector_default_value_input input[type="text"]',run:"edit defValue",},{content:"Click on the insert button",trigger:"div.o_model_field_selector_popover button:first-child",run:"click",},{content:"Wait for the popover to disappear",trigger:"body:not(:has(.o_model_field_selector_popover))",run:"click",},{content:"Check if subject value was correctly updated",trigger:'div[name="subject"] input[type="text"]',run(){const subjectValue=this.anchor.value;const correctValue="yes_model_id {{object.company_name|||defValue}}";if(subjectValue!==correctValue){console.error(`Email template should have "${correctValue}" in subject input (actual: ${subjectValue})`);}},},{content:"Insert text inside editable",trigger:".note-editable.odoo-editor-editable",async run(actions){await actions.editor(`/`);document.querySelector(".note-editable").dispatchEvent(new InputEvent("input",{inputType:"insertText",data:"/",}));},},{content:"Click on the the dynamic placeholder powerBox options",trigger:"div.o-we-powerbox .o-we-command:contains(Dynamic Placeholder)",run:"click",},{content:"Check if the dynamic placeholder popover is opened",trigger:"div.o_model_field_selector_popover",run:"click",},{content:"filter the dph result",trigger:"div.o_model_field_selector_popover_search input[type='text']",run:"edit name",},{content:"Click on the first entry of the dynamic placeholder",trigger:'div.o_model_field_selector_popover button:contains("Company Name")',run:"click",},{content:"Enter a default value",trigger:'div.o_model_field_selector_popover .o_model_field_selector_default_value_input input[type="text"]',run:"edit defValue",},{content:"Click on the insert button",trigger:"div.o_model_field_selector_popover button:first-child",run:"click",},{content:"Ensure the editable contain the dynamic placeholder t tag",trigger:`.note-editable.odoo-editor-editable t[t-out="object.company_name"]:contains("defValue")`,run:"click",},{content:"Discard form changes",trigger:"button.o_form_button_cancel",run:"click",},{content:"Wait for the form view to disappear",trigger:"body:not(:has(.o_form_sheet))",},],});return __exports;});;

/* /mail/static/tests/tours/user_modify_own_profile_tour.js */
odoo.define('@mail/../tests/tours/user_modify_own_profile_tour',['@web/core/registry','@web/../tests/utils'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{contains,insertText}=require("@web/../tests/utils");registry.category("web_tour.tours").add("mail/static/tests/tours/user_modify_own_profile_tour.js",{steps:()=>[{content:"Open user account menu",trigger:".o_user_menu button",run:"click",},{content:"Open preferences / profile screen",trigger:"[data-menu=settings]",run:"click",},{content:"Update the email address",trigger:'div[name="email"] input',async run(){await insertText("div[name='email'] input","updatedemail@example.com",{replace:true,});await contains(".o_form_dirty",{count:1});},},{trigger:"body.modal-open",},{content:"Save the form",trigger:'button[name="preference_save"]',run:"click",},{content:"Wait until the modal is closed",trigger:"body:not(.modal-open)",async run(){await contains(".o_form_dirty",{count:0});},},],});return __exports;});;

/* /auth_totp/static/tests/totp_flow.js */
odoo.define('@auth_totp/../tests/totp_flow',['@odoo/hoot-dom','@web/core/network/rpc','@web/core/registry','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{waitFor}=require("@odoo/hoot-dom");const{rpc}=require("@web/core/network/rpc");const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");function openRoot(){return[{content:"return to client root to avoid race condition",trigger:'body',run(){document.querySelector("body").classList.add("wait");window.location='/odoo';},expectUnloadPage:true,},{content:"wait for client reload",trigger:'body:not(.wait)',}];}
function openUserProfileAtSecurityTab(){return[{content:'Open user account menu',trigger:'.o_user_menu .dropdown-toggle',run:'click',},{content:"Open preferences / profile screen",trigger:'[data-menu=settings]',run:'click',},{content:"Switch to security tab",trigger:'a[role=tab]:contains("Account Security")',run:'click',}];}
function closeProfileDialog({content,totp_state}){let trigger;switch(totp_state){case true:trigger='button[name=action_totp_disable]';break;case false:trigger='button[name=action_totp_enable_wizard]';break;case undefined:trigger='button.o_auth_2fa_btn';break;default:throw new Error(`Invalid totp state ${totp_state}`)}
return[{content,trigger:'a[role=tab]:contains("Account Security").active',async run(helpers){await waitFor(trigger,{timeout:5000});const modal=document.querySelector(".o_dialog");if(modal){modal.querySelector("button[name=preference_cancel]").click();}}},{trigger:'body:not(:has(.o_dialog))',}];}
registry.category("web_tour.tours").add('totp_tour_setup',{url:'/odoo',steps:()=>[...openUserProfileAtSecurityTab(),{content:"Open totp wizard",trigger:'button[name=action_totp_enable_wizard]',run:"click",},{trigger:".modal div:contains(entering your password)",},{content:"Check that we have to enter enhanced security mode and input password",trigger:'[name=password] input',run:'edit test_user',},{content:"Confirm",trigger:"button:contains(Confirm Password)",run:"click",},{content:"Check the wizard has opened",trigger:'.modal li:contains("When requested to do so")',},{content:"Get secret from collapsed div",trigger:`.modal a:contains("Cannot scan it?")`,async run(helpers){const secret=this.anchor.closest("div").querySelector("[name=secret] span:first-child");const copyBtn=secret.querySelector("button");if(copyBtn){copyBtn.remove();}
const token=await rpc('/totphook',{secret:secret.textContent});await helpers.edit(token,'[name=code] input');}},{trigger:".modal button.btn-primary:contains(Activate)",run:"click",},{trigger:".o_notification_content:contains(2-Factor authentication is now enabled)",},...openRoot(),...openUserProfileAtSecurityTab(),...closeProfileDialog({content:"Check that the button has changed",totp_state:true,}),]});registry.category("web_tour.tours").add('totp_login_enabled',{url:'/',steps:()=>[{content:"check that we're on the login page or go to it",isActive:["body:not(:has(input#login))"],trigger:"a:contains(Sign in)",run:"click",expectUnloadPage:true,},{content:"input login",trigger:'input#login',run:"edit test_user",},{content:'input password',trigger:'input#password',run:"edit test_user",},{content:"click da button",trigger:'button:contains("Log in")',run:"click",expectUnloadPage:true,},{content:"expect totp screen",trigger:'label:contains(Authentication Code)',run:"click",},{content:"input code",trigger:'input[name=totp_token]',async run(helpers){const token=await rpc('/totphook');helpers.edit(token);}},{trigger:`button:contains("Log in")`,run:"click",expectUnloadPage:true,},{content:"check we're logged in",trigger:".o_user_menu .dropdown-toggle",}]});registry.category("web_tour.tours").add('totp_login_device',{url:'/',steps:()=>[{content:"check that we're on the login page or go to it",isActive:["body:not(:has(input#login))"],trigger:"a:contains(Sign in)",run:"click",expectUnloadPage:true,},{content:"input login",trigger:'input#login',run:"edit test_user",},{content:'input password',trigger:'input#password',run:"edit test_user",},{content:"click da button",trigger:'button:contains("Log in")',run:"click",expectUnloadPage:true,},{content:"expect totp screen",trigger:'label:contains(Authentication Code)',run:"click",},{content:"check remember device box",trigger:'label[for=switch-remember]',run:"click",},{content:"input code",trigger:'input[name=totp_token]',async run(helpers){const token=await rpc('/totphook')
helpers.edit(token);}},{trigger:"button:contains(Log in)",run:"click",expectUnloadPage:true,},{content:"check we're logged in",trigger:".o_user_menu .dropdown-toggle",run:'click',},{content:"click the Log out button",trigger:'.dropdown-item[data-menu=logout]',run:"click",expectUnloadPage:true,},{content:"check that we're back on the login page or go to it",trigger:'input#login, a:contains(Log in)',run:"edit Test",},{content:"input login again",trigger:'input#login',run:"edit test_user",},{content:'input password again',trigger:'input#password',run:"edit test_user",},{content:"click da button again",trigger:'button:contains("Log in")',run:"click",expectUnloadPage:true,},{content:"check we're logged in without 2FA",trigger:".o_user_menu .dropdown-toggle",},...openUserProfileAtSecurityTab(),{content:"Open totp wizard",trigger:'a[role=tab]:contains("Account Security").active',},{trigger:"button[name=action_totp_disable]",run:"click",},{trigger:".modal div:contains(entering your password)",},{content:"Check that we have to enter enhanced security mode and input password",trigger:'.modal [name=password] input',run:"edit test_user",},{content:"Confirm",trigger:".modal button:contains(Confirm Password)",run:"click",},{trigger:".o_notification_content:contains(Two-factor authentication disabled)",},...openRoot(),...openUserProfileAtSecurityTab(),...closeProfileDialog({content:"Check that the button has changed",totp_state:false}),]});registry.category("web_tour.tours").add('totp_login_disabled',{url:'/',steps:()=>[{content:"check that we're on the login page or go to it",isActive:["body:not(:has(input#login))"],trigger:"a:contains(Sign in)",run:"click",expectUnloadPage:true,},{content:"input login",trigger:'input#login',run:"edit test_user",},{content:'input password',trigger:'input#password',run:"edit test_user",},{content:"click da button",trigger:'button:contains("Log in")',run:"click",expectUnloadPage:true,},...openUserProfileAtSecurityTab(),...closeProfileDialog({})]});registry.category("web_tour.tours").add('totp_admin_disables',{url:'/odoo',steps:()=>[stepUtils.showAppsMenuItem(),{content:'Go to settings',trigger:'[data-menu-xmlid="base.menu_administration"]',run:"click",},{content:'Wait for page',trigger:'.o_menu_brand:contains("Settings")',},{content:"Open Users menu",trigger:'[data-menu-xmlid="base.menu_users"]',run:"click",},{content:"Open Users view",trigger:'[data-menu-xmlid="base.menu_action_res_users"]',run:"click",},{content:"Find test_user User",trigger:'tr:has(td.o_data_cell:contains("test_user")) '+'.o_list_record_selector input[type=checkbox]',run:"click",},{content:"Open Actions menu",trigger:'button.dropdown-toggle:contains("Action")',run:"click",},{content:"Select totp remover",trigger:'span.dropdown-item:contains(Disable two-factor authentication)',run:"click",},{trigger:".modal div:contains(entering your password)",},{content:"Check that we have to enter enhanced security mode & input password",trigger:'.modal [name=password] input',run:"edit admin",},{content:"Confirm",trigger:".modal button:contains(Confirm Password)",run:"click",},{content:"Wait for user to be unchecked (~ action done)",trigger:'tr:has(td.o_data_cell:contains(test_user)) '+'.o_list_record_selector input[type=checkbox]:not(:checked)',},{content:"open the user's form",trigger:"td.o_data_cell:contains(test_user)",run:"click",},{content:"go to Account security Tab",trigger:"a.nav-link:contains(Account Security)",run:"click",},{content:"check 2FA button: should be disabled",trigger:'button[name=action_totp_enable_wizard]:disabled',}]})
return __exports;});;

/* /auth_totp_mail/static/tests/totp_flow.js */
odoo.define('@auth_totp_mail/../tests/totp_flow',['@web/core/registry','@web_tour/tour_service/tour_utils','@odoo/hoot-dom'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");const{queryFirst}=require("@odoo/hoot-dom");function openAccountSettingsTab(){return[{content:'Go to settings',trigger:'[data-menu-xmlid="base.menu_administration"]',run:"click",},{content:'Wait for page',trigger:'.o_menu_brand:contains("Settings")',},{content:"Open Users menu",trigger:'[data-menu-xmlid="base.menu_users"]',run:"click",},{content:"Open Users view",trigger:'[data-menu-xmlid="base.menu_action_res_users"]',run:function(helpers){const breadcrumb=document.querySelector('.breadcrumb');if(!breadcrumb||!breadcrumb.textContent.includes("Users")){helpers.click();}else{helpers.click('[data-menu-xmlid="base.menu_users"]');}}}];}
registry.category("web_tour.tours").add('totp_admin_self_invite',{url:'/odoo',steps:()=>[stepUtils.showAppsMenuItem(),...openAccountSettingsTab(),{content:"open the user's form",trigger:"td.o_data_cell:contains(admin)",run:"click",},{content:"go to Account security Tab",trigger:"a.nav-link:contains(Account Security)",run:"click",},{content:"check that user cannot invite themselves to use 2FA.",trigger:"body",run:function(){const inviteBtn=queryFirst('button:contains(Invite to use 2FA)');if(!inviteBtn){document.body.classList.add('CannotInviteYourself');}}},{content:"check that user cannot invite themself.",trigger:"body.CannotInviteYourself",}]});registry.category("web_tour.tours").add('totp_admin_invite',{url:'/odoo',steps:()=>[stepUtils.showAppsMenuItem(),...openAccountSettingsTab(),{content:"open the user's form",trigger:"td.o_data_cell:contains(test_user)",run:"click",},{content:"go to Account security Tab",trigger:"a.nav-link:contains(Account Security)",run:"click",},{content:"check that test_user user can be invited to use 2FA.",trigger:"button:contains(Invite to use 2FA)",}]});return __exports;});;

/* /web_enterprise/static/tests/tours/web_enterprise_tours.js */
odoo.define('@web_enterprise/../tests/tours/web_enterprise_tours',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("web_enterprise.test_studio_list_upsell",{steps:()=>[{trigger:".o_list_view",},{trigger:".o_optional_columns_dropdown > button",run:"click",},{trigger:" .o-dropdown--menu .dropdown-item-studio",},],});return __exports;});;

/* /mail_enterprise/static/tests/tours/discuss_channel_expand_test_tour.js */
odoo.define('@mail_enterprise/../tests/tours/discuss_channel_expand_test_tour',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");registry.category("web_tour.tours").add("mail_enterprise/static/tests/tours/discuss_channel_expand_test_tour.js",{steps:()=>[{content:"Click on 'Open Actions Menu' in the chat window header to show expand button",trigger:'.o-mail-ChatWindow:contains("test-mail-channel-expand-tour") [title="Open Actions Menu"]',run:"click",},{content:"Click on expand button to open channel in Discuss",trigger:'.o-dropdown-item:contains("Open in Discuss")',run:"click",},{content:"Check that first message of #test-mail-channel-expand-tour is shown in Discuss app",trigger:'.o-mail-Discuss-content .o-mail-Message-body:contains("test-message-mail-channel-expand-tour")',},],});return __exports;});