UNPKG

@openfin/automation-helpers

Version:

Helper methods for automation testing in the OpenFin ecosystem

1 lines 37.5 kB
"use strict";var t,e,n=require("fs/promises"),i=require("path"),s=require("@openfin/node-adapter"),r=require("child_process"),o=require("os"),a=require("http"),c=require("https"),l=require("crypto"),u=require("webdriver"),h=require("selenium-webdriver");exports.MouseButton=void 0,(t=exports.MouseButton||(exports.MouseButton={}))[t.Left=0]="Left",t[t.Middle=1]="Middle",t[t.Right=2]="Right",exports.WebDriverKeys=void 0,(e=exports.WebDriverKeys||(exports.WebDriverKeys={})).Cancel="",e.Help="",e.Backspace="",e.Tab="",e.Clear="",e.Return="",e.Enter="",e.Shift="",e.Control="",e.ControlRight="",e.Alt="",e.Pause="",e.Escape="",e.Space="",e.PageUp="",e.PageDown="",e.End="",e.Home="",e.ArrowLeft="",e.ArrowUp="",e.ArrowRight="",e.ArrowDown="",e.Insert="",e.Delete="",e.SemiColon="",e.Equals="",e.NumPad0="",e.NumPad1="",e.NumPad2="",e.NumPad3="",e.NumPad4="",e.NumPad5="",e.NumPad6="",e.NumPad7="",e.NumPad8="",e.NumPad9="",e.Multiply="",e.Add="",e.Separator="",e.Subtract="",e.Decimal="",e.Divide="",e.F1="",e.F2="",e.F3="",e.F4="",e.F5="",e.F6="",e.F7="",e.F8="",e.F9="",e.F10="",e.F11="",e.F12="",e.CommandMeta="";class d{static waitForObjectExisting(){return'\nfunction ofWaitForObjectExisting(objectPath) {\n console.log("ofWaitForObjectExisting: ", objectPath);\n\tconst objectPathParts = objectPath.split(".");\n\tlet obj = globalThis;\n\tlet foundObj = undefined;\n\tfor (let i = 0; i < objectPathParts.length && foundObj === undefined; i++) {\n\t\tif (obj[objectPathParts[i]] !== undefined && obj[objectPathParts[i]] !== null) {\n\t\t\tobj = obj[objectPathParts[i]];\n\t\t\tif (i === objectPathParts.length - 1) {\n\t\t\t\tfoundObj = obj;\n\t\t\t}\n\t\t}\n\t}\n console.log("ofWaitForObjectExisting returns: ", foundObj);\n\treturn foundObj;\n}\n '}static convertToProxy(){return'\nfunction ofConvertToProxy(obj) {\n\tif (obj !== null && obj !== undefined && typeof obj === "object") {\n\t\tconst skipNames = new Set([\n\t\t\t"constructor",\n\t\t\t"hasOwnProperty",\n\t\t\t"isPrototypeOf",\n\t\t\t"propertyIsEnumerable",\n\t\t\t"toLocaleString",\n\t\t\t"toString",\n\t\t\t"valueOf",\n\t\t\t"__defineGetter__",\n\t\t\t"__defineSetter__",\n\t\t\t"__lookupGetter__",\n\t\t\t"__lookupSetter__",\n\t\t]);\n\n\t\tlet propNames = Object.getOwnPropertyNames(obj);\n\t\tconst isArray = Array.isArray(obj);\n\n\t\tif (isArray) {\n\t\t\tskipNames.add("length");\n\t\t}\n\t\tif (obj.__proto__ && !isArray && !(obj instanceof Set) && !(obj instanceof Map)) {\n\t\t\tpropNames = propNames.concat(Object.getOwnPropertyNames(obj.__proto__));\n\t\t}\n\n\t\tconst isIterable = typeof obj[Symbol.iterator] === "function";\n\t\tif (isIterable || isArray) {\n\t\t\tconst arr = Array.from(obj);\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tarr[i] = ofConvertToProxy(arr[i]);\n\t\t\t}\n\t\t\treturn arr;\n\t\t}\n\n\t\tconst returnObj = {};\n\t\tfor (const propName of propNames.filter(p => !skipNames.has(p) && !p.startsWith("_"))) {\n\t\t\tif (typeof obj[propName] === "function") {\n\t\t\t\treturnObj["@@function@@" + propName] = "function";\n\t\t\t} else {\n\t\t\t\treturnObj[propName] = ofConvertToProxy(obj[propName]);\n\t\t\t}\n\t\t}\n\t\treturn returnObj;\n\t}\n\treturn obj;\n}\n\t\t'}static callMethodAndProxyResult(t){return`\n\t\t\t${d.convertToProxy()}\n\t\t\t${d.mapProxyFieldNames()}\n\t\t\tconst callback = arguments[arguments.length - 1];\n\t\t\tconst args = [];\n\t\t\tfor (let i = 0; i < arguments.length - 1; i++) {\n\t\t\t\targs[i] = arguments[i];\n\t\t\t}\n\t\t\tconsole.log("callMethodAndProxyResult: ", ${t}, args);\n\t\t\tconst result = await ${t}(...args);\n\t\t\tconst proxyCacheId = crypto.randomUUID();\n\t\t\twindow.proxyCache = window.proxyCache || {};\n\t\t\twindow.proxyCache[proxyCacheId] = result;\n\t\t\tcallback({ proxyCacheId: proxyCacheId, result: ofConvertToProxy(result) });\n\t\t`}static mapProxyFieldNames(){return'\nfunction ofMapProxyFieldNames(obj) {\n\tif (obj !== null && obj !== undefined && typeof obj === "object" && !Array.isArray(obj)) {\n\t const mappedObj = {};\n\t\tconst nameMap = new Map([["Window", "proxyWindow"]]);\n\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tif (nameMap.has(key)) {\n\t\t\t\tmappedObj[nameMap.get(key)] = obj[key];\n\t\t\t} else {\n\t\t\t\tmappedObj[key] = obj[key];\n\t\t\t}\n\t\t}\n\t\treturn mappedObj;\n\t}\n\treturn obj;\n}\n\t\t'}}class y{static async executeAsync(t,e){return globalThis.webDriver.executeAsyncScript(`const asyncResult = ${t};arguments[arguments.length - 1](asyncResult);`,e)}static async callMethod(t,e,n){const i=`\n const callback = arguments[arguments.length - 1];\n const args = [];\n for (let i = 0; i < arguments.length - 1; i++) {\n args[i] = arguments[i];\n }\n callback(${n?"await ":""}${t}(...args))\n `;return globalThis.webDriver.executeAsyncScript(i,e??[])}static async callMethodUntilCondition(t,e,n,i,s=1e4,r=200){const o=Date.now();let a;do{try{a=await y.callMethod(t,e,n)}catch(t){a=t}if(i(a))return a;r>0&&await y.sleep(r)}while(Date.now()-o<s);return a}static async waitForObjectExisting(t,e=1e4,n=200){const i=`\n\t\t${d.waitForObjectExisting()}\n\t\t${d.mapProxyFieldNames()}\n const callback = arguments[arguments.length - 1];\n\t\tconst obj = ofWaitForObjectExisting(arguments[0]);\n callback(ofMapProxyFieldNames(obj));\n `,s=Date.now();do{try{const e=await globalThis.webDriver.executeAsyncScript(i,[t]);if(e)return this.ofMapProxyNames(e)}catch(e){console.error(`Error in WebDriver.waitForObjectExisting: ${t}`,e)}n>0&&await y.sleep(n)}while(Date.now()-s<e)}static async sleep(t){return new Promise((e=>setTimeout(e,t)))}static async getTitle(){return globalThis.webDriver.getTitle()}static async getUrl(){return globalThis.webDriver.getUrl()}static async setUrl(t){return globalThis.webDriver.setUrl(t)}static async getWindows(){return globalThis.webDriver.getWindows()}static async getWindow(){return globalThis.webDriver.getWindow()}static async switchToWindow(t,e,n=!0){return globalThis.webDriver.switchToWindow(t,e,n)}static async waitForWindow(t,e,n=1e4,i=200,s=!0){const r=Date.now();do{if(await this.switchToWindow(t,e,s))return!0;i>0&&await y.sleep(i)}while(Date.now()-r<n);return!1}static async findElementByPath(t){return globalThis.webDriver.findElement("xpath",t)}static async waitForElementByPath(t,e=1e4,n=200){return y.waitForElementByLocator("xpath",t,e,n)}static async findElementsByPath(t){return globalThis.webDriver.findElements("xpath",t)}static async findElementByTag(t){return globalThis.webDriver.findElement("tag name",t)}static async findElementsByTag(t){return globalThis.webDriver.findElements("tag name",t)}static async waitForElementByTag(t,e=1e4,n=200){return y.waitForElementByLocator("tag name",t,e,n)}static async findElementByCssSelector(t){return globalThis.webDriver.findElement("css selector",t)}static async findElementsCssSelector(t){return globalThis.webDriver.findElements("css selector",t)}static async waitForElementByCssSelector(t,e=1e4,n=200){return y.waitForElementByLocator("css selector",t,e,n)}static async findElementById(t){return globalThis.webDriver.findElement("xpath",`//*[@id='${t}']`)}static async waitForElementById(t,e=1e4,n=200){return y.waitForElementByLocator("xpath",`//*[@id='${t}']`,e,n)}static async findElementByClass(t,e="*"){return globalThis.webDriver.findElement("xpath",`//${e}[contains(@class,"${t}")]`)}static async findElementsByClass(t,e="*"){return globalThis.webDriver.findElements("xpath",`//${e}[contains(@class,"${t}")]`)}static async waitForElementByClass(t,e="*",n=1e4,i=200){return y.waitForElementByLocator("xpath",`//${e}[contains(@class,"${t}")]`,n,i)}static async findElementByLocator(t,e){return globalThis.webDriver.findElement(t,e)}static async findElementsByLocator(t,e){return globalThis.webDriver.findElements(t,e)}static async waitForElementByLocator(t,e,n=1e4,i=200){const s=Date.now();do{const n=await globalThis.webDriver.findElement(t,e);if(n)return n;i>0&&await y.sleep(i)}while(Date.now()-s<n)}static async waitForCondition(t,e=1e4,n=200){const i=Date.now();do{if(await t())return!0;n>0&&await y.sleep(n)}while(Date.now()-i<e);return!1}static async screenshot(){return globalThis.webDriver.screenshot()}static async saveScreenshot(t,e){const s=i.resolve(t??globalThis.automation?.screenshotFolder??"./reports/screenshots/");let r=e;if(!r){const t=new Date,e=`${t.getFullYear()}${(t.getMonth()+1).toString().padStart(2,"0")}${t.getDate().toString().padStart(2,"0")}`,n=`${t.getHours().toString().padStart(2,"0")}${t.getMinutes().toString().padStart(2,"0")}${t.getSeconds().toString().padStart(2,"0")}`,i=process.hrtime();let s=globalThis?.automation?.currentTestName;s&&0!==s.length||(s="test"),r=`${e} - ${n}.${i[1]} - ${s}`}r.endsWith(".png")||(r+=".png");const o=i.join(s,r);try{const t=await globalThis.webDriver.screenshot(),e=Buffer.from(t,"base64");await n.mkdir(s,{recursive:!0}),await n.writeFile(i.join(s,r),e)}catch(t){console.error(`Unable to save screenshot to '${o}'.\n${t}`)}}static async actions(t){return globalThis.webDriver.actions(t)}static ofMapProxyNames(t){if(null!=t&&"object"==typeof t&&!Array.isArray(t)){const e=t,n=new Map([["proxyWindow","Window"]]);for(const t of Object.keys(e)){const i=n.get(t);i&&void 0!==e[t]&&(e[i]=e[t],delete e[t])}}return t}}class w{static async show(t){return!(!await y.waitForWindow("identity",{name:"openfin-home",uuid:"openfin-workspace"},t)||null!==await y.callMethodUntilCondition("fin.Workspace.Home.show",void 0,!0,(t=>null===t),t))}static async hide(){await y.callMethod("fin.Workspace.Home.hide",void 0,!0)}static async search(t,e=1e4,n=200){for(const e of t){const t=await y.findElementById("search-input");if(!t)throw new Error("Element missing search-input");await t.sendKeys(e)}if(!await y.waitForElementById("result-list",e,n))throw new Error("Search results could not be found")}static async searchClear(){const t=await y.findElementById("search-input");if(!t)throw new Error("Element missing search-input");await t.sendKeys("")}static async searchResultByIndex(t,e){const n=await y.findElementByPath(`//*[@id='result-list']/div[${t+1}]`);if(n){const i=await w.searchResultSelectedIndex();"select"!==e&&"open"!==e||i===t||await n.click(),"open"===e&&await n.click()}return n}static async searchResultById(t,e){const n=await y.findElementByPath(`//*[@id='result-list']/*[@id='${t}']`);if(n){const i=await w.searchResultSelectedId();"select"!==e&&"open"!==e||i===t||await n.click(),"open"===e&&await n.click()}return n}static async searchResultIds(){const t=await y.findElementsByPath("//*[@id='result-list']/div"),e=[];for(let n=0;n<t.length;n++){const t=await y.findElementByPath(`(//*[@id='result-list']/div)[${n+1}]`);if(t){const n=await t.getAttribute("id");n&&e.push(n)}}return e}static async searchResultSelectedId(){const t=await y.findElementByPath("//*[@id='result-list']/div[@aria-selected='true']");if(t)return t.getAttribute("id")}static async searchResultSelectedIndex(){const t=await w.searchResultSelectedId();if(t){return(await w.searchResultIds()).indexOf(t)}return-1}static async searchResultSelectedItem(){const t=await y.findElementByPath("//*[@id='result-list']/div[@aria-selected='true']/div");if(t)return t.getHTML()}static async searchResultSelectedDetails(){const t=await y.findElementByPath("//*[contains(@aria-label,'Search result details section')]/div | //*[contains(@aria-label,'return to search results')]/div");if(t)return t.getHTML()}static async filtersOpen(){const t=await y.findElementByPath("//button[@shape='square']");t&&await t.click()}static async filtersClose(t){const e=await y.findElementsByPath("//div[@id='modal-root']//button"),n=e.map((async t=>t.getText())),i=await Promise.all(n);let s=-1;t?(s=i.indexOf("OK"),-1===s&&(s=i.indexOf("Apply"))):s=i.indexOf("Cancel"),-1!==s&&await e[s].click(),await y.waitForCondition((async()=>0===(await y.findElementsByPath("//div[@id='modal-root']//button")).length))}static async filtersIds(){const t=await y.findElementsByPath("//div[@id='modal-root']//input[@type='checkbox']"),e=[];for(let n=0;n<t.length;n++){const t=await y.findElementByPath(`(//div[@id='modal-root']//input[@type='checkbox'])[${n+1}]`);if(t){const i=await t.getAttribute("id");i&&(n>0||"select-all"!==i)&&e.push(i)}}return e}static async filtersByIndexSet(t,e){const n=await y.findElementByPath(`(//div[@id='modal-root']//input[@type='checkbox'])[${t+1}]`);if(n){const i=await this.filtersByIndexGet(t);(i&&!e||!i&&e)&&await n.click()}}static async filtersByIndexGet(t){const e=await y.findElementByPath(`(//div[@id='modal-root']//input[@type='checkbox'])[${t+1}]`);return!!e&&(await e.getProperty("checked")??!1)}static async filtersByIdSet(t,e){const n=await y.findElementByPath(`//div[@id='modal-root']//input[@type='checkbox'][@id='${t}']`);if(n){const i=await this.filtersByIdGet(t);(i&&!e||!i&&e)&&await n.click()}}static async filtersByIdGet(t){const e=await y.findElementByPath(`//div[@id='modal-root']//input[@type='checkbox'][@id='${t}']`);return!!e&&(await e.getProperty("checked")??!1)}}class f{static async build(t,e,n=5e3,i=200){const s=await f.waitForProxy(t,n,i);return f.proxyMethods(s,t,e)}static async fin(t,e=5e3,n=200){return void 0!==t&&await y.waitForWindow("identity",t,e,n),f.build("fin",["wrapSync","getCurrentSync","connectSync"],e)}static async finConnection(t,e=5e3,n=200){try{if(void 0===t&&(t=await y.waitForObjectExisting("fin.me.identity",e,n)),t){const n=`${t.name}:${t.uuid}`;if(!f._connections[n]){const i=await y.callMethod("fin.System.getRuntimeInfo");if(i){const r=await s.launch({uuid:t?.uuid,name:t?.name,runtime:{version:i.version},timeout:e}),o=await s.connect({address:`ws://localhost:${r}`,uuid:`dev-connection-${Date.now()}`,timeout:e});f._connections[n]=o}}return f._connections[n]}}catch(t){console.error(t)}}static async waitForProxy(t,e=1e4,n=200){const i=`\n\t\t${d.waitForObjectExisting()}\n\t\t${d.convertToProxy()}\n\t\t${d.mapProxyFieldNames()}\n\t\tconst callback = arguments[arguments.length - 1];\n\t\tlet obj = ofWaitForObjectExisting(arguments[0]);\n\t\tif (obj) {\n\t\t\tobj = ofConvertToProxy(obj);\n\t\t\tconsole.log("waitForProxy.ofConvertToProxy: ", obj);\n\n\t\t\tobj = ofMapProxyFieldNames(obj);\n\t\t\tconsole.log("waitForProxy.ofMapProxyFieldNames: ", obj);\n\t\t}\n\t\tcallback(obj);\n\t\t`,s=Date.now();do{try{const e=await globalThis.webDriver.executeAsyncScript(i,[t]);if(e)return y.ofMapProxyNames(e);n>0&&await y.sleep(n)}catch{}}while(Date.now()-s<e)}static proxyMethods(t,e,n){if(null!=t&&"object"==typeof t){const i=t,s=Object.keys(i);for(const t of s)if(t.startsWith("@@function@@")&&"string"==typeof i[t]&&"function"===i[t]){delete i[t];const s=t.replace("@@function@@","");n.includes(s)?i[s]=()=>{throw new Error(`The method '${s}' is not supported through the proxy`)}:i[s]=async(...t)=>{const i=d.callMethodAndProxyResult(`${e}.${s}`);try{const e=await globalThis.webDriver.executeAsyncScript(i,t);return null==e?null:f.proxyMethods(e.result,`globalThis.proxyCache["${e.proxyCacheId}"]`,n)}catch(t){throw console.error(`Error calling method '${s}' on '${e}':`,t),t}}}else i[t]=f.proxyMethods(i[t],`${e}.${t}`,n);return i}return t}}async function p(t){return new Promise(((e,n)=>{(t.startsWith("https")?c:a).get(t,(i=>{const s=[];i.on("data",(t=>{s.push(t)})),i.on("end",(()=>{const r=i.statusCode??400;r>=200||r<=299?e(Buffer.concat(s)):n(new Error(`Failure when downloading from ${t}, Status: ${r}`))}))})).on("error",(e=>{n(new Error(`Failure when downloading from ${t}, ${e}`))}))}))}async function m(t){return(await p(t)).toString()}async function g(t){const e=await m(t);return JSON.parse(e)}function b(t){return null!=t&&"object"==typeof t&&!Array.isArray(t)}function _(t,e){const n={...t};if(b(t)&&b(e))for(const i of Object.keys(e))b(e[i])?i in t?n[i]=_(t[i],e[i]):Object.assign(n,{[i]:e[i]}):Object.assign(n,{[i]:e[i]});return n}f._connections={};class x{static async waitForReady(t=1e4,e=200){const n=Date.now();do{const t=await y.getWindows();for(const n of t)if(n.identity){await n.switchTo();if(await y.waitForObjectExisting("window.fin",e))return!0}e>0&&await y.sleep(e)}while(Date.now()-n<t);return!1}static async launchManifest(t,e){let n;return e?.runtimeVersion&&(n={runtime:{version:e.runtimeVersion}}),this.launchManifestAdvanced(t,n,[{arg:"security-realm",op:e?.realm?.length?"replace":"delete",value:e?.realm}])}static async launchManifestAdvanced(t,e,s){let r;try{let a=await g(t);if(a.devtools_port=global.automation?.devToolsPort??a.devtools_port,e&&(a=_(a,e)),a.runtime=a.runtime??{},a.runtime.arguments=a.runtime.arguments??"",Array.isArray(s)&&s.length>0){const t=a.runtime.arguments.split(" "),e=s.filter((t=>"delete"===t.op||"replace"===t.op)),n=t.filter((t=>!e.some((e=>t.startsWith(`--${e.arg}`)))));for(const t of s)"add"!==t.op&&"replace"!==t.op||n.push(`--${t.arg}=${t.value}`);a.runtime.arguments=n.join(" ")}const c=o.tmpdir();r=i.join(c,`openfin-${Date.now()}.json`),await n.writeFile(r,JSON.stringify(a,null,"\t"));const l=await f.fin();try{await(l?.System.launchManifest(r))}catch(t){if(!(t instanceof Error&&"darwin"===o.platform()&&t.message.includes("not implemented on mac")&&global.automation?.openFinRVMPath))throw t;x.spawnWithOutput("open",[global.automation?.openFinRVMPath,"--args",`--config=${r}`,`--runtime-arguments="--remote-debugging-port=${global.automation?.devToolsPort}"`],void 0,!0,!0)}return!0}catch(t){console.log(t)}finally{setTimeout((async()=>{try{r&&await n.rm(r)}catch{}}),5e3)}return!1}static spawnWithOutput(t,e,n,i,s,o){const a=r.spawn(t,e,n);let c="",l="",u="",h="";return a.stdout.setEncoding("utf8"),a.stdout.on("data",(t=>{if(o&&(u+=t.toString()),!i){c+=t.toString();const e=c.split("\n");c=e.pop()??"";for(const t of e)console.log(t)}})),a.stderr.setEncoding("utf8"),a.stderr.on("data",(t=>{if(o&&(h+=t.toString()),!s){l+=t.toString();const e=l.split("\n");l=e.pop()??"";for(const t of e)console.error(t)}})),a.on("close",(()=>{c.trim().length>0&&console.log(c),l.trim().length>0&&console.error(l),o&&o(u,h)})),a}}class E{constructor(t,e,n,i){this._client=t,this._locator=e,this._locatorValue=n,this._locatorIndex=i}async setText(t){await this.setProperty("textContent",t)}async getHTML(){return this.getProperty("innerHTML")}async setHTML(t){await this.setProperty("innerHTML",t)}async getAttribute(t){return this.callMethod("getAttribute",[t])}async setAttribute(t,e){return this.callMethod("setAttribute",[t,e])}async removeAttribute(t){return this.callMethod("removeAttribute",[t])}async getProperty(t){const e=`\n const callback = arguments[arguments.length - 1];\n const propertyName = arguments[0];\n const elem = ${this.buildLocatorLookup()};\n const value = elem[propertyName];\n callback(JSON.stringify({ "value": value }));\n `,n=await this.executeAsyncScript(e,[t]);return JSON.parse(n).value}async setProperty(t,e){const n=`\n const callback = arguments[arguments.length - 1];\n const propertyName = arguments[0];\n const propertyValue = JSON.parse(arguments[1]).value;\n const elem = ${this.buildLocatorLookup()};\n elem[propertyName] = propertyValue;\n callback();\n `;return this.executeAsyncScript(n,[t,JSON.stringify({value:e})])}async removeProperty(t){const e=`\n const callback = arguments[arguments.length - 1];\n const propertyName = arguments[0];\n const elem = ${this.buildLocatorLookup()};\n delete elem[propertyName];\n callback();\n `;return this.executeAsyncScript(e,[t])}async getStyle(){const t=`\n const callback = arguments[arguments.length - 1];\n const elem = ${this.buildLocatorLookup()};\n const computed = getComputedStyle(elem);\n const keys = Object.keys(computed);\n const returnStyle = {};\n for (const key of keys) {\n const idx = Number.parseInt(key, 10);\n if (Number.isNaN(idx)) {\n returnStyle[key] = computed[key];\n }\n }\n callback(returnStyle);\n `;return this.executeAsyncScript(t,[])}async setStyle(t){const e=`\n const callback = arguments[arguments.length - 1];\n const style = arguments[0];\n const elem = ${this.buildLocatorLookup()};\n const keys = Object.keys(style);\n for (const key of keys) {\n elem.style[key] = style[key];\n }\n callback();\n `;return this.executeAsyncScript(e,[t])}async removeStyle(t){const e=`\n const callback = arguments[arguments.length - 1];\n const styles = arguments[0];\n const elem = ${this.buildLocatorLookup()};\n for (const key of styles) {\n elem.style[key] = null;\n }\n callback();\n `;return this.executeAsyncScript(e,[t])}async focus(){return this.callMethod("focus",[])}async callMethod(t,e,n){const i=`\n const callback = arguments[arguments.length - 1];\n const elem = ${this.buildLocatorLookup()};\n\t\tconst args = [];\n\t\tfor (let i = 0; i < arguments.length - 1; i++) {\n\t\t\targs[i] = arguments[i];\n\t\t}\n\t\tconst result = ${n?"await ":""}elem.${t}(...args);\n callback(result);\n `;return globalThis.webDriver.executeAsyncScript(i,e)}buildLocatorLookup(){let t="";if("xpath"===this._locator){let e=this._locatorValue;this._locatorIndex>=0&&(e=`(${e})[${this._locatorIndex+1}]`),t=`document.evaluate("${e.replace(/"/g,"'")}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue`}else"css selector"===this._locator?(t=`document.querySelector(".${this._locatorValue}")`,this._locatorIndex>=0&&(t+=`[${this._locatorIndex}]`)):"tag name"===this._locator&&(t=`document.querySelector("${this._locatorValue}")`,this._locatorIndex>=0&&(t+=`[${this._locatorIndex}]`));return t}}class v{constructor(t){t&&(this._client=t),this._windowCache={}}async getWindows(){if(!this._client)throw new Error("No session started");const t=[],e=await this.safeGetWindowHandles();for(const n of e){const e=await this.getWindowFromCacheByHandle(n);e&&t.push(e)}for(const t of Object.keys(this._windowCache))e.includes(t)||delete this._windowCache[t];return t}async getWindow(){if(!this._client)throw new Error("No session started");const t=await this.safeGetWindowHandle();if(t)return this.getWindowFromCacheByHandle(t)}async switchToWindow(t,e,n=!0){if(!this._client)throw new Error("No session started");const i=await this.getWindow();if(i&&await this.matchWindow(t,e,i))return await i.switchTo(n),!0;const s=await this.getWindows();for(const i of s)if(await this.matchWindow(t,e,i))return await i.switchTo(n),!0;return!1}async getTitle(){if(!this._client)throw new Error("No session started");let t=await this.safeGetTitle();if(!t||0===t.length){const e=await f.fin(void 0,500),n=e?.me.identity;n&&(t=n.name)}return t}async getUrl(){if(!this._client)throw new Error("No session started");return this.safeGetUrl()}async setUrl(t){if(!this._client)throw new Error("No session started");await this.safeSetUrl(t)}async getWindowFromCacheByHandle(t){if(!this._client)throw new Error("No session started");try{let e,n=this._windowCache[t],i=n?.identity,s=n?.title,r=n?.url;const o=await this.safeGetWindowHandle();if(await this.safeSwitchToWindow(t,!1)){if(!i)try{e=await f.fin(void 0,500),i=e?.me?.identity}catch(e){console.error("Failed to get OpenFin identity",t,e)}s=await this.safeGetTitle(),r=await this.safeGetUrl(),o&&await this.safeSwitchToWindow(o,!1)}return n?(n.identity=i,n.title=s??"",n.url=r??""):(n=this.createWebDriverWindow(this._client,t,s??"",r??"",i),this._windowCache[t]=n),this._windowCache[t]}catch{}}locatorMatcher(t,e){if(null==e)return e;const n=Array.isArray(t)?t:[t];let i=!1;for(const t of n){const n=t;if(n&&"function"==typeof n.test){i=n.test(e);break}if("string"==typeof t){i=t===e;break}throw new TypeError("OpenFin.Identity is not supported in arrays")}return i}async matchWindow(t,e,n){if("handle"===t)return this.locatorMatcher(e,n.handle);if("title"===t)return this.locatorMatcher(e,n.title);if("url"===t)return this.locatorMatcher(e,n.url);if("identity"===t){if(n.identity){const t=e;return t.name===n.identity.name&&t.uuid===n.identity.uuid}}else{if("identityString"!==t)throw new Error(`Unrecognized locator type: "${t}"`);if(n.identity&&Array.isArray(e)&&2===e.length)return this.locatorMatcher(e[0],n.identity.name)&&this.locatorMatcher(e[1],n.identity.uuid)}return!1}}class T extends E{constructor(t,e,n,i,s){super(t,e,n,i),this._elementId=s}static elementIdFromReference(t){return t["element-6066-11e4-a52e-4f735466cecf"]}async findElement(t,e){try{const n=await this._client.findElementFromElement(this._elementId,t,e),i=T.elementIdFromReference(n);if(i)return new T(this._client,t,e,-1,i)}catch{}}async findElements(t,e){try{const n=await this._client.findElementsFromElement(this._elementId,t,e);return n.map((t=>T.elementIdFromReference(t))).filter(Boolean).map(((n,i)=>new T(this._client,t,e,i,n)))}catch{}return[]}async click(){await this._client.elementClick(this._elementId)}async sendKeys(t){await this._client.elementSendKeys(this._elementId,t)}async getText(){return this._client.getElementText(this._elementId)}async isEnabled(){return this._client.isElementEnabled(this._elementId)}async isDisplayed(){return this._client.isElementDisplayed(this._elementId)}async isSelected(){return this._client.isElementSelected(this._elementId)}async screenshot(){return this._client.takeElementScreenshot(this._elementId)}async executeAsyncScript(t,e){return this._client.executeAsyncScript(t,e??[])}async rect(){return this._client.getElementRect(this._elementId)}nativeElement(){return{"element-6066-11e4-a52e-4f735466cecf":this._elementId}}}class k{constructor(t,e,n,i,s){this._client=t,this.handle=e,this.title=n,this.url=i,this.identity=s}async info(){if(!this._client)throw new Error("No session started");if(this.identity){const t=await f.fin();if(t){const e=await t.Window.wrap(this.identity),n=await e.getBounds(),i=await e.isShowing(),s=await e.getState();return{x:n.left,y:n.top,width:n.width,height:n.height,isShowing:i,state:s}}}}}class S extends k{static async safeSwitchToWindow(t,e,n=!0){try{if(await t.switchToWindow(e),n)try{const t=await f.fin(void 0,500);if(t){const e=await t.Window.wrap(t.me.identity);"window"===e.wire?.me?.entityType&&(await e.bringToFront(),await e.setAsForeground())}}catch{}return!0}catch{}return!1}async switchTo(t=!0){return S.safeSwitchToWindow(this._client,this.handle,t)}}class P extends E{constructor(t,e,n,i,s){super(t,e,n,i),this._webElement=s}async findElement(t,e){try{const n=this.createLocator(t,e);if(n){const i=await this._webElement.findElement(n);return new P(this._client,t,e,-1,i)}}catch(t){if(t instanceof Error&&"NoSuchElementError"===t.name)return;throw t}}async findElements(t,e){const n=this.createLocator(t,e);if(n){return(await this._webElement.findElements(n)).map(((n,i)=>new P(this._client,t,e,i,n)))}return[]}async click(){await this._webElement.click()}async sendKeys(t){await this._webElement.sendKeys(t)}async getText(){return this._webElement.getText()}async isEnabled(){return this._webElement.isEnabled()}async isDisplayed(){return this._webElement.isDisplayed()}async isSelected(){return this._webElement.isSelected()}async screenshot(){return this._webElement.takeScreenshot()}async executeAsyncScript(t,e){return this._client.executeAsyncScript(t,...e??[])}async rect(){return this._webElement.getRect()}nativeElement(){return this._webElement}createLocator(t,e){let n;return"xpath"===t?n=h.By.xpath(e):"tag name"===t||"css selector"===t?n=h.By.css(e):"link text"===t?n=h.By.linkText(e):"partial link text"===t&&(n=h.By.partialLinkText(e)),n}}class j extends k{static async safeSwitchToWindow(t,e,n=!0){try{if(await t.switchTo().window(e),n)try{const t=await f.fin(void 0,500);if(t){const e=await t.Window.wrap(t.me.identity);await e.bringToFront(),await e.setAsForeground()}}catch{}return!0}catch{}return!1}async switchTo(t=!0){return j.safeSwitchToWindow(this._client,this.handle,t)}}exports.BaseWebDriverElement=E,exports.NodeWebDriver=class extends v{constructor(t){super(t),globalThis.nodeWebDriver=t}async startSession(t,e,n,i,s,r){this._client||(this._client=await u.newSession({capabilities:{browserName:"chrome","goog:chromeOptions":{debuggerAddress:`localhost:${t}`}},hostname:"localhost",port:e,logLevel:n}),globalThis.nodeWebDriver=this._client,globalThis.automation=globalThis.automation??{screenshotFolder:i,currentTestName:"",openFinRVMPath:s,devToolsPort:t,openFinEnv:r})}async endSession(){if(!this._client)throw new Error("No session started");await this._client.deleteSession(),this._client=void 0}async executeAsyncScript(t,e){if(!this._client)throw new Error("No session started");return this._client.executeAsyncScript(t,e??[])}async findElement(t,e){if(!this._client)throw new Error("No session started");try{const n=await this._client.findElement(t,e),i=T.elementIdFromReference(n);if(i)return new T(this._client,t,e,-1,i)}catch{}}async findElements(t,e){if(!this._client)throw new Error("No session started");try{const n=await this._client.findElements(t,e);return n.map((t=>T.elementIdFromReference(t))).filter(Boolean).map(((n,i)=>new T(this._client,t,e,i,n)))}catch{}return[]}async screenshot(){if(!this._client)throw new Error("No session started");return this._client.takeScreenshot()}async actions(t){let e,n=[];if(!this._client)throw new Error("No session started");try{for(const i of t)if(i.type.startsWith("mouse")&&"pointer"!==e?.type?(e&&(await this._client.performActions(n),n=[]),e={type:"pointer",id:l.randomUUID(),pointerType:"mouse",actions:[]},n.push(e)):i.type.startsWith("key")&&"key"!==e?.type?(e&&(await this._client.performActions(n),n=[]),e={type:"key",id:l.randomUUID(),actions:[]},n.push(e)):i.type.startsWith("pause")&&e&&(await this._client.performActions(n),n=[],e=void 0),"mouseDown"===i.type)e?.actions.push({type:"pointerDown",button:i.button??exports.MouseButton.Left});else if("mouseUp"===i.type)e?.actions.push({type:"pointerUp",button:i.button??exports.MouseButton.Left});else if("mouseClick"===i.type)e?.actions.push({type:"pointerDown",button:i.button??exports.MouseButton.Left}),e?.actions.push({type:"pointerUp",button:i.button??exports.MouseButton.Left});else if("mouseMove"===i.type){let t=i.origin??"viewport",n=i.x,s=i.y;if(i.origin&&"string"!=typeof i.origin){t="viewport";const e=await i.origin.rect();if(void 0===i.x){const t=e.width/2;n=e.x+t}else n=e.x+i.x;if(void 0===i.y){const t=e.height/2;s=e.y+t}else s=e.y+i.y}e?.actions.push({type:"pointerMove",x:Math.round(n??0),y:Math.round(s??0),origin:t,duration:i.duration})}else if("keyDown"===i.type)e?.actions.push({type:"keyDown",value:i.key});else if("keyUp"===i.type)e?.actions.push({type:"keyUp",value:i.key});else if("keyPress"===i.type)for(const t of i.key)e?.actions.push({type:"keyDown",value:t}),e?.actions.push({type:"keyUp",value:t});else"pause"===i.type&&i.duration>0&&await new Promise((t=>setTimeout(t,i.duration)));return await this._client.performActions(n),!0}catch{}return!1}createWebDriverWindow(t,e,n,i,s){return new S(t,e,n,i,s)}async safeGetTitle(){try{if(this._client){return await this._client.getTitle()}}catch{}}async safeGetUrl(){try{if(this._client){return await this._client.getUrl()}}catch{}}async safeSetUrl(t){try{this._client&&await this._client.navigateTo(t)}catch{}}async safeGetWindowHandle(){try{if(this._client){return await this._client.getWindowHandle()}}catch{}}async safeGetWindowHandles(){try{if(this._client){return await this._client.getWindowHandles()}}catch{}return[]}async safeSwitchToWindow(t,e){return!!this._client&&S.safeSwitchToWindow(this._client,t,e)}},exports.NodeWebDriverElement=T,exports.NodeWebDriverWindow=S,exports.OpenFinHome=w,exports.OpenFinNotifications=class{static async launch(t){const e=global.automation?.openFinEnv?.notificationsVersion??"stable";let n;return n="stable"===e?"https://cdn.openfin.co/release/system-apps/notification-center/app.json":`https://cdn.openfin.co/release/system-apps/notification-center/${e}/app.json`,x.launchManifest(n,t)}static async toggle(){const t=await f.fin();if(t){const e=await t.InterApplicationBus.Channel.connect("of-notifications-service-v1");if(e)return await e.dispatch("toggle-notification-center"),!0}return!1}static async show(){const t=await f.fin();if(t){const e=await t.InterApplicationBus.Channel.connect("of-notifications-service-v1");if(e)return await e.dispatch("show-notification-center"),!0}return!1}static async hide(){const t=await f.fin();if(t){const e=await t.InterApplicationBus.Channel.connect("of-notifications-service-v1");if(e)return await e.dispatch("hide-notification-center"),!0}return!1}},exports.OpenFinProxy=f,exports.OpenFinStore=class{static async show(t){if(await y.waitForWindow("identity",{name:"openfin-storefront",uuid:"openfin-workspace"},t)){const t=await f.fin(),e=await(t?.InterApplicationBus.Channel.connect("__of_workspace_protocol__"));return await(e?.dispatch("show-storefront")),!0}return!1}static async hide(){const t=await f.fin(),e=await(t?.InterApplicationBus.Channel.connect("__of_workspace_protocol__"));await(e?.dispatch("hide-storefront"))}},exports.OpenFinSystem=x,exports.SeleniumWebDriver=class extends v{constructor(t){super(t),t&&(globalThis.seleniumWebDriver=t)}async startSession(t,e,n,i,s,r){if(!this._client){const o=new h.Capabilities({"goog:chromeOptions":{debuggerAddress:`localhost:${t}`}});if("debug"===n){const t=new h.logging.Preferences;t.setLevel(h.logging.Type.DRIVER,h.logging.Level.ALL),o.setLoggingPrefs(t)}this._client=(new h.Builder).usingServer(`http://localhost:${e}`).withCapabilities(o).forBrowser("chrome").build(),"debug"===n&&(this._logTimer=setInterval((async()=>{if(this._client){const t=await this._client.manage().logs().get(h.logging.Type.DRIVER);t.reverse();for(const e of t)console.log(e.message)}}),1e3)),globalThis.seleniumWebDriver=this._client,globalThis.automation=globalThis.automation??{screenshotFolder:i,currentTestName:"",openFinRVMPath:s,devToolsPort:t,openFinEnv:r}}}async endSession(){if(!this._client)throw new Error("No session started");await this._client.quit(),this._logTimer&&(clearInterval(this._logTimer),this._logTimer=void 0),this._client=void 0}async executeAsyncScript(t,e){if(!this._client)throw new Error("No session started");return this._client.executeAsyncScript(t,...e??[])}async findElement(t,e){if(!this._client)throw new Error("No session started");try{const n=this.createLocator(t,e);if(n){const i=await this._client.findElement(n);return new P(this._client,t,e,-1,i)}}catch(t){if(t instanceof Error&&"NoSuchElementError"===t.name)return;throw t}}async findElements(t,e){if(!this._client)throw new Error("No session started");const n=this.createLocator(t,e);if(n){return(await this._client.findElements(n)).map(((n,i)=>new P(this._client,t,e,i,n)))}return[]}async screenshot(){if(!this._client)throw new Error("No session started");return this._client.takeScreenshot()}async actions(t){if(!this._client)throw new Error("No session started");try{const e=this._client.actions(),n=[h.Button.LEFT,h.Button.MIDDLE,h.Button.RIGHT];for(const i of t)if("mouseDown"===i.type)e.press(n[i.button??exports.MouseButton.Left]);else if("mouseUp"===i.type)e.release(n[i.button??exports.MouseButton.Left]);else if("mouseClick"===i.type)e.press(n[i.button??exports.MouseButton.Left]),e.release(n[i.button??exports.MouseButton.Left]);else if("mouseMove"===i.type){let t,n=i.x,s=i.y;if("pointer"===i.origin)t=h.Origin.POINTER;else if("viewport"===i.origin)t=h.Origin.VIEWPORT;else if(i.origin&&"string"!=typeof i.origin){t=h.Origin.VIEWPORT;const e=await i.origin.rect();if(void 0===i.x){const t=e.width/2;n=e.x+t}else n=e.x+i.x;if(void 0===i.y){const t=e.height/2;s=e.y+t}else s=e.y+i.y}e.move({x:Math.round(n??0),y:Math.round(s??0),duration:i.duration,origin:t})}else if("keyDown"===i.type)e.keyDown(i.key);else if("keyUp"===i.type)e.keyUp(i.key);else if("keyPress"===i.type)for(const t of i.key)e.keyDown(t),e.keyUp(t);else"pause"===i.type&&e.pause(i.duration);return await e.perform(),!0}catch{}return!1}createWebDriverWindow(t,e,n,i,s){return new j(t,e,n,i,s)}async safeGetTitle(){try{if(this._client){return await this._client.getTitle()}}catch{}}async safeGetUrl(){try{if(this._client){return await this._client.getCurrentUrl()}}catch{}}async safeSetUrl(t){try{this._client&&await this._client.get(t)}catch{}}async safeGetWindowHandle(){try{if(this._client){return await this._client.getWindowHandle()}}catch{}}async safeGetWindowHandles(){try{if(this._client){return await this._client.getAllWindowHandles()}}catch{}return[]}async safeSwitchToWindow(t,e){return!!this._client&&j.safeSwitchToWindow(this._client,t,e)}createLocator(t,e){let n;return"xpath"===t?n=h.By.xpath(e):"tag name"===t||"css selector"===t?n=h.By.css(e):"link text"===t?n=h.By.linkText(e):"partial link text"===t&&(n=h.By.partialLinkText(e)),n}},exports.SeleniumWebDriverElement=P,exports.SeleniumWebDriverWindow=j,exports.WebDriver=y,exports.automation=undefined,exports.fetchBuffer=p,exports.fetchJson=g,exports.fetchText=m,exports.nodeWebDriver=undefined,exports.seleniumWebDriver=undefined,exports.webDriver=undefined;