@checksum-ai/runtime 4.16.2 → 4.16.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -11,7 +11,6 @@ import {
11
11
  Dialog,
12
12
  } from "@playwright/test";
13
13
 
14
- // import { ExpectWrapper } from "./index.helpers";
15
14
  interface ChecksumAIMethod {
16
15
  (title: string): IChecksumPage;
17
16
  <T>(
@@ -110,7 +109,6 @@ export interface CompoundSelectionInterface {
110
109
  * target?: (base) => base.locator("<relative selector to target element>")
111
110
  * }).first().click();
112
111
  * ```
113
- * @param selection
114
112
  * @returns Locator to the common parent(s) or the target element(s) if specified.
115
113
  */
116
114
  compoundSelection(selection: {
package/index.js CHANGED
@@ -416,7 +416,7 @@ ${c}
416
416
  })`,{filename:i})(s,(0,joe.createRequire)(i),r,i,(0,Hoe.dirname)(i));let p=r.exports,d=p.default;return d===void 0?p:d}u(Joe,"requireChecksumConfig");var kw=require("fs"),Zoe=require("module"),Xoe=require("node:util");var hc={defaultMerge:Symbol("deepmerge-ts: default merge"),skip:Symbol("deepmerge-ts: skip")},Y_t={defaultMerge:hc.defaultMerge};function QFe(i,n){return n}u(QFe,"defaultMetaDataUpdater");function MFe(i,n){return i.filter(c=>c!==void 0)}u(MFe,"defaultFilterValues");var qoe;(function(i){i[i.NOT=0]="NOT",i[i.RECORD=1]="RECORD",i[i.ARRAY=2]="ARRAY",i[i.SET=3]="SET",i[i.MAP=4]="MAP",i[i.OTHER=5]="OTHER"})(qoe||(qoe={}));function $oe(i){return typeof i!="object"||i===null?0:Array.isArray(i)?2:jFe(i)?1:i instanceof Set?3:i instanceof Map?4:5}u($oe,"getObjectType");function FFe(i){let n=new Set;for(let c of i)for(let s of[...Object.keys(c),...Object.getOwnPropertySymbols(c)])n.add(s);return n}u(FFe,"getKeys");function UFe(i,n){return typeof i=="object"&&Object.prototype.propertyIsEnumerable.call(i,n)}u(UFe,"objectHasProperty");function zoe(i){let n=0,c=i[0]?.[Symbol.iterator]();return{[Symbol.iterator](){return{next(){do{if(c===void 0)return{done:!0,value:void 0};let s=c.next();if(s.done===!0){n+=1,c=i[n]?.[Symbol.iterator]();continue}return{done:!1,value:s.value}}while(!0)}}}}}u(zoe,"getIterableOfIterables");var Voe=["[object Object]","[object Module]"];function jFe(i){if(!Voe.includes(Object.prototype.toString.call(i)))return!1;let{constructor:n}=i;if(n===void 0)return!0;let c=n.prototype;return!(c===null||typeof c!="object"||!Voe.includes(Object.prototype.toString.call(c))||!c.hasOwnProperty("isPrototypeOf"))}u(jFe,"isRecord");function HFe(i,n,c){let s={};for(let r of FFe(i)){let f=[];for(let h of i)UFe(h,r)&&f.push(h[r]);if(f.length===0)continue;let p=n.metaDataUpdater(c,{key:r,parents:i}),d=Koe(f,n,p);d!==hc.skip&&(r==="__proto__"?Object.defineProperty(s,r,{value:d,configurable:!0,enumerable:!0,writable:!0}):s[r]=d)}return s}u(HFe,"mergeRecords$1");function WFe(i){return i.flat()}u(WFe,"mergeArrays$1");function GFe(i){return new Set(zoe(i))}u(GFe,"mergeSets$1");function JFe(i){return new Map(zoe(i))}u(JFe,"mergeMaps$1");function qFe(i){return i.at(-1)}u(qFe,"mergeOthers$1");var Cw={mergeRecords:HFe,mergeArrays:WFe,mergeSets:GFe,mergeMaps:JFe,mergeOthers:qFe};function Yoe(...i){return $Fe({})(...i)}u(Yoe,"deepmerge");function $Fe(i,n){let c=VFe(i,s);function s(...r){return Koe(r,c,n)}return u(s,"customizedDeepmerge"),s}u($Fe,"deepmergeCustom");function VFe(i,n){return{defaultMergeFunctions:Cw,mergeFunctions:{...Cw,...Object.fromEntries(Object.entries(i).filter(([c,s])=>Object.hasOwn(Cw,c)).map(([c,s])=>s===!1?[c,Cw.mergeOthers]:[c,s]))},metaDataUpdater:i.metaDataUpdater??QFe,deepmerge:n,useImplicitDefaultMerging:i.enableImplicitDefaultMerging??!1,filterValues:i.filterValues===!1?void 0:i.filterValues??MFe,actions:hc}}u(VFe,"getUtils");function Koe(i,n,c){let s=n.filterValues?.(i,c)??i;if(s.length===0)return;if(s.length===1)return NM(s,n,c);let r=$oe(s[0]);if(r!==0&&r!==5){for(let f=1;f<s.length;f++)if($oe(s[f])!==r)return NM(s,n,c)}switch(r){case 1:return zFe(s,n,c);case 2:return YFe(s,n,c);case 3:return KFe(s,n,c);case 4:return ZFe(s,n,c);default:return NM(s,n,c)}}u(Koe,"mergeUnknowns");function zFe(i,n,c){let s=n.mergeFunctions.mergeRecords(i,n,c);return s===hc.defaultMerge||n.useImplicitDefaultMerging&&s===void 0&&n.mergeFunctions.mergeRecords!==n.defaultMergeFunctions.mergeRecords?n.defaultMergeFunctions.mergeRecords(i,n,c):s}u(zFe,"mergeRecords");function YFe(i,n,c){let s=n.mergeFunctions.mergeArrays(i,n,c);return s===hc.defaultMerge||n.useImplicitDefaultMerging&&s===void 0&&n.mergeFunctions.mergeArrays!==n.defaultMergeFunctions.mergeArrays?n.defaultMergeFunctions.mergeArrays(i):s}u(YFe,"mergeArrays");function KFe(i,n,c){let s=n.mergeFunctions.mergeSets(i,n,c);return s===hc.defaultMerge||n.useImplicitDefaultMerging&&s===void 0&&n.mergeFunctions.mergeSets!==n.defaultMergeFunctions.mergeSets?n.defaultMergeFunctions.mergeSets(i):s}u(KFe,"mergeSets");function ZFe(i,n,c){let s=n.mergeFunctions.mergeMaps(i,n,c);return s===hc.defaultMerge||n.useImplicitDefaultMerging&&s===void 0&&n.mergeFunctions.mergeMaps!==n.defaultMergeFunctions.mergeMaps?n.defaultMergeFunctions.mergeMaps(i):s}u(ZFe,"mergeMaps");function NM(i,n,c){let s=n.mergeFunctions.mergeOthers(i,n,c);return s===hc.defaultMerge||n.useImplicitDefaultMerging&&s===void 0&&n.mergeFunctions.mergeOthers!==n.defaultMergeFunctions.mergeOthers?n.defaultMergeFunctions.mergeOthers(i):s}u(NM,"mergeOthers");var ere=!1;function Foe(i){ere=i}u(Foe,"setLogToConsole");function ye(...i){ere&&process.stdout.write(`${(0,Xoe.format)(...i)}
417
417
  `)}u(ye,"log");function XFe(i,n){return i in n}u(XFe,"isLocatorMethod");async function ZX(i,n,c,s=6e4){if(!XFe(n,i))return i;let r=u(()=>{let f=i[n];return typeof f=="function"?Reflect.apply(f,i,c):f},"executor");return s===null?r():dt(r(),s,"Execution timeout")}u(ZX,"executePlaywrightMethodWithTimeout");function LM({envName:i,role:n}={}){let c=process.env.CHECKSUM_RUNTIME_ENV_OVERRIDE_NAME??i,s=process.env.CHECKSUM_RUNTIME_ENV_OVERRIDE_ROLE??n;return{...c!==void 0?{envName:c}:{},...s!==void 0?{role:s}:{}}}u(LM,"applyRuntimeEnvOverrides");function QM(i,{role:n,environment:c}={},s=!1){let r;if(c&&(r=i.environments?.find(({name:d})=>c===d)),r??=i.environments?.find(({default:d})=>d),!r)throw new Error("Environment not found. Please make sure your environments are properly defined in the checksum.config.ts file.");let f=r.users,p;if(f&&(n!==void 0&&(p=f.find(d=>d.role===n)),p??=f.find(d=>d.default)),!p)throw new Error(`User not found. Please make sure the users array for the "${r.name}" environment is properly defined in the checksum.config.ts file.`);if(c&&r.name!==c){if(s)throw new Error(`Could not find environment with name "${c}" in config file`);console.warn(`Could not find environment with name "${c}" in config file, trying to use default environment`)}if(n&&p.role!==n){if(s)throw new Error(`Could not find user with role "${n}" for environment "${c}" in config file`);console.warn(`Could not find user with role "${n}" for environment "${c}" in config file, trying to login with environment's default user`)}return{environment:r,user:p}}u(QM,"resolveEnvironment");function e3e(i){let n=`${i??Po()}/login.ts`;if(!(0,kw.existsSync)(n))throw console.warn(`Could not locate the login.ts file. Please make sure your login file exists at ${n}`),new Error("Could not find login.ts file");try{return(0,Zoe.createRequire)(__filename)(n).default}catch(c){throw console.warn("Error loading login.ts file",c),c}}u(e3e,"requireLogin");async function t3e(i,n,{environment:c,user:s,config:r}){try{let f=u(()=>n(i,{environment:c,user:s,config:r}),"performLogin");"checksumAI"in i?await i.checksumAI(`Log in${s.role?` using ${s.role} role`:""}${c.name?` in ${c.name} environment`:""}`,f,{skipAutoRecovery:!0}):await f()}catch(f){throw console.warn(`The login method threw an exception, please check the login.ts file for the following error:
418
418
  `,f),f}}u(t3e,"proceedWithLogin");function ds(i){let{config:n,folder:c,throwIfAuthFailed:s}=i,r=e3e(c);return async(f,{role:p,environment:d}={})=>{let{envName:h,role:o}=LM({...d!==void 0?{envName:d}:{},...p!==void 0?{role:p}:{}}),{environment:a,user:e}=QM(n,{...o!==void 0?{role:o}:{},...h!==void 0?{environment:h}:{}},i.throwIfEnvInfoInvalid);if(s&&!e)throw new Error("Could not find user credentials matching the provided role and/or environment");await t3e(f,r,{environment:a,user:e,config:n})}}u(ds,"makeUnboundLogin");function tre(i,{environmentName:n,userRole:c}){let s=ds(i);return r=>s(r,{environment:n,role:c})}u(tre,"makeBoundLogin");var or;function AI(){if(or)return or;try{let i=(0,kw.existsSync)(`${Po()}/checksum.config.ts`)?"checksum.config.ts":(0,kw.existsSync)(`${Po()}/checksum.config.tmp.ts`)?"checksum.config.tmp.ts":void 0;if(i)return Tw(Joe(`${Po()}/${i}`))}catch{console.warn("Could not find checksum config file, will run with defaults")}return Tw()}u(AI,"loadChecksumConfig");function Tw(i={}){let n={apiKey:"",runMode:"normal",apiURL:"https://api.checksum.ai",options:{useChecksumSelectors:!0,useChecksumAI:{actions:!0,assertions:!1,skipTestsWithKnownBugs:!0},newAssertionsEnabled:!0,useMockData:!1,printLogs:!1,consecutiveActionDelay:100,hideReports:process.env.AUTHORIZE_REPORTS==="true"}};return i.options?.useChecksumAI?.visualComparison===void 0&&i.options?.useChecksumAI?.assertions&&(i.options.useChecksumAI.visualComparison=!0),or=Yoe(n,i),process.env.CHECKSUM_API_URL&&(or.apiURL=process.env.CHECKSUM_API_URL),Fe.testRun.disableAutoRecovery&&or.options&&(or.options.useChecksumAI={actions:!1,assertions:!1,visualComparison:!1}),Fe.testRun.disableHostReports&&or.options&&(or.options.hostReports=!1),or.options&&(Fe.testRun.disableTimeMachine&&(or.options.disableTimeMachine=!0),Fe.testRun.disableRrwebRecording&&(or.options.disableRrwebRecording=!0)),or}u(Tw,"getChecksumConfig");var sc="Checksum failed connecting to the server";var IBt=require("@playwright/test");async function nre(i){await i.body?.cancel().catch(()=>{})}u(nre,"drainBody");var n3e="http://127.0.0.1";async function MM(i,n){let c=n.fetchImpl??globalThis.fetch;try{let s=await c(`${n3e}:${n.port}/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),signal:AbortSignal.timeout(n.timeoutMs)});return await nre(s),s.ok?!0:(n.onError?.(new Error(`monitor rejected message with status ${s.status}`)),!1)}catch(s){return n.onError?.(s),!1}}u(MM,"postToMonitor");async function FM(i,n){return await MM(i,n)?!0:n.attempts<=1?!1:(await o3e(n.retryDelayMs),FM(i,{...n,attempts:n.attempts-1}))}u(FM,"postToMonitorWithRetry");function o3e(i){return new Promise(n=>{setTimeout(n,i)})}u(o3e,"sleep");var xw={uploadTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_TIMEOUT_MS",fallback:6e5,min:5e3,max:36e5},noProgressAbortMs:{env:"CHECKSUM_RUNTIME_UPLOAD_NO_PROGRESS_MS",fallback:6e4,min:5e3,max:6e5},assetDeadlineMs:{env:"CHECKSUM_RUNTIME_UPLOAD_ASSET_DEADLINE_MS",fallback:12e5,min:3e4,max:54e5},maxAttempts:{env:"CHECKSUM_RUNTIME_UPLOAD_MAX_ATTEMPTS",fallback:6,min:1,max:20},stallTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_STALL_TIMEOUT_MS",fallback:6e5,min:3e4,max:36e5},minProgressBytes:{env:"CHECKSUM_RUNTIME_UPLOAD_MIN_PROGRESS_BYTES",fallback:65536,min:1,max:67108864},finalizeBudgetMs:{env:"CHECKSUM_RUNTIME_UPLOAD_FINALIZE_BUDGET_MS",fallback:18e5,min:6e4,max:54e5},finalizeCeilingMs:{env:"CHECKSUM_RUNTIME_UPLOAD_FINALIZE_CEILING_MS",fallback:24e5,min:12e4,max:72e5},cliHardCapMs:{env:"CHECKSUM_RUNTIME_UPLOAD_CLI_HARD_CAP_MS",fallback:27e5,min:12e4,max:72e5},watchTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_WATCH_TIMEOUT_MS",fallback:12e4,min:5e3,max:18e5},ipcTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_IPC_TIMEOUT_MS",fallback:5e3,min:500,max:6e4},onEndFlushTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_ONEND_FLUSH_TIMEOUT_MS",fallback:5e3,min:500,max:6e4},resumableChunkBytes:{env:"CHECKSUM_RUNTIME_UPLOAD_RESUMABLE_CHUNK_BYTES",fallback:8388608,min:262144,max:268435456},connectTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_CONNECT_TIMEOUT_MS",fallback:1e4,min:1e3,max:6e4},headersTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_HEADERS_TIMEOUT_MS",fallback:3e5,min:5e3,max:18e5},bodyTimeoutMs:{env:"CHECKSUM_RUNTIME_UPLOAD_BODY_TIMEOUT_MS",fallback:3e5,min:5e3,max:18e5},maxConcurrentUploads:{env:"CHECKSUM_RUNTIME_UPLOAD_MAX_CONCURRENT",fallback:15,min:1,max:64}};function r3e(i,n,c,s){if(i===void 0||i.trim()==="")return n;let r=Number(i);return Number.isInteger(r)?Math.min(s,Math.max(c,r)):n}u(r3e,"clampEnvInt");var i3e=[["cliHardCapMs",["finalizeCeilingMs"],.9],["finalizeCeilingMs",["finalizeBudgetMs"],1],["finalizeBudgetMs",["stallTimeoutMs","assetDeadlineMs","watchTimeoutMs"],1],["assetDeadlineMs",["uploadTimeoutMs"],1],["uploadTimeoutMs",["noProgressAbortMs"],.5]];function a3e(i){let n={...i},c=[];for(let[s,r,f]of i3e)for(let p of r){let d=Math.floor(n[s]*f);n[p]>d&&(c.push(`${xw[p].env} (${n[p]}ms) exceeds its bound under ${xw[s].env} (${n[s]}ms); using ${d}ms`),n[p]=d)}return{tunables:n,warnings:c}}u(a3e,"coerceScopeHierarchy");function c3e(i){let n={};for(let c of Object.keys(xw)){let s=xw[c];n[c]=r3e(i[s.env],s.fallback,s.min,s.max)}return n.resumableChunkBytes=Math.max(1,Math.floor(n.resumableChunkBytes/262144))*262144,a3e(n)}u(c3e,"resolveUploadTunablesDetailed");function UM(i){return c3e(i).tunables}u(UM,"resolveUploadTunables");var gBt=UM({});var l3e=4,ore=3,s3e=500,Pw=class i{constructor(n){this.workerInfo=n;this.hasMonitor=!1;i.monitorAgentPort?this.hasMonitor=!0:ye("CHECKSUM_UPLOAD_AGENT_PORT is not defined"),this.sendPlaywrightConfig()}static{u(this,"TestRunMonitorBridge")}static{this.monitorAgentHost="http://localhost"}static{this.monitorAgentPort=process.env.CHECKSUM_UPLOAD_AGENT_PORT}static{this.playwrightConfigSent=!1}static{this.tunables=UM(process.env)}addAsset(n){this.signalUpload(n,["trace","har","rrweb-recording"].includes(n.type))}addChecksumTestMetadata(n){let c={type:"checksumTestMetadata",payload:n};this.sendMessage(c)}addTestInfo(n,c,s=!1){this.sendMessage({type:"testInfo",payload:{checksumTestId:n,pwTestId:c,usingChecksumTestIdPlaceholder:s}})}addSingleTestStats(n,c){this.sendMessage({type:"testStats",payload:{passed:n,healed:c}})}sendPlaywrightConfig(){if(i.playwrightConfigSent)return;let n=this.buildPlaywrightConfig();this.sendMessage({type:"playwrightConfig",payload:n}),i.playwrightConfigSent=!0}buildPlaywrightConfig(){let{use:n,testDir:c,testMatch:s,testIgnore:r,timeout:f,outputDir:p,retries:d}=this.workerInfo.project,{reporter:h,configFile:o,projects:a}=this.workerInfo.config,e=Object.keys(a).filter(t=>[n,c,s,r,f,p,d].includes(t)).reduce((t,l)=>({...t,[l]:a[Number(l)]}),{});return{reporter:h,...o!==void 0?{configFile:o}:{},filteredProjects:e,use:n,testDir:c,testMatch:s,testIgnore:r,timeout:f,outputDir:p,retries:d}}sendMessage(n){return this.hasMonitor&&i.monitorAgentPort?MM(n,{port:i.monitorAgentPort,timeoutMs:i.tunables.ipcTimeoutMs,onError:u(c=>ye("Failed to send message to test run monitor",n,c),"onError")}):void 0}async signalUpload(n,c=!1){let s=i.monitorAgentPort;if(!this.hasMonitor||!s)return;let r={type:"asset",payload:n,watch:c},f;await FM(r,{port:s,timeoutMs:i.tunables.ipcTimeoutMs*l3e,attempts:ore,retryDelayMs:s3e,onError:u(d=>{f=d,ye("Failed to register asset with test run monitor",r,d)},"onError")})||pv("asset_registration_failed",{test_suite_run_id:process.env.CHECKSUM_TEST_SUITE_ID,outcome:"error",asset_type:n.type,asset_path:n.path,attempts:ore,error:vp(f)})}};var rre=require("@playwright/test"),ire=require("puppeteer-extra-plugin"),are=require("module");var _w=(0,are.createRequire)(__filename),Bw=class i{constructor(n){this.options=n;this.importPluginPackages()}static{u(this,"StealthProvider")}importPluginPackages(){i.pw??=_w("playwright-extra"),i.StealthPlugin??=_w("puppeteer-extra-plugin-stealth")}static createFreshInstance(){try{let{addExtra:n}=_w("playwright-extra");return n(i.pw.chromium)}catch(n){throw console.error("[StealthProvider] Error creating fresh instance:",n),n}}buildChromiumWithPlugins(n){let{project:c}=this.options,s=c.use.userAgent,r=c.use.playwrightExtra??[],f=i.StealthPlugin();if(r.push(f),this.isCustomUserAgent(s)){f.enabledEvasions.delete("user-agent-override");let h=_w("puppeteer-extra-plugin-stealth/evasions/user-agent-override")({userAgent:s});r.push(h)}let p=n??i.pw.chromium;return r.forEach((d,h)=>{try{!(d instanceof ire.PuppeteerExtraPlugin)&&d!==f&&console.warn(`Plugin at index ${h} in the project's checksum.config.ts file is not an instance of PuppeteerExtraPlugin.`),p.use(d)}catch(o){console.warn(o)}}),p}isCustomUserAgent(n){return n?!Object.values(rre.devices).some(c=>n===c.userAgent):!1}};function cre(i,n){return{testSuiteRunId:n,appName:"generic-app",commitHash:"generic-commit-hash",envName:"generic-env-name",branch:"generic-branch",checksumRuntimeVersion:i}}u(cre,"createDefaultTestSuiteRunInfo");var ure=require("crypto");var RBt=require("@playwright/test");var UBt=require("@playwright/test");function lre(i,n){return Reflect.get(i,n)}u(lre,"readDynamicProperty");var Rw=class i{constructor(n){this.context=n;this._pages={};this._pagesInProgress=new Map;this._testAssets=null;this.pageGuidMap=new WeakMap;this.instanceId=++i.instanceCounter,this.proxy=this.createContextProxy()}static{u(this,"ChecksumBrowserContext")}static{this.instanceCounter=0}static{this.guidCounter=0}static makeContext(n){return new i(n).proxy}_rawContext(){return this.context}setTestAssets(n){this._testAssets=n,this.setupPageListener()}getTestAssets(){return this._testAssets}cleanup(){this._pagesInProgress.clear(),this._pages={}}async newPage(){let n=await this.context.newPage();return this.makePage(n)}async makePage(n){if(n._isChecksumPage===!0)return n;if(n.isClosed())throw new Error("Cannot initialize closed page");let c=this.getPageGuid(n),s=this.getPageByGuid(c);if(s)return s;let r=this._pagesInProgress.get(c);if(r)return r;let f=this._createPageInstance(n);this._pagesInProgress.set(c,f);try{let p=await f;return this._pagesInProgress.delete(c),this.addPage(p),p}catch(p){throw this._pagesInProgress.delete(c),p}}addPage(n){let c=this.getPageGuid(n);this._pages[c]=n,n.once("close",()=>{this.removePage(c)})}removePage(n){this._pages[n]&&delete this._pages[n]}async _createPageInstance(n){if(n.isClosed())throw new Error("Cannot initialize page: Page has already been closed");if(this._testAssets)try{return await Sw.init(n,this.proxy,this._testAssets.testRunAnalytics,this._testAssets.monitorBridge,this._testAssets.variableStore,this._testAssets.testInfo,this._testAssets.checksumTestId,this._testAssets.test,this._testAssets.config,this._testAssets.isReplMode)}catch(c){throw new Error(`Failed to initialize RuntimePage: ${c instanceof Error?c.message:String(c)}. Test assets must be properly configured.`)}throw new Error("Cannot create page: Test assets not set. Use setTestAssets() before creating pages.")}createContextProxy(){return new Proxy(this,{get:u(function(c,s){return c.getContextMethod(s)},"get")})}setupPageListener(){this.context.on("page",async n=>{try{if(n.isClosed())return;await this.makePage(n)}catch(c){let s=c instanceof Error?c.message:String(c);if(s.includes("Page has already been closed")||s.includes("Target page, context or browser has been closed"))return;throw console.error("[ChecksumBrowserContext] Failed to initialize page created by application:",c),c}})}getPageGuid(n){let c=this.pageGuidMap.get(n);return c||(c=`page@checksumctx_${this.instanceId}_${++i.guidCounter}`,this.pageGuidMap.set(n,c)),c}getPageByGuid(n){return this._pages[n]}getAllPages(){return Object.values(this._pages)}getContextMethod(n){if(n in this){let s=lre(this,n);return typeof s=="function"?s.bind(this):s}let c=lre(this.context,n);return typeof c=="function"?c.bind(this.context):c}pages(){return this.getAllPages()}getPage(n){let c=this.getAllPages(),s=c[n];if(!s)throw new Error(`Page with index ${n} not found. Total pages: ${c.length}`);return s}};var jM={},fre=u((i,n,c={},s=!1)=>{let{environments:r}=n,f=r?.find(d=>d.default),p=i.extend({baseURL:f?.baseURL,bypassCSP:!0,permissions:u(async({},d,h)=>{await d(h.project.use.permissions)},"permissions"),proxy:u(async({proxy:d},h)=>{d?await h({...d,bypass:"127.0.0.1,localhost"}):await h(d)},"proxy"),browser:u(async({browser:d,launchOptions:h},o,a)=>{let e=u(()=>(a.project.use.playwrightExtra||[]).some(g=>g.constructor.name==="StealthPlugin"),"checkIfStealthPluginExists"),t=u(async()=>{let g=await(await new Bw({project:a.project}).buildChromiumWithPlugins()).launch(h);await o(g)},"launchBrowserWithStealthPlugin");Fe.useRemoteDebugging.enabled&&e()?await t():await o(d)},"browser"),launchOptions:u(async({launchOptions:d},h)=>{let o=d.args?[...d.args]:[],a=u(e=>{o.includes(e)||o.push(e)},"pushArg");c.useMockData&&a("--disable-web-security"),Fe.bypassProxyForLocalhost&&a("--proxy-bypass-list=localhost,127.0.0.1"),Fe.useRemoteDebugging.enabled&&a(`--remote-debugging-port=${Fe.useRemoteDebugging.port}`),await h({...d,args:o})},"launchOptions"),variableStore:u(async({},d)=>{let h=new Jf;await d(h)},"variableStore"),vs:u(async({variableStore:d},h)=>{await h(d)},"vs"),variablesStore:u(async({variableStore:d},h)=>{await h(d)},"variablesStore"),testRunAnalytics:u(async({},d,h)=>{let o=(()=>{try{if(process.env.CHECKSUM_TEST_SUITE_INFO)return JSON.parse(process.env.CHECKSUM_TEST_SUITE_INFO);throw new Error("Missing Checksum test suite info")}catch{return console.warn("\u26A0\uFE0F Warning: It seems like you ran the test suite directly via Playwright. This can lead to degraded functionality and unexpected issues. To ensure a fully supported and stable test run, please use: 'npx checksumai test'."),cre("playwright-run-version-unknown",(0,ure.randomUUID)())}})(),a=sre(h)??"",e=Xo.getTestRunInstance({...o,checksumTestId:a},process.env.CHECKSUM_ISOLATED_MODE==="true",h);await d(e)},"testRunAnalytics"),monitorBridge:[async({},d,h)=>{let o=new Pw(h);await d(o)},{scope:"worker"}],context:u(async({context:d,monitorBridge:h,variableStore:o,testRunAnalytics:a},e,t)=>{let l=Rw.makeContext(d);l.setTestAssets({testRunAnalytics:a,monitorBridge:h,variableStore:o,testInfo:t,checksumTestId:sre(t),test:p,config:n,isReplMode:s}),await e(l),l.cleanup()},"context"),page:u(async({page:d,context:h},o,a)=>{let e=await h.makePage(d);Object.defineProperty(e.constructor,"name",{value:"Page"}),await o(e),e&&typeof e.onTestComplete=="function"&&await e.onTestComplete(a.status==="passed"),e&&typeof e.shutdown=="function"&&await e.shutdown()},"page")});return{test:p,defineChecksumTest:u3e}},"createChecksumTestExtension"),u3e=u((i,n,c)=>{let r=(new Error().stack?.split(`
419
- `)??[]).find(f=>f.includes(".checksum.spec.ts"));if(!r)throw new Error("Could not locate test location. Make sure test is run from valid checksum test file");return jM[r]=n,i},"defineChecksumTest");function sre(i){let{file:n,line:c}=i,s=Object.keys(jM).filter(f=>f.trim().includes(n.trim()));if(!s.length)return;let r=4;for(let f=0;f<r;f++)for(let p of s){let d;try{d=parseInt(p.split(":").reverse()[1]??"")}catch{continue}if(d-f===c)return jM[p]}}u(sre,"getCurrentTestIdFromMapping");var mRt=require("@playwright/test");var cRt=require("@playwright/test");var f3e=["toMatchSnapshot"],d3e=["toBe","toBeCloseTo","toBeDefined","toBeFalsy","toBeGreaterThan","toBeGreaterThanOrEqual","toBeInstanceOf","toBeLessThan","toBeLessThanOrEqual","toBeNaN","toBeNull","toBeTruthy","toBeUndefined","toContain","toContainEqual","toEqual","toHaveLength","toHaveProperty","toMatch","toMatchObject","toStrictEqual","toThrow","toThrowError"],dre=[...d3e,...f3e];var Dw=class{constructor(n,c,s=!1,r=!1,f={}){this.page=n;this.soft=s;this.skipAutoRecovery=r;this.configuration=f;this.fallbackEnabled=!1;this.withChecksumAI=!1;this.withChecksumAIMatcher=u(()=>(this.withChecksumAI=!0,Promise.reject(new Error)),"withChecksumAIMatcher");this.setThought(c)}static{u(this,"ExpectCallProxyHandler")}setThought(n){n&&(this.checksumAIThought=this.page.addNewThought(n,"assertion"),this.useChecksumAIOptions=this.page.getRuntimeOptions().useChecksumAI,this.useChecksumAIOptions.assertions&&(this.page.setAIFallback(n,"assertion"),this.fallbackEnabled=!0))}get(n,c,s){if(typeof c!="string")return Reflect.get(n,c);if(c==="checksumAI")return f=>(this.setThought(f),s);if(c==="withChecksumAI"||typeof Reflect.get(n,c)=="function"){let f=c==="withChecksumAI"?this.withChecksumAIMatcher:Reflect.get(n,c);return(...p)=>dre.includes(c)?f.call(n,...p):this.checksumAIThought?this.executeMatcherWithinStep(f,n,...p):this.executeMatcher(f,n,...p)}let r=Reflect.get(n,c);return new Proxy(r,this)}findNestedErrors(n,c){n.error&&n.infectParentStepsWithError&&c.push(n.error);for(let s of n.steps)this.findNestedErrors(s,c)}async callMatcher(n,c,...s){this.beforeMatcherCall();let r=n.call(c,...s),f=r instanceof Promise?await r:r;if(this.step){let p=[];if(this.step.error?p.push(this.step.error):this.findNestedErrors(this.step,p),p.length)throw p[0]}return f}executeMatcherWithinStep(n,c,...s){let r=this.checksumAIThought;if(!r)throw new Error("ExpectCallProxyHandler: checksumAIThought is not set");return this.page.step(r.thought,()=>this.callMatcher(n,c,...s).catch(this.onMatcherFailure.bind(this)),!1,{obtainStep:u(f=>this.step=f,"obtainStep")}).catch(f=>{if(!this.soft&&!(this.withChecksumAI&&f.message===sc))throw f}).finally(this.afterMatcherExecute.bind(this))}async executeMatcher(n,c,...s){try{return await this.callMatcher(n,c,...s)}catch(r){await this.onMatcherFailure(r);return}finally{this.afterMatcherExecute()}}beforeMatcherCall(){this.page.setExpectConfiguration(this.configuration)}afterMatcherExecute(){this.checksumAIThought=void 0,this.fallbackEnabled=!1,this.withChecksumAI=!1,this.page.resetFallbacks(),this.page.setExpectConfiguration(void 0)}shouldInitiateFallback(n){return!(!this.fallbackEnabled||Reflect.get(n,"matcherResult")?.name==="toHaveScreenshot"&&!this.useChecksumAIOptions?.visualComparison)}async onMatcherFailure(n){if(!this.shouldInitiateFallback(n))throw ye("[onMatcherFailure] fallback disabled, continuing with error."),this.page.testRunAnalytics.testRunAssertionExecutionFailure({failedThought:this.checksumAIThought?.thought??"",error:n.message,matcher:n.matcherResult?.name}),n;if(Bm()){if(ye("[onMatcherFailure] assertion failed inside a locator handler, skipping fallback"),this.soft)return;throw n}if(ye("[onMatcherFailure] initiating fallback sequence with thought:",this.checksumAIThought?.thought),this.skipAutoRecovery){if(this.soft)return;throw n}try{await this.page.initiateFallbackSequence({type:"assertion",error:n,withChecksumAI:this.withChecksumAI,testInfo:this.page.testInfo})}catch(c){if(this.soft)return;throw c}throw this.soft=!0,n}};var Nw=class i{constructor(n,c={}){this.page=n;this.configuration=c}static{u(this,"ExpectProxyHandler")}get(n,c){if(c==="setPage")return r=>{this.page=r};if(c==="extend")return(...r)=>{let f=n.extend(...r);return new Proxy(f,this)};if(c==="configure")return r=>{let f=n.configure(r);return new Proxy(f,new i(this.page,{...this.configuration,...r}))};if(c==="soft")return(...r)=>{let f=this.manipulateArgsAndExtractThought(r),p=n.soft(...r);return new Proxy(p,this.makeExpectCallProxyHandler(f,!0))};if(c==="poll")return(...r)=>{let f=this.manipulateArgsAndExtractThought(r),p=n.poll(...r);return new Proxy(p,this.makeExpectCallProxyHandler(f))};if(c==="skipAutoRecovery")return new Proxy(()=>{},{apply:u((f,p,d)=>{let h=this.manipulateArgsAndExtractThought(d),o=n.apply(p,d);return new Proxy(o,this.makeExpectCallProxyHandler(h,void 0,!0))},"apply"),get:u((f,p)=>{let d=new Proxy(n,new i(this.page,{...this.configuration,skipAutoRecovery:!0}));return Reflect.get(d,p)},"get")});let s=Reflect.get(n,c);return s instanceof Function?s.bind(n):s}apply(n,c,s){let r=this.manipulateArgsAndExtractThought(s),f=n.apply(c,s);return new Proxy(f,this.makeExpectCallProxyHandler(r))}makeExpectCallProxyHandler(n,c,s){if(!this.page)throw new Error("ExpectProxyHandler: page is not set");return new Dw(this.page,n,c===!0?!0:this.configuration.soft,s===!0?!0:this.configuration.skipAutoRecovery,this.configuration)}manipulateArgsAndExtractThought(n){let c,s=n[1];if(typeof s=="string")c=s,n[1]=void 0;else if(s!==null&&typeof s=="object"){let r=s;if(r.checksumAI===!1){r.checksumAI=void 0;return}r.checksumAI&&typeof r.checksumAI=="string"?(c=r.checksumAI,r.checksumAI=void 0):r.message&&(c=r.message,r.message=void 0)}return c}};var Lw=class i{constructor(n){this.expect=n;this.proxy=new Proxy(this.expect,new Nw)}static{u(this,"ChecksumExpect")}static init(n){return new i(n).proxy}};var pre=require("@playwright/test");function p3e(i,n=AI()){let{options:c,apiKey:s,environments:r,defaultEnvironmentName:f}=n,p=r?.find(g=>g.default);if(f&&(p=r?.find(g=>g.name===f)),!p)throw new Error("No default environment found. Please set the default field to true on one of the environments in the checksum.config.ts file.");if(!p.baseURL)throw new Error("A baseURL is required. Please set the baseURL field in the default environment in the checksum.config.ts file.");if(!p.users?.find(g=>g.default))throw new Error("A default user within the default environment is required. Please set one of the default environment users as default in the checksum.config.ts file.");if(!s)throw new Error("An API key is required. Please set the apiKey field in the checksum.config.ts file.");let h=process.env.CHECKSUM_REPL==="true",{test:o,defineChecksumTest:a}=fre(i??pre.test,n,c,h),e=Lw.init(o.expect),t=h3e();o._checksum={expect:e,checksumAI:t},h&&(o.beforeEach(async()=>{o.setTimeout(0)}),o.afterEach(async()=>{for(;;)await ct(1e3)}));let l=u(({name:g,userRole:A})=>{let{envName:y,role:v}=LM({...g!==void 0?{envName:g}:{},...A!==void 0?{role:A}:{}}),{environment:O,user:m}=QM(n,{...y!==void 0?{environment:y}:{},...v!==void 0?{role:v}:{}},!0),k=tre({config:n,throwIfEnvInfoInvalid:!0},{environmentName:O.name,userRole:m.role});return{environment:O,user:m,login:k}},"getEnvironment");return{test:o,expect:e,login:ds({config:n}),defineChecksumTest:a,getEnvironment:l,checksumAI:t}}u(p3e,"init");var HM=u(i=>new Proxy(i,{apply:u(function(c,s,r){let f={...c.options,...r[2]};return c.page.checksumAI(r[0],r[1],f)},"apply"),get:u(function(c,s){return s==="withDialog"?(c.options.withDialog=!0,HM(i)):s==="skipAutoRecovery"?(c.options.skipAutoRecovery=!0,HM(i)):c[s]},"get"),set:u(function(c,s,r){return s!=="page"?!1:(c[s]=r,!!r)},"set")}),"makeChecksumAIProxy"),h3e=u(()=>{let i=u(function(){},"func");return i.page=void 0,i.options={withDialog:!1,skipAutoRecovery:!1},HM(i)},"makeChecksumAI");0&&(module.exports={AutoRecoveryMode,RunMode,getChecksumConfig,getLogin,init});
419
+ `)??[]).find(f=>f.includes(".checksum.spec.ts"));if(!r)throw new Error("Could not locate test location. Make sure test is run from valid checksum test file");return jM[r]=n,i},"defineChecksumTest");function sre(i){let{file:n,line:c}=i,s=Object.keys(jM).filter(f=>f.trim().includes(n.trim()));if(!s.length)return;let r=4;for(let f=0;f<r;f++)for(let p of s){let d;try{d=parseInt(p.split(":").reverse()[1]??"")}catch{continue}if(d-f===c)return jM[p]}}u(sre,"getCurrentTestIdFromMapping");var mRt=require("@playwright/test");var cRt=require("@playwright/test");var f3e=["toMatchSnapshot"],d3e=["toBe","toBeCloseTo","toBeDefined","toBeFalsy","toBeGreaterThan","toBeGreaterThanOrEqual","toBeInstanceOf","toBeLessThan","toBeLessThanOrEqual","toBeNaN","toBeNull","toBeTruthy","toBeUndefined","toContain","toContainEqual","toEqual","toHaveLength","toHaveProperty","toMatch","toMatchObject","toStrictEqual","toThrow","toThrowError"],dre=[...d3e,...f3e];var Dw=class{constructor(n,c,s=!1,r=!1,f={}){this.page=n;this.soft=s;this.skipAutoRecovery=r;this.configuration=f;this.fallbackEnabled=!1;this.withChecksumAI=!1;this.withChecksumAIMatcher=u(()=>(this.withChecksumAI=!0,Promise.reject(new Error)),"withChecksumAIMatcher");this.setThought(c)}static{u(this,"ExpectCallProxyHandler")}setThought(n){n&&(this.checksumAIThought=this.page.addNewThought(n,"assertion"),this.useChecksumAIOptions=this.page.getRuntimeOptions().useChecksumAI,this.useChecksumAIOptions.assertions&&(this.page.setAIFallback(n,"assertion"),this.fallbackEnabled=!0))}get(n,c,s){if(typeof c!="string")return Reflect.get(n,c);if(c==="checksumAI")return f=>(this.setThought(f),s);if(c==="withChecksumAI"||typeof Reflect.get(n,c)=="function"){let f=c==="withChecksumAI"?this.withChecksumAIMatcher:Reflect.get(n,c);return(...p)=>dre.includes(c)?f.call(n,...p):this.checksumAIThought?this.executeMatcherWithinStep(f,n,...p):this.executeMatcher(f,n,...p)}let r=Reflect.get(n,c);return new Proxy(r,this)}findNestedErrors(n,c){n.error&&n.infectParentStepsWithError&&c.push(n.error);for(let s of n.steps)this.findNestedErrors(s,c)}async callMatcher(n,c,...s){this.beforeMatcherCall();let r=n.call(c,...s),f=r instanceof Promise?await r:r;if(this.step){let p=[];if(this.step.error?p.push(this.step.error):this.findNestedErrors(this.step,p),p.length)throw p[0]}return f}executeMatcherWithinStep(n,c,...s){let r=this.checksumAIThought;if(!r)throw new Error("ExpectCallProxyHandler: checksumAIThought is not set");return this.page.step(r.thought,()=>this.callMatcher(n,c,...s).catch(this.onMatcherFailure.bind(this)),!1,{obtainStep:u(f=>this.step=f,"obtainStep")}).catch(f=>{if(!this.soft&&!(this.withChecksumAI&&f.message===sc))throw f}).finally(this.afterMatcherExecute.bind(this))}async executeMatcher(n,c,...s){try{return await this.callMatcher(n,c,...s)}catch(r){await this.onMatcherFailure(r);return}finally{this.afterMatcherExecute()}}beforeMatcherCall(){this.page.setExpectConfiguration(this.configuration)}afterMatcherExecute(){this.checksumAIThought=void 0,this.fallbackEnabled=!1,this.withChecksumAI=!1,this.page.resetFallbacks(),this.page.setExpectConfiguration(void 0)}shouldInitiateFallback(n){return!(!this.fallbackEnabled||Reflect.get(n,"matcherResult")?.name==="toHaveScreenshot"&&!this.useChecksumAIOptions?.visualComparison)}async onMatcherFailure(n){if(!this.shouldInitiateFallback(n))throw ye("[onMatcherFailure] fallback disabled, continuing with error."),this.page.testRunAnalytics.testRunAssertionExecutionFailure({failedThought:this.checksumAIThought?.thought??"",error:n.message,matcher:n.matcherResult?.name}),n;if(Bm()){if(ye("[onMatcherFailure] assertion failed inside a locator handler, skipping fallback"),this.soft)return;throw n}if(ye("[onMatcherFailure] initiating fallback sequence with thought:",this.checksumAIThought?.thought),this.skipAutoRecovery){if(this.soft)return;throw n}try{await this.page.initiateFallbackSequence({type:"assertion",error:n,withChecksumAI:this.withChecksumAI,testInfo:this.page.testInfo})}catch(c){if(this.soft)return;throw c}throw this.soft=!0,n}};var Nw=class i{constructor(n,c={}){this.page=n;this.configuration=c}static{u(this,"ExpectProxyHandler")}get(n,c){if(c==="setPage")return r=>{this.page=r};if(c==="extend")return(...r)=>{let f=n.extend(...r);return new Proxy(f,this)};if(c==="configure")return r=>{let f=n.configure(r);return new Proxy(f,new i(this.page,{...this.configuration,...r}))};if(c==="soft")return(...r)=>{let f=this.manipulateArgsAndExtractThought(r),p=n.soft(...r);return new Proxy(p,this.makeExpectCallProxyHandler(f,!0))};if(c==="poll")return(...r)=>{let f=this.manipulateArgsAndExtractThought(r),p=n.poll(...r);return new Proxy(p,this.makeExpectCallProxyHandler(f))};if(c==="skipAutoRecovery")return new Proxy(()=>{},{apply:u((f,p,d)=>{let h=this.manipulateArgsAndExtractThought(d),o=n.apply(p,d);return new Proxy(o,this.makeExpectCallProxyHandler(h,void 0,!0))},"apply"),get:u((f,p)=>{let d=new Proxy(n,new i(this.page,{...this.configuration,skipAutoRecovery:!0}));return Reflect.get(d,p)},"get")});let s=Reflect.get(n,c);return s instanceof Function?s.bind(n):s}apply(n,c,s){let r=this.manipulateArgsAndExtractThought(s),f=n.apply(c,s);return new Proxy(f,this.makeExpectCallProxyHandler(r))}makeExpectCallProxyHandler(n,c,s){if(!this.page)throw new Error("ExpectProxyHandler: page is not set");return new Dw(this.page,n,c===!0?!0:this.configuration.soft,s===!0?!0:this.configuration.skipAutoRecovery,this.configuration)}manipulateArgsAndExtractThought(n){let c,s=n[1];if(typeof s=="string")c=s,n[1]=void 0;else if(s!==null&&typeof s=="object"){let r=s;if(r.checksumAI===!1){r.checksumAI=void 0;return}r.checksumAI&&typeof r.checksumAI=="string"?(c=r.checksumAI,r.checksumAI=void 0):r.message&&(c=r.message,r.message=void 0)}return c}};var Lw=class i{constructor(n){this.expect=n;let c=new Proxy(this.expect,new Nw);this.proxy=c}static{u(this,"ChecksumExpect")}static init(n){return new i(n).proxy}};var pre=require("@playwright/test");function p3e(i,n=AI()){let{options:c,apiKey:s,environments:r,defaultEnvironmentName:f}=n,p=r?.find(g=>g.default);if(f&&(p=r?.find(g=>g.name===f)),!p)throw new Error("No default environment found. Please set the default field to true on one of the environments in the checksum.config.ts file.");if(!p.baseURL)throw new Error("A baseURL is required. Please set the baseURL field in the default environment in the checksum.config.ts file.");if(!p.users?.find(g=>g.default))throw new Error("A default user within the default environment is required. Please set one of the default environment users as default in the checksum.config.ts file.");if(!s)throw new Error("An API key is required. Please set the apiKey field in the checksum.config.ts file.");let h=process.env.CHECKSUM_REPL==="true",{test:o,defineChecksumTest:a}=fre(i??pre.test,n,c,h),e=Lw.init(o.expect),t=h3e();o._checksum={expect:e,checksumAI:t},h&&(o.beforeEach(async()=>{o.setTimeout(0)}),o.afterEach(async()=>{for(;;)await ct(1e3)}));let l=u(({name:g,userRole:A})=>{let{envName:y,role:v}=LM({...g!==void 0?{envName:g}:{},...A!==void 0?{role:A}:{}}),{environment:O,user:m}=QM(n,{...y!==void 0?{environment:y}:{},...v!==void 0?{role:v}:{}},!0),k=tre({config:n,throwIfEnvInfoInvalid:!0},{environmentName:O.name,userRole:m.role});return{environment:O,user:m,login:k}},"getEnvironment");return{test:o,expect:e,login:ds({config:n}),defineChecksumTest:a,getEnvironment:l,checksumAI:t}}u(p3e,"init");var HM=u(i=>new Proxy(i,{apply:u(function(c,s,r){let f={...c.options,...r[2]};return c.page.checksumAI(r[0],r[1],f)},"apply"),get:u(function(c,s){return s==="withDialog"?(c.options.withDialog=!0,HM(i)):s==="skipAutoRecovery"?(c.options.skipAutoRecovery=!0,HM(i)):c[s]},"get"),set:u(function(c,s,r){return s!=="page"?!1:(c[s]=r,!!r)},"set")}),"makeChecksumAIProxy"),h3e=u(()=>{let i=u(function(){},"func");return i.page=void 0,i.options={withDialog:!1,skipAutoRecovery:!1},HM(i)},"makeChecksumAI");0&&(module.exports={AutoRecoveryMode,RunMode,getChecksumConfig,getLogin,init});
420
420
  /*! Bundled license information:
421
421
 
422
422
  playwright-extra/dist/index.cjs.js:
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Checksum.ai test runtime",
4
4
  "main": "index.js",
5
5
  "dependencies": {
6
- "@playwright/test": "1.60.0",
6
+ "@playwright/test": "1.62.1",
7
7
  "dotenv": "17.4.2",
8
8
  "jsdom": "30.0.1",
9
9
  "playwright-extra": "4.3.6",
@@ -45,5 +45,5 @@
45
45
  "url": "https://github.com/checksum-ai/checksum-ai-monorepo/issues"
46
46
  },
47
47
  "homepage": "https://github.com/checksum-ai/checksum-ai-monorepo/tree/main/packages/runtime#readme",
48
- "version": "4.16.2"
48
+ "version": "4.16.3"
49
49
  }
package/scripts/patch.js CHANGED
@@ -11,8 +11,6 @@ const availablePatchVersions = fs
11
11
  .map((patchFile) => path.basename(patchFile, ".js"))
12
12
  .sort();
13
13
 
14
- // console.log("patchVersions", availablePatchVersions);
15
-
16
14
  function findSuitablePatchVersion(version) {
17
15
  let suitablePatchVersion = availablePatchVersions[0];
18
16
  for (const patchVersion of availablePatchVersions) {
@@ -39,20 +37,12 @@ for (const projectPath of projectPaths) {
39
37
  const packageJSON = require(absolutePathToPackageJSON);
40
38
  const playwrightVersion = packageJSON.version;
41
39
  const patchVersion = findSuitablePatchVersion(playwrightVersion);
42
- // console.log(
43
- // "Found installed version",
44
- // playwrightVersion,
45
- // "and will use patch for version",
46
- // patchVersion
47
- // );
48
40
  const patchPath = resolve(
49
41
  join(getPlaywrightPatchesDirectory(), `${patchVersion}.js`)
50
42
  );
51
43
  require(patchPath)(projectPath);
52
- } else {
53
- // console.warn("Project path not found", projectPath);
54
44
  }
55
45
  } catch (e) {
56
- // ignore for now although we might want to notify users that patching wasn't successful
46
+ // Patching is best-effort: a failure here must not block the install.
57
47
  }
58
48
  }
@@ -1,52 +1,41 @@
1
1
  const fs = require("fs");
2
2
  const { join } = require("path");
3
3
 
4
- // Args
5
4
  const on = process.argv[2] !== "off";
6
5
 
7
- // -------- [Modifiers] -------- //
8
-
9
- // Amends the file with the given entry point text and append text
10
- // When "on" is true, the append text is added to the entry point,
11
- // otherwise the append text is completely removed from the file
6
+ // When `on`, appendText is spliced in after entryPointText; when off, it is
7
+ // stripped back out. Leaves no marker, so an amend cannot be detected later.
12
8
  function amend(filePath, entryPointText, appendText) {
13
9
  const data = fs.readFileSync(filePath, "utf8");
14
10
  if (!data.includes(entryPointText)) {
15
11
  throw new Error("Entry point not found!", entryPointText);
16
12
  }
17
- // Ignore if the append text is already present
18
13
  if (on && data.includes(appendText)) {
19
14
  return;
20
15
  }
21
- // Add or clear according to on state
22
16
  const result = on
23
17
  ? data.replace(entryPointText, entryPointText + appendText)
24
18
  : data.replace(appendText, "");
25
19
 
26
- // Write
27
20
  fs.writeFileSync(filePath, result, "utf8");
28
21
  }
29
22
 
30
- // Replaces content.
31
- // When "on" is true, the new content is written to the file replacing the original content,
32
- // otherwise the original content is restored.
23
+ // When `on`, newContent replaces originalContent; when off, the original is
24
+ // restored. The `/* checksumai */` prefix is the marker that makes the off
25
+ // direction findable.
33
26
  function replaceContent(filePath, originalContent, newContent) {
34
- // Read the file content
35
27
  const fileContent = fs.readFileSync(filePath, "utf8");
36
28
 
37
- // add a marker for newContent that can be later recognized for "off" state
38
29
  newContent = `/* checksumai */ ${newContent}`;
39
30
 
40
31
  if (on && fileContent.includes(newContent)) {
41
32
  return;
42
33
  }
43
34
 
44
- // Join the lines back into a single string
45
35
  const updatedContent = on
46
36
  ? fileContent.replace(originalContent, newContent)
47
37
  : fileContent.replace(newContent, originalContent);
48
38
 
49
- // Write the modified content back to the file
50
39
  fs.writeFileSync(filePath, updatedContent, "utf8");
51
40
  }
52
41
 
@@ -58,9 +47,6 @@ function doesFileExist(filePath) {
58
47
  return true;
59
48
  }
60
49
 
61
- // -------- [Modifications] -------- //
62
-
63
- // Remove conditions for injecting Playwright scripts
64
50
  function alwaysInjectScripts(projectRoot) {
65
51
  const file = join(
66
52
  projectRoot,
@@ -78,7 +64,6 @@ function alwaysInjectScripts(projectRoot) {
78
64
  replaceContent(file, originalContent, newContent);
79
65
  }
80
66
 
81
- // Add implementation for generateSelectorAndLocator and inject to Playwright console API
82
67
  function addGenerateSelectorAndLocator(projectRoot) {
83
68
  const file = join(
84
69
  projectRoot,
@@ -99,8 +84,6 @@ function addGenerateSelectorAndLocator(projectRoot) {
99
84
  amend(file, entryPointText2, appendText2);
100
85
  }
101
86
 
102
- // -------- [Runtime modifications] -------- //
103
-
104
87
  function expect(projectRoot) {
105
88
  const file = join(
106
89
  projectRoot,
@@ -216,12 +199,18 @@ function testType(projectRoot) {
216
199
  }
217
200
 
218
201
  function indexContent(projectRoot) {
219
- const file = join(projectRoot, "node_modules", "playwright", "lib", "index.js")
202
+ const file = join(
203
+ projectRoot,
204
+ "node_modules",
205
+ "playwright",
206
+ "lib",
207
+ "index.js"
208
+ );
220
209
  if (!doesFileExist) {
221
210
  return;
222
211
  }
223
212
  let originalContent, newContent;
224
- originalContent = `const browser = await playwright[browserName].launch();`
213
+ originalContent = `const browser = await playwright[browserName].launch();`;
225
214
  newContent = `
226
215
  let browser = playwright[browserName];
227
216
  try {
@@ -250,8 +239,8 @@ function indexContent(projectRoot) {
250
239
  );
251
240
  }
252
241
  browser = await browser.launch();
253
- `
254
- replaceContent(file, originalContent, newContent)
242
+ `;
243
+ replaceContent(file, originalContent, newContent);
255
244
  }
256
245
 
257
246
  function channelOwner(projectRoot) {
@@ -283,8 +272,6 @@ function channelOwner(projectRoot) {
283
272
  amend(file, entryPointText, appendText);
284
273
  }
285
274
 
286
- // -------- [Run] -------- //
287
-
288
275
  const isRuntime = true || process.env.RUNTIME === "true";
289
276
 
290
277
  function run(projectPath) {
@@ -299,11 +286,9 @@ function run(projectPath) {
299
286
  channelOwner(projectPath);
300
287
  indexContent(projectPath);
301
288
  }
302
- } else {
303
- // console.warn("Project path not found", projectPath);
304
289
  }
305
290
  } catch (e) {
306
- // ignore
291
+ // Patching is best-effort: a failure here must not block the install.
307
292
  }
308
293
  }
309
294
 
@@ -1,52 +1,41 @@
1
1
  const fs = require("fs");
2
2
  const { join } = require("path");
3
3
 
4
- // Args
5
4
  const on = process.argv[2] !== "off";
6
5
 
7
- // -------- [Modifiers] -------- //
8
-
9
- // Amends the file with the given entry point text and append text
10
- // When "on" is true, the append text is added to the entry point,
11
- // otherwise the append text is completely removed from the file
6
+ // When `on`, appendText is spliced in after entryPointText; when off, it is
7
+ // stripped back out. Leaves no marker, so an amend cannot be detected later.
12
8
  function amend(filePath, entryPointText, appendText) {
13
9
  const data = fs.readFileSync(filePath, "utf8");
14
10
  if (!data.includes(entryPointText)) {
15
11
  throw new Error("Entry point not found!", entryPointText);
16
12
  }
17
- // Ignore if the append text is already present
18
13
  if (on && data.includes(appendText)) {
19
14
  return;
20
15
  }
21
- // Add or clear according to on state
22
16
  const result = on
23
17
  ? data.replace(entryPointText, entryPointText + appendText)
24
18
  : data.replace(appendText, "");
25
19
 
26
- // Write
27
20
  fs.writeFileSync(filePath, result, "utf8");
28
21
  }
29
22
 
30
- // Replaces content.
31
- // When "on" is true, the new content is written to the file replacing the original content,
32
- // otherwise the original content is restored.
23
+ // When `on`, newContent replaces originalContent; when off, the original is
24
+ // restored. The `/* checksumai */` prefix is the marker that makes the off
25
+ // direction findable.
33
26
  function replaceContent(filePath, originalContent, newContent) {
34
- // Read the file content
35
27
  const fileContent = fs.readFileSync(filePath, "utf8");
36
28
 
37
- // add a marker for newContent that can be later recognized for "off" state
38
29
  newContent = `/* checksumai */ ${newContent}`;
39
30
 
40
31
  if (on && fileContent.includes(newContent)) {
41
32
  return;
42
33
  }
43
34
 
44
- // Join the lines back into a single string
45
35
  const updatedContent = on
46
36
  ? fileContent.replace(originalContent, newContent)
47
37
  : fileContent.replace(newContent, originalContent);
48
38
 
49
- // Write the modified content back to the file
50
39
  fs.writeFileSync(filePath, updatedContent, "utf8");
51
40
  }
52
41
 
@@ -58,9 +47,6 @@ function doesFileExist(filePath) {
58
47
  return true;
59
48
  }
60
49
 
61
- // -------- [Modifications] -------- //
62
-
63
- // Remove conditions for injecting Playwright scripts
64
50
  function alwaysInjectScripts(projectRoot) {
65
51
  const file = join(
66
52
  projectRoot,
@@ -78,7 +64,6 @@ function alwaysInjectScripts(projectRoot) {
78
64
  replaceContent(file, originalContent, newContent);
79
65
  }
80
66
 
81
- // Add implementation for generateSelectorAndLocator and inject to Playwright console API
82
67
  function addGenerateSelectorAndLocator(projectRoot) {
83
68
  const file = join(
84
69
  projectRoot,
@@ -99,8 +84,6 @@ function addGenerateSelectorAndLocator(projectRoot) {
99
84
  amend(file, entryPointText2, appendText2);
100
85
  }
101
86
 
102
- // -------- [Runtime modifications] -------- //
103
-
104
87
  function expect(projectRoot) {
105
88
  const file = join(
106
89
  projectRoot,
@@ -110,30 +93,6 @@ function expect(projectRoot) {
110
93
  return;
111
94
  }
112
95
  let originalContent, newContent;
113
-
114
- // originalContent = `return (...args) => {
115
- // const testInfo = (0, _globals.currentTestInfo)();`;
116
- // newContent = `return (...args) => {
117
- // let noSoft = false;
118
- // if (args.find(arg=>arg==='no-soft')){
119
- // noSoft = true;
120
- // args.pop();
121
- // }
122
- // const testInfo = (0, _globals.currentTestInfo)();`;
123
- // replaceContent(file, originalContent, newContent);
124
-
125
- // originalContent = `step.complete({
126
- // error
127
- // })`;
128
- // newContent = `step.complete({
129
- // error,
130
- // noSoft
131
- // })`;
132
- // replaceContent(file, originalContent, newContent);
133
-
134
- // originalContent = `if (this._info.isSoft) testInfo._failWithError(error);else throw error;`;
135
- // newContent = `if (this._info.isSoft && !noSoft) testInfo._failWithError(error);else throw error;`;
136
- // replaceContent(file, originalContent, newContent);
137
96
  }
138
97
 
139
98
  function testInfo(projectRoot) {
@@ -147,10 +106,6 @@ function testInfo(projectRoot) {
147
106
  let originalContent, newContent;
148
107
  let entryPointText, appendText;
149
108
 
150
- // originalContent = `const filteredStack = (0, _util.filteredStackTrace)((0, _utils.captureRawStack)());`;
151
- // newContent = `const filteredStack = (0, _util.filteredStackTrace)((0, _utils.captureRawStack)().filter(s=>!s.includes('@checksum-ai/runtime')));`;
152
- // replaceContent(file, originalContent, newContent);
153
-
154
109
  entryPointText = `data.location = data.location || filteredStack[0];`;
155
110
  appendText = `\nif (this._checksumInternal) {
156
111
  data.location = undefined;
@@ -256,10 +211,6 @@ function channelOwner(projectRoot) {
256
211
  }`;
257
212
  amend(file, entryPointText, appendText);
258
213
 
259
- // originalContent = `const stack = (0, _stackTrace.captureRawStack)();`;
260
- // newContent = `const stack = (0, _stackTrace.captureRawStack)().filter(s=>!s.includes('@checksum-ai/runtime'));`;
261
- // replaceContent(file, originalContent, newContent);
262
-
263
214
  entryPointText = `let apiName = stackTrace.apiName;`;
264
215
  appendText = `\nif (!isInternal && this._checksumTitle){
265
216
  apiName = this._checksumTitle;
@@ -289,8 +240,6 @@ function stackTrace(projectRoot) {
289
240
  replaceContent(file, originalContent, newContent);
290
241
  }
291
242
 
292
- // -------- [Run] -------- //
293
-
294
243
  const isRuntime = true || process.env.RUNTIME === "true";
295
244
 
296
245
  function run(projectPath) {
@@ -306,11 +255,9 @@ function run(projectPath) {
306
255
  stackTrace(projectPath);
307
256
  indexContent(projectPath);
308
257
  }
309
- } else {
310
- // console.warn("Project path not found", projectPath);
311
258
  }
312
259
  } catch (e) {
313
- // ignore
260
+ // Patching is best-effort: a failure here must not block the install.
314
261
  }
315
262
  }
316
263
 
@@ -1,52 +1,41 @@
1
1
  const fs = require("fs");
2
2
  const { join } = require("path");
3
3
 
4
- // Args
5
4
  const on = process.argv[2] !== "off";
6
5
 
7
- // -------- [Modifiers] -------- //
8
-
9
- // Amends the file with the given entry point text and append text
10
- // When "on" is true, the append text is added to the entry point,
11
- // otherwise the append text is completely removed from the file
6
+ // When `on`, appendText is spliced in after entryPointText; when off, it is
7
+ // stripped back out. Leaves no marker, so an amend cannot be detected later.
12
8
  function amend(filePath, entryPointText, appendText) {
13
9
  const data = fs.readFileSync(filePath, "utf8");
14
10
  if (!data.includes(entryPointText)) {
15
11
  throw new Error("Entry point not found!", entryPointText);
16
12
  }
17
- // Ignore if the append text is already present
18
13
  if (on && data.includes(appendText)) {
19
14
  return;
20
15
  }
21
- // Add or clear according to on state
22
16
  const result = on
23
17
  ? data.replace(entryPointText, entryPointText + appendText)
24
18
  : data.replace(appendText, "");
25
19
 
26
- // Write
27
20
  fs.writeFileSync(filePath, result, "utf8");
28
21
  }
29
22
 
30
- // Replaces content.
31
- // When "on" is true, the new content is written to the file replacing the original content,
32
- // otherwise the original content is restored.
23
+ // When `on`, newContent replaces originalContent; when off, the original is
24
+ // restored. The `/* checksumai */` prefix is the marker that makes the off
25
+ // direction findable.
33
26
  function replaceContent(filePath, originalContent, newContent) {
34
- // Read the file content
35
27
  const fileContent = fs.readFileSync(filePath, "utf8");
36
28
 
37
- // add a marker for newContent that can be later recognized for "off" state
38
29
  newContent = `/* checksumai */ ${newContent}`;
39
30
 
40
31
  if (on && fileContent.includes(newContent)) {
41
32
  return;
42
33
  }
43
34
 
44
- // Join the lines back into a single string
45
35
  const updatedContent = on
46
36
  ? fileContent.replace(originalContent, newContent)
47
37
  : fileContent.replace(newContent, originalContent);
48
38
 
49
- // Write the modified content back to the file
50
39
  fs.writeFileSync(filePath, updatedContent, "utf8");
51
40
  }
52
41
 
@@ -58,9 +47,6 @@ function doesFileExist(filePath) {
58
47
  return true;
59
48
  }
60
49
 
61
- // -------- [Modifications] -------- //
62
-
63
- // Remove conditions for injecting Playwright scripts
64
50
  function alwaysInjectScripts(projectRoot) {
65
51
  const file = join(
66
52
  projectRoot,
@@ -71,7 +57,6 @@ function alwaysInjectScripts(projectRoot) {
71
57
  }
72
58
  const originalContent =
73
59
  "if ((0, _debug.debugMode)() === 'console') await this.extendInjectedScript(consoleApiSource.source);";
74
- // "if ((0, _utils.debugMode)() === 'console') await this.extendInjectedScript(consoleApiSource.source);";
75
60
 
76
61
  const newContent =
77
62
  "await this.extendInjectedScript(consoleApiSource.source);";
@@ -79,7 +64,6 @@ function alwaysInjectScripts(projectRoot) {
79
64
  replaceContent(file, originalContent, newContent);
80
65
  }
81
66
 
82
- // Add implementation for generateSelectorAndLocator and inject to Playwright console API
83
67
  function addGenerateSelectorAndLocator(projectRoot) {
84
68
  const file = join(
85
69
  projectRoot,
@@ -100,8 +84,6 @@ function addGenerateSelectorAndLocator(projectRoot) {
100
84
  amend(file, entryPointText2, appendText2);
101
85
  }
102
86
 
103
- // -------- [Runtime modifications] -------- //
104
-
105
87
  function expect(projectRoot) {
106
88
  const file = join(
107
89
  projectRoot,
@@ -111,30 +93,6 @@ function expect(projectRoot) {
111
93
  return;
112
94
  }
113
95
  let originalContent, newContent;
114
-
115
- // originalContent = `return (...args) => {
116
- // const testInfo = (0, _globals.currentTestInfo)();`;
117
- // newContent = `return (...args) => {
118
- // let noSoft = false;
119
- // if (args.find(arg=>arg==='no-soft')){
120
- // noSoft = true;
121
- // args.pop();
122
- // }
123
- // const testInfo = (0, _globals.currentTestInfo)();`;
124
- // replaceContent(file, originalContent, newContent);
125
-
126
- // originalContent = `step.complete({
127
- // error
128
- // })`;
129
- // newContent = `step.complete({
130
- // error,
131
- // noSoft
132
- // })`;
133
- // replaceContent(file, originalContent, newContent);
134
-
135
- // originalContent = `if (this._info.isSoft) testInfo._failWithError(error);else throw error;`;
136
- // newContent = `if (this._info.isSoft && !noSoft) testInfo._failWithError(error);else throw error;`;
137
- // replaceContent(file, originalContent, newContent);
138
96
  }
139
97
 
140
98
  function testInfo(projectRoot) {
@@ -148,10 +106,6 @@ function testInfo(projectRoot) {
148
106
  let originalContent, newContent;
149
107
  let entryPointText, appendText;
150
108
 
151
- // originalContent = `const filteredStack = (0, _util.filteredStackTrace)((0, _utils.captureRawStack)());`;
152
- // newContent = `const filteredStack = (0, _util.filteredStackTrace)((0, _utils.captureRawStack)().filter(s=>!s.includes('@checksum-ai/runtime')));`;
153
- // replaceContent(file, originalContent, newContent);
154
-
155
109
  entryPointText = `data.location = data.location || filteredStack[0];`;
156
110
  appendText = `\nif (this._checksumInternal) {
157
111
  data.location = undefined;
@@ -189,7 +143,6 @@ function testType(projectRoot) {
189
143
  }
190
144
 
191
145
  entryPointText = `return await (0, _utils.currentZone)().with('stepZone', step).run(async () => {`;
192
- // entryPointText = `return await _utils.zones.run('stepZone', step, async () => {`;
193
146
  appendText = `\nif (options.obtainStep){
194
147
  options.obtainStep(step);
195
148
  }`;
@@ -253,18 +206,12 @@ function channelOwner(projectRoot) {
253
206
  let entryPointText, appendText;
254
207
 
255
208
  entryPointText = `async _wrapApiCall(func, isInternal) {`;
256
- // entryPointText = `async _wrapApiCall(func, isInternal = false) {`;
257
209
 
258
210
  appendText = `\nif (this._checksumInternal){
259
211
  isInternal = true;
260
212
  }`;
261
213
  amend(file, entryPointText, appendText);
262
214
 
263
- // originalContent = `const stack = (0, _stackTrace.captureRawStack)();`;
264
- // newContent = `const stack = (0, _stackTrace.captureRawStack)().filter(s=>!s.includes('@checksum-ai/runtime'));`;
265
- // replaceContent(file, originalContent, newContent);
266
-
267
- // entryPointText = `let apiName = stackTrace.apiName;`;
268
215
  entryPointText = `const apiZone = {
269
216
  apiName: stackTrace.apiName,
270
217
  frames: stackTrace.frames,
@@ -287,18 +234,11 @@ function channelOwner(projectRoot) {
287
234
  apiZone.apiName = apiZone.apiName.replace('proxy', 'page');
288
235
  }`;
289
236
  amend(file, entryPointText, appendText);
290
-
291
- // entryPointText = `if (isInternal) apiName = undefined;`;
292
- // appendText = `\nif (apiName && apiName.startsWith('proxy')) {
293
- // apiName = apiName.replace('proxy', 'page');
294
- // }`;
295
- // amend(file, entryPointText, appendText);
296
237
  }
297
238
 
298
239
  function stackTrace(projectRoot) {
299
240
  const file = join(
300
241
  projectRoot,
301
- // "node_modules/playwright-core/lib/utils/stackTrace.js"
302
242
  "node_modules/playwright-core/lib/utils/isomorphic/stackTrace.js"
303
243
  );
304
244
  if (!doesFileExist(file)) {
@@ -311,8 +251,6 @@ function stackTrace(projectRoot) {
311
251
  replaceContent(file, originalContent, newContent);
312
252
  }
313
253
 
314
- // -------- [Run] -------- //
315
-
316
254
  const isRuntime = true || process.env.RUNTIME === "true";
317
255
 
318
256
  function run(projectPath) {
@@ -328,11 +266,9 @@ function run(projectPath) {
328
266
  stackTrace(projectPath);
329
267
  indexContent(projectPath);
330
268
  }
331
- } else {
332
- // console.warn("Project path not found", projectPath);
333
269
  }
334
270
  } catch (e) {
335
- // ignore
271
+ // Patching is best-effort: a failure here must not block the install.
336
272
  }
337
273
  }
338
274