chainwright 0.9.7 → 0.9.8

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.
@@ -1,3 +1,3 @@
1
- import Q from"fs";import bt from"path";import{chromium as kt}from"@playwright/test";import At from"path";var J=".wallet-cache",Y=".wallet-context";var X="13.33.0",E="https://github.com/amaify/chainwright/releases/download/v0.1.0/",Ut=`https://github.com/MetaMask/metamask-extension/releases/download/v${X}/metamask-chrome-${X}.zip`,Mt=`${E}solflare-wallet-extension-v2.19.1.zip`,Ht=`${E}petra-wallet-extension-v2.4.8.zip`,jt=`${E}phantom-wallet-extension-v26.10.0.zip`,zt=`${E}meteor-wallet-extension-v0.7.0.zip`,Gt=`${E}keplr-wallet-extension-v0.13.3.zip`;async function I(t){return At.resolve(process.cwd(),Y,t)}import Pt from"path";function x(t){return Pt.resolve(process.cwd(),J,t)}import q from"fs";import vt from"path";async function N(t){try{let o=x(t),e=vt.resolve(o,"extension-path.txt");if(!q.existsSync(e))throw new Error("\u274C extension-path.txt not found. Run setup script first.");let a=q.readFileSync(e,"utf-8").trim();if(!a)throw new Error("\u274C extension-path.txt is empty. Run setup script first.");return a}catch(o){throw new Error(`\u274C Failed to get ${t} extension path: ${o.message}`)}}async function Z({wallet:t,workerInfo:o,profileName:e,slowMo:a}){let r=await I(o.workerIndex.toString()),i=x(t.name),l=bt.resolve(i,e??"wallet-data");if(!Q.existsSync(l))throw new Error(`Cache for ${t.name} does not exist. Create it first!`);Q.cpSync(l,r,{recursive:!0,force:!0});let d=await N(t.name),p=await kt.launchPersistentContext(r,{headless:!1,args:[`--disable-extensions-except=${d}`],slowMo:process.env.HEADLESS?0:a}),m=await t.indexUrl(),n=p.pages()[0];return n||(n=await p.newPage()),await n.goto(m),{context:p,walletPage:n,contextPath:r}}import{expect as rt}from"@playwright/test";function S(t){return new Promise(o=>setTimeout(o,t))}async function k(t){await t.waitForLoadState("load",{timeout:15e3}),await t.waitForLoadState("domcontentloaded",{timeout:15e3})}import tt from"fs";import St from"path";async function _(t){let o=x(t),e=St.resolve(o,"password.txt");try{if(!tt.existsSync(e))throw new Error("\u274C password.txt not found. Run setup script first.");return tt.readFileSync(e,"utf-8")}catch(a){throw new Error(`\u274C Failed to get ${t} password from cache: ${a.message}`)}}import{expect as Ct}from"@playwright/test";async function et({context:t,path:o,locator:e}){let a;try{await Ct.poll(async()=>(a=t.pages().filter(r=>r.url().startsWith("chrome-extension://")).find(r=>r.url().match(o)),!!a),{timeout:3e4}).toBe(!0)}catch{let r=t.pages().filter(i=>i.url().startsWith("chrome-extension://")).map(i=>i.url());throw new Error(`Popup page with path "${o}" not found in context after 30s. Pages in context: ${JSON.stringify(r)}`)}if(!a)throw new Error(`Popup page with path ${o} not found in context.`);return await Bt(a,e),await a.setViewportSize({width:360,height:592}),a}async function Bt(t,o){await t.waitForLoadState("load",{timeout:4e4}),await t.waitForLoadState("domcontentloaded",{timeout:4e4}),await t.locator(o).first().waitFor({state:"attached",timeout:4e4})}import ot from"fs";import Tt from"path";async function at(t){let o=x(t),e=Tt.resolve(o,"extension-id.txt");try{if(!ot.existsSync(e))throw new Error("\u274C extension-id.txt not found. Run setup script first.");return ot.readFileSync(e,"utf-8")}catch(a){throw new Error(`\u274C Failed to get ${t} extension ID from cache: ${a.message}`)}}var y=class{name="keplr";onboardingPath="register.html";async indexUrl(){return`chrome-extension://${await this.extensionId()}/sidePanel.html`}async onboardingUrl(){return`chrome-extension://${await this.extensionId()}/${this.onboardingPath}`}async promptUrl(){return`chrome-extension://${await this.extensionId()}/popup.html`}async extensionId(){return await at(this.name)}async promptPage(o){let e=await this.promptUrl();return await et({context:o,path:e,locator:"div[data-simplebar='init']"})}};var g={importExistingWalletButton:"button:has-text('Import an existing wallet')",usePrivateKeyButton:"button:has-text('Use recovery phrase or private key')",privateKeyTabButton:"button:has-text('Private key')",privateKeyInput:"input[type='password']",importButton:"button:has-text('Import')",walletNameInput:"input[name='name']",walletPasswordInput:"input[name='password']",confirmWalletPasswordInput:"input[name='confirmPassword']",nextButton:"button:has-text('Next')",searchNetworkInput:"input[placeholder='Search networks']",saveButton:"button:has-text('Save')",finishButton:"button:has-text('Finish')"};function Wt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function C({page:t,privateKey:o,walletName:e,chains:a,mode:r="onboard"}){await t.locator(g.importExistingWalletButton).click(),await t.locator(g.usePrivateKeyButton).click(),await t.getByRole("button",{name:"Private key",exact:!0}).click(),await t.locator(g.privateKeyInput).fill(o),await nt({page:t,walletName:e,mode:r,chains:a})}async function B({page:t,seedPhrase:o,walletName:e,chains:a,mode:r="onboard"}){await t.locator(g.importExistingWalletButton).click(),await t.locator(g.usePrivateKeyButton).click(),await t.getByRole("button",{name:"12 words",exact:!0}).click();let p=t.locator("input[type='password']"),m=o.split(" ");await p.first().fill(m[0]),await p.first().press("Tab");for(let n=1;n<m.length;n++){let u=p.nth(n),w=m[n];await u.fill(w),n<m.length-1&&await u.press("Tab")}await nt({page:t,walletName:e,mode:r,chains:a})}async function nt({page:t,walletName:o,mode:e,chains:a}){let r=new y,i=await _("keplr");if(await t.getByRole("button",{name:"Import",exact:!0}).click(),await t.locator(g.walletNameInput).fill(o),e==="onboard"){let f=t.locator(g.walletPasswordInput),b=t.locator(g.confirmWalletPasswordInput);await f.fill(i),await b.fill(i)}await t.locator(g.nextButton).click();let m=t.locator("div:has-text('All Native Chains')").nth(-4),n=t.locator("div[cursor='pointer']:has-text('Cosmos Hub')"),u=await m.locator("input[type='checkbox']").getAttribute("checked"),w=await n.locator("input[type='checkbox']").getAttribute("checked");u!==null&&await m.click(),w!==null&&await n.click();let P=t.locator(g.searchNetworkInput);for(let f of a){await P.fill(f);let v=t.locator("div[class='simplebar-content']").locator("div[cursor] > div").first().locator("div").filter({hasText:new RegExp(`^${Wt(f)}$`,"i")}).nth(2).locator("../../../../..");await v.waitFor({state:"visible",timeout:2e4}),await v.locator("input[type='checkbox']").getAttribute("checked")===null&&await v.click()}let h=t.locator(g.saveButton);if(await h.scrollIntoViewIfNeeded(),await h.click(),await S(2e3),e==="onboard"){await t.goto(await r.indexUrl());return}if(e==="add-account-single"){let f=t.locator(g.finishButton);await f.waitFor({state:"visible",timeout:2e4}),await rt(f).toBeEnabled({timeout:2e4}),await f.click()}}async function K(t){let e=await new y().onboardingUrl();await t.getByRole("link",{name:"Settings",exact:!0}).click(),await t.locator("div[cursor='pointer']").first().click(),await t.getByRole("button",{name:"Add Wallet",exact:!0}).click();let l;if(await rt.poll(async()=>(l=t.context().pages().find(d=>d.url().match(e)),!!l),{timeout:3e4}).toBe(!0).catch(d=>{console.error(`Failed to find onboarding page with URL matching ${e}. Original error: ${d}`)}),!l)throw new Error(`Onboarding page not found. Expected URL: ${e}`);return await k(l),await l.bringToFront(),l}async function it({page:t,chains:o,walletName:e,mode:a,...r}){let i=await K(t);"privateKey"in r&&await C({page:i,privateKey:r.privateKey,walletName:e,chains:o,mode:a}),"seedPhrase"in r&&await B({page:i,seedPhrase:r.seedPhrase,walletName:e,chains:o,mode:a}),await t.locator("div:has(div:has-text('Select Wallet'))").nth(-4).locator("div:has(> div > svg)").first().click(),await t.getByRole("link",{name:"Home",exact:!0}).click()}import{expect as Et}from"@playwright/test";var O={approveButton:"button:has-text('Approve')",rejectButton:"button[color='secondary']"};async function st(t){let o=t.locator(O.approveButton);await Et(o).toBeEnabled({timeout:2e4}),await o.click()}async function ct(t){t.getByRole("button",{name:"Approve",exact:!0}).click(),await S(1e3)}import{expect as It}from"@playwright/test";import A from"zod";var lt=A.discriminatedUnion("chain",[A.object({chain:A.literal(["Injective","Injective (Testnet)","Polygon"]),walletName:A.string().min(1,"Wallet name cannot be an empty string")}),A.object({chain:A.literal(["Bitcoin","Bitcoin Signet","Bitcoin Testnet"]),chainTag:A.literal(["Taproot","Native Segwit"]),walletName:A.string().min(1,"Wallet name cannot be an empty string")})]),pt=A.object({currentAccountName:A.string().min(1,"Current account name cannot be an empty string"),newAccountName:A.string().min(1,"New account name cannot be an empty string")});async function mt({page:t,...o}){let e=lt.parse({...o});await t.getByRole("textbox",{name:"Search for asset or chain (i.e. ATOM, Cosmos)",exact:!0}).fill(e.chain);let r=t.locator(`div:has-text("${e.chain}")`).nth(-2).filter({hasNot:t.locator("span")});if(await r.waitFor({state:"attached",timeout:2e4}),!await r.isVisible().catch(()=>!1))throw Error(`Make sure "${e.chain}" is activated.`);let l=await r.locator("div").all();It(l.length).toBeGreaterThan(0),await t.locator(`div:has(div:has-text('${e.walletName}'))`).nth(-3).locator("div:has(> div > svg)").click();let m=t.locator("div:has(> div[data-simplebar='init'])").last(),u=m.locator("div:has(> div > input)").locator("input");await u.fill(e.chain);let P=await m.locator("div[cursor='pointer']",{hasText:e.chain}).all(),h;for(let b of P){let v;"chainTag"in o&&(v=o.chainTag);let $=b.locator("div",{hasText:e.chain}).last(),V=v?b.locator("div",{hasText:v}).last():null,z=(V?await V?.isVisible().catch(()=>!1):!1)?await V?.textContent():null,G=await $.textContent(),xt=z?`${G} ${z}`:G,yt=v?`${e.chain} ${v}`:e.chain;if(xt===yt){h=$.locator("xpath=../../../.."),await u.clear();break}}if(!h)throw Error(`Address for ${e.walletName} account on "${e.chain}" chain not found.`);return await h.hover(),await h.scrollIntoViewIfNeeded(),await h.click(),await h.waitFor({state:"detached",timeout:7e3}),await t.evaluate(async()=>await navigator.clipboard.readText())}var F={openSidebarMenuButton:"div[cursor='pointer']:has(> div[cursor='pointer'])",menuPopupContent:"div[id='modal-root-3']",lockWalletButton:"div:has(> div:has-text('Lock Wallet'))",settingsButton:"div:has(a[href='#/settings'])"},U={unlockButton:"button[type='submit']:has-text('Unlock')",passwordInput:"input[placeholder='Type Your Password']"};async function dt(t){await t.locator(F.openSidebarMenuButton).click(),await t.locator(F.lockWalletButton).nth(-1).click(),await t.getByText("Welcome Back").waitFor({state:"visible",timeout:3e4})}import{styleText as ut}from"util";import{expect as Ft}from"@playwright/test";async function R(t,o){let e=t.locator("div[color]").nth(1);if(await e.textContent()===o){console.info(`
1
+ import Q from"fs";import bt from"path";import{chromium as kt}from"@playwright/test";import At from"path";var J=".wallet-cache",Y=".wallet-context";var X="13.33.0",E="https://github.com/amaify/chainwright/releases/download/v0.1.0/",Ut=`https://github.com/MetaMask/metamask-extension/releases/download/v${X}/metamask-chrome-${X}.zip`,Mt=`${E}solflare-wallet-extension-v2.19.1.zip`,Ht=`${E}petra-wallet-extension-v2.4.8.zip`,jt=`${E}phantom-wallet-extension-v26.10.0.zip`,zt=`${E}meteor-wallet-extension-v0.7.0.zip`,Gt=`${E}keplr-wallet-extension-v0.13.3.zip`;async function I(t){return At.resolve(process.cwd(),Y,t)}import Pt from"path";function y(t){return Pt.resolve(process.cwd(),J,t)}import q from"fs";import vt from"path";async function N(t){try{let o=y(t),e=vt.resolve(o,"extension-path.txt");if(!q.existsSync(e))throw new Error("\u274C extension-path.txt not found. Run setup script first.");let a=q.readFileSync(e,"utf-8").trim();if(!a)throw new Error("\u274C extension-path.txt is empty. Run setup script first.");return a}catch(o){throw new Error(`\u274C Failed to get ${t} extension path: ${o.message}`)}}async function Z({wallet:t,workerInfo:o,profileName:e,slowMo:a}){let r=await I(o.workerIndex.toString()),n=y(t.name),l=bt.resolve(n,e??"wallet-data");if(!Q.existsSync(l))throw new Error(`Cache for ${t.name} does not exist. Create it first!`);Q.cpSync(l,r,{recursive:!0,force:!0});let m=await N(t.name),p=await kt.launchPersistentContext(r,{headless:!1,args:[`--disable-extensions-except=${m}`],slowMo:process.env.HEADLESS?0:a}),d=await t.indexUrl(),i=p.pages()[0];return i||(i=await p.newPage()),await i.goto(d),{context:p,walletPage:i,contextPath:r}}import{expect as rt}from"@playwright/test";function S(t){return new Promise(o=>setTimeout(o,t))}async function k(t){await t.waitForLoadState("load",{timeout:15e3}),await t.waitForLoadState("domcontentloaded",{timeout:15e3})}import tt from"fs";import St from"path";async function _(t){let o=y(t),e=St.resolve(o,"password.txt");try{if(!tt.existsSync(e))throw new Error("\u274C password.txt not found. Run setup script first.");return tt.readFileSync(e,"utf-8")}catch(a){throw new Error(`\u274C Failed to get ${t} password from cache: ${a.message}`)}}import{expect as Ct}from"@playwright/test";async function et({context:t,path:o,locator:e}){let a;try{await Ct.poll(async()=>(a=t.pages().filter(r=>r.url().startsWith("chrome-extension://")).find(r=>r.url().match(o)),!!a),{timeout:3e4}).toBe(!0)}catch{let r=t.pages().filter(n=>n.url().startsWith("chrome-extension://")).map(n=>n.url());throw new Error(`Popup page with path "${o}" not found in context after 30s. Pages in context: ${JSON.stringify(r)}`)}if(!a)throw new Error(`Popup page with path ${o} not found in context.`);return await Bt(a,e),await a.setViewportSize({width:360,height:592}),a}async function Bt(t,o){await t.waitForLoadState("load",{timeout:4e4}),await t.waitForLoadState("domcontentloaded",{timeout:4e4}),await t.locator(o).first().waitFor({state:"attached",timeout:4e4})}import ot from"fs";import Tt from"path";async function at(t){let o=y(t),e=Tt.resolve(o,"extension-id.txt");try{if(!ot.existsSync(e))throw new Error("\u274C extension-id.txt not found. Run setup script first.");return ot.readFileSync(e,"utf-8")}catch(a){throw new Error(`\u274C Failed to get ${t} extension ID from cache: ${a.message}`)}}var A=class{name="keplr";onboardingPath="register.html";async indexUrl(){return`chrome-extension://${await this.extensionId()}/sidePanel.html`}async onboardingUrl(){return`chrome-extension://${await this.extensionId()}/${this.onboardingPath}`}async promptUrl(){return`chrome-extension://${await this.extensionId()}/popup.html`}async extensionId(){return await at(this.name)}async promptPage(o){let e=await this.promptUrl();return await et({context:o,path:e,locator:"div[data-simplebar='init']"})}};var g={importExistingWalletButton:"button:has-text('Import an existing wallet')",usePrivateKeyButton:"button:has-text('Use recovery phrase or private key')",privateKeyTabButton:"button:has-text('Private key')",privateKeyInput:"input[type='password']",importButton:"button:has-text('Import')",walletNameInput:"input[name='name']",walletPasswordInput:"input[name='password']",confirmWalletPasswordInput:"input[name='confirmPassword']",nextButton:"button:has-text('Next')",searchNetworkInput:"input[placeholder='Search networks']",saveButton:"button:has-text('Save')",finishButton:"button:has-text('Finish')"};function Wt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function C({page:t,privateKey:o,walletName:e,chains:a,mode:r="onboard"}){await t.locator(g.importExistingWalletButton).click(),await t.locator(g.usePrivateKeyButton).click(),await t.getByRole("button",{name:"Private key",exact:!0}).click(),await t.locator(g.privateKeyInput).fill(o),await nt({page:t,walletName:e,mode:r,chains:a})}async function B({page:t,seedPhrase:o,walletName:e,chains:a,mode:r="onboard"}){await t.locator(g.importExistingWalletButton).click(),await t.locator(g.usePrivateKeyButton).click(),await t.getByRole("button",{name:"12 words",exact:!0}).click();let p=t.locator("input[type='password']"),d=o.split(" ");await p.first().fill(d[0]),await p.first().press("Tab");for(let i=1;i<d.length;i++){let u=p.nth(i),h=d[i];await u.fill(h),i<d.length-1&&await u.press("Tab")}await nt({page:t,walletName:e,mode:r,chains:a})}async function nt({page:t,walletName:o,mode:e,chains:a}){let r=new A,n=await _("keplr");if(await t.getByRole("button",{name:"Import",exact:!0}).click(),await t.locator(g.walletNameInput).fill(o),e==="onboard"){let w=t.locator(g.walletPasswordInput),b=t.locator(g.confirmWalletPasswordInput);await w.fill(n),await b.fill(n)}await t.locator(g.nextButton).click();let d=t.locator("div:has-text('All Native Chains')").nth(-4),i=t.locator("div[cursor='pointer']:has-text('Cosmos Hub')"),u=await d.locator("input[type='checkbox']").getAttribute("checked"),h=await i.locator("input[type='checkbox']").getAttribute("checked");u!==null&&await d.click(),h!==null&&await i.click();let x=t.locator(g.searchNetworkInput);for(let w of a){await x.fill(w);let v=t.locator("div[class='simplebar-content']").locator("div[cursor] > div").first().locator("div").filter({hasText:new RegExp(`^${Wt(w)}$`,"i")}).nth(2).locator("../../../../..");await v.waitFor({state:"visible",timeout:2e4}),await v.locator("input[type='checkbox']").getAttribute("checked")===null&&await v.click()}let f=t.locator(g.saveButton);if(await f.scrollIntoViewIfNeeded(),await f.click(),await S(2e3),e==="onboard"){await t.goto(await r.indexUrl());return}if(e==="add-account-single"){let w=t.locator(g.finishButton);await w.waitFor({state:"visible",timeout:2e4}),await rt(w).toBeEnabled({timeout:2e4}),await w.click()}}async function K(t){let e=await new A().onboardingUrl();await t.getByRole("link",{name:"Settings",exact:!0}).click(),await t.locator("div[cursor='pointer']").first().click(),await t.getByRole("button",{name:"Add Wallet",exact:!0}).click();let l;if(await rt.poll(async()=>(l=t.context().pages().find(m=>m.url().match(e)),!!l),{timeout:3e4}).toBe(!0).catch(m=>{console.error(`Failed to find onboarding page with URL matching ${e}. Original error: ${m}`)}),!l)throw new Error(`Onboarding page not found. Expected URL: ${e}`);return await k(l),await l.bringToFront(),l}async function it({page:t,chains:o,walletName:e,mode:a,...r}){let n=await K(t);"privateKey"in r&&await C({page:n,privateKey:r.privateKey,walletName:e,chains:o,mode:a}),"seedPhrase"in r&&await B({page:n,seedPhrase:r.seedPhrase,walletName:e,chains:o,mode:a}),await t.locator("div:has(div:has-text('Select Wallet'))").nth(-4).locator("div:has(> div > svg)").first().click(),await t.getByRole("link",{name:"Home",exact:!0}).click()}import{expect as Et}from"@playwright/test";var O={approveButton:"button:has-text('Approve')",rejectButton:"button[color='secondary']"};async function st(t){let o=t.locator(O.approveButton);await Et(o).toBeEnabled({timeout:2e4}),await o.click()}async function ct(t){t.getByRole("button",{name:"Approve",exact:!0}).click(),await S(1e3)}import{expect as It}from"@playwright/test";import P from"zod";var lt=P.discriminatedUnion("chain",[P.object({chain:P.literal(["Injective","Injective (Testnet)","Polygon"]),walletName:P.string().min(1,"Wallet name cannot be an empty string")}),P.object({chain:P.literal(["Bitcoin","Bitcoin Signet","Bitcoin Testnet"]),chainTag:P.literal(["Taproot","Native Segwit"]),walletName:P.string().min(1,"Wallet name cannot be an empty string")})]),pt=P.object({currentAccountName:P.string().min(1,"Current account name cannot be an empty string"),newAccountName:P.string().min(1,"New account name cannot be an empty string")});async function dt({page:t,...o}){let e=lt.parse({...o});await t.getByRole("textbox",{name:"Search for asset or chain (i.e. ATOM, Cosmos)",exact:!0}).fill(e.chain);let r=t.locator(`div:has-text("${e.chain}")`).nth(-2).filter({hasNot:t.locator("span")});if(await r.waitFor({state:"attached",timeout:2e4}),!await r.isVisible().catch(()=>!1))throw Error(`Make sure "${e.chain}" is activated.`);let l=await r.locator("div").all();It(l.length).toBeGreaterThan(0),await t.locator(`div:has(div:has-text('${e.walletName}'))`).nth(-3).locator("div:has(> div > svg)").click();let d=t.locator("div:has(> div[data-simplebar='init'])").last(),u=d.locator("div:has(> div > input)").locator("input");await u.fill(e.chain);let x=await d.locator("div[cursor='pointer']",{hasText:e.chain}).all(),f;for(let b of x){let v;"chainTag"in o&&(v=o.chainTag);let $=b.locator("div",{hasText:e.chain}).last(),V=v?b.locator("div",{hasText:v}).last():null,z=(V?await V?.isVisible().catch(()=>!1):!1)?await V?.textContent():null,G=await $.textContent(),xt=z?`${G} ${z}`:G,yt=v?`${e.chain} ${v}`:e.chain;if(xt===yt){f=$.locator("xpath=../../../.."),await u.clear();break}}if(!f)throw Error(`Address for ${e.walletName} account on "${e.chain}" chain not found.`);return await f.hover(),await f.scrollIntoViewIfNeeded(),await f.click(),await f.waitFor({state:"detached",timeout:7e3}),await t.evaluate(async()=>await navigator.clipboard.readText())}var F={openSidebarMenuButton:"div[cursor='pointer']:has(> div[cursor='pointer'])",menuPopupContent:"div[id='modal-root-3']",lockWalletButton:"div:has(> div:has-text('Lock Wallet'))",settingsButton:"div:has(a[href='#/settings'])"},U={unlockButton:"button[type='submit']:has-text('Unlock')",passwordInput:"input[placeholder='Type Your Password']"};async function mt(t){await t.locator(F.openSidebarMenuButton).click(),await t.locator(F.lockWalletButton).nth(-1).click(),await t.getByText("Welcome Back").waitFor({state:"visible",timeout:3e4})}import{styleText as ut}from"util";import{expect as Ft}from"@playwright/test";async function R(t,o){let e=t.locator("div[color]").nth(1);if(await e.textContent()===o){console.info(`
2
2
  Already on ${o} account. No need to switch.`);return}await e.click();let r=t.locator("div[class='simplebar-content'] > div").locator("> div",{hasText:o});if(!await r.isVisible().catch(()=>!1))throw new Error(`Account "${o}" not found. Make sure the account is onboarded or verify the account name.`);let l=t.locator("div:has-text('Select Wallet')").last();await r.click(),await l.waitFor({state:"detached",timeout:3e4})}async function M({page:t,onboard:o}){if(console.info(ut("yellowBright",`
3
- Keplr onboarding started...`,{validateStream:!1})),o.length===1){let e=o[0];if(e&&e.mode==="privateKey"){let{privateKey:a,walletName:r,chains:i}=e;await C({page:t,privateKey:a,walletName:r,chains:i,mode:"onboard"})}if(e&&e.mode==="seedPhrase"){let{seedPhrase:a,walletName:r,chains:i}=e;await B({page:t,seedPhrase:a,walletName:r,chains:i,mode:"onboard"})}}if(o.length>1){let e=o[0];if(e&&e.mode==="privateKey"){let{privateKey:n,walletName:u,chains:w}=e;await C({page:t,privateKey:n,walletName:u,chains:w,mode:"onboard"})}if(e&&e.mode==="seedPhrase"){let{seedPhrase:n,walletName:u,chains:w}=e;await B({page:t,seedPhrase:n,walletName:u,chains:w,mode:"onboard"})}let a=o.slice(1);for(let{...n}of a){let u=await K(t);if(n.mode==="privateKey"){let{privateKey:w,walletName:P,chains:h}=n;await C({page:u,privateKey:w,walletName:P,chains:h,mode:"add-account-single"})}if(n.mode==="seedPhrase"){let{seedPhrase:w,walletName:P,chains:h}=n;await B({page:u,seedPhrase:w,walletName:P,chains:h,mode:"add-account-single"})}}await t.locator("div",{hasText:"Select Wallet"}).last().locator("../../..").locator("div > svg").click(),await t.getByRole("link",{name:"Home",exact:!0}).click();let d=t.locator(F.openSidebarMenuButton);await Ft(d).toBeVisible({timeout:3e4});let p=o.at(-1)?.walletName,m=o[0]?.walletName;p&&m&&await R(t,m)}await S(3e3),console.info(ut("greenBright","\u2728 Keplr onboarding completed successfully",{validateStream:!1}))}async function wt(t){let o=t.locator(O.rejectButton);await o.waitFor({state:"visible",timeout:2e4}),await o.click()}async function ht({page:t,currentAccountName:o,newAccountName:e}){let a=pt.parse({currentAccountName:o,newAccountName:e});await t.getByRole("link",{name:"Settings",exact:!0}).click(),await t.locator("div[cursor='pointer']").first().click();let l=t.locator("div",{hasText:a.currentAccountName}).nth(-4);if(!await l.isVisible().catch(()=>!1))throw Error(`Account with name "${a.currentAccountName}" not found`);await l.locator("div[cursor='pointer'] svg").click(),await t.locator("div > div[cursor='pointer'] > div:has-text('Change Wallet Name')").last().click(),await t.locator("input[name='name']").fill(a.newAccountName),await t.locator("button:has-text('Save')").click()}async function D(t){let o=await _("keplr");await t.locator(U.passwordInput).fill(o),await t.locator(U.unlockButton).click(),await t.locator("div:has-text('Deposit')").last().waitFor({state:"visible",timeout:3e4})}var T=class extends y{page;constructor(o){super(),this.page=o}async onboard(o){await M({page:this.page,onboard:o})}async unlock(){await D(this.page)}async lock(){await dt(this.page)}async renameAccount({currentAccountName:o,newAccountName:e}){await ht({page:this.page,currentAccountName:o,newAccountName:e})}async switchAccount(o){await R(this.page,o)}async getAccountAddress({...o}){return await mt({page:this.page,...o})}async addAccount({chains:o,walletName:e,mode:a="add-account-multiple",...r}){await it({page:this.page,walletName:e,chains:o,mode:a,...r})}async connectToApp(){await ct(await this.promptPage(this.page.context()))}async confirmTransaction(){await st(await this.promptPage(this.page.context()))}async rejectTransaction(){await wt(await this.promptPage(this.page.context()))}};import gt from"fs";import Ot from"path";import{test as Rt,chromium as Dt}from"@playwright/test";import{expect as Nt}from"@playwright/test";async function H(t,o){let e=await t.newPage();return await Nt(async()=>{await e.goto(o),await k(e)}).toPass(),e}async function j(t,o){let e=await o.newPage();for(let{origin:a,localStorage:r}of t){let i=e.mainFrame();await i.goto(a),await i.evaluate(l=>{l.forEach(({name:d,value:p})=>{window.localStorage.setItem(d,p)})},r)}await e.close()}import _t from"fs/promises";async function ft(t){await _t.rm(t,{maxRetries:50,retryDelay:500,recursive:!0,force:!0})}var Kt=35e3;async function L(t,o){try{await Promise.race([t.close(),new Promise((e,a)=>setTimeout(()=>a(new Error("Context close timed out")),Kt))])}catch(e){console.warn(`Browser context close did not complete cleanly: ${e.message}`)}try{await ft(o)}catch(e){console.error(`Failed to remove temporary context directory at ${o}. Error:`,e)}}var W,ba=({slowMo:t=0,profileName:o}={})=>Rt.extend({contextPath:async({browserName:e},a,r)=>{let i=await I(`${e}-${r.testId}`);await a(i)},context:async({context:e,contextPath:a},r)=>{let i=new y,l=x(i.name),d=await N(i.name),p=Ot.resolve(l,o??"wallet-data");if(!gt.existsSync(p))throw new Error("\u274C Cache for Keplr wallet data not found. Create it first");gt.cpSync(p,a,{recursive:!0,force:!0});let m=[`--disable-extensions-except=${d}`,`--load-extension=${d}`];process.env.HEADLESS&&(m.push("--headless=new"),t>0&&console.warn("\u26A0\uFE0F Slow motion makes no sense in headless mode. It will be ignored!"));let n=await Dt.launchPersistentContext(a,{headless:!1,args:m,slowMo:process.env.HEADLESS?0:t});await n.grantPermissions(["clipboard-read"]);let{cookies:u,origins:w}=await e.storageState();u&&await n.addCookies(u),w&&w.length>0&&j(w,n);let P=await i.indexUrl();W=n.pages().find(f=>f.url().startsWith(P))||await H(n,P),await k(W);for(let f of n.pages()){let b=f.url();(b.includes("about:blank")||b.includes(i.onboardingPath))&&await f.close()}await W.bringToFront(),await D(W),await r(n),await L(n,a)},keplrPage:async({context:e},a)=>{await a(W)},keplr:async({context:e},a)=>{let r=new T(W);await a(r)}});import{test as Lt}from"@playwright/test";var Ia=({slowMo:t,profileName:o}={})=>Lt.extend({workerScopeContents:[async({browser:e},a,r)=>{let i=new y,{context:l,contextPath:d,walletPage:p}=await Z({wallet:i,workerInfo:r,profileName:o,slowMo:t});await l.grantPermissions(["clipboard-read"]);for(let n of l.pages())n.url().includes("about:blank")&&await n.close();let m=new T(p);await m.unlock(),await a({wallet:m,walletPage:p,context:l}),await L(l,d)},{scope:"worker"}]});export{T as Keplr,ba as keplrFixture,Ia as keplrWorkerScopeFixture,Z as workerScopeContext};
3
+ Keplr onboarding started...`,{validateStream:!1})),o.length===1){let e=o[0];if(e&&e.mode==="privateKey"){let{privateKey:a,walletName:r,chains:n}=e;await C({page:t,privateKey:a,walletName:r,chains:n,mode:"onboard"})}if(e&&e.mode==="seedPhrase"){let{seedPhrase:a,walletName:r,chains:n}=e;await B({page:t,seedPhrase:a,walletName:r,chains:n,mode:"onboard"})}}if(o.length>1){let e=o[0];if(e&&e.mode==="privateKey"){let{privateKey:i,walletName:u,chains:h}=e;await C({page:t,privateKey:i,walletName:u,chains:h,mode:"onboard"})}if(e&&e.mode==="seedPhrase"){let{seedPhrase:i,walletName:u,chains:h}=e;await B({page:t,seedPhrase:i,walletName:u,chains:h,mode:"onboard"})}let a=o.slice(1);for(let[i,u]of a.entries()){let h=await K(t);if(u.mode==="privateKey"){let{privateKey:x,walletName:f,chains:w}=u;await C({page:h,privateKey:x,walletName:f,chains:w,mode:"add-account-single"})}if(u.mode==="seedPhrase"){let{seedPhrase:x,walletName:f,chains:w}=u;await B({page:h,seedPhrase:x,walletName:f,chains:w,mode:"add-account-single"})}i!==a.length-1&&await t.locator("div",{hasText:"Select Wallet"}).last().locator("../../..").locator("div > svg").click()}await t.locator("div",{hasText:"Select Wallet"}).last().locator("../../..").locator("div > svg").click(),await t.getByRole("link",{name:"Home",exact:!0}).click();let m=t.locator(F.openSidebarMenuButton);await Ft(m).toBeVisible({timeout:3e4});let p=o.at(-1)?.walletName,d=o[0]?.walletName;p&&d&&await R(t,d)}await S(3e3),console.info(ut("greenBright","\u2728 Keplr onboarding completed successfully",{validateStream:!1}))}async function wt(t){let o=t.locator(O.rejectButton);await o.waitFor({state:"visible",timeout:2e4}),await o.click()}async function ht({page:t,currentAccountName:o,newAccountName:e}){let a=pt.parse({currentAccountName:o,newAccountName:e});await t.getByRole("link",{name:"Settings",exact:!0}).click(),await t.locator("div[cursor='pointer']").first().click();let l=t.locator("div",{hasText:a.currentAccountName}).nth(-4);if(!await l.isVisible().catch(()=>!1))throw Error(`Account with name "${a.currentAccountName}" not found`);await l.locator("div[cursor='pointer'] svg").click(),await t.locator("div > div[cursor='pointer'] > div:has-text('Change Wallet Name')").last().click(),await t.locator("input[name='name']").fill(a.newAccountName),await t.locator("button:has-text('Save')").click()}async function D(t){let o=await _("keplr");await t.locator(U.passwordInput).fill(o),await t.locator(U.unlockButton).click(),await t.locator("div:has-text('Deposit')").last().waitFor({state:"visible",timeout:3e4})}var T=class extends A{page;constructor(o){super(),this.page=o}async onboard(o){await M({page:this.page,onboard:o})}async unlock(){await D(this.page)}async lock(){await mt(this.page)}async renameAccount({currentAccountName:o,newAccountName:e}){await ht({page:this.page,currentAccountName:o,newAccountName:e})}async switchAccount(o){await R(this.page,o)}async getAccountAddress({...o}){return await dt({page:this.page,...o})}async addAccount({chains:o,walletName:e,mode:a="add-account-multiple",...r}){await it({page:this.page,walletName:e,chains:o,mode:a,...r})}async connectToApp(){await ct(await this.promptPage(this.page.context()))}async confirmTransaction(){await st(await this.promptPage(this.page.context()))}async rejectTransaction(){await wt(await this.promptPage(this.page.context()))}};import gt from"fs";import Ot from"path";import{test as Rt,chromium as Dt}from"@playwright/test";import{expect as Nt}from"@playwright/test";async function H(t,o){let e=await t.newPage();return await Nt(async()=>{await e.goto(o),await k(e)}).toPass(),e}async function j(t,o){let e=await o.newPage();for(let{origin:a,localStorage:r}of t){let n=e.mainFrame();await n.goto(a),await n.evaluate(l=>{l.forEach(({name:m,value:p})=>{window.localStorage.setItem(m,p)})},r)}await e.close()}import _t from"fs/promises";async function ft(t){await _t.rm(t,{maxRetries:50,retryDelay:500,recursive:!0,force:!0})}var Kt=35e3;async function L(t,o){try{await Promise.race([t.close(),new Promise((e,a)=>setTimeout(()=>a(new Error("Context close timed out")),Kt))])}catch(e){console.warn(`Browser context close did not complete cleanly: ${e.message}`)}try{await ft(o)}catch(e){console.error(`Failed to remove temporary context directory at ${o}. Error:`,e)}}var W,ba=({slowMo:t=0,profileName:o}={})=>Rt.extend({contextPath:async({browserName:e},a,r)=>{let n=await I(`${e}-${r.testId}`);await a(n)},context:async({context:e,contextPath:a},r)=>{let n=new A,l=y(n.name),m=await N(n.name),p=Ot.resolve(l,o??"wallet-data");if(!gt.existsSync(p))throw new Error("\u274C Cache for Keplr wallet data not found. Create it first");gt.cpSync(p,a,{recursive:!0,force:!0});let d=[`--disable-extensions-except=${m}`,`--load-extension=${m}`];process.env.HEADLESS&&(d.push("--headless=new"),t>0&&console.warn("\u26A0\uFE0F Slow motion makes no sense in headless mode. It will be ignored!"));let i=await Dt.launchPersistentContext(a,{headless:!1,args:d,slowMo:process.env.HEADLESS?0:t});await i.grantPermissions(["clipboard-read"]);let{cookies:u,origins:h}=await e.storageState();u&&await i.addCookies(u),h&&h.length>0&&j(h,i);let x=await n.indexUrl();W=i.pages().find(w=>w.url().startsWith(x))||await H(i,x),await k(W);for(let w of i.pages()){let b=w.url();(b.includes("about:blank")||b.includes(n.onboardingPath))&&await w.close()}await W.bringToFront(),await D(W),await r(i),await L(i,a)},keplrPage:async({context:e},a)=>{await a(W)},keplr:async({context:e},a)=>{let r=new T(W);await a(r)}});import{test as Lt}from"@playwright/test";var Ia=({slowMo:t,profileName:o}={})=>Lt.extend({workerScopeContents:[async({browser:e},a,r)=>{let n=new A,{context:l,contextPath:m,walletPage:p}=await Z({wallet:n,workerInfo:r,profileName:o,slowMo:t});await l.grantPermissions(["clipboard-read"]);for(let i of l.pages())i.url().includes("about:blank")&&await i.close();let d=new T(p);await d.unlock(),await a({wallet:d,walletPage:p,context:l}),await L(l,m)},{scope:"worker"}]});export{T as Keplr,ba as keplrFixture,Ia as keplrWorkerScopeFixture,Z as workerScopeContext};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chainwright",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "Playwright Web3 wallet testing framework for end-to-end dApp automation with MetaMask, Phantom, Solflare, Petra, Meteor, and Keplr",
5
5
  "type": "module",
6
6
  "license": "MIT",