@checksum-ai/runtime 1.0.32 → 1.0.34
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/checksum-root/playwright.config.ts +1 -1
- package/cli.js +1 -1
- package/helpers.ts +22 -0
- package/index.d.ts +5 -0
- package/index.js +2 -2
- package/package.json +1 -1
- package/test-run-monitor.js +7 -7
|
@@ -37,7 +37,7 @@ export default defineConfig({
|
|
|
37
37
|
locale: "en-US",
|
|
38
38
|
timezoneId: "America/Los_Angeles",
|
|
39
39
|
permissions: ["clipboard-read"],
|
|
40
|
-
actionTimeout:
|
|
40
|
+
actionTimeout: 1000 * 5, // set action timeout for 5 seconds. In case an aciton times out, checksum's selectors will kick in.
|
|
41
41
|
},
|
|
42
42
|
expect: {
|
|
43
43
|
toHaveScreenshot: { maxDiffPixelRatio: 0.05, maxDiffPixels: 200 },
|
package/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ show-report [options] [report] show HTML report
|
|
|
10
10
|
`);break;case"test":try{let e="npx playwright test --help",s=(await this.getCmdOutput(e)).replace(/npx playwright/g,"yarn checksum").split(`
|
|
11
11
|
`);s.splice(5,0," --checksum-config=<config> Checksum configuration in JSON format").join(`
|
|
12
12
|
`),console.log(s.join(`
|
|
13
|
-
`))}catch(e){console.log("Error",e.message)}break;case"show-report":try{let e="npx playwright show-report --help",s=(await this.getCmdOutput(e)).replace(/npx playwright/g,"yarn checksum");console.log(s)}catch(e){console.log("Error",e.message)}break}}async showReport(t){let e=`npx playwright show-report ${t.join(" ")}`;try{await this.execCmd(e)}catch(s){console.log("Error showing report",s.message)}}async test(t){if(this.processChecksumArguments(t),this.setChecksumConfig(),!await this.getSession())return;let e;try{e=await this.guardReturn(this.startTestRunMonitor(this.testSession),1e4,"test run monitor timeout")}catch{console.log("Error starting test run monitor. Test results will not be available on checksum.")}this.buildVolatileConfig();let s=`${e?`CHECKSUM_UPLOAD_AGENT_PORT=${e} `:""}${this.config.options.hostReports?" PW_TEST_HTML_REPORT_OPEN=never":""} npx playwright test --config ${this.getPlaywrightConfigFile()} ${t.join(" ")}`;await this.patchPlaywright();try{await this.execCmd(s),console.log("Tests execution finished")}catch(o){this.didFail=!0,console.log("Error during test",o.message)}finally{this.sendReportUploadRequest(),await this.patchPlaywright(!0),this.completeIndicators.tests=!0,await this.handleCompleteMessage()}}sendReportUploadRequest(){this.isolationMode||console.log("Waiting for test files to upload to Checksum..");let t=this.getPlaywrightReportPath();if(!(0,i.existsSync)(t)){console.log(`Could not find report file at ${t}`);return}this.testRunMonitorProcess.stdin.write(`cli:report=${t}`)}async patchPlaywright(t=!1){let e=`bash ${(0,r.join)(__dirname,"scripts/patch.sh")}${t?" off":""}`;try{await this.execCmd(e)}catch(s){console.log("Error patching playwright",s.message)}}getPlaywrightReportPath(){var o,a;let t=(0,r.join)(process.cwd(),"playwright-report"),e=require(this.getPlaywrightConfigFile()),{reporter:s}=e;return s instanceof Array&&s.length>1&&((o=s[1])!=null&&o.outputFolder)&&(t=(a=s[1])==null?void 0:a.outputFolder),process.env.PLAYWRIGHT_HTML_REPORT&&(t=process.env.PLAYWRIGHT_HTML_REPORT),(0,r.join)(t,"index.html")}getPlaywrightConfigFile(){return(0,r.join)(this.getRootDirPath(),"playwright.config.ts")}startTestRunMonitor(t){return new Promise(e=>{console.log("Starting test run monitor"),this.testRunMonitorProcess=l.spawn("node",[this.TEST_RUN_MONITOR_PATH,JSON.stringify({sessionId:t,checksumApiURL:this.CHECKSUM_API_URL,apiKey:this.config.apiKey}),...this.isolationMode?["isolated"]:[]]),this.testRunMonitorProcess.stdout.on("data",s=>{var p,d;let o=s.toString().trim();if(!o.startsWith("monitor")){(d=(p=this.config)==null?void 0:p.options)!=null&&d.printLogs&&console.log(`Message from test run monitor: ${o}`);return}let[a,c]=o.substring(o.indexOf(":")+1).split("=");a==="port"?e(c):this.handleTestRunMonitorMessage(a,c)}),this.testRunMonitorProcess.on("exit",(s,o)=>{console.log(`test run monitor process exited with code ${s} and signal ${o}`)}),this.testRunMonitorProcess.on("error",s=>{console.error(`Error starting test run monitor: ${s.message}`)})})}async handleTestRunMonitorMessage(t,e){switch(t){case"complete":this.isolationMode||console.log("Test
|
|
13
|
+
`))}catch(e){console.log("Error",e.message)}break;case"show-report":try{let e="npx playwright show-report --help",s=(await this.getCmdOutput(e)).replace(/npx playwright/g,"yarn checksum");console.log(s)}catch(e){console.log("Error",e.message)}break}}async showReport(t){let e=`npx playwright show-report ${t.join(" ")}`;try{await this.execCmd(e)}catch(s){console.log("Error showing report",s.message)}}async test(t){if(this.processChecksumArguments(t),this.setChecksumConfig(),!await this.getSession())return;let e;try{e=await this.guardReturn(this.startTestRunMonitor(this.testSession),1e4,"test run monitor timeout")}catch{console.log("Error starting test run monitor. Test results will not be available on checksum.")}this.buildVolatileConfig();let s=`${e?`CHECKSUM_UPLOAD_AGENT_PORT=${e} `:""}${this.config.options.hostReports?" PW_TEST_HTML_REPORT_OPEN=never":""} npx playwright test --config ${this.getPlaywrightConfigFile()} ${t.join(" ")}`;await this.patchPlaywright();try{await this.execCmd(s),console.log("Tests execution finished")}catch(o){this.didFail=!0,console.log("Error during test",o.message)}finally{this.sendReportUploadRequest(),await this.patchPlaywright(!0),this.completeIndicators.tests=!0,await this.handleCompleteMessage()}}sendReportUploadRequest(){this.isolationMode||console.log("Waiting for test files to upload to Checksum..");let t=this.getPlaywrightReportPath();if(!(0,i.existsSync)(t)){console.log(`Could not find report file at ${t}`);return}this.testRunMonitorProcess.stdin.write(`cli:report=${t}`)}async patchPlaywright(t=!1){let e=`bash ${(0,r.join)(__dirname,"scripts/patch.sh")}${t?" off":""}`;try{await this.execCmd(e)}catch(s){console.log("Error patching playwright",s.message)}}getPlaywrightReportPath(){var o,a;let t=(0,r.join)(process.cwd(),"playwright-report"),e=require(this.getPlaywrightConfigFile()),{reporter:s}=e;return s instanceof Array&&s.length>1&&((o=s[1])!=null&&o.outputFolder)&&(t=(a=s[1])==null?void 0:a.outputFolder),process.env.PLAYWRIGHT_HTML_REPORT&&(t=process.env.PLAYWRIGHT_HTML_REPORT),(0,r.join)(t,"index.html")}getPlaywrightConfigFile(){return(0,r.join)(this.getRootDirPath(),"playwright.config.ts")}startTestRunMonitor(t){return new Promise(e=>{console.log("Starting test run monitor"),this.testRunMonitorProcess=l.spawn("node",[this.TEST_RUN_MONITOR_PATH,JSON.stringify({sessionId:t,checksumApiURL:this.CHECKSUM_API_URL,apiKey:this.config.apiKey}),...this.isolationMode?["isolated"]:[]]),this.testRunMonitorProcess.stdout.on("data",s=>{var p,d;let o=s.toString().trim();if(!o.startsWith("monitor")){(d=(p=this.config)==null?void 0:p.options)!=null&&d.printLogs&&console.log(`Message from test run monitor: ${o}`);return}let[a,c]=o.substring(o.indexOf(":")+1).split("=");a==="port"?e(c):this.handleTestRunMonitorMessage(a,c)}),this.testRunMonitorProcess.on("exit",(s,o)=>{console.log(`test run monitor process exited with code ${s} and signal ${o}`)}),this.testRunMonitorProcess.on("error",s=>{console.error(`Error starting test run monitor: ${s.message}`)})})}async handleTestRunMonitorMessage(t,e){switch(t){case"complete":this.isolationMode||console.log("Test files uploaded successfully"),this.sendUploadsComplete().then(()=>{this.completeIndicators.upload=!0});break;case"report-uploaded":{if(this.isolationMode){this.completeIndicators.report=!0;break}console.log("Report generated and uploaded to Checksum");let s={};try{s=JSON.parse(e)}catch(o){console.log("Error parsing stats",o.message)}await this.sendTestRunEnd(s),this.completeIndicators.report=!0,console.log(`*******************
|
|
14
14
|
* Checksum report URL: ${this.CHECKSUM_APP_URL}/#/test-runs/${this.testSession}
|
|
15
15
|
*******************`);break}default:console.warn(`Unhandled test run monitor message: ${t}=${e}`)}}async handleCompleteMessage(){for(;;)Object.keys(this.completeIndicators).find(t=>!this.completeIndicators[t])?await this.awaitSleep(1e3):(console.log("Checksum test run complete"),this.shutdown(this.didFail?1:0))}shutdown(t=0){this.cleanup(),process.exit(t)}buildVolatileConfig(){if(!this.volatileChecksumConfig)return;let t=this.getVolatileConfigPath(),e=`
|
|
16
16
|
import { RunMode, getChecksumConfig } from "@checksum-ai/runtime";
|
package/helpers.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Page } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
export async function simulateDate(datetime: string, page: Page) {
|
|
4
|
+
const simulatedDate = new Date(datetime).valueOf();
|
|
5
|
+
|
|
6
|
+
await page.addInitScript(`{
|
|
7
|
+
// Extend Date constructor to default to fakeNow
|
|
8
|
+
Date = class extends Date {
|
|
9
|
+
constructor(...args) {
|
|
10
|
+
if (args.length === 0) {
|
|
11
|
+
super(${simulatedDate});
|
|
12
|
+
} else {
|
|
13
|
+
super(...args);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Override Date.now() to start from fakeNow
|
|
18
|
+
const __DateNowOffset = ${simulatedDate} - Date.now();
|
|
19
|
+
const __DateNow = Date.now;
|
|
20
|
+
Date.now = () => __DateNow() + __DateNowOffset;
|
|
21
|
+
}`);
|
|
22
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -81,6 +81,11 @@ export function getChecksumConfig(
|
|
|
81
81
|
config: Partial<ChecksumConfig>
|
|
82
82
|
): ChecksumConfig;
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Initialize Checksum runtime
|
|
86
|
+
*
|
|
87
|
+
* @param base
|
|
88
|
+
*/
|
|
84
89
|
export function init(
|
|
85
90
|
base: TestType<
|
|
86
91
|
PlaywrightTestArgs & PlaywrightTestOptions,
|
package/index.js
CHANGED
|
@@ -270,10 +270,10 @@ m2: `).concat(this.mapper2.__debugToString().split(`
|
|
|
270
270
|
current running checksum id index: ${this.runningChecksumIdIndex[this.runningChecksumIdIndex.length-1]}`),await this.page.evaluate(async O=>window.checksum.testGenerator.getSelectorForChecksumId(O),y))}getFailedThought(){return Gf.thoughts[Gf.thoughts.length-1]}toString(){return`Checksum AI Selector: ${this.getFailedThought()}`}},hp=Gf;r(hp,"AIFallback"),hp.API_BASE_URL="https://api.checksum.ai/client-api/runtime/ai-fallback",hp.CLIENT_MAX_ITERATIONS=10,hp.thoughts=[];var bS=P1(require("path")),SS=require("fs");var uF="checksum-playwright-runtime.js",lF=__dirname+"/checksumlib.js";var $p=class{constructor(a,y="normal",v,O,h,B,re,z,p){this.page=a;this.runMode=y;this.testIdSelector=v;this.codeMirror=O;this.monitorBridge=h;this.testInfo=B;this.options=re;this.apiKey=z;this.apiURL=p;this.locatorTypeEnumToFieldMap={[0]:"element",[1]:"visibleElement",[2]:"atPointElement"};this.minSelectionScore=.5;this.phasePayload=void 0;this.locatorStack=[];this.fallbacks=[];this.checksumStepStack=[];this.isTracingActive=!1;this.hasRuntimeStartedTrace=!1;this.didFail=!1;this.didHeal=!1;this.phaseMap={};this.setPhase=a=>{let{phase:y,payload:v,clear:O}=a;O&&(this.phase=void 0,this.phasePayload=void 0),y&&(this.phase=y),v&&(this.phasePayload=v)};E6(re.printLogs),this.proxy=new Proxy(this,{get:r(function(fe,le){return fe.getPageMethod(le)},"get")}),this.registerPageEvents(),this.resetFallbacks(),this.setupStepInterceptors(),this.phase="script"}async prepareAPIMock(){let a={GET:0,POST:0,PUT:0,DELETE:0},y=bS.join(gS(Ym(this.testInfo.file),this.checksumTestId),"test.har");if(!(0,SS.existsSync)(y)){wc("Could not find har file for test, will not use mock");return}await this.page.routeFromHAR(y,{url:"*/**",notFound:"fallback",update:!1});let v=this.page._routes[0].handler;await this.page.route("**/*",O=>{let h=O.request().headers(),B=O.request().method();h["Checksum-Id"]=(++a[B]).toString(),O.request()._applyFallbackOverrides({headers:h}),v(O)})}getPlaywrightConfig(){let a=bS.join(xh(),"playwright.config.ts");if((0,SS.existsSync)(a))return require(a).default}registerPageEvents(){var O;this.page.on("framenavigated",async h=>{h===this.page.mainFrame()&&(this.navigationPromise=new Promise((B,re)=>this.loadScript().then(B).catch(re)))});let y=(O=this.getPlaywrightConfig().use)==null?void 0:O.trace;!y||y==="off"||(this.isTracingActive=!0)}getPageMethod(a){return this.phase=void 0,typeof this[a]=="function"?this[a].bind(this):!Object.values(I1).includes(a)||!this.testInfo?this.page[a]:(this.locatorStack.length===0&&(this.pageInitialCallInTestFile=this.getFirstStackTraceFromTestFile()),this.pushToLocatorStack([{type:a,base:this.page,line:this.pageInitialCallInTestFile.line}]),r(function(v,O){try{return this.executeLocator(v,O)}catch(h){throw this.popLocatorChain(),h}},"Page").bind(this))}static async init(a,y,v,O,{runMode:h="normal",testIdSelector:B=void 0,apiKey:re,apiURL:z,options:p={}}){let m=new $p(a,h,B,y,v,O,{useChecksumSelectors:!0,useChecksumAI:!0,newAssertionsEnabled:!0,useMockData:!1,printLogs:!1,...p},re,z);return v.addTestInfo(m.getChecksumTestId(),O.testId),await m.asyncInit(),m.proxy}popLocatorChain(){return this.locatorStack.pop()}async asyncInit(){await this.page.addInitScript(()=>{window.sessionStorage.setItem("checksumai:disable","true")})}async onTestComplete(){await this.sendTestArtifacts(),this.monitorBridge.addSingleTestStats(!this.didFail,this.didHeal&&!this.didFail)}async sendTestArtifacts(){this.runMode!=="normal"&&(await this.codeMirror.write()).forEach(a=>this.monitorBridge.addAsset(a))}async getTraceFilePath(){if(this.isTracingActive)return this.hasRuntimeStartedTrace?x6(Ym(this.testInfo.file),this.checksumTestId).replace(".zip",".original.zip"):this.testInfo.outputPath("trace.zip")}didTestFail(){return this.didFail}async testId(a){a||(a=Ch(5),console.warn(`Checksum test id was not defined for test, will auto-generate. Please replace - "${this.testInfo.title}" with -
|
|
271
271
|
test(defineChecksumTest("${this.testInfo.title}", "${a}"), async ({ page }) => {...`)),this.checksumTestId=a,(this.options.useMockData||this.runMode==="refactor")&&await this.prepareAPIMock();let y=await this.getTraceFilePath();if(y&&this.monitorBridge.addAsset({type:"trace",path:y,testId:this.checksumTestId}),!1){let O=gS(Ym(this.testInfo.file),this.checksumTestId);this.monitorBridge.addAsset({type:"har",path:O,testId:this.checksumTestId})}}getChecksumTestId(){return this.checksumTestId}checksumSelector(a){return this.options.useChecksumSelectors&&(this.fallbacks.push(this.constructFallback(Kv).init({checksumId:a,fileName:this.testInfo.file,testId:this.checksumTestId})),this.sortFallbacks()),this.checksumStepId=a,this.proxy}checksumAI(...a){if(a.length===0)throw new Error("checksumAI missing arguments");if(!this.options.useChecksumAI)return this.proxy;let{apiKey:y,apiURL:v}=this;if(this.fallbacks.push(this.constructFallback(hp).init({goal:this.testInfo.title,apiKey:y,apiURL:v})),this.sortFallbacks(),this.fallbacks.filter(O=>O instanceof hp).forEach(O=>O.addMetadata({thought:a[0]})),this.checksumStepInitialCallInTestFile=this.getFirstStackTraceFromTestFile(),a.length===1)return this.proxy;if(typeof a[1]!="function")throw new Error("Second argument for withChecksumStep must be a function");this.checksumStepStack.push(a[0]);try{console.log("=== running test function");let O=this;return r(async function(){await a[1](),console.log("==== done running test function"),O.checksumStepStack.pop()},"Page")()}catch(O){console.log(O),this.checksumStepStack.pop()}}async loadScript(){try{return this.navigationPromise&&await this.navigationPromise,await this.page.addScriptTag({path:lF}),await this.page.evaluate(async({initModules:a,ESRAselectionRules:y})=>{window.checksum.testRunner.init(y,[],a)},{ESRAselectionRules:{testIdSelector:this.testIdSelector},initModules:{assertionGenerator:!0}}),wc(`[init] init script loaded for ${this.page.url()}`),!0}catch{return!1}}pushToLocatorStack(a){this.locatorStack.push(a)}getCurrentLocatorChain(){if(this.locatorStack.length)return this.locatorStack[this.locatorStack.length-1]}getCurrentLocatorInChain(){let a=this.getCurrentLocatorChain();return a==null?void 0:a[a.length-1]}getMessage(a,{initialSelector:y,selector:v,thought:O}={}){switch(a){case"script":return"Firing up checksum";case"initial":return`${y} failed, trying some checksum magic...`;case"force":return"check/uncheck methods failed, falling back to click action";case"esra-search":return"Checksum is looking for potential alternatives to resolve the issue...";case"esra-action":return`AI: use selector ${v}`;case"llm-prompt":return`Checksum is trying to achieve step "${O}" using AI...`;case"llm-action":return`AI: "${O}" using selector "${v}"`;case"fail":return`Checksum couldn't resolve the issue executing ${y}`}}onFallbackSuccess(){let a=this.testInfo._steps[this.testInfo._steps.length-1];a&&!a.endWallTime&&a.complete({error:{message:`Failed to resolve ${this.initialLocatorTitle}`,stack:""}})}setupStepInterceptors(){let a=["checksum-page.ts","checksum-test-extension.ts","checksum-playwright-runtime.js","code-mirror.ts","utils.ts","fallback/esra-fallback.ts","fallback/force-fallback.ts","fallback/llm-fallback.ts","index.js"].map(B=>(0,N6.join)(__dirname,B)),y={},v=r(B=>{var z,p,m,fe;return y[B.stepId]!==void 0?y[B.stepId]:B.location&&!a.includes(B.location.file)?!1:!!(B.stepId.includes(".evaluate@")||B.stepId.includes(".addScriptTag@")||(z=B.title)!=null&&z.includes("evaluate")||(p=B.title)!=null&&p.includes("addScriptTag")||(m=B.title)!=null&&m.includes("waitForLoadState")||B.category==="fixture"||(fe=B.title)!=null&&fe.includes("tracing.stop"))},"shouldFilterStep"),O=this.testInfo._onStepBegin;this.testInfo._onStepBegin=B=>{if(!this.phase&&v(B)){y[B.stepId]=!0;return}return y[B.stepId]=!1,this.phase==="initial"&&(this.initialLocatorTitle=B.title,B.location=this.pageInitialCallInTestFile),B.title.startsWith("proxy.")&&(B.title=B.title.replace("proxy.","page.")),this.phase&&this.phase!=="initial"&&(this.phaseMap[B.stepId]={phase:this.phase,payload:this.phasePayload,initialLocatorTitle:this.initialLocatorTitle},B.location=void 0,B.title=this.getMessage(this.phase,{initialSelector:this.initialLocatorTitle,...this.phasePayload})),this.phase=void 0,this.phasePayload=void 0,O(B)};let h=this.testInfo._onStepEnd;this.testInfo._onStepEnd=B=>{if(!y[B.stepId]){if(this.phaseMap[B.stepId]){let{phase:re,initialLocatorTitle:z,payload:p}=this.phaseMap[B.stepId];re==="fail"&&(B.error={message:`Failed to resolve ${z}`,stack:""})}return h(B)}}}getFirstStackTraceFromTestFile(){let a=this.getTestFileStackTrace()[0];if(!a)throw new Error(`Could not find test file location from stack trace ${$p.getStackTrace()}`);let v=[/\((.*):(\d+):(\d+)\)$/,/.*at (.*):(\d+):(\d+)$/].map(re=>re.exec(a)).find(re=>re!==null);if(!v)throw new Error(`Could not find test file location from stack trace ${a}`);let[,O,h,B]=v;return{file:O,line:parseInt(h),column:parseInt(B)}}getTestFileStackTrace(){return $p.getStackTrace().filter(y=>y.includes(this.testInfo.file))}isCalledDirectlyFromTestFunction(){let a=this.getTestFileStackTrace();if(a.length!==1+this.checksumStepStack.length)return!1;let y=a[0],v=/.*at (.*):(\d+):(\d+)$/;return this.checksumStepStack.length===0&&!v.exec(y)?!1:!this.isCalledThroughMethodInAnotherFile(y)}isCalledThroughMethodInAnotherFile(a){let y=$p.getStackTrace(),v=["node:internal","/node_modules/@playwright"],O=y.indexOf(a)-1;for(;O>=0&&v.some(B=>y[O].includes(B));)O--;let h=y[O];return!h.includes("checksum-page.ts")&&!h.includes(uF)}static getStackTrace(){return new Error().stack.split(`
|
|
272
272
|
`)}getLocator(a,y){let v=this.getCurrentLocatorInChain();return v.base[v.type](a,y)}executeLocator(a,y){try{wc(`
|
|
273
|
-
Executing locator ${this.getCurrentLocatorInChain().type} with ${typeof a=="string"?`selector ${a}`:"locator"}`);let v=this.getLocator(a,y);return new Proxy(v,{get:r(function(h,B){return this.getLocatorMethod(v,h,B)},"get").bind(this)})}catch(v){wc("Failed to locate",v)}}getLocatorMethod(a,y,v){return v==="constructor"?r(function(...h){return this.popLocatorChain(),y.constructor(...h)},"Locator"):v in y&&typeof y[v]!="function"||v===Symbol.toPrimitive||v in Object?(this.popLocatorChain(),y[v]):[...Object.values(I1),...Object.values(w1)].includes(v)?v==="or"?(wc("'Or' locator not supported, will execute normally"),this.popLocatorChain(),y[v]):(this.getCurrentLocatorChain().push({type:v,base:a}),r(function(...h){return this.executeLocator(...h)},"Locator").bind(this)):r(async function(...h){let B=await this.executeLocatorAction(a,v,h);return this.popLocatorChain(),B},"Locator").bind(this)}async executeLocatorAction(a,y,v){this.selector=a._selector;let O=this.getChecksumStepId();wc("Executing",y,this.selector);let h=y==="_expect";try{wc("Running initial locator..."),await this.navigationPromise,await this.page.evaluate(()=>!!window.checksum)||wc("[loadScript] checksum libs missing, marking as failed"),await this.stepWillExecute(h),this.phase="initial";let re=await L1(a,y,v,this.getTimeout(y,v));if(h&&(re==null?void 0:re.timedOut)===!0)return wc("Expect timeout"),this.didFail=!0,re;if(re!==!1)return await this.onStepSuccess(O,y==="_expect"),re;await this.onStepFailure()}catch(B){wc("Failed initial execution. Exception:",B.message)}return this.initiateFallbackSequence(O,a,y,v)}getChecksumStepId(){let a=this.checksumStepId;return this.checksumStepId=void 0,a}async stepWillExecute(a){this.selectionData=void 0,this.runMode==="refactor"&&(wc(`stepWillExecute called for line ${this.pageInitialCallInTestFile.line}`),this.isCalledDirectlyFromTestFunction()&&(await this.evaluateWithChecksum(async()=>await window.checksum.testRunner.startMonitoringForAssertions()),this.selectionData=[await M1(this.selector,this.page)].filter(y=>y),Object.values(this.selectionData).length===0?wc(`Failed fetching selection data ${a?"- maybe because it is not visible and running inside expect":""}`):wc("Successfully fetched selection data")))}async onStepSuccess(a,y,v=!1){var B,re,z,p;let O=(B=this.fallbacks.find(m=>m instanceof hp))==null?void 0:B.getFailedThought();if(this.resetFallbacks(),this.runMode==="normal"||this.runMode==="heal"&&!v||!this.codeMirror||!this.getCurrentLocatorChain())return;if(!this.isCalledDirectlyFromTestFunction()){wc("<!> Step called from helper function, will not refactor step");return}if(this.runMode==="refactor"&&!this.selectionData.length){wc("Failed fetching selection data, will not refactor step");return}wc("Will update in-memory code"+(this.selectionData&&this.selectionData.length>0?`
|
|
273
|
+
Executing locator ${this.getCurrentLocatorInChain().type} with ${typeof a=="string"?`selector ${a}`:"locator"}`);let v=this.getLocator(a,y);return new Proxy(v,{get:r(function(h,B){return this.getLocatorMethod(v,h,B)},"get").bind(this)})}catch(v){wc("Failed to locate",v)}}getLocatorMethod(a,y,v){return v==="constructor"?r(function(...h){return this.popLocatorChain(),y.constructor(...h)},"Locator"):v in y&&typeof y[v]!="function"||v===Symbol.toPrimitive||v in Object?(this.popLocatorChain(),y[v]):[...Object.values(I1),...Object.values(w1)].includes(v)?v==="or"?(wc("'Or' locator not supported, will execute normally"),this.popLocatorChain(),y[v]):(this.getCurrentLocatorChain().push({type:v,base:a}),r(function(...h){return this.executeLocator(...h)},"Locator").bind(this)):r(async function(...h){let B=await this.executeLocatorAction(a,v,h);return this.popLocatorChain(),B},"Locator").bind(this)}async executeLocatorAction(a,y,v){this.originalActionError=void 0,this.selector=a._selector;let O=this.getChecksumStepId();wc("Executing",y,this.selector);let h=y==="_expect";try{wc("Running initial locator..."),await this.navigationPromise,await this.page.evaluate(()=>!!window.checksum)||wc("[loadScript] checksum libs missing, marking as failed"),await this.stepWillExecute(h),this.phase="initial";let re=await L1(a,y,v,this.getTimeout(y,v));if(h&&(re==null?void 0:re.timedOut)===!0)return wc("Expect timeout"),this.didFail=!0,re;if(re!==!1)return await this.onStepSuccess(O,y==="_expect"),re;await this.onStepFailure()}catch(B){this.originalActionError=B,wc("Failed initial execution. Exception:",B.message)}return this.initiateFallbackSequence(O,a,y,v)}getChecksumStepId(){let a=this.checksumStepId;return this.checksumStepId=void 0,a}async stepWillExecute(a){this.selectionData=void 0,this.runMode==="refactor"&&(wc(`stepWillExecute called for line ${this.pageInitialCallInTestFile.line}`),this.isCalledDirectlyFromTestFunction()&&(await this.evaluateWithChecksum(async()=>await window.checksum.testRunner.startMonitoringForAssertions()),this.selectionData=[await M1(this.selector,this.page)].filter(y=>y),Object.values(this.selectionData).length===0?wc(`Failed fetching selection data ${a?"- maybe because it is not visible and running inside expect":""}`):wc("Successfully fetched selection data")))}async onStepSuccess(a,y,v=!1){var B,re,z,p;let O=(B=this.fallbacks.find(m=>m instanceof hp))==null?void 0:B.getFailedThought();if(this.resetFallbacks(),this.runMode==="normal"||this.runMode==="heal"&&!v||!this.codeMirror||!this.getCurrentLocatorChain())return;if(!this.isCalledDirectlyFromTestFunction()){wc("<!> Step called from helper function, will not refactor step");return}if(this.runMode==="refactor"&&!this.selectionData.length){wc("Failed fetching selection data, will not refactor step");return}wc("Will update in-memory code"+(this.selectionData&&this.selectionData.length>0?`
|
|
274
274
|
locators:
|
|
275
275
|
${this.selectionData.map(m=>m.generatedLocator).join(`
|
|
276
|
-
`)}`:"")),await O1(this.page.waitForLoadState("networkidle"));let h=y||!this.options.newAssertionsEnabled?[]:await this.evaluateWithChecksum(async()=>await window.checksum.testRunner.stopMonitoringAndGenerateAssertions());this.selectionData.forEach(m=>{y&&(m.esraMetadata=void 0,m.generatedLocator=void 0)}),this.runMode==="heal"&&(this.didHeal=!0),this.codeMirror.load(this.testInfo.file,this.checksumTestId),(z=(re=this.selectionData)==null?void 0:re[0].method)!=null&&z.name?this.codeMirror.updateChecksumStep(this.checksumStepInitialCallInTestFile.line,O,this.selectionData,!this.checksumStepStack.length):this.codeMirror.updateCommandFromLine((p=this.getCurrentLocatorChain())==null?void 0:p[0].line,this.getCurrentLocatorChain(),a,h,this.selectionData[0])}async onStepFailure(){await this.evaluateWithChecksum(async()=>{var a,y;return await((y=(a=window.checksum)==null?void 0:a.testRunner)==null?void 0:y.stopMonitoring())})}async initiateFallbackSequence(a,y,v,O){for(let B of this.fallbacks)try{B.toString()&&console.log(`Executing ${B.toString()}`);let re=await B.resolve({locator:y,method:v,args:O});if(!re){B.toString()&&console.log("Execution failed.");continue}return console.log("Executed successfully."),this.onFallbackSuccess(),this.runMode==="heal"&&(this.selectionData=re),await this.onStepSuccess(a,!1,!0),this.resetFallbacks(),!0}catch(re){wc(`Exception during ${B.toString()} `,re);continue}this.didFail=!0,await this.addFailPhase(),this.resetFallbacks();let h=new Error("Checksum failed to recover from the errors. Please review the test, fix the code and try again.");throw h.stack="",h}async addFailPhase(){return this.phase="fail",this.page.evaluate(async()=>!0)}getTimeout(a,y){let v=["fill","dragTo"].includes(a)?1:0;return(y[v]??{}).timeout??
|
|
276
|
+
`)}`:"")),await O1(this.page.waitForLoadState("networkidle"));let h=y||!this.options.newAssertionsEnabled?[]:await this.evaluateWithChecksum(async()=>await window.checksum.testRunner.stopMonitoringAndGenerateAssertions());this.selectionData.forEach(m=>{y&&(m.esraMetadata=void 0,m.generatedLocator=void 0)}),this.runMode==="heal"&&(this.didHeal=!0),this.codeMirror.load(this.testInfo.file,this.checksumTestId),(z=(re=this.selectionData)==null?void 0:re[0].method)!=null&&z.name?this.codeMirror.updateChecksumStep(this.checksumStepInitialCallInTestFile.line,O,this.selectionData,!this.checksumStepStack.length):this.codeMirror.updateCommandFromLine((p=this.getCurrentLocatorChain())==null?void 0:p[0].line,this.getCurrentLocatorChain(),a,h,this.selectionData[0])}async onStepFailure(){await this.evaluateWithChecksum(async()=>{var a,y;return await((y=(a=window.checksum)==null?void 0:a.testRunner)==null?void 0:y.stopMonitoring())})}async initiateFallbackSequence(a,y,v,O){for(let B of this.fallbacks)try{B.toString()&&console.log(`Executing ${B.toString()}`);let re=await B.resolve({locator:y,method:v,args:O});if(!re){B.toString()&&console.log("Execution failed.");continue}return console.log("Executed successfully."),this.onFallbackSuccess(),this.runMode==="heal"&&(this.selectionData=re),await this.onStepSuccess(a,!1,!0),this.resetFallbacks(),!0}catch(re){wc(`Exception during ${B.toString()} `,re);continue}if(this.didFail=!0,await this.addFailPhase(),this.resetFallbacks(),this.originalActionError)throw this.originalActionError;let h=new Error("Checksum failed to recover from the errors. Please review the test, fix the code and try again.");throw h.stack="",h}async addFailPhase(){return this.phase="fail",this.page.evaluate(async()=>!0)}getTimeout(a,y){let v=["fill","dragTo"].includes(a)?1:0;return(y[v]??{}).timeout??3e4}async evaluateWithChecksum(a,y){return this.navigationPromise&&await this.navigationPromise,this.page.evaluate(a,y)}resetFallbacks(){this.fallbacks=[this.constructFallback(Qv).init()]}sortFallbacks(){let a=[Qv,Kv,hp];this.fallbacks.sort((y,v)=>a.indexOf(y.constructor)-a.indexOf(v.constructor))}constructFallback(a){return new a(this.page,this.setPhase,{generateSelectionData:this.runMode!=="normal"})}};r($p,"ChecksumPage");var tv=P1(fA()),_A=P1(require("path")),kg=require("fs");var iv=class{constructor(a){this.appRules=a}toAssertionCode(a){switch(a.type){case"text_element_appear":case"text_element_disappear":return this.makeTextElementAssertion(a);case"page_url_change":{let y=this.appRules?this.appRules.resolvePageIdFromUrl(a.url):null;if(y!==a.url&&y!==null&&y!=="unknown-page"){let v=this.appRules.getPageRegexMatchingUrl(a.url);if(v){let O=v.toString().replace(/\//g,"\\/");return O.startsWith("^")&&(O=O.substring(1)),O.endsWith("$")&&(O=O.substring(0,O.length-1)),`await expect(page).toHaveURL(/${O}(\\?.*)?(\\#.*)?$/)`}throw new Error("None of the page URLs matched the assertion url.")}else return`await expect(page).toHaveURL("${a.url.toString().replace(/"/g,'\\"')}")`}default:throw new Error(`Unexpected value for assertion.type: ${a.type} in TestGeneratorCodegen.addAssertion`)}}makeTextElementAssertion(a){let v=`await expect(page.getByText("${iv.escapeString(a.text.toString())}").first())`;switch(a.type){case"text_element_appear":return`${v}.toBeVisible()`;case"text_element_disappear":return`${v}.not.toBeVisible()`}}static escapeString(a){let y=this.replaceAll(a,"'","\\'");return y=this.replaceAll(a,/\\/g,"\\\\"),y=this.replaceAll(a,/"/g,'\\"'),y=this.replaceAll(a,`
|
|
277
277
|
`,"\\n"),y}static replaceAll(a,y,v){return a&&a.replace(new RegExp(y,"g"),v)}};r(iv,"AssertionCodeGenerator");var pm=class{constructor(a){this.runMode=a;this.lines=[];this.linesOffsetFromOriginalFile=0;let y={getPageRegexMatchingUrl:()=>null,resolvePageIdFromUrl:()=>null};this.assertionCodeGenerator=new iv(y)}static init(a){return new pm(a)}static initWithContent(a,y){let v=new pm("normal");return v.lines=[a],v}async load(a,y){if(this.filename)return;this.filename=a,this.testId=y;let v=this.getProcessedFilename(this.filename);(0,kg.existsSync)(v)&&(0,kg.unlinkSync)(v),this.lines=["",...(0,kg.readFileSync)(this.filename,"utf-8").split(`
|
|
278
278
|
`)];try{this.esraMetadataMap=await F1(Ym(v),y)}catch{console.log("[CodeMirror] Failed loading ESRA metadata for test file, creating new ESRA map"),this.esraMetadataMap={}}}addTestToCode(a,y){let v=tv.createSourceFile("",this.lines.join(""),tv.ScriptTarget.ES2015),O=this.findTitleInParentNode(this.getSourceFileChildren(v),v,a.description);if(O){let re=v.text.substring(0,O.pos)+y.generateSingleTestCode(a)+v.text.substring(O.end);return y.styleCode(re)}let h=this.getLastDescribeNode(this.getSourceFileChildren(v),v);if(h){let re=v.text.substring(0,v.text.substring(0,h.end).lastIndexOf("}")-1)+y.generateSingleTestCode(a)+"});";return y.styleCode(re)}let B=v.text+`
|
|
279
279
|
|