chainwright 0.9.6 → 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.
|
@@ -18,14 +18,29 @@ declare class KeplrProfile {
|
|
|
18
18
|
declare const keplrChains: readonly ["Injective", "Injective (Testnet)", "Polygon", "Bitcoin", "Bitcoin Signet", "Bitcoin Testnet"];
|
|
19
19
|
type KeplrChains = (typeof keplrChains)[number];
|
|
20
20
|
type AddAndOnboardingArgs = {
|
|
21
|
+
walletName: string;
|
|
22
|
+
seedPhrase: string;
|
|
23
|
+
mode: "seedPhrase";
|
|
24
|
+
chains: Array<KeplrChains>;
|
|
25
|
+
} | {
|
|
21
26
|
walletName: string;
|
|
22
27
|
privateKey: string;
|
|
28
|
+
mode: "privateKey";
|
|
23
29
|
chains: Array<KeplrChains>;
|
|
24
30
|
};
|
|
25
31
|
type OnboardingArgs = Array<AddAndOnboardingArgs>;
|
|
26
|
-
type
|
|
32
|
+
type AddAccount = {
|
|
33
|
+
walletName: string;
|
|
34
|
+
chains: Array<KeplrChains>;
|
|
35
|
+
} & {
|
|
27
36
|
mode: "add-account-multiple" | "add-account-single" | "onboard";
|
|
28
37
|
};
|
|
38
|
+
interface AddAccountViaPrivateKey extends AddAccount {
|
|
39
|
+
privateKey: string;
|
|
40
|
+
}
|
|
41
|
+
interface AddAccountViaSeedPhrase extends AddAccount {
|
|
42
|
+
seedPhrase: string;
|
|
43
|
+
}
|
|
29
44
|
declare const getAccountAddressSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
30
45
|
chain: z.ZodLiteral<"Injective" | "Injective (Testnet)" | "Polygon">;
|
|
31
46
|
walletName: z.ZodString;
|
|
@@ -113,13 +128,14 @@ declare class Keplr extends KeplrProfile {
|
|
|
113
128
|
* @param {AddAccountArgs} args - The arguments to add the account.
|
|
114
129
|
* @param args.chains - The chains of the account to add.
|
|
115
130
|
* @param args.privateKey - The private key of the account to add, if the mode is "privateKey".
|
|
131
|
+
* @param args.seedPhrase - The seed phrase of the account to add, if the mode is "seedPhrase".
|
|
116
132
|
* @param args.walletName - The name of the wallet to add the account to.
|
|
117
133
|
* @param args.mode - The mode of adding the account (default: "add-account-multiple").
|
|
118
134
|
* @example
|
|
119
135
|
* const keplr = new Keplr(page);
|
|
120
136
|
* await keplr.addAccount({ chains: ["Testnet"], privateKey: "private key", walletName: "Keplr Wallet", mode: "add-account-multiple" });
|
|
121
137
|
*/
|
|
122
|
-
addAccount({ chains,
|
|
138
|
+
addAccount({ chains, walletName, mode, ...args }: AddAccountViaPrivateKey | AddAccountViaSeedPhrase): Promise<void>;
|
|
123
139
|
/**
|
|
124
140
|
* Connects to the wallet.
|
|
125
141
|
* This function connects to the wallet by opening the connect page and then clicking on the connect button.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import Z from"fs";import vt from"path";import{chromium as bt}from"@playwright/test";import yt from"path";var Y=".wallet-cache",q=".wallet-context";var J="13.33.0",_="https://github.com/amaify/chainwright/releases/download/v0.1.0/",Kt=`https://github.com/MetaMask/metamask-extension/releases/download/v${J}/metamask-chrome-${J}.zip`,Ut=`${_}solflare-wallet-extension-v2.19.1.zip`,Mt=`${_}petra-wallet-extension-v2.4.8.zip`,Vt=`${_}phantom-wallet-extension-v26.10.0.zip`,Ht=`${_}meteor-wallet-extension-v0.7.0.zip`,jt=`${_}keplr-wallet-extension-v0.13.3.zip`;async function N(t){return yt.resolve(process.cwd(),q,t)}import At from"path";function w(t){return At.resolve(process.cwd(),Y,t)}import Q from"fs";import Pt from"path";async function R(t){try{let e=w(t),o=Pt.resolve(e,"extension-path.txt");if(!Q.existsSync(o))throw new Error("\u274C extension-path.txt not found. Run setup script first.");let a=Q.readFileSync(o,"utf-8").trim();if(!a)throw new Error("\u274C extension-path.txt is empty. Run setup script first.");return a}catch(e){throw new Error(`\u274C Failed to get ${t} extension path: ${e.message}`)}}async function tt({wallet:t,workerInfo:e,profileName:o,slowMo:a}){let r=await N(e.workerIndex.toString()),s=w(t.name),c=vt.resolve(s,o??"wallet-data");if(!Z.existsSync(c))throw new Error(`Cache for ${t.name} does not exist. Create it first!`);Z.cpSync(c,r,{recursive:!0,force:!0});let p=await R(t.name),m=await bt.launchPersistentContext(r,{headless:!1,args:[`--disable-extensions-except=${p}`],slowMo:process.env.HEADLESS?0:a}),u=await t.indexUrl(),l=m.pages()[0];return l||(l=await m.newPage()),await l.goto(u),{context:m,walletPage:l,contextPath:r}}import{expect as nt}from"@playwright/test";function T(t){return new Promise(e=>setTimeout(e,t))}async function C(t){await t.waitForLoadState("load",{timeout:15e3}),await t.waitForLoadState("domcontentloaded",{timeout:15e3})}import et from"fs";import kt from"path";async function L(t){let e=w(t),o=kt.resolve(e,"password.txt");try{if(!et.existsSync(o))throw new Error("\u274C password.txt not found. Run setup script first.");return et.readFileSync(o,"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 ot({context:t,path:e,locator:o}){let a;try{await Ct.poll(async()=>(a=t.pages().filter(r=>r.url().startsWith("chrome-extension://")).find(r=>r.url().match(e)),!!a),{timeout:3e4}).toBe(!0)}catch{let r=t.pages().filter(s=>s.url().startsWith("chrome-extension://")).map(s=>s.url());throw new Error(`Popup page with path "${e}" not found in context after 30s. Pages in context: ${JSON.stringify(r)}`)}if(!a)throw new Error(`Popup page with path ${e} not found in context.`);return await St(a,o),await a.setViewportSize({width:360,height:592}),a}async function St(t,e){await t.waitForLoadState("load",{timeout:4e4}),await t.waitForLoadState("domcontentloaded",{timeout:4e4}),await t.locator(e).first().waitFor({state:"attached",timeout:4e4})}import at from"fs";import Bt from"path";async function rt(t){let e=w(t),o=Bt.resolve(e,"extension-id.txt");try{if(!at.existsSync(o))throw new Error("\u274C extension-id.txt not found. Run setup script first.");return at.readFileSync(o,"utf-8")}catch(a){throw new Error(`\u274C Failed to get ${t} extension ID from cache: ${a.message}`)}}var h=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 rt(this.name)}async promptPage(e){let o=await this.promptUrl();return await ot({context:e,path:o,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 Tt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function W({page:t,privateKey:e,walletName:o,chains:a,mode:r="onboard"}){let s=await L("keplr"),c=new h;if(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(e),await t.getByRole("button",{name:"Import",exact:!0}).click(),await t.locator(g.walletNameInput).fill(o),r==="onboard"){let A=t.locator(g.walletPasswordInput),F=t.locator(g.confirmWalletPasswordInput);await A.fill(s),await F.fill(s)}await t.locator(g.nextButton).click();let x=t.locator("div:has-text('All Native Chains')").nth(-4),P=t.locator("div[cursor='pointer']:has-text('Cosmos Hub')"),b=await x.locator("input[type='checkbox']").getAttribute("checked"),k=await P.locator("input[type='checkbox']").getAttribute("checked");b!==null&&await x.click(),k!==null&&await P.click();let D=t.locator(g.searchNetworkInput);for(let A of a){await D.fill(A);let B=t.locator("div[class='simplebar-content']").locator("div[cursor] > div").first().locator("div").filter({hasText:new RegExp(`^${Tt(A)}$`,"i")}).nth(2).locator("../../../../..");await B.waitFor({state:"visible",timeout:2e4}),await B.locator("input[type='checkbox']").getAttribute("checked")===null&&await B.click()}let S=t.locator(g.saveButton);if(await S.scrollIntoViewIfNeeded(),await S.click(),await T(2e3),r==="onboard"){await t.goto(await c.indexUrl());return}if(r==="add-account-single"){let A=t.locator(g.finishButton);await A.waitFor({state:"visible",timeout:2e4}),await nt(A).toBeEnabled({timeout:2e4}),await A.click()}}async function $(t){let o=await new h().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 c;if(await nt.poll(async()=>(c=t.context().pages().find(p=>p.url().match(o)),!!c),{timeout:3e4}).toBe(!0).catch(p=>{console.error(`Failed to find onboarding page with URL matching ${o}. Original error: ${p}`)}),!c)throw new Error(`Onboarding page not found. Expected URL: ${o}`);return await C(c),await c.bringToFront(),c}async function it({page:t,privateKey:e,chains:o,walletName:a,mode:r}){let s=await $(t);await W({page:s,privateKey:e,walletName:a,chains:o,mode:r}),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 Wt}from"@playwright/test";var K={approveButton:"button:has-text('Approve')",rejectButton:"button[color='secondary']"};async function ct(t){let e=t.locator(K.approveButton);await Wt(e).toBeEnabled({timeout:2e4}),await e.click()}async function st(t){t.getByRole("button",{name:"Approve",exact:!0}).click(),await T(1e3)}import{expect as Et}from"@playwright/test";import f from"zod";var lt=f.discriminatedUnion("chain",[f.object({chain:f.literal(["Injective","Injective (Testnet)","Polygon"]),walletName:f.string().min(1,"Wallet name cannot be an empty string")}),f.object({chain:f.literal(["Bitcoin","Bitcoin Signet","Bitcoin Testnet"]),chainTag:f.literal(["Taproot","Native Segwit"]),walletName:f.string().min(1,"Wallet name cannot be an empty string")})]),pt=f.object({currentAccountName:f.string().min(1,"Current account name cannot be an empty string"),newAccountName:f.string().min(1,"New account name cannot be an empty string")});async function mt({page:t,...e}){let o=lt.parse({...e});await t.getByRole("textbox",{name:"Search for asset or chain (i.e. ATOM, Cosmos)",exact:!0}).fill(o.chain);let r=t.locator(`div:has-text("${o.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 "${o.chain}" is activated.`);let c=await r.locator("div").all();Et(c.length).toBeGreaterThan(0),await t.locator(`div:has(div:has-text('${o.walletName}'))`).nth(-3).locator("div:has(> div > svg)").click();let u=t.locator("div:has(> div[data-simplebar='init'])").last(),d=u.locator("div:has(> div > input)").locator("input");await d.fill(o.chain);let v=await u.locator("div[cursor='pointer']",{hasText:o.chain}).all(),x;for(let b of v){let k;"chainTag"in e&&(k=e.chainTag);let D=b.locator("div",{hasText:o.chain}).last(),S=k?b.locator("div",{hasText:k}).last():null,F=(S?await S?.isVisible().catch(()=>!1):!1)?await S?.textContent():null,B=await D.textContent(),X=F?`${B} ${F}`:B,xt=k?`${o.chain} ${k}`:o.chain;if(X===xt){x=D.locator("xpath=../../../.."),await d.clear();break}}if(!x)throw Error(`Address for ${o.walletName} account on "${o.chain}" chain not found.`);return await x.hover(),await x.scrollIntoViewIfNeeded(),await x.click(),await x.waitFor({state:"detached",timeout:7e3}),await t.evaluate(async()=>await navigator.clipboard.readText())}var O={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'])"},H={unlockButton:"button[type='submit']:has-text('Unlock')",passwordInput:"input[placeholder='Type Your Password']"};async function ut(t){await t.locator(O.openSidebarMenuButton).click(),await t.locator(O.lockWalletButton).nth(-1).click(),await t.getByText("Welcome Back").waitFor({state:"visible",timeout:3e4})}import{styleText as dt}from"util";import{expect as It}from"@playwright/test";async function U(t,e){let o=t.locator("div[color]").nth(1);if(await o.textContent()===e){console.info(`
|
|
2
|
-
Already on ${
|
|
3
|
-
Keplr onboarding started...`,{validateStream:!1})),
|
|
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
|
+
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: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};
|
|
@@ -14,20 +14,32 @@ declare class MeteorProfile {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
type MeteorNetwork = "Mainnet" | "Testnet";
|
|
17
|
-
type
|
|
17
|
+
type SharedOnboardArgs = {
|
|
18
18
|
network: MeteorNetwork;
|
|
19
|
-
privateKey: string;
|
|
20
19
|
accountName: string;
|
|
21
20
|
additionalAccounts?: Array<AddAccountArgs>;
|
|
22
21
|
};
|
|
22
|
+
type OnboardingArgs = ({
|
|
23
|
+
mode: "privateKey";
|
|
24
|
+
privateKey: string;
|
|
25
|
+
} | {
|
|
26
|
+
mode: "secretPhrase";
|
|
27
|
+
secretPhrase: string;
|
|
28
|
+
}) & SharedOnboardArgs;
|
|
23
29
|
type RenameAccountArgs = {
|
|
24
30
|
newAccountName: string;
|
|
25
31
|
};
|
|
26
|
-
type
|
|
27
|
-
privateKey: string;
|
|
32
|
+
type AddAccountCommonArgs = {
|
|
28
33
|
accountName: string;
|
|
29
34
|
network: MeteorNetwork;
|
|
30
35
|
};
|
|
36
|
+
type AddAccountArgs = ({
|
|
37
|
+
privateKey: string;
|
|
38
|
+
mode: "privateKey";
|
|
39
|
+
} | {
|
|
40
|
+
secretPhrase: string;
|
|
41
|
+
mode: "secretPhrase";
|
|
42
|
+
}) & AddAccountCommonArgs;
|
|
31
43
|
type MeteorFixture = {
|
|
32
44
|
contextPath: string;
|
|
33
45
|
meteor: Meteor;
|
|
@@ -47,7 +59,7 @@ declare class Meteor extends MeteorProfile {
|
|
|
47
59
|
* const meteor = new Meteor(page);
|
|
48
60
|
* await meteor.onboard({ mode: "importPrivateKey", password: "password", privateKey: "private key" });
|
|
49
61
|
*/
|
|
50
|
-
onboard({ network,
|
|
62
|
+
onboard({ network, accountName, additionalAccounts, ...args }: OnboardingArgs): Promise<void>;
|
|
51
63
|
/**
|
|
52
64
|
* Unlocks the wallet by entering the password.
|
|
53
65
|
* @example
|
|
@@ -107,7 +119,7 @@ declare class Meteor extends MeteorProfile {
|
|
|
107
119
|
* const meteor = new Meteor(page);
|
|
108
120
|
* await meteor.addAccount(TBD);
|
|
109
121
|
*/
|
|
110
|
-
addAccount({ accountName, network,
|
|
122
|
+
addAccount({ accountName, network, ...args }: AddAccountArgs): Promise<void>;
|
|
111
123
|
/**
|
|
112
124
|
* Opens the settings page for the wallet.
|
|
113
125
|
* @example
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import tt from"fs";import gt from"path";import{chromium as yt}from"@playwright/test";import ft from"path";var Y=".wallet-cache",Q=".wallet-context";var J="13.33.0",
|
|
2
|
-
Already on ${o}, no need to switch network.`),"Exit";await
|
|
3
|
-
Switching to the ${o} account aborted. Account is already selected.`);return}await t.locator(
|
|
4
|
-
`))}async function R({page:t,
|
|
5
|
-
Meteor onboarding started...`,{validateStream:!1}));let c=await
|
|
6
|
-
Retrying search for account. ${
|
|
7
|
-
`),{validateStream:!1}))}await t.locator("button:not([aria-label='Back'],[id^='menu-button']):has-text('Account')").click();let j=t.locator("section[role='dialog']").locator("button:has-text('Close')").first();if(await j.isVisible().then(()=>!0).catch(()=>!1)&&await j.click(),await
|
|
1
|
+
import tt from"fs";import gt from"path";import{chromium as yt}from"@playwright/test";import ft from"path";var Y=".wallet-cache",Q=".wallet-context";var J="13.33.0",M="https://github.com/amaify/chainwright/releases/download/v0.1.0/",Dt=`https://github.com/MetaMask/metamask-extension/releases/download/v${J}/metamask-chrome-${J}.zip`,Ot=`${M}solflare-wallet-extension-v2.19.1.zip`,Rt=`${M}petra-wallet-extension-v2.4.8.zip`,Ut=`${M}phantom-wallet-extension-v26.10.0.zip`,$t=`${M}meteor-wallet-extension-v0.7.0.zip`,Vt=`${M}keplr-wallet-extension-v0.13.3.zip`;async function E(t){return ft.resolve(process.cwd(),Q,t)}import ht from"path";function f(t){return ht.resolve(process.cwd(),Y,t)}import Z from"fs";import xt from"path";async function N(t){try{let o=f(t),r=xt.resolve(o,"extension-path.txt");if(!Z.existsSync(r))throw new Error("\u274C extension-path.txt not found. Run setup script first.");let e=Z.readFileSync(r,"utf-8").trim();if(!e)throw new Error("\u274C extension-path.txt is empty. Run setup script first.");return e}catch(o){throw new Error(`\u274C Failed to get ${t} extension path: ${o.message}`)}}async function ot({wallet:t,workerInfo:o,profileName:r,slowMo:e}){let a=await E(o.workerIndex.toString()),c=f(t.name),w=gt.resolve(c,r??"wallet-data");if(!tt.existsSync(w))throw new Error(`Cache for ${t.name} does not exist. Create it first!`);tt.cpSync(w,a,{recursive:!0,force:!0});let l=await N(t.name),p=await yt.launchPersistentContext(a,{headless:!1,args:[`--disable-extensions-except=${l}`],slowMo:process.env.HEADLESS?0:e}),s=await t.indexUrl(),d=p.pages()[0];return d||(d=await p.newPage()),await d.goto(s),{context:p,walletPage:d,contextPath:a}}var u={openSidebarMenuButton:"button[aria-label='open sidebar']",addWalletButton:"button:has-text('Add Wallet')",settingsButton:"button:has-text('Settings')",settingsMenuBackButton:"button[aria-label='Back']"};var m={importExistingWalletButton:'button:has-text("Import an existing wallet")',switchNetworkButton:"button[id^='menu-button']",privateKeyButton:"button:has-text('Private Key')",secretPhraseButton:"button:has-text('Secret Phrase')",findMyAccountButton:"button:has-text('Find my account')"};async function I(t,o,r){let e=t.locator(m.switchNetworkButton).last();await e.scrollIntoViewIfNeeded();let a=await e.textContent(),c=o.split("net")[0]?.toLowerCase()??"";if(a?.toLowerCase()===c)return console.info(`
|
|
2
|
+
Already on ${o}, no need to switch network.`),"Exit";await e.click();let l=t.locator(r).last().locator(`> button:has-text('${o}')`);await l.click(),await t.locator("div > h2:has-text('Meteor Community')").isVisible().catch(()=>!1)&&await l.click()}async function k({page:t,newAccountName:o}){await t.locator(u.openSidebarMenuButton).click(),await t.locator("div:has(> h2):has(> svg)").click();let a=t.locator("input[placeholder='Ex. My Meteor Wallet']"),c=t.locator("button[type='submit']:has-text('Update')");await a.fill(o),await c.click(),await t.locator("div[id='root'] button[aria-label='Close']").click()}async function _({page:t,accountName:o,network:r,...e}){await t.locator(u.openSidebarMenuButton).click(),await t.locator(u.addWalletButton).click(),await I(t,r,"section[role='dialog'] div[role='menu']"),await t.locator(m.importExistingWalletButton).click();let l=t.locator('button:has-text("Continue")');e.mode==="secretPhrase"&&(await t.locator(m.secretPhraseButton).click(),await l.scrollIntoViewIfNeeded(),await l.click(),await t.locator("textarea:not([disabled])").fill(e.secretPhrase)),e.mode==="privateKey"&&(await t.locator(m.privateKeyButton).click(),await l.scrollIntoViewIfNeeded(),await l.click(),await t.locator("textarea:not([disabled])").fill(e.privateKey)),await t.locator(m.findMyAccountButton).click(),await t.locator("button[type='submit'][data-loading]").waitFor({state:"detached",timeout:25e3}),await t.locator("button:not([aria-label='Back'],[id^='menu-button']):has-text('Account')").click(),await k({page:t,newAccountName:o})}var B={approveButton:"button:has-text('Approve')",connectButton:"button:has-text('Connect')",cancelButton:"button:has-text('Cancel')"};import et from"fs";import Pt from"path";async function F(t){let o=f(t),r=Pt.resolve(o,"password.txt");try{if(!et.existsSync(r))throw new Error("\u274C password.txt not found. Run setup script first.");return et.readFileSync(r,"utf-8")}catch(e){throw new Error(`\u274C Failed to get ${t} password from cache: ${e.message}`)}}async function x(t){let o=await F("meteor"),r=t.locator("input[placeholder='Enter Password']"),e=t.locator('button:has-text("Unlock")');await r.fill(o),await e.click()}async function rt(t){await x(t),await t.locator(B.approveButton).click(),await t.locator("h2:has-text('Executing Transaction')").waitFor({state:"attached"}),await t.waitForEvent("close",{timeout:15e3})}async function C(t,o){if((await t.locator("div:has(button[type='button'][aria-label='open sidebar'])").nth(-2).locator("div:has(div > h2)").locator("div > h2").textContent())?.toLowerCase()===o.toLowerCase()){console.info(`
|
|
3
|
+
Switching to the ${o} account aborted. Account is already selected.`);return}await t.locator(u.openSidebarMenuButton).click();let p=await t.locator("div:has(div > button[type='button'][aria-label='Close'])").nth(-2).locator("div").nth(2).locator("> div").nth(1).locator("div").nth(1).locator("div > h2").all(),s=null;for(let d of p)if((await d.textContent())?.toLowerCase()===o.toLowerCase()){s=d;break}if(!s)throw new Error(`Account with name "${o}" not found.`);await s.click()}async function at(t,o){await x(t),o&&await C(t,o);let r=t.getByRole("heading",{name:"Connect Request",exact:!0});await Promise.all([t.locator(B.connectButton).click(),r.waitFor({state:"detached",timeout:3e4})])}async function nt(t){return await t.locator("div:has(button[type='button'][aria-label='open sidebar'])").nth(-2).locator("div:has(div > h2)").locator("div > svg").click(),await t.evaluate(async()=>await navigator.clipboard.readText())}async function it(t){await t.locator(u.openSidebarMenuButton).click(),await t.locator("button:has-text('Lock Wallet')").click()}import{styleText as O}from"util";function T(t){return new Promise(o=>setTimeout(o,t))}import{expect as bt}from"@playwright/test";async function ct({context:t,path:o,locator:r}){let e;try{await bt.poll(async()=>(e=t.pages().filter(a=>a.url().startsWith("chrome-extension://")).find(a=>a.url().match(o)),!!e),{timeout:3e4}).toBe(!0)}catch{let a=t.pages().filter(c=>c.url().startsWith("chrome-extension://")).map(c=>c.url());throw new Error(`Popup page with path "${o}" not found in context after 30s. Pages in context: ${JSON.stringify(a)}`)}if(!e)throw new Error(`Popup page with path ${o} not found in context.`);return await At(e,r),await e.setViewportSize({width:360,height:592}),e}async function At(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 st from"fs";import kt from"path";async function lt(t){let o=f(t),r=kt.resolve(o,"extension-id.txt");try{if(!st.existsSync(r))throw new Error("\u274C extension-id.txt not found. Run setup script first.");return st.readFileSync(r,"utf-8")}catch(e){throw new Error(`\u274C Failed to get ${t} extension ID from cache: ${e.message}`)}}var g=class{name="meteor";onboardingPath="ext_index_popup.html";async indexUrl(){return`chrome-extension://${await this.extensionId()}/ext_index_popup.html`}async promptUrl(){return`chrome-extension://${await this.extensionId()}/ext_index.html`}async extensionId(){return await lt(this.name)}async promptPage(o){let r=await this.promptUrl();return await ct({context:o,path:r,locator:"div[id='root']"})}};async function S(t){await t.locator(u.openSidebarMenuButton).click(),await t.locator(u.settingsButton).click()}async function L(t,o){if(await S(t),await I(t,o,"div[role='menu']")==="Exit"){let c=t.locator(u.settingsMenuBackButton);await c.scrollIntoViewIfNeeded(),await c.click();return}let e=t.locator("p:has-text('Available Balance')");if(await T(1e3),!await e.isVisible().catch(()=>!1))throw new Error([`There is no associated account for the ${o} network in your wallet.`,`Please add an account to the ${o} network in your wallet using the "addAccount" method.`,"NOTE: For the account to be persisted across tests, do this when onboarding the wallet."].join(`
|
|
4
|
+
`))}async function R({page:t,network:o,accountName:r,additionalAccounts:e,...a}){console.info(O("yellowBright",`
|
|
5
|
+
Meteor onboarding started...`,{validateStream:!1}));let c=await F("meteor"),l=await new g().indexUrl();await t.goto(l);let p=t.locator(m.switchNetworkButton),s=await p.textContent(),d=o.split("net")[0]?.toLowerCase()??"";s?.toLowerCase().includes(d)||(await p.click(),await t.locator("div[role='menu']").locator(`> button:has-text('${o}')`).click());let P=t.locator("input[placeholder='Enter Password']"),A=t.locator("input[placeholder='Confirm Password']"),K=t.locator("label.chakra-checkbox .chakra-checkbox__control"),h=t.locator('button:has-text("Continue")');await P.fill(c),await A.fill(c),await K.click(),await h.click(),await t.locator(m.importExistingWalletButton).click(),a.mode==="secretPhrase"&&(await t.locator(m.secretPhraseButton).click(),await h.scrollIntoViewIfNeeded(),await h.click(),await t.locator("textarea:not([disabled])").fill(a.secretPhrase)),a.mode==="privateKey"&&(await t.locator(m.privateKeyButton).click(),await h.scrollIntoViewIfNeeded(),await h.click(),await t.locator("textarea:not([disabled])").fill(a.privateKey));let H=t.locator(m.findMyAccountButton);await H.click();let z=t.locator("button[type='submit'][data-loading]");if(await z.waitFor({state:"detached",timeout:25e3}),await t.getByRole("status").locator("div[id='toast-1-title']:has-text('No Account Found')").isVisible().catch(()=>!1)){let y=5,b=!1;for(;y>0;){if(console.info(`
|
|
6
|
+
Retrying search for account. ${y} attempts left`),await T(15e3),await H.click(),await z.waitFor({state:"detached",timeout:2e4}),await t.locator("div:has-text('Import Your Account')").nth(-2).locator("button").isVisible().catch(()=>!1)){b=!0;break}y-=1}if(!b)throw Error(O("redBright",["No Account Found","Account associated with the private key not found. Please make sure you are trying to import an account on the correct network(Mainnet/Testnet)."].join(`
|
|
7
|
+
`),{validateStream:!1}))}await t.locator("button:not([aria-label='Back'],[id^='menu-button']):has-text('Account')").click();let j=t.locator("section[role='dialog']").locator("button:has-text('Close')").first();if(await j.isVisible().then(()=>!0).catch(()=>!1)&&await j.click(),await k({page:t,newAccountName:r}),e&&e.length>0){for(let{accountName:q,network:G,...dt}of e)await _({page:t,accountName:q,network:G,...dt});await S(t);let y=t.locator(m.switchNetworkButton).last();await y.scrollIntoViewIfNeeded();let b=await y.textContent(),X=o.split("net")[0]?.toLowerCase()??"";b?.toLowerCase()!==X&&await L(t,o),await C(t,r)}await T(3e3),console.info(O("greenBright","\u2728 Meteor onboarding completed successfully"))}async function pt(t){await x(t),await t.locator(B.cancelButton).click()}var v=class extends g{page;constructor(o){super(),this.page=o}async onboard({network:o,accountName:r,additionalAccounts:e,...a}){await R({page:this.page,network:o,accountName:r,additionalAccounts:e,...a})}async unlock(){await x(this.page)}async lock(){await it(this.page)}async renameAccount({newAccountName:o}){await k({page:this.page,newAccountName:o})}async switchNetwork(o){await L(this.page,o)}async switchAccount(o){await C(this.page,o)}async getAccountAddress(){return await nt(this.page)}async addAccount({accountName:o,network:r,...e}){await _({page:this.page,accountName:o,network:r,...e})}async openSettings(){await S(this.page)}async connectToApp(o){await at(await this.promptPage(this.page.context()),o)}async confirmTransaction(){await rt(await this.promptPage(this.page.context()))}async rejectTransaction(){await pt(await this.promptPage(this.page.context()))}};import mt from"fs";import vt from"path";import{test as Mt,chromium as Et}from"@playwright/test";import{expect as Bt}from"@playwright/test";async function U(t){await t.waitForLoadState("load",{timeout:15e3}),await t.waitForLoadState("domcontentloaded",{timeout:15e3})}async function $(t,o){let r=await t.newPage();return await Bt(async()=>{await r.goto(o),await U(r)}).toPass(),r}async function V(t,o){let r=await o.newPage();for(let{origin:e,localStorage:a}of t){let c=r.mainFrame();await c.goto(e),await c.evaluate(w=>{w.forEach(({name:l,value:p})=>{window.localStorage.setItem(l,p)})},a)}await r.close()}import Ct from"fs/promises";async function ut(t){await Ct.rm(t,{maxRetries:50,retryDelay:500,recursive:!0,force:!0})}var St=35e3;async function D(t,o){try{await Promise.race([t.close(),new Promise((r,e)=>setTimeout(()=>e(new Error("Context close timed out")),St))])}catch(r){console.warn(`Browser context close did not complete cleanly: ${r.message}`)}try{await ut(o)}catch(r){console.error(`Failed to remove temporary context directory at ${o}. Error:`,r)}}var W,Mr=({slowMo:t=0,profileName:o}={})=>Mt.extend({contextPath:async({browserName:r},e,a)=>{let c=await E(`${r}-${a.testId}`);await e(c)},context:async({context:r,contextPath:e},a)=>{let c=new g,w=f(c.name),l=await N(c.name),p=vt.resolve(w,o??"wallet-data");if(!mt.existsSync(p))throw new Error("\u274C Cache for Meteor wallet data not found. Create it first");mt.cpSync(p,e,{recursive:!0,force:!0}),process.env.HEADLESS&&t>0&&console.warn("\u26A0\uFE0F Slow motion makes no sense in headless mode. It will be ignored!");let s=await Et.launchPersistentContext(e,{headless:!1,args:[`--disable-extensions-except=${l}`,`--load-extension=${l}`],slowMo:process.env.HEADLESS?0:t});await s.grantPermissions(["clipboard-read"]);let{cookies:d,origins:P}=await r.storageState();d&&await s.addCookies(d),P&&P.length>0&&V(P,s);let A=await c.indexUrl();W=s.pages().find(h=>h.url().startsWith(A))||await $(s,A);for(let h of s.pages())h.url().includes("about:blank")&&await h.close();await W.bringToFront(),await x(W),await a(s),await D(s,e)},meteorPage:async({context:r},e)=>{await e(W)},meteor:async({context:r},e)=>{let a=new v(W);await e(a)}});import{test as Tt}from"@playwright/test";var Lr=({slowMo:t,profileName:o}={})=>Tt.extend({workerScopeContents:[async({browser:r},e,a)=>{let{context:c,contextPath:w,walletPage:l}=await ot({workerInfo:a,profileName:o,slowMo:t,wallet:new g});await c.grantPermissions(["clipboard-read"]);for(let s of c.pages())s.url().includes("about:blank")&&await s.close();let p=new v(l);await p.unlock(),await e({wallet:p,walletPage:l,context:c}),await D(c,w)},{scope:"worker"}]});export{v as Meteor,Mr as meteorFixture,Lr as meteorWorkerScopeFixture,ot as workerScopeContext};
|
package/package.json
CHANGED