From 1db80d27547b4ede16b7a006fe0c0cfe5a81f364 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Thu, 4 Jul 2024 07:00:26 -0400 Subject: [PATCH 01/16] setup --- wallets/phantom/environment.d.ts | 19 +++++++ wallets/phantom/package.json | 54 +++++++++++++++++++ wallets/phantom/playwright.config.ts | 50 +++++++++++++++++ .../.env => phantom/src/PhantomWallet.ts} | 0 wallets/phantom/src/index.ts | 3 ++ wallets/phantom/test/synpress.ts | 5 ++ wallets/phantom/tsconfig.build.json | 12 +++++ wallets/phantom/tsconfig.json | 12 +++++ wallets/phantom/tsup.config.ts | 12 +++++ 9 files changed, 167 insertions(+) create mode 100644 wallets/phantom/environment.d.ts create mode 100644 wallets/phantom/package.json create mode 100644 wallets/phantom/playwright.config.ts rename wallets/{keplr/.env => phantom/src/PhantomWallet.ts} (100%) create mode 100644 wallets/phantom/src/index.ts create mode 100644 wallets/phantom/test/synpress.ts create mode 100644 wallets/phantom/tsconfig.build.json create mode 100644 wallets/phantom/tsconfig.json create mode 100644 wallets/phantom/tsup.config.ts diff --git a/wallets/phantom/environment.d.ts b/wallets/phantom/environment.d.ts new file mode 100644 index 000000000..fed78f861 --- /dev/null +++ b/wallets/phantom/environment.d.ts @@ -0,0 +1,19 @@ +declare global { + namespace NodeJS { + interface ProcessEnv { + CI: boolean + HEADLESS: boolean + } + } +} + +declare global { + interface Window { + ethereum: import('ethers').Eip1193Provider + } + + // biome-ignore lint/suspicious/noExplicitAny: Web3Mock is a mock object + const Web3Mock: any +} + +export {} diff --git a/wallets/phantom/package.json b/wallets/phantom/package.json new file mode 100644 index 000000000..603a27017 --- /dev/null +++ b/wallets/phantom/package.json @@ -0,0 +1,54 @@ +{ + "name": "@synthetixio/synpress-phantom", + "version": "0.0.1-alpha.0", + "type": "module", + "exports": { + "types": "./types/index.d.ts", + "default": "./dist/index.js" + }, + "main": "./dist/index.js", + "types": "./types/index.d.ts", + "files": [ + "dist", + "src", + "types" + ], + "scripts": { + "build": "pnpm run clean && pnpm run build:dist && pnpm run build:types", + "build:cache": "synpress-cache test/wallet-setup --phantom", + "build:dist": "tsup --tsconfig tsconfig.build.json", + "build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json", + "clean": "rimraf dist types", + "test:coverage": "vitest run --coverage", + "test:e2e:headful": "playwright test", + "test:e2e:headless": "HEADLESS=true playwright test", + "test:e2e:headless:ui": "HEADLESS=true playwright test --ui", + "test:watch": "vitest watch", + "types:check": "tsc --noEmit" + }, + "dependencies": { + "@synthetixio/synpress-cache": "workspace:*", + "@synthetixio/synpress-core": "workspace:*", + "@viem/anvil": "0.0.7", + "clipboardy": "4.0.0", + "fs-extra": "11.2.0", + "node-fetch": "3.3.2", + "underscore": "1.13.6", + "zod": "3.22.4" + }, + "devDependencies": { + "@synthetixio/synpress-tsconfig": "workspace:*", + "@types/fs-extra": "11.0.4", + "@types/node": "20.11.17", + "@types/underscore": "1.11.15", + "@vitest/coverage-v8": "1.2.2", + "cypress": "13.9.0", + "rimraf": "5.0.5", + "tsup": "8.0.2", + "typescript": "5.3.3", + "vitest": "1.2.2" + }, + "peerDependencies": { + "@playwright/test": "1.44.0" + } +} \ No newline at end of file diff --git a/wallets/phantom/playwright.config.ts b/wallets/phantom/playwright.config.ts new file mode 100644 index 000000000..f9b8903a4 --- /dev/null +++ b/wallets/phantom/playwright.config.ts @@ -0,0 +1,50 @@ +import { defineConfig, devices } from '@playwright/test' + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + // Look for test files in the "test/e2e" directory, relative to this configuration file. + testDir: './test/e2e', + + // We're increasing the timeout to 60 seconds to allow all traces to be recorded. + // Sometimes it threw an error saying that traces were not recorded in the 30 seconds timeout limit. + timeout: 60_000, + + // Run all tests in parallel. + fullyParallel: true, + + // Fail the build on CI if you accidentally left test.only in the source code. + forbidOnly: !!process.env.CI, + + // Fail all remaining tests on CI after the first failure. We want to reduce the feedback loop on CI to minimum. + maxFailures: process.env.CI ? 1 : 0, + + // Opt out of parallel tests on CI since it supports only 1 worker. + workers: process.env.CI ? 1 : undefined, + + // Concise 'dot' for CI, default 'html' when running locally. + // See https://playwright.dev/docs/test-reporters. + reporter: process.env.CI + ? [['html', { open: 'never', outputFolder: `playwright-report-${process.env.HEADLESS ? 'headless' : 'headful'}` }]] + : 'html', + + // Shared settings for all the projects below. + // See https://playwright.dev/docs/api/class-testoptions. + use: { + // We are using locally deployed MetaMask Test Dapp. + baseURL: '/', + + // Collect all traces on CI, and only traces for failed tests when running locally. + // See https://playwright.dev/docs/trace-viewer. + trace: process.env.CI ? 'on' : 'retain-on-failure' + }, + + // Configure projects for major browsers. + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] } + } + ] +}) diff --git a/wallets/keplr/.env b/wallets/phantom/src/PhantomWallet.ts similarity index 100% rename from wallets/keplr/.env rename to wallets/phantom/src/PhantomWallet.ts diff --git a/wallets/phantom/src/index.ts b/wallets/phantom/src/index.ts new file mode 100644 index 000000000..237c76da9 --- /dev/null +++ b/wallets/phantom/src/index.ts @@ -0,0 +1,3 @@ +export * from './PhantomWallet' +export * from './utils' +export * from './fixtures/phantomFixtures' \ No newline at end of file diff --git a/wallets/phantom/test/synpress.ts b/wallets/phantom/test/synpress.ts new file mode 100644 index 000000000..4fffc0e54 --- /dev/null +++ b/wallets/phantom/test/synpress.ts @@ -0,0 +1,5 @@ +import { testWithSynpress } from '@synthetixio/synpress-core' +import { phantomFixtures } from '../src' +import importPhantom from './wallet-setup/import-wallet.setup' + +export default testWithSynpress(phantomFixtures(importPhantom)) diff --git a/wallets/phantom/tsconfig.build.json b/wallets/phantom/tsconfig.build.json new file mode 100644 index 000000000..9af73f809 --- /dev/null +++ b/wallets/phantom/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "@synthetixio/synpress-tsconfig/base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "types", + "declaration": true, + "sourceMap": true, + "declarationMap": true + }, + "include": ["src"], + "files": ["environment.d.ts"] +} diff --git a/wallets/phantom/tsconfig.json b/wallets/phantom/tsconfig.json new file mode 100644 index 000000000..138492f5e --- /dev/null +++ b/wallets/phantom/tsconfig.json @@ -0,0 +1,12 @@ +{ + "type": "commonjs", + "extends": "./tsconfig.build.json", + "compilerOptions": { + "rootDir": ".", + "exactOptionalPropertyTypes": false, // Allows for `undefined` in `playwright.config.ts` + "types": ["cypress"], + "sourceMap": false + }, + "include": ["src", "test"], + "files": ["environment.d.ts", "playwright.config.ts"] +} diff --git a/wallets/phantom/tsup.config.ts b/wallets/phantom/tsup.config.ts new file mode 100644 index 000000000..02624a177 --- /dev/null +++ b/wallets/phantom/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + name: 'phantom', + entry: ['src/index.ts'], + outDir: 'dist', + format: 'esm', + splitting: false, + treeshake: true, + sourcemap: true, + external: ['@playwright/test'] +}) From e7fb08216c8a385af8f4680b19a3c558edbf3411 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Thu, 4 Jul 2024 08:14:45 -0400 Subject: [PATCH 02/16] pages --- wallets/phantom/src/PhantomWallet.ts | 58 +++++ .../pages/ConfirmationPage/actions/index.ts | 0 .../src/pages/ConfirmationPage/page.ts | 13 + .../pages/ConfirmationPage/selectors/index.ts | 12 + .../src/pages/HomePage/actions/index.ts | 0 wallets/phantom/src/pages/HomePage/page.ts | 13 + .../src/pages/HomePage/selectors/index.ts | 165 +++++++++++++ .../src/pages/LockPage/actions/index.ts | 0 wallets/phantom/src/pages/LockPage/page.ts | 13 + .../src/pages/LockPage/selectors/index.ts | 109 +++++++++ .../pages/NotificationPage/actions/index.ts | 0 .../src/pages/NotificationPage/page.ts | 13 + .../pages/NotificationPage/selectors/index.ts | 225 ++++++++++++++++++ .../src/pages/SettingPage/actions/index.ts | 0 wallets/phantom/src/pages/SettingPage/page.ts | 13 + .../src/pages/SettingPage/selectors/index.ts | 5 + .../phantom/src/utils/selectors/loading.ts | 16 ++ 17 files changed, 655 insertions(+) create mode 100644 wallets/phantom/src/pages/ConfirmationPage/actions/index.ts create mode 100644 wallets/phantom/src/pages/ConfirmationPage/page.ts create mode 100644 wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts create mode 100644 wallets/phantom/src/pages/HomePage/actions/index.ts create mode 100644 wallets/phantom/src/pages/HomePage/page.ts create mode 100644 wallets/phantom/src/pages/HomePage/selectors/index.ts create mode 100644 wallets/phantom/src/pages/LockPage/actions/index.ts create mode 100644 wallets/phantom/src/pages/LockPage/page.ts create mode 100644 wallets/phantom/src/pages/LockPage/selectors/index.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/index.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/page.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/selectors/index.ts create mode 100644 wallets/phantom/src/pages/SettingPage/actions/index.ts create mode 100644 wallets/phantom/src/pages/SettingPage/page.ts create mode 100644 wallets/phantom/src/pages/SettingPage/selectors/index.ts create mode 100644 wallets/phantom/src/utils/selectors/loading.ts diff --git a/wallets/phantom/src/PhantomWallet.ts b/wallets/phantom/src/PhantomWallet.ts index e69de29bb..76e713570 100644 --- a/wallets/phantom/src/PhantomWallet.ts +++ b/wallets/phantom/src/PhantomWallet.ts @@ -0,0 +1,58 @@ +import { type BrowserContext, type Page } from '@playwright/test' +import { HomePage } from './pages/HomePage/page' +import { LockPage } from './pages/LockPage/page' +import { NotificationPage } from './pages/NotificationPage/page' + +export class KeplrWallet { + readonly lockPage: LockPage + readonly homePage: HomePage + readonly notificationPage: NotificationPage + + constructor( + readonly page: Page, + readonly context?: BrowserContext, + readonly password?: string, + readonly extensionId?: string | undefined + ) { + this.lockPage = new LockPage(page) + this.homePage = new HomePage(page) + this.notificationPage = new NotificationPage(page) + } + /** + * Does initial setup for the wallet. + * + * @param playwrightInstance. The playwright instance to use. + * @param secretWordsOrPrivateKey. The secret words or private key to import. + * @param password. The password to set. + */ + async setupWallet({ secretWordsOrPrivateKey, password }: { secretWordsOrPrivateKey: string; password: string }) { + const wallet = await this.lockPage.importWallet(secretWordsOrPrivateKey, password) + return wallet + } + + async createWallet(password: string) { + const wallet = await this.lockPage.createWallet(password) + return wallet + } + + async getWalletAddress(wallet: string) { + const walletAddress = await this.homePage.getWalletAddress(wallet) + return walletAddress + } + + async addNewTokensFound() { + return await this.homePage.addNewTokensFound() + } + + async disconnectWalletFromDapps() { + return await this.homePage.disconnectWalletFromDapps() + } + + async acceptAccess() { + return await this.notificationPage.acceptAccess() + } + + async rejectAccess() { + return await this.notificationPage.rejectAccess() + } +} diff --git a/wallets/phantom/src/pages/ConfirmationPage/actions/index.ts b/wallets/phantom/src/pages/ConfirmationPage/actions/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/wallets/phantom/src/pages/ConfirmationPage/page.ts b/wallets/phantom/src/pages/ConfirmationPage/page.ts new file mode 100644 index 000000000..52c37d3ec --- /dev/null +++ b/wallets/phantom/src/pages/ConfirmationPage/page.ts @@ -0,0 +1,13 @@ +import type { Page } from '@playwright/test' +import { confirmationPageElements } from './selectors' + +export class ConfirmationPage { + static readonly selectors = confirmationPageElements + readonly selectors = confirmationPageElements + + readonly page: Page + + constructor(page: Page) { + this.page = page + } +} diff --git a/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts b/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts new file mode 100644 index 000000000..224ff168e --- /dev/null +++ b/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts @@ -0,0 +1,12 @@ +const confirmationPage = '.confirmation-page'; +const confirmationPageFooter = `${confirmationPage} .confirmation-footer`; +const footer = { + footer: confirmationPageFooter, + cancelButton: `${confirmationPageFooter} .btn-secondary`, + approveButton: `${confirmationPageFooter} .btn-primary`, +}; + +export const confirmationPageElements = { + confirmationPage, + footer, +}; \ No newline at end of file diff --git a/wallets/phantom/src/pages/HomePage/actions/index.ts b/wallets/phantom/src/pages/HomePage/actions/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/wallets/phantom/src/pages/HomePage/page.ts b/wallets/phantom/src/pages/HomePage/page.ts new file mode 100644 index 000000000..8b2424843 --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/page.ts @@ -0,0 +1,13 @@ +import type { Page } from '@playwright/test' +import { homePageElements } from './selectors' + +export class HomePage { + static readonly selectors = homePageElements + readonly selectors = homePageElements + + readonly page: Page + + constructor(page: Page) { + this.page = page + } +} diff --git a/wallets/phantom/src/pages/HomePage/selectors/index.ts b/wallets/phantom/src/pages/HomePage/selectors/index.ts new file mode 100644 index 000000000..783d34845 --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/selectors/index.ts @@ -0,0 +1,165 @@ +const networkSwitcherButtonSelector = '.network-display'; + +const networkSwitcher = { + button: networkSwitcherButtonSelector, + networkName: `${networkSwitcherButtonSelector} .typography`, + dropdownMenu: '[data-testid="network-droppo"]', + dropdownMenuItem: `[data-testid="network-droppo"] .dropdown-menu-item`, + mainnetNetworkItem: `[data-testid="network-droppo"] [data-testid="mainnet-network-item"]`, + goerliNetworkItem: `[data-testid="network-droppo"] [data-testid="goerli-network-item"]`, + sepoliaNetworkItem: `[data-testid="network-droppo"] [data-testid="sepolia-network-item"]`, + localhostNetworkItem: `[data-testid="network-droppo"] [data-testid="Localhost 8545-network-item"]`, + networkButton: number => + `[data-testid="network-droppo"] .dropdown-menu-item:nth-child(${ + 3 + number + })`, +}; + + +const walletOverview = '.wallet-overview'; + +const tabs = { + assetsButton: '[data-testid="home__asset-tab"] button', + activityButton: '[data-testid="home__activity-tab"] button', +}; + +const transactionList = '.transaction-list__transactions'; +const pendingTransactionsList = `${transactionList} .transaction-list__pending-transactions`; +const completedTransactionsList = `${transactionList} .transaction-list__completed-transactions`; +const activityTab = { + transactionList, + pendingTransactionsList, + completedTransactionsList, + unconfirmedTransaction: `${pendingTransactionsList} .transaction-list-item--unconfirmed`, + confirmedTransaction: `${completedTransactionsList} .transaction-list-item`, +}; + +const popupSelector = '.popover-container'; +const sendPopupSelector = `${popupSelector} .transaction-list-item-details`; +const popup = { + container: popupSelector, + closeButton: '.popover-header__button', + background: '.popover-bg', + sendPopup: { + container: sendPopupSelector, + speedUpButton: `${sendPopupSelector} .btn-primary`, + cancelButton: `${sendPopupSelector} .btn-secondary`, + transactionStatus: `${sendPopupSelector} .transaction-status`, + copyTxIdButton: `${sendPopupSelector} .transaction-list-item-details__tx-hash .transaction-list-item-details__header-button a`, + }, +}; + +const tippyTooltipSelector = '.tippy-popper'; +const tippyTooltip = { + container: tippyTooltipSelector, + closeButton: `${tippyTooltipSelector} button`, +}; + +const actionableMessageSelector = '.actionable-message'; +const actionableMessage = { + container: actionableMessageSelector, + closeButton: `${actionableMessageSelector} button`, +}; + +const accountMenu = { + accountButton: number => `[data-testid="account-menu"] [data-testid="tooltip_interactive-wrapper"]:nth-child(${number})`, +}; + +const settingsMenu = { + settingsMenuButton: '[data-testid="settings-menu-open-button"]', + settingsSidebarButton: '[data-testid="sidebar_menu-button-settings"]', + settingsSidebarCloseButton: '[data-testid="settings-menu-close-button"]', + settingsPreferencesButton: '[data-testid="settings-item-preferences"]', + trustedAppsRow: '[data-testid="settings-item-trusted-apps"]', + developerSettingsRow: '[data-testid="settings-item-developer-settings"]', + defaultAppWalletRow: '[data-testid="settings-item-metamask-override"]', +}; +const whatsNew = { + header: '[data-testid="whats_new-header"]', + continueButton: '[data-testid="whats_new-continue_button"]', +}; + +const welcome = { + takeTheTourButton: '[data-testid="welcome-take_the_tour"]', + takeTheTourButtonNext: '[data-testid="primary-button"]', + finishSetup: ['data-testid="onboarding-form-submit-button"'], +}; + +const accountBar = { + title: '[data-testid="tooltip_interactive-wrapper"]', + ethRow: '[data-testid="account-header-chain-eip155:1"]', + solanaRow: '[data-testid="account-header-chain-solana:101"]', +}; + +const defaultWallet = { + metamask: '[data-testid="metamask-override--USE_METAMASK"]', + phantom: '[data-testid="metamask-override--USE_PHANTOM"]', + always_ask: '[data-testid="metamask-override--ALWAYS_ASK"]', +}; + +const connectedSites = { + trustedAppsRevokeButton: '[data-testid="trusted-apps-revoke-button"]', + trustedAppsBackButton: '[data-testid="header--back"]', + rowButton: '[data-testid="trusted_apps_row-button"]', +}; + +const accountModal = { + walletAddressInput: '.account-modal .qr-code__address', + closeButton: '.account-modal__close', +}; + +const importAccountSelector = '.new-account'; +const importAccount = { + page: importAccountSelector, + input: `${importAccountSelector} #private-key-box`, + cancelButton: `${importAccountSelector} .new-account-create-form__button:nth-child(1)`, + importButton: `${importAccountSelector} .new-account-create-form__button:nth-child(2)`, +}; + +const createAccount = { + page: importAccountSelector, + input: `${importAccountSelector} .new-account-create-form__input`, + cancelButton: `${importAccountSelector} .new-account-create-form__button:nth-child(1)`, + createButton: `${importAccountSelector} .new-account-create-form__button:nth-child(2)`, +}; + +const importTokenFormSelector = '.import-token__custom-token-form'; +const importToken = { + form: importTokenFormSelector, + tokenContractAddressInput: `${importTokenFormSelector} #custom-address`, + tokenSymbolInput: `${importTokenFormSelector} #custom-symbol`, + tokenEditButton: `${importTokenFormSelector} .import-token__custom-symbol__edit`, + tokenDecimalInput: `${importTokenFormSelector} #custom-decimals`, + addCustomTokenButton: `[data-testid="page-container-footer-next"]`, + confirmImportTokenContent: '.confirm-import-token', + importTokensButton: `.btn-primary`, +}; + +const assetNavigationSelector = '.asset-navigation'; +const asset = { + navigation: assetNavigationSelector, + backButton: `${assetNavigationSelector} [data-testid="asset__back"]`, +}; + + +export const homePageElements = { + networkSwitcher, + importToken, + importAccount, + createAccount, + accountMenu, + accountBar, + asset, + tabs, + walletOverview, + accountModal, + connectedSites, + welcome, + defaultWallet, + whatsNew, + popup, + activityTab, + settingsMenu, + actionableMessage, + tippyTooltip +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/actions/index.ts b/wallets/phantom/src/pages/LockPage/actions/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/wallets/phantom/src/pages/LockPage/page.ts b/wallets/phantom/src/pages/LockPage/page.ts new file mode 100644 index 000000000..79c072879 --- /dev/null +++ b/wallets/phantom/src/pages/LockPage/page.ts @@ -0,0 +1,13 @@ +import type { Page } from '@playwright/test' +import { lockPageElements } from './selectors' + +export class LockPage { + static readonly selectors = lockPageElements + readonly selectors = lockPageElements + + readonly page: Page + + constructor(page: Page) { + this.page = page + } +} diff --git a/wallets/phantom/src/pages/LockPage/selectors/index.ts b/wallets/phantom/src/pages/LockPage/selectors/index.ts new file mode 100644 index 000000000..79a764285 --- /dev/null +++ b/wallets/phantom/src/pages/LockPage/selectors/index.ts @@ -0,0 +1,109 @@ +const app = '#root'; +const welcomePage = '#root'; +const confirmButton = `${welcomePage} .first-time-flow__button`; +const welcomePageElements = { + app, + welcomePage, + confirmButton, +}; + +const metametricsPage = '.metametrics-opt-in'; +const optOutAnalyticsButton = `${metametricsPage} [data-testid="page-container-footer-cancel"]`; + +const metametricsPageElements = { + metametricsPage, + optOutAnalyticsButton, +}; + +const firstTimeFlowPage = '.first-time-flow'; +const importWalletButton = `[data-testid="import-wallet-button"]`; +const importRecoveryPhraseButton = `[data-testid="import-seed-phrase-button"]`; +const createWalletButton = `${firstTimeFlowPage} [data-testid="create-wallet-button"]`; + +const firstTimeFlowPageElements = { + firstTimeFlowPage, + importWalletButton, + importRecoveryPhraseButton, + createWalletButton, +}; + +const firstTimeFlowImportPage = '.first-time-flow__import'; +const newVaultForm = `${firstTimeFlowImportPage} .create-new-vault__form`; +const secretWordsInput = number => + `[data-testid="secret-recovery-phrase-word-input-${number}"]`; +const confirmWordsButton = `[data-testid="onboarding-form-submit-button"]`; +const passwordInput = `[data-testid="onboarding-form-password-input"]`; +const confirmPasswordInput = `[data-testid="onboarding-form-confirm-password-input"]`; +const termsCheckbox = `[data-testid="onboarding-form-terms-of-service-checkbox"]`; +const continueAfterPasswordButton = + '[data-testid="onboarding-form-submit-button"]'; +const getStartedButton = '[data-testid="onboarding-form-submit-button"]'; +const importButton = `${newVaultForm} .create-new-vault__submit-button`; + +const firstTimeFlowImportPageElements = { + firstTimeFlowImportPage, + newVaultForm, + secretWordsInput, + passwordInput, + confirmPasswordInput, + termsCheckbox, + importButton, + confirmWordsButton, + continueAfterPasswordButton, + getStartedButton, +}; + +const firstTimeFlowCreatePage = '.first-time-flow'; +const newPasswordInput = `${firstTimeFlowCreatePage} [data-testid="create-password"]`; +const confirmNewPasswordInput = `${firstTimeFlowCreatePage} [data-testid="confirm-password"]`; +const newSignupCheckbox = `${firstTimeFlowCreatePage} .first-time-flow__checkbox`; +const createButton = `${firstTimeFlowCreatePage} .first-time-flow__button`; + +const firstTimeFlowCreatePagePageElements = { + firstTimeFlowCreatePage, + newPasswordInput, + confirmNewPasswordInput, + newSignupCheckbox, + createButton, +}; + +const secureYourWalletPage = '[data-testid="seed-phrase-intro"]'; +const nextButton = `${secureYourWalletPage} button`; + +const secureYourWalletPageElements = { + secureYourWalletPage, + nextButton, +}; + +const revealSeedPage = '[data-testid="reveal-seed-phrase"]'; +const remindLaterButton = `${revealSeedPage} .first-time-flow__button`; + +const revealSeedPageElements = { + revealSeedPage, + remindLaterButton, +}; + +const endOfFlowPage = '[data-testid="end-of-flow"]'; +const allDoneButton = `${endOfFlowPage} [data-testid="EOF-complete-button"]`; + +const endOfFlowPageElements = { + endOfFlowPage, + allDoneButton, +}; + +const unlockPageElements = { + passwordInput: '[data-testid="unlock-form-password-input"]', + unlockButton: '[data-testid="unlock-form-submit-button"]', +}; + +export const lockPageElements = { + endOfFlowPageElements, + revealSeedPageElements, + secureYourWalletPageElements, + firstTimeFlowCreatePagePageElements, + firstTimeFlowImportPageElements, + firstTimeFlowPageElements, + metametricsPageElements, + welcomePageElements, + unlockPageElements, +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/index.ts b/wallets/phantom/src/pages/NotificationPage/actions/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/wallets/phantom/src/pages/NotificationPage/page.ts b/wallets/phantom/src/pages/NotificationPage/page.ts new file mode 100644 index 000000000..ce89b0f5c --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/page.ts @@ -0,0 +1,13 @@ +import type { Page } from '@playwright/test' +import { notificationPageElements } from './selectors' + +export class LockPage { + static readonly selectors = notificationPageElements + readonly selectors = notificationPageElements + + readonly page: Page + + constructor(page: Page) { + this.page = page + } +} diff --git a/wallets/phantom/src/pages/NotificationPage/selectors/index.ts b/wallets/phantom/src/pages/NotificationPage/selectors/index.ts new file mode 100644 index 000000000..da3521978 --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/selectors/index.ts @@ -0,0 +1,225 @@ +const notificationPage = '.notification'; +const notificationAppContent = `${notificationPage} #app-content .app`; +const loadingLogo = `${notificationPage} #loading__logo`; +const loadingSpinner = `${notificationPage} #loading__spinner`; +const nextButton = `${notificationPage} .permissions-connect-choose-account__bottom-buttons .btn-primary`; +const allowToSpendButton = `${notificationPage} [data-testid="page-container-footer-next"]`; +const rejectToSpendButton = `${notificationPage} [data-testid="page-container-footer-cancel"]`; +const selectAllCheckbox = `${notificationPage} .choose-account-list__header-check-box`; + +const notificationElements = { + notificationPage, + notificationAppContent, + loadingLogo, + loadingSpinner, + nextButton, + allowToSpendButton, + rejectToSpendButton, + selectAllCheckbox, +}; + +const confirmSignatureRequestButton = `${notificationPage} .request-signature__footer__sign-button`; +const rejectSignatureRequestButton = `${notificationPage} .request-signature__footer__cancel-button`; +const signatureRequestScrollDownButton = `${notificationPage} [data-testid="signature-request-scroll-button"]`; + +const confirmDataSignatureRequestButton = `${notificationPage} [data-testid="signature-sign-button"]`; +const rejectDataSignatureRequestButton = `${notificationPage} [data-testid="signature-cancel-button"]`; + +const dataSignaturePageElements = { + confirmDataSignatureRequestButton, + rejectDataSignatureRequestButton, + signatureRequestScrollDownButton, +}; + +const permissionsPage = '.permissions-connect'; +const connectButton = `${permissionsPage} .permission-approval-container__footers .btn-primary`; + +const permissionsPageElements = { + permissionsPage, + connectButton, +}; + +const popupContainer = '.popover-container'; +const popupCloseButton = `${popupContainer} .popover-header__button`; +const popupCopyRecipientPublicAddressButton = `${popupContainer} .nickname-popover__public-address button`; +const recipientPublicAddress = `${popupContainer} .nickname-popover__public-address__constant`; + +const recipientPopupElements = { + popupContainer, + popupCloseButton, + popupCopyRecipientPublicAddressButton, + recipientPublicAddress, +}; + +const confirmPageHeader = `${notificationPage} .confirm-page-container-header`; +const confirmPageContent = `${notificationPage} .confirm-page-container-content`; +const networkLabel = `${confirmPageHeader} .network-display`; +const senderButton = `${confirmPageHeader} .sender-to-recipient__party--sender`; +const recipientButton = `${confirmPageHeader} .sender-to-recipient__party--recipient-with-address`; +const editGasFeeLegacyButton = `${notificationPage} .transaction-detail-edit button`; +const editGasFeeLegacyOverrideAckButton = `${notificationPage} .edit-gas-display .edit-gas-display__dapp-acknowledgement-button`; +const editGasLegacyPopup = `${notificationPage} .edit-gas-popover__wrapper`; +const advancedLegacyGasControls = `${editGasLegacyPopup} .edit-gas-display .advanced-gas-controls`; +const gasLimitLegacyInput = `${advancedLegacyGasControls} .form-field:nth-child(1) input`; +const gasPriceLegacyInput = `${advancedLegacyGasControls} .form-field:nth-child(2) input`; +const saveLegacyButton = `${editGasLegacyPopup} .popover-footer .btn-primary`; +const editGasFeeButton = `${notificationPage} [data-testid="edit-gas-fee-button"]`; +const gasOptionLowButton = `${notificationPage} [data-testid="edit-gas-fee-item-low"]`; +const gasOptionMediumButton = `${notificationPage} [data-testid="edit-gas-fee-item-medium"]`; +const gasOptionHighButton = `${notificationPage} [data-testid="edit-gas-fee-item-high"]`; +const gasOptionDappSuggestedButton = `${notificationPage} [data-testid="edit-gas-fee-item-dappSuggested"]`; +const gasOptionCustomButton = `${notificationPage} [data-testid="edit-gas-fee-item-custom"]`; +const baseFeeInput = `${notificationPage} [data-testid="base-fee-input"]`; +const priorityFeeInput = `${notificationPage} [data-testid="priority-fee-input"]`; +const editGasLimitButton = `${notificationPage} [data-testid="advanced-gas-fee-edit"]`; +const gasLimitInput = `${notificationPage} [data-testid="gas-limit-input"]`; +const saveCustomGasFeeButton = `${notificationPage} .popover-container .btn-primary`; +const totalLabel = `${confirmPageContent} .transaction-detail-item:nth-child(2) .transaction-detail-item__detail-values h6:nth-child(2)`; +const customNonceInput = `${confirmPageContent} .custom-nonce-input input`; +const tabs = `${confirmPageContent} .tabs`; +const detailsButton = `${tabs} .tab:nth-child(1) button`; +const dataButton = `${tabs} .tab:nth-child(2) button`; +const dataTab = `${tabs} .confirm-page-container-content__data`; +const originValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(1) .confirm-page-container-content__data-field:nth-child(1) div:nth-child(2)`; +const bytesValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(1) .confirm-page-container-content__data-field:nth-child(2) div:nth-child(2)`; +const hexDataValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(3)`; +const rejectButton = `${confirmPageContent} [data-testid="page-container-footer-cancel"]`; +const confirmButton = `${confirmPageContent} [data-testid="page-container-footer-next"]`; + +const confirmPageElements = { + notificationPage, + confirmPageHeader, + confirmPageContent, + networkLabel, + senderButton, + recipientButton, + editGasFeeLegacyButton, + editGasFeeLegacyOverrideAckButton, + editGasLegacyPopup, + advancedLegacyGasControls, + gasLimitLegacyInput, + gasPriceLegacyInput, + saveLegacyButton, + editGasFeeButton, + gasOptionLowButton, + gasOptionMediumButton, + gasOptionHighButton, + gasOptionDappSuggestedButton, + gasOptionCustomButton, + baseFeeInput, + priorityFeeInput, + editGasLimitButton, + gasLimitInput, + saveCustomGasFeeButton, + totalLabel, + customNonceInput, + tabs, + detailsButton, + dataButton, + dataTab, + originValue, + bytesValue, + hexDataValue, + rejectButton, + confirmButton, +}; + +const confirmEncryptionPublicKeyButton = `${notificationPage} .request-encryption-public-key__footer__sign-button`; +const rejectEncryptionPublicKeyButton = `${notificationPage} .request-encryption-public-key__footer__cancel-button`; + +const encryptionPublicKeyPageElements = { + confirmEncryptionPublicKeyButton, + rejectEncryptionPublicKeyButton, +}; + +const confirmDecryptionRequestButton = `${notificationPage} .request-decrypt-message__footer__sign-button`; +const rejectDecryptionRequestButton = `${notificationPage} .request-decrypt-message__footer__cancel-button`; + +const decryptPageElements = { + confirmDecryptionRequestButton, + rejectDecryptionRequestButton, +}; + +const confirmAddTokenButton = `${notificationPage} .btn-primary`; +const rejectAddTokenButton = `${notificationPage} .btn-secondary`; + +const addTokenPageElements = { + confirmAddTokenButton, + rejectAddTokenButton, +}; + +/** + * ADJUSTED + */ +const root = '#root'; + +const app = { + root, +}; + +const primaryButton = '[data-testid="primary-button"]'; + +const buttons = { + primaryButton, +}; + +/** + * NEW + */ +const signaturePageElements = { + buttons: { + confirmSign: '[data-testid="primary-button"]', + rejectSign: '[data-testid="secondary-button"]', + signatureRequestScrollDownButton, + }, +}; + +const transactionPageElements = { + buttons: { + confirmTransaction: '[data-testid="primary-button"]', + rejectTransaction: '[data-testid="secondary-button"]', + }, +}; + +const menu = { + buttons: { + settings: '[data-testid="settings-menu-open-button"]', + sidebar: { + settings: '[data-testid="sidebar_menu-button-settings"]', + }, + }, +}; + +const incorrectModePageElements = { + buttons: { + close: '[data-testid="incorrect-mode"] button', + }, +}; + +const selectWalletElements = { + buttons: { + continueWithPhantom: '[data-testid="select_wallet--phantom"]', + continueWithMetamask: '[data-testid="select_wallet--metamask"]', + }, +}; + +export const notificationPageElements = { + notificationElements, + incorrectModePageElements, + menu, + transactionPageElements, + signaturePageElements, + buttons, + app, + addTokenPageElements, + decryptPageElements, + encryptionPublicKeyPageElements, + confirmPageElements, + recipientPopupElements, + dataSignaturePageElements, + permissionsPage, + permissionsPageElements, + confirmSignatureRequestButton, + rejectSignatureRequestButton, + selectWalletElements, +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/SettingPage/actions/index.ts b/wallets/phantom/src/pages/SettingPage/actions/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/wallets/phantom/src/pages/SettingPage/page.ts b/wallets/phantom/src/pages/SettingPage/page.ts new file mode 100644 index 000000000..10804c906 --- /dev/null +++ b/wallets/phantom/src/pages/SettingPage/page.ts @@ -0,0 +1,13 @@ +import type { Page } from '@playwright/test' +import { settingsPageElements } from './selectors' + +export class LockPage { + static readonly selectors = settingsPageElements + readonly selectors = settingsPageElements + + readonly page: Page + + constructor(page: Page) { + this.page = page + } +} diff --git a/wallets/phantom/src/pages/SettingPage/selectors/index.ts b/wallets/phantom/src/pages/SettingPage/selectors/index.ts new file mode 100644 index 000000000..0e5207508 --- /dev/null +++ b/wallets/phantom/src/pages/SettingPage/selectors/index.ts @@ -0,0 +1,5 @@ +export const settingsPageElements = { + buttons: { + lockWallet: '[data-testid="lock-menu-item"]', + }, +}; \ No newline at end of file diff --git a/wallets/phantom/src/utils/selectors/loading.ts b/wallets/phantom/src/utils/selectors/loading.ts new file mode 100644 index 000000000..762984e45 --- /dev/null +++ b/wallets/phantom/src/utils/selectors/loading.ts @@ -0,0 +1,16 @@ +const loadingLogo = '.loading-logo'; +const loadingSpinner = '.loading-spinner'; +const loadingOverlay = '.loading-overlay'; +const loadingOverlaySpinner = '.loading-overlay__spinner'; +const loadingOverlayErrorButtons = '.loading-overlay__error-buttons'; +const loadingOverlayErrorButtonsRetryButton = + '.loading-overlay__error-buttons .btn-primary'; + +export const loadingElements = { + loadingLogo, + loadingSpinner, + loadingOverlay, + loadingOverlaySpinner, + loadingOverlayErrorButtons, + loadingOverlayErrorButtonsRetryButton, +}; \ No newline at end of file From f9b211ee5f512f3b426481a5ddb37ba928e6e0be Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Thu, 4 Jul 2024 08:34:24 -0400 Subject: [PATCH 03/16] fixtures --- wallets/phantom/src/PhantomWallet.ts | 25 +++-- .../phantom/src/fixtures/phantomFixtures.ts | 105 ++++++++++++++++++ .../src/pages/NotificationPage/page.ts | 2 +- .../actions/index.ts | 0 .../{SettingPage => SettingsPage}/page.ts | 2 +- .../selectors/index.ts | 0 wallets/phantom/src/utils/constants.ts | 0 wallets/phantom/src/utils/index.ts | 1 + 8 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 wallets/phantom/src/fixtures/phantomFixtures.ts rename wallets/phantom/src/pages/{SettingPage => SettingsPage}/actions/index.ts (100%) rename wallets/phantom/src/pages/{SettingPage => SettingsPage}/page.ts (90%) rename wallets/phantom/src/pages/{SettingPage => SettingsPage}/selectors/index.ts (100%) create mode 100644 wallets/phantom/src/utils/constants.ts create mode 100644 wallets/phantom/src/utils/index.ts diff --git a/wallets/phantom/src/PhantomWallet.ts b/wallets/phantom/src/PhantomWallet.ts index 76e713570..7836620db 100644 --- a/wallets/phantom/src/PhantomWallet.ts +++ b/wallets/phantom/src/PhantomWallet.ts @@ -2,11 +2,15 @@ import { type BrowserContext, type Page } from '@playwright/test' import { HomePage } from './pages/HomePage/page' import { LockPage } from './pages/LockPage/page' import { NotificationPage } from './pages/NotificationPage/page' +import { SettingsPage } from './pages/SettingsPage/page' +import { ConfirmationPage } from './pages/ConfirmationPage/page' -export class KeplrWallet { +export class PhantomWallet { readonly lockPage: LockPage readonly homePage: HomePage readonly notificationPage: NotificationPage + readonly settingsPage: SettingsPage + readonly confirmationPage: ConfirmationPage constructor( readonly page: Page, @@ -17,6 +21,8 @@ export class KeplrWallet { this.lockPage = new LockPage(page) this.homePage = new HomePage(page) this.notificationPage = new NotificationPage(page) + this.settingsPage = new SettingsPage(page) + this.confirmationPage = new ConfirmationPage(page) } /** * Does initial setup for the wallet. @@ -26,33 +32,30 @@ export class KeplrWallet { * @param password. The password to set. */ async setupWallet({ secretWordsOrPrivateKey, password }: { secretWordsOrPrivateKey: string; password: string }) { - const wallet = await this.lockPage.importWallet(secretWordsOrPrivateKey, password) - return wallet + console.log(secretWordsOrPrivateKey, password) } async createWallet(password: string) { - const wallet = await this.lockPage.createWallet(password) - return wallet + console.log(password) } async getWalletAddress(wallet: string) { - const walletAddress = await this.homePage.getWalletAddress(wallet) - return walletAddress + console.log(wallet) } async addNewTokensFound() { - return await this.homePage.addNewTokensFound() + console.log('') } async disconnectWalletFromDapps() { - return await this.homePage.disconnectWalletFromDapps() + console.log('') } async acceptAccess() { - return await this.notificationPage.acceptAccess() + console.log('') } async rejectAccess() { - return await this.notificationPage.rejectAccess() + console.log('') } } diff --git a/wallets/phantom/src/fixtures/phantomFixtures.ts b/wallets/phantom/src/fixtures/phantomFixtures.ts new file mode 100644 index 000000000..91850a790 --- /dev/null +++ b/wallets/phantom/src/fixtures/phantomFixtures.ts @@ -0,0 +1,105 @@ +import path from 'node:path' +import { type Page, chromium } from '@playwright/test' + +import { test as base } from '@playwright/test' +import { + CACHE_DIR_NAME, + createTempContextDir, + defineWalletSetup, + removeTempContextDir +} from '@synthetixio/synpress-cache' +import { prepareExtension } from '@synthetixio/synpress-cache' +import fs from 'fs-extra' +import { PhantomWallet } from '../PhantomWallet' +import { getExtensionId } from '../fixtureActions' +import { persistLocalStorage } from '../fixtureActions/persistLocalStorage' +// import unlockForFixtures from '../fixtureActions/unlockForFixtures' +import { PASSWORD } from '../utils' + +type PhantomFixtures = { + _contextPath: string + phantom: PhantomWallet + phantomPage: Page + extensionId: string +} + +let _phantomPage: Page + +export const phantomFixtures = (walletSetup: ReturnType, slowMo = 0) => { + return base.extend({ + _contextPath: async ({ browserName }, use, testInfo) => { + const contextDir = await createTempContextDir(browserName, testInfo.testId) + + await use(contextDir) + + const error = await removeTempContextDir(contextDir) + if (error) { + console.log('contextDir', error) + } + }, + context: async ({ context: currentContext, _contextPath }, use) => { + // @todo: This is some weird behaviour, if there is only 1 setup file the hash function will always produce a different hash than cache. + const cacheDirPath = path.join(process.cwd(), CACHE_DIR_NAME, walletSetup.hash) + if (!(await fs.exists(cacheDirPath))) { + throw new Error(`Cache for ${cacheDirPath} does not exist. Create it first!`) + } + + // Copying the cache to the temporary context directory. + await fs.copy(cacheDirPath, _contextPath) + + const phantomPath = await prepareExtension('Phantom') + // We don't need the `--load-extension` arg since the extension is already loaded in the cache. + const browserArgs = [`--disable-extensions-except=${phantomPath}`, '--enable-features=SharedClipboardUI'] + if (process.env.HEADLESS) { + browserArgs.push('--headless=new') + + if (slowMo) { + console.warn('[WARNING] Slow motion makes no sense in headless mode. It will be ignored!') + } + } + + const context = await chromium.launchPersistentContext(_contextPath, { + headless: false, + args: browserArgs, + slowMo: process.env.HEADLESS ? 0 : slowMo + }) + + const { cookies, origins } = await currentContext.storageState() + + if (cookies) { + await context.addCookies(cookies) + } + if (origins && origins.length > 0) { + await persistLocalStorage(origins, context) + } + + const extensionId = await getExtensionId(context, 'Phantom') + + _phantomPage = context.pages()[0] as Page + + await _phantomPage.goto(`chrome-extension://${extensionId}/popup.html`) + + // await unlockForFixtures(_phantomPage, PASSWORD) + + await use(context) + }, + phantomPage: async ({ context: _ }, use) => { + await use(_phantomPage) + }, + extensionId: async ({ context }, use) => { + const extensionId = await getExtensionId(context, 'Keplr') + + await use(extensionId) + }, + phantom: async ({ context, extensionId }, use) => { + const phantomWallet = new PhantomWallet(_phantomPage, context, PASSWORD, extensionId) + + await use(phantomWallet) + }, + + page: async ({ page }, use) => { + await page.goto('') + await use(page) + } + }) +} diff --git a/wallets/phantom/src/pages/NotificationPage/page.ts b/wallets/phantom/src/pages/NotificationPage/page.ts index ce89b0f5c..c34847eb3 100644 --- a/wallets/phantom/src/pages/NotificationPage/page.ts +++ b/wallets/phantom/src/pages/NotificationPage/page.ts @@ -1,7 +1,7 @@ import type { Page } from '@playwright/test' import { notificationPageElements } from './selectors' -export class LockPage { +export class NotificationPage { static readonly selectors = notificationPageElements readonly selectors = notificationPageElements diff --git a/wallets/phantom/src/pages/SettingPage/actions/index.ts b/wallets/phantom/src/pages/SettingsPage/actions/index.ts similarity index 100% rename from wallets/phantom/src/pages/SettingPage/actions/index.ts rename to wallets/phantom/src/pages/SettingsPage/actions/index.ts diff --git a/wallets/phantom/src/pages/SettingPage/page.ts b/wallets/phantom/src/pages/SettingsPage/page.ts similarity index 90% rename from wallets/phantom/src/pages/SettingPage/page.ts rename to wallets/phantom/src/pages/SettingsPage/page.ts index 10804c906..3809723cb 100644 --- a/wallets/phantom/src/pages/SettingPage/page.ts +++ b/wallets/phantom/src/pages/SettingsPage/page.ts @@ -1,7 +1,7 @@ import type { Page } from '@playwright/test' import { settingsPageElements } from './selectors' -export class LockPage { +export class SettingsPage { static readonly selectors = settingsPageElements readonly selectors = settingsPageElements diff --git a/wallets/phantom/src/pages/SettingPage/selectors/index.ts b/wallets/phantom/src/pages/SettingsPage/selectors/index.ts similarity index 100% rename from wallets/phantom/src/pages/SettingPage/selectors/index.ts rename to wallets/phantom/src/pages/SettingsPage/selectors/index.ts diff --git a/wallets/phantom/src/utils/constants.ts b/wallets/phantom/src/utils/constants.ts new file mode 100644 index 000000000..e69de29bb diff --git a/wallets/phantom/src/utils/index.ts b/wallets/phantom/src/utils/index.ts new file mode 100644 index 000000000..d6f677629 --- /dev/null +++ b/wallets/phantom/src/utils/index.ts @@ -0,0 +1 @@ +export * from './selectors/loading' \ No newline at end of file From c16163481b680b482b1de3ed67c0fa5bceeb9709 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Thu, 4 Jul 2024 10:44:38 -0400 Subject: [PATCH 04/16] add import and clean up --- wallets/phantom/src/PhantomWallet.ts | 6 ++-- .../pages/LockPage/actions/importAccount.ts | 32 +++++++++++++++++++ .../src/pages/LockPage/actions/index.ts | 1 + wallets/phantom/src/pages/LockPage/page.ts | 5 +++ wallets/phantom/src/utils/constants.ts | 12 +++++++ .../phantom/test/wallet-setup/import.setup.ts | 0 6 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 wallets/phantom/src/pages/LockPage/actions/importAccount.ts create mode 100644 wallets/phantom/test/wallet-setup/import.setup.ts diff --git a/wallets/phantom/src/PhantomWallet.ts b/wallets/phantom/src/PhantomWallet.ts index 7836620db..0095863ec 100644 --- a/wallets/phantom/src/PhantomWallet.ts +++ b/wallets/phantom/src/PhantomWallet.ts @@ -28,11 +28,11 @@ export class PhantomWallet { * Does initial setup for the wallet. * * @param playwrightInstance. The playwright instance to use. - * @param secretWordsOrPrivateKey. The secret words or private key to import. + * @param secretWords. The secret words or private key to import. * @param password. The password to set. */ - async setupWallet({ secretWordsOrPrivateKey, password }: { secretWordsOrPrivateKey: string; password: string }) { - console.log(secretWordsOrPrivateKey, password) + async importWallet({ secretWords, password }: { secretWords: string; password: string }) { + this.lockPage.importWallet(secretWords, password) } async createWallet(password: string) { diff --git a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts new file mode 100644 index 000000000..de4622f64 --- /dev/null +++ b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts @@ -0,0 +1,32 @@ +import type { Page } from '@playwright/test' +import { lockPageElements } from "../selectors"; + +export const importWallet = async (page: Page, secretWords: string, password: string) => { + await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) + await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) + + for (const [index, word] of secretWords.split(' ').entries()) { + const inputField = await page.selectors(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) + await inputField.fill(word) + } + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + + await page.waitForLoadState('domcontentloaded') + + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + + const walletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.passwordInput) + await walletInput.fill(password) + + const confirmWalletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.confirmPasswordInput) + await confirmWalletInput.fill(password) + + const checkbox = await page.locator(lockPageElements.firstTimeFlowImportPageElements.termsCheckbox) + await checkbox.click() + + await page.click(lockPageElements.firstTimeFlowImportPageElements.continueAfterPasswordButton) + + await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/actions/index.ts b/wallets/phantom/src/pages/LockPage/actions/index.ts index e69de29bb..4aaa3d5e9 100644 --- a/wallets/phantom/src/pages/LockPage/actions/index.ts +++ b/wallets/phantom/src/pages/LockPage/actions/index.ts @@ -0,0 +1 @@ +export * from './importAccount' \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/page.ts b/wallets/phantom/src/pages/LockPage/page.ts index 79c072879..829a0adfc 100644 --- a/wallets/phantom/src/pages/LockPage/page.ts +++ b/wallets/phantom/src/pages/LockPage/page.ts @@ -1,5 +1,6 @@ import type { Page } from '@playwright/test' import { lockPageElements } from './selectors' +import { importWallet } from './actions' export class LockPage { static readonly selectors = lockPageElements @@ -10,4 +11,8 @@ export class LockPage { constructor(page: Page) { this.page = page } + + async importWallet(secretWords: string, password: string) { + await importWallet(this.page, secretWords, password) + } } diff --git a/wallets/phantom/src/utils/constants.ts b/wallets/phantom/src/utils/constants.ts index e69de29bb..2bd168758 100644 --- a/wallets/phantom/src/utils/constants.ts +++ b/wallets/phantom/src/utils/constants.ts @@ -0,0 +1,12 @@ +const PROVIDER = 'phantom' + +const extensionInitialUrl = await playwright.windows(PROVIDER).url(); +const extensionId = extensionInitialUrl.match('//(.*?)/')[1]; +const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html`; +const extensionSettingsUrl = `${extensionHomeUrl}#settings`; +const extensionAdvancedSettingsUrl = `${extensionSettingsUrl}/advanced`; +const extensionExperimentalSettingsUrl = `${extensionSettingsUrl}/experimental`; +const extensionAddNetworkUrl = `${extensionSettingsUrl}/networks/add-network`; +const extensionNewAccountUrl = `${extensionHomeUrl}#new-account`; +const extensionImportAccountUrl = `${extensionNewAccountUrl}/import`; +const extensionImportTokenUrl = `${extensionHomeUrl}#import-token`; \ No newline at end of file diff --git a/wallets/phantom/test/wallet-setup/import.setup.ts b/wallets/phantom/test/wallet-setup/import.setup.ts new file mode 100644 index 000000000..e69de29bb From 092f3c76550f377545248702230c7ea2ec1eced4 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Fri, 5 Jul 2024 07:02:06 -0400 Subject: [PATCH 05/16] setup --- packages/cache/package.json | 2 + packages/cache/src/cli/cliEntrypoint.ts | 8 +- packages/cache/src/prepareExtension.ts | 24 +- pnpm-lock.yaml | 647 +++++++++++++++++- wallets/phantom/package.json | 2 +- .../src/fixtureActions/getExtensionId.ts | 46 ++ wallets/phantom/src/fixtureActions/index.ts | 1 + .../src/fixtureActions/persistLocalStorage.ts | 24 + .../phantom/src/fixtures/phantomFixtures.ts | 3 +- .../src/pages/HomePage/selectors/index.ts | 4 +- .../pages/LockPage/actions/importAccount.ts | 2 +- .../src/pages/LockPage/selectors/index.ts | 2 +- wallets/phantom/src/utils/constants.ts | 22 +- wallets/phantom/src/utils/index.ts | 3 +- .../phantom/test/wallet-setup/import.setup.ts | 19 + .../test/wallet-setup/import2.setup.ts | 19 + 16 files changed, 785 insertions(+), 43 deletions(-) create mode 100644 wallets/phantom/src/fixtureActions/getExtensionId.ts create mode 100644 wallets/phantom/src/fixtureActions/index.ts create mode 100644 wallets/phantom/src/fixtureActions/persistLocalStorage.ts create mode 100644 wallets/phantom/test/wallet-setup/import2.setup.ts diff --git a/packages/cache/package.json b/packages/cache/package.json index c06037c4c..051030d11 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -32,6 +32,7 @@ "axios": "1.6.7", "chalk": "5.3.0", "commander": "12.0.0", + "download": "8.0.0", "esbuild": "0.20.0", "fs-extra": "11.2.0", "glob": "10.3.10", @@ -44,6 +45,7 @@ "devDependencies": { "@synthetixio/synpress-tsconfig": "0.0.1-alpha.7", "@types/archiver": "6.0.2", + "@types/download": "8.0.5", "@types/fs-extra": "11.0.4", "@types/gradient-string": "1.1.5", "@types/node": "20.11.17", diff --git a/packages/cache/src/cli/cliEntrypoint.ts b/packages/cache/src/cli/cliEntrypoint.ts index dfe449c4c..b4ed57cf6 100644 --- a/packages/cache/src/cli/cliEntrypoint.ts +++ b/packages/cache/src/cli/cliEntrypoint.ts @@ -12,6 +12,7 @@ import { footer } from './footer' interface CliFlags { keplr: boolean metamask: boolean + phantom: boolean headless: boolean force: boolean debug: boolean @@ -34,6 +35,7 @@ export const cliEntrypoint = async () => { .option('-d, --debug', 'If this flag is present, the compilation files are not going to be deleted', false) .option('-k, --keplr', 'Prepare the Keplr extension', false) .option('-m, --metamask', 'Prepare the MetaMask extension', false) + .option('-p, --phantom', 'Prepare the Phantom extension', false) .helpOption(undefined, 'Display help for command') .addHelpText('afterAll', `\n${footer}\n`) .parse(process.argv) @@ -57,12 +59,15 @@ export const cliEntrypoint = async () => { if (flags.metamask) { extensions.push('MetaMask') } + if (flags.phantom) { + extensions.push('Phantom') + } return extensions } let extensionNames = extensionsToSetup() if (!extensionNames.length) { - extensionNames = ['Keplr'] + extensionNames = ['Metamask'] } if (os.platform() === 'win32') { @@ -81,7 +86,6 @@ export const cliEntrypoint = async () => { for (const extensionName of extensionNames) { await createCache(compiledWalletSetupDirPath, () => prepareExtension(extensionName), flags.force) // Pass extensionName } - // TODO: We should be using `prepareExtension` function from the wallet itself! if (!flags.debug) { await rimraf(compiledWalletSetupDirPath) diff --git a/packages/cache/src/prepareExtension.ts b/packages/cache/src/prepareExtension.ts index d393b0e67..1919301f1 100644 --- a/packages/cache/src/prepareExtension.ts +++ b/packages/cache/src/prepareExtension.ts @@ -1,3 +1,4 @@ +// import download from 'download' import { downloadFile, ensureCacheDirExists, unzipArchive } from '.' interface ExtensionConfig { @@ -20,6 +21,12 @@ export async function getExtensionConfig(name: string): Promise version: '0.12.102', downloadUrl: 'https://github.com/chainapsis/keplr-wallet/releases/download/v0.12.102/keplr-extension-manifest-v2-v0.12.102.zip' + }, + { + name: 'Phantom', + version: 'phantom-chrome-latest', + downloadUrl: + 'https://crx-backup.phantom.dev/latest.crx' } ] } @@ -34,13 +41,22 @@ export async function getExtensionConfig(name: string): Promise export async function prepareExtension(extensionName: string) { const cacheDirPath = ensureCacheDirExists() const extensionConfig = await getExtensionConfig(extensionName) // Get config - - const downloadResult = await downloadFile({ + let downloadResult + // if (extensionConfig.name === 'Phantom') { + // downloadResult = await download(extensionConfig.downloadUrl, cacheDirPath, { + // headers: { + // Accept: 'application/octet-stream', + // }, + // }); + // } + // else { + + // } + downloadResult = await downloadFile({ url: extensionConfig.downloadUrl, outputDir: cacheDirPath, - fileName: `${extensionConfig.name.toLowerCase()}-chrome-${extensionConfig.version}.zip` + fileName: extensionName === 'Phantom' ? 'latest.crx' : `${extensionConfig.name.toLowerCase()}-chrome-${extensionConfig.version}.zip` }) - const unzipResult = await unzipArchive({ archivePath: downloadResult.filePath }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e104837d..0910748ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -99,6 +99,9 @@ importers: commander: specifier: 12.0.0 version: 12.0.0 + download: + specifier: 8.0.0 + version: 8.0.0 esbuild: specifier: 0.20.0 version: 0.20.0 @@ -133,6 +136,9 @@ importers: '@types/archiver': specifier: 6.0.2 version: 6.0.2 + '@types/download': + specifier: 8.0.5 + version: 8.0.5 '@types/fs-extra': specifier: 11.0.4 version: 11.0.4 @@ -378,6 +384,67 @@ importers: specifier: 1.2.2 version: 1.2.2(@types/node@20.11.17) + wallets/phantom: + dependencies: + '@playwright/test': + specifier: 1.44.0 + version: 1.44.0 + '@synthetixio/synpress-cache': + specifier: workspace:* + version: link:../../packages/cache + '@synthetixio/synpress-core': + specifier: workspace:* + version: link:../../packages/core + '@viem/anvil': + specifier: 0.0.7 + version: 0.0.7 + clipboardy: + specifier: 4.0.0 + version: 4.0.0 + fs-extra: + specifier: 11.2.0 + version: 11.2.0 + node-fetch: + specifier: 3.3.2 + version: 3.3.2 + underscore: + specifier: 1.13.6 + version: 1.13.6 + zod: + specifier: 3.22.4 + version: 3.22.4 + devDependencies: + '@synthetixio/synpress-tsconfig': + specifier: workspace:* + version: link:../../packages/tsconfig + '@types/fs-extra': + specifier: 11.0.4 + version: 11.0.4 + '@types/node': + specifier: 20.11.17 + version: 20.11.17 + '@types/underscore': + specifier: 1.11.15 + version: 1.11.15 + '@vitest/coverage-v8': + specifier: 1.2.2 + version: 1.2.2(vitest@1.2.2) + cypress: + specifier: 13.9.0 + version: 13.9.0 + rimraf: + specifier: 5.0.5 + version: 5.0.5 + tsup: + specifier: 8.0.2 + version: 8.0.2(typescript@5.3.3) + typescript: + specifier: 5.3.3 + version: 5.3.3 + vitest: + specifier: 1.2.2 + version: 1.2.2(@types/node@20.11.17) + packages: /@adraffy/ens-normalize@1.10.0: @@ -2396,6 +2463,11 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true + /@sindresorhus/is@0.7.0: + resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==} + engines: {node: '>=4'} + dev: false + /@sindresorhus/is@5.6.0: resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} @@ -2436,6 +2508,20 @@ packages: resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} dev: true + /@types/decompress@4.2.7: + resolution: {integrity: sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g==} + dependencies: + '@types/node': 20.11.17 + dev: true + + /@types/download@8.0.5: + resolution: {integrity: sha512-Ad68goc/BsL3atP3OP/lWKAKhiC6FduN1mC5yg9lZuGYmUY7vyoWBcXgt8GE9OzVWRq5IBXwm4o/QiE+gipZAg==} + dependencies: + '@types/decompress': 4.2.7 + '@types/got': 9.6.12 + '@types/node': 20.11.17 + dev: true + /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -2446,6 +2532,14 @@ packages: '@types/node': 20.11.17 dev: true + /@types/got@9.6.12: + resolution: {integrity: sha512-X4pj/HGHbXVLqTpKjA2ahI4rV/nNBc9mGO2I/0CgAra+F2dKgMXnENv2SRpemScBzBAI4vMelIVYViQxlSE6xA==} + dependencies: + '@types/node': 20.11.17 + '@types/tough-cookie': 4.0.5 + form-data: 2.5.1 + dev: true + /@types/gradient-string@1.1.5: resolution: {integrity: sha512-Z2VPQ0q+IhrAO7XjJSjpDsoPc+CsCshRNah1IE9LCo/NzHMHylssvx73i0BAKzuaGj9cdhmgq9rLaietpYAbKQ==} dependencies: @@ -2466,6 +2560,12 @@ packages: '@types/node': 20.11.17 dev: true + /@types/keyv@3.1.4: + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + dependencies: + '@types/node': 20.11.17 + dev: false + /@types/linkify-it@5.0.0: resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} dev: true @@ -2499,7 +2599,6 @@ packages: resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} dependencies: undici-types: 5.26.5 - dev: true /@types/node@20.12.12: resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} @@ -2523,6 +2622,12 @@ packages: '@types/node': 20.11.17 dev: true + /@types/responselike@1.0.3: + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + dependencies: + '@types/node': 20.11.17 + dev: false + /@types/semver@7.5.8: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true @@ -2542,6 +2647,10 @@ packages: /@types/tinycolor2@1.4.6: resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} + /@types/tough-cookie@4.0.5: + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + dev: true + /@types/underscore@1.11.15: resolution: {integrity: sha512-HP38xE+GuWGlbSRq9WrZkousaQ7dragtZCruBVMi0oX1migFZavZ3OROKHSkNp/9ouq82zrWtZpg18jFnVN96g==} dev: true @@ -3002,6 +3111,13 @@ packages: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} dev: true + /archive-type@4.0.0: + resolution: {integrity: sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==} + engines: {node: '>=4'} + dependencies: + file-type: 4.4.0 + dev: false + /archiver-utils@4.0.1: resolution: {integrity: sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==} engines: {node: '>= 12.0.0'} @@ -3166,7 +3282,6 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true /bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} @@ -3201,6 +3316,13 @@ packages: chainsaw: 0.1.0 dev: false + /bl@1.2.3: + resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==} + dependencies: + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + dev: false + /blob-util@2.0.2: resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} dev: true @@ -3282,9 +3404,23 @@ packages: base-x: 4.0.0 dev: false + /buffer-alloc-unsafe@1.1.0: + resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} + dev: false + + /buffer-alloc@1.2.0: + resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} + dependencies: + buffer-alloc-unsafe: 1.1.0 + buffer-fill: 1.0.0 + dev: false + /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: true + + /buffer-fill@1.0.0: + resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} + dev: false /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -3300,7 +3436,6 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true /buffers@0.1.1: resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} @@ -3387,6 +3522,18 @@ packages: responselike: 3.0.0 dev: true + /cacheable-request@2.1.4: + resolution: {integrity: sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==} + dependencies: + clone-response: 1.0.2 + get-stream: 3.0.0 + http-cache-semantics: 3.8.1 + keyv: 3.0.0 + lowercase-keys: 1.0.0 + normalize-url: 2.0.1 + responselike: 1.0.2 + dev: false + /cachedir@2.4.0: resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} engines: {node: '>=6'} @@ -3610,6 +3757,12 @@ packages: wrap-ansi: 7.0.0 dev: true + /clone-response@1.0.2: + resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} + dependencies: + mimic-response: 1.0.1 + dev: false + /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -3664,6 +3817,10 @@ packages: engines: {node: '>=18'} dev: false + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -3759,7 +3916,6 @@ packages: /content-disposition@0.5.2: resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} engines: {node: '>= 0.6'} - dev: true /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -3981,6 +4137,18 @@ packages: engines: {node: '>=0.10.0'} dev: true + /decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + dev: false + + /decompress-response@3.3.0: + resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} + engines: {node: '>=4'} + dependencies: + mimic-response: 1.0.1 + dev: false + /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -3988,6 +4156,59 @@ packages: mimic-response: 3.1.0 dev: true + /decompress-tar@4.1.1: + resolution: {integrity: sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==} + engines: {node: '>=4'} + dependencies: + file-type: 5.2.0 + is-stream: 1.1.0 + tar-stream: 1.6.2 + dev: false + + /decompress-tarbz2@4.1.1: + resolution: {integrity: sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==} + engines: {node: '>=4'} + dependencies: + decompress-tar: 4.1.1 + file-type: 6.2.0 + is-stream: 1.1.0 + seek-bzip: 1.0.6 + unbzip2-stream: 1.4.3 + dev: false + + /decompress-targz@4.1.1: + resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==} + engines: {node: '>=4'} + dependencies: + decompress-tar: 4.1.1 + file-type: 5.2.0 + is-stream: 1.1.0 + dev: false + + /decompress-unzip@4.0.1: + resolution: {integrity: sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==} + engines: {node: '>=4'} + dependencies: + file-type: 3.9.0 + get-stream: 2.3.1 + pify: 2.3.0 + yauzl: 2.10.0 + dev: false + + /decompress@4.2.1: + resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==} + engines: {node: '>=4'} + dependencies: + decompress-tar: 4.1.1 + decompress-tarbz2: 4.1.1 + decompress-targz: 4.1.1 + decompress-unzip: 4.0.1 + graceful-fs: 4.2.11 + make-dir: 1.3.0 + pify: 2.3.0 + strip-dirs: 2.1.0 + dev: false + /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} @@ -4075,12 +4296,33 @@ packages: engines: {node: '>=12'} dev: false + /download@8.0.0: + resolution: {integrity: sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==} + engines: {node: '>=10'} + dependencies: + archive-type: 4.0.0 + content-disposition: 0.5.2 + decompress: 4.2.1 + ext-name: 5.0.0 + file-type: 11.1.0 + filenamify: 3.0.0 + get-stream: 4.1.0 + got: 8.3.2 + make-dir: 2.1.0 + p-event: 2.3.1 + pify: 4.0.1 + dev: false + /duplexer2@0.1.4: resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} dependencies: readable-stream: 2.3.8 dev: false + /duplexer3@0.1.5: + resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} + dev: false + /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -4125,7 +4367,6 @@ packages: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 - dev: true /enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} @@ -4355,7 +4596,6 @@ packages: /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - dev: true /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} @@ -4492,6 +4732,21 @@ packages: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} dev: true + /ext-list@2.2.2: + resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} + engines: {node: '>=0.10.0'} + dependencies: + mime-db: 1.52.0 + dev: false + + /ext-name@5.0.0: + resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} + engines: {node: '>=4'} + dependencies: + ext-list: 2.2.2 + sort-keys-length: 1.0.1 + dev: false + /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true @@ -4569,7 +4824,6 @@ packages: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} dependencies: pend: 1.2.0 - dev: true /fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} @@ -4586,6 +4840,45 @@ packages: escape-string-regexp: 1.0.5 dev: true + /file-type@11.1.0: + resolution: {integrity: sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==} + engines: {node: '>=6'} + dev: false + + /file-type@3.9.0: + resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==} + engines: {node: '>=0.10.0'} + dev: false + + /file-type@4.4.0: + resolution: {integrity: sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==} + engines: {node: '>=4'} + dev: false + + /file-type@5.2.0: + resolution: {integrity: sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==} + engines: {node: '>=4'} + dev: false + + /file-type@6.2.0: + resolution: {integrity: sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==} + engines: {node: '>=4'} + dev: false + + /filename-reserved-regex@2.0.0: + resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} + engines: {node: '>=4'} + dev: false + + /filenamify@3.0.0: + resolution: {integrity: sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==} + engines: {node: '>=6'} + dependencies: + filename-reserved-regex: 2.0.0 + strip-outer: 1.0.1 + trim-repeated: 1.0.0 + dev: false + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -4662,6 +4955,15 @@ packages: mime-types: 2.1.35 dev: true + /form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -4683,6 +4985,17 @@ packages: engines: {node: '>=10'} dev: true + /from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + dev: false + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: false + /fs-extra@11.2.0: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} @@ -4834,6 +5147,26 @@ packages: engines: {node: '>=12'} dev: true + /get-stream@2.3.1: + resolution: {integrity: sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==} + engines: {node: '>=0.10.0'} + dependencies: + object-assign: 4.1.1 + pinkie-promise: 2.0.1 + dev: false + + /get-stream@3.0.0: + resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} + engines: {node: '>=4'} + dev: false + + /get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + dependencies: + pump: 3.0.0 + dev: false + /get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -4978,6 +5311,31 @@ packages: responselike: 3.0.0 dev: true + /got@8.3.2: + resolution: {integrity: sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==} + engines: {node: '>=4'} + dependencies: + '@sindresorhus/is': 0.7.0 + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.3 + cacheable-request: 2.1.4 + decompress-response: 3.3.0 + duplexer3: 0.1.5 + get-stream: 3.0.0 + into-stream: 3.1.0 + is-retry-allowed: 1.2.0 + isurl: 1.0.0 + lowercase-keys: 1.0.1 + mimic-response: 1.0.1 + p-cancelable: 0.4.1 + p-timeout: 2.0.1 + pify: 3.0.0 + safe-buffer: 5.2.1 + timed-out: 4.0.1 + url-parse-lax: 3.0.0 + url-to-options: 1.0.1 + dev: false + /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} dev: true @@ -5031,11 +5389,21 @@ packages: engines: {node: '>= 0.4'} dev: true + /has-symbol-support-x@1.4.2: + resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} + dev: false + /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} dev: true + /has-to-string-tag-x@1.4.1: + resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} + dependencies: + has-symbol-support-x: 1.4.2 + dev: false + /has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} @@ -5104,6 +5472,10 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true + /http-cache-semantics@3.8.1: + resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} + dev: false + /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} dev: true @@ -5214,7 +5586,6 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true /ignore-walk@6.0.5: resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} @@ -5278,6 +5649,14 @@ packages: side-channel: 1.0.6 dev: true + /into-stream@3.1.0: + resolution: {integrity: sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==} + engines: {node: '>=4'} + dependencies: + from2: 2.3.0 + p-is-promise: 1.1.0 + dev: false + /ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} @@ -5408,6 +5787,10 @@ packages: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} dev: true + /is-natural-number@4.0.1: + resolution: {integrity: sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==} + dev: false + /is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -5438,6 +5821,10 @@ packages: engines: {node: '>=8'} dev: true + /is-object@1.0.2: + resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} + dev: false + /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -5446,7 +5833,6 @@ packages: /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} - dev: true /is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} @@ -5466,6 +5852,11 @@ packages: has-tostringtag: 1.0.2 dev: true + /is-retry-allowed@1.2.0: + resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} + engines: {node: '>=0.10.0'} + dev: false + /is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} @@ -5473,6 +5864,11 @@ packages: call-bind: 1.0.7 dev: true + /is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + dev: false + /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -5610,6 +6006,14 @@ packages: istanbul-lib-report: 3.0.1 dev: true + /isurl@1.0.0: + resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} + engines: {node: '>= 4'} + dependencies: + has-to-string-tag-x: 1.4.1 + is-object: 1.0.2 + dev: false + /jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} @@ -5657,6 +6061,10 @@ packages: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} dev: true + /json-buffer@3.0.0: + resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} + dev: false + /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true @@ -5746,6 +6154,12 @@ packages: verror: 1.10.0 dev: true + /keyv@3.0.0: + resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} + dependencies: + json-buffer: 3.0.0 + dev: false + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -5942,6 +6356,16 @@ packages: get-func-name: 2.0.2 dev: true + /lowercase-keys@1.0.0: + resolution: {integrity: sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==} + engines: {node: '>=0.10.0'} + dev: false + + /lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + dev: false + /lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5981,6 +6405,21 @@ packages: source-map-js: 1.2.0 dev: true + /make-dir@1.3.0: + resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + dev: false + + /make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.2 + dev: false + /make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -6131,6 +6570,11 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + /mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + dev: false + /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -6431,6 +6875,15 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + /normalize-url@2.0.1: + resolution: {integrity: sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==} + engines: {node: '>=4'} + dependencies: + prepend-http: 2.0.0 + query-string: 5.1.1 + sort-keys: 2.0.0 + dev: false + /normalize-url@8.0.1: resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} engines: {node: '>=14.16'} @@ -6623,11 +7076,23 @@ packages: resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} dev: true + /p-cancelable@0.4.1: + resolution: {integrity: sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==} + engines: {node: '>=4'} + dev: false + /p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} dev: true + /p-event@2.3.1: + resolution: {integrity: sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==} + engines: {node: '>=6'} + dependencies: + p-timeout: 2.0.1 + dev: false + /p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -6635,6 +7100,16 @@ packages: p-map: 2.1.0 dev: true + /p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + dev: false + + /p-is-promise@1.1.0: + resolution: {integrity: sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==} + engines: {node: '>=4'} + dev: false + /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -6682,6 +7157,13 @@ packages: aggregate-error: 3.1.0 dev: true + /p-timeout@2.0.1: + resolution: {integrity: sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==} + engines: {node: '>=4'} + dependencies: + p-finally: 1.0.0 + dev: false + /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -6795,7 +7277,6 @@ packages: /pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - dev: true /perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} @@ -6822,12 +7303,27 @@ packages: /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: false /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - dev: true + + /pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + dependencies: + pinkie: 2.0.4 + dev: false + + /pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + dev: false /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} @@ -6907,6 +7403,11 @@ packages: which-pm: 2.0.0 dev: true + /prepend-http@2.0.0: + resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} + engines: {node: '>=4'} + dev: false + /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} @@ -6994,7 +7495,6 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: true /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -7018,6 +7518,15 @@ packages: side-channel: 1.0.6 dev: true + /query-string@5.1.1: + resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} + engines: {node: '>=0.10.0'} + dependencies: + decode-uri-component: 0.2.2 + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + dev: false + /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: true @@ -7252,6 +7761,12 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /responselike@1.0.2: + resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} + dependencies: + lowercase-keys: 1.0.1 + dev: false + /responselike@3.0.0: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} @@ -7363,7 +7878,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} @@ -7386,6 +7900,13 @@ packages: resolution: {integrity: sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==} dev: true + /seek-bzip@1.0.6: + resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} + hasBin: true + dependencies: + commander: 2.20.3 + dev: false + /semver-diff@4.0.0: resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} engines: {node: '>=12'} @@ -7400,7 +7921,6 @@ packages: /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true - dev: true /semver@7.6.2: resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} @@ -7627,6 +8147,27 @@ packages: smart-buffer: 4.2.0 dev: true + /sort-keys-length@1.0.1: + resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} + engines: {node: '>=0.10.0'} + dependencies: + sort-keys: 1.1.2 + dev: false + + /sort-keys@1.1.2: + resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-obj: 1.1.0 + dev: false + + /sort-keys@2.0.0: + resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} + engines: {node: '>=4'} + dependencies: + is-plain-obj: 1.1.0 + dev: false + /sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} dev: true @@ -7778,6 +8319,11 @@ packages: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} dev: true + /strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + dev: false + /string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -7863,6 +8409,12 @@ packages: engines: {node: '>=4'} dev: true + /strip-dirs@2.1.0: + resolution: {integrity: sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==} + dependencies: + is-natural-number: 4.0.1 + dev: false + /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -7894,6 +8446,13 @@ packages: acorn: 8.11.3 dev: true + /strip-outer@1.0.1: + resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} + engines: {node: '>=0.10.0'} + dependencies: + escape-string-regexp: 1.0.5 + dev: false + /sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -7940,6 +8499,19 @@ packages: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} dev: true + /tar-stream@1.6.2: + resolution: {integrity: sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==} + engines: {node: '>= 0.8.0'} + dependencies: + bl: 1.2.3 + buffer-alloc: 1.2.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + readable-stream: 2.3.8 + to-buffer: 1.1.1 + xtend: 4.0.2 + dev: false + /tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} dependencies: @@ -8000,7 +8572,11 @@ packages: /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true + + /timed-out@4.0.1: + resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} + engines: {node: '>=0.10.0'} + dev: false /tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} @@ -8039,6 +8615,10 @@ packages: engines: {node: '>=14.14'} dev: true + /to-buffer@1.1.1: + resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==} + dev: false + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -8078,6 +8658,13 @@ packages: engines: {node: '>=8'} dev: true + /trim-repeated@1.0.0: + resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} + engines: {node: '>=0.10.0'} + dependencies: + escape-string-regexp: 1.0.5 + dev: false + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -8356,13 +8943,19 @@ packages: which-boxed-primitive: 1.0.2 dev: true + /unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + dependencies: + buffer: 5.7.1 + through: 2.3.8 + dev: false + /underscore@1.13.6: resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} dev: false /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true /unique-filename@2.0.1: resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} @@ -8466,6 +9059,13 @@ packages: punycode: 2.3.1 dev: true + /url-parse-lax@3.0.0: + resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} + engines: {node: '>=4'} + dependencies: + prepend-http: 2.0.0 + dev: false + /url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} dependencies: @@ -8473,6 +9073,11 @@ packages: requires-port: 1.0.0 dev: true + /url-to-options@1.0.1: + resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==} + engines: {node: '>= 4'} + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -8935,6 +9540,11 @@ packages: engines: {node: '>=12'} dev: true + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: false + /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} dev: true @@ -9010,7 +9620,6 @@ packages: dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} diff --git a/wallets/phantom/package.json b/wallets/phantom/package.json index 603a27017..265aafa75 100644 --- a/wallets/phantom/package.json +++ b/wallets/phantom/package.json @@ -15,7 +15,7 @@ ], "scripts": { "build": "pnpm run clean && pnpm run build:dist && pnpm run build:types", - "build:cache": "synpress-cache test/wallet-setup --phantom", + "build:cache": "synpress-cache test/wallet-setup --phantom --debug", "build:dist": "tsup --tsconfig tsconfig.build.json", "build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json", "clean": "rimraf dist types", diff --git a/wallets/phantom/src/fixtureActions/getExtensionId.ts b/wallets/phantom/src/fixtureActions/getExtensionId.ts new file mode 100644 index 000000000..aaa88cf3e --- /dev/null +++ b/wallets/phantom/src/fixtureActions/getExtensionId.ts @@ -0,0 +1,46 @@ +import type { BrowserContext } from '@playwright/test' +import { z } from 'zod' + +const Extension = z.object({ + id: z.string(), + name: z.string() +}) + +const Extensions = z.array(Extension) + +/** + * Returns the extension ID for the given extension name. The ID is fetched from the `chrome://extensions` page. + * + * ::: tip + * This function soon will be removed to improve the developer experience! 😇 + * ::: + * + * @param context - The browser context. + * @param extensionName - The name of the extension, e.g., `Keplr`. + * + * @returns The extension ID. + */ +export async function getExtensionId(context: BrowserContext, extensionName: string) { + const page = await context.newPage() + await page.goto('chrome://extensions') + + const unparsedExtensions = await page.evaluate('chrome.management.getAll()') + const allExtensions = Extensions.parse(unparsedExtensions) + + const targetExtension = allExtensions.find( + (extension: { name: string }) => extension.name.toLowerCase() === extensionName.toLowerCase() + ) + + if (!targetExtension) { + throw new Error( + [ + `[GetExtensionId] Extension with name ${extensionName} not found.`, + `Available extensions: ${allExtensions.map((extension: { name: string }) => extension.name).join(', ')}` + ].join('\n') + ) + } + + await page.close() + + return targetExtension.id +} diff --git a/wallets/phantom/src/fixtureActions/index.ts b/wallets/phantom/src/fixtureActions/index.ts new file mode 100644 index 000000000..77a094411 --- /dev/null +++ b/wallets/phantom/src/fixtureActions/index.ts @@ -0,0 +1 @@ +export * from './getExtensionId' \ No newline at end of file diff --git a/wallets/phantom/src/fixtureActions/persistLocalStorage.ts b/wallets/phantom/src/fixtureActions/persistLocalStorage.ts new file mode 100644 index 000000000..e24deb66d --- /dev/null +++ b/wallets/phantom/src/fixtureActions/persistLocalStorage.ts @@ -0,0 +1,24 @@ +import type { BrowserContext } from '@playwright/test' + +export async function persistLocalStorage( + origins: { + origin: string + localStorage: { name: string; value: string }[] + }[], + context: BrowserContext +) { + const newPage = await context.newPage() + + for (const { origin, localStorage } of origins) { + const frame = newPage.mainFrame() + await frame.goto(origin) + + await frame.evaluate((localStorageData) => { + localStorageData.forEach(({ name, value }) => { + window.localStorage.setItem(name, value) + }) + }, localStorage) + } + + await newPage.close() +} diff --git a/wallets/phantom/src/fixtures/phantomFixtures.ts b/wallets/phantom/src/fixtures/phantomFixtures.ts index 91850a790..3df589fb9 100644 --- a/wallets/phantom/src/fixtures/phantomFixtures.ts +++ b/wallets/phantom/src/fixtures/phantomFixtures.ts @@ -14,7 +14,8 @@ import { PhantomWallet } from '../PhantomWallet' import { getExtensionId } from '../fixtureActions' import { persistLocalStorage } from '../fixtureActions/persistLocalStorage' // import unlockForFixtures from '../fixtureActions/unlockForFixtures' -import { PASSWORD } from '../utils' + +const PASSWORD = '12345678' type PhantomFixtures = { _contextPath: string diff --git a/wallets/phantom/src/pages/HomePage/selectors/index.ts b/wallets/phantom/src/pages/HomePage/selectors/index.ts index 783d34845..0bddd2f03 100644 --- a/wallets/phantom/src/pages/HomePage/selectors/index.ts +++ b/wallets/phantom/src/pages/HomePage/selectors/index.ts @@ -9,7 +9,7 @@ const networkSwitcher = { goerliNetworkItem: `[data-testid="network-droppo"] [data-testid="goerli-network-item"]`, sepoliaNetworkItem: `[data-testid="network-droppo"] [data-testid="sepolia-network-item"]`, localhostNetworkItem: `[data-testid="network-droppo"] [data-testid="Localhost 8545-network-item"]`, - networkButton: number => + networkButton: (number: number) => `[data-testid="network-droppo"] .dropdown-menu-item:nth-child(${ 3 + number })`, @@ -62,7 +62,7 @@ const actionableMessage = { }; const accountMenu = { - accountButton: number => `[data-testid="account-menu"] [data-testid="tooltip_interactive-wrapper"]:nth-child(${number})`, + accountButton: (number: number) => `[data-testid="account-menu"] [data-testid="tooltip_interactive-wrapper"]:nth-child(${number})`, }; const settingsMenu = { diff --git a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts index de4622f64..ac82a3293 100644 --- a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts @@ -6,7 +6,7 @@ export const importWallet = async (page: Page, secretWords: string, password: st await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) for (const [index, word] of secretWords.split(' ').entries()) { - const inputField = await page.selectors(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) + const inputField = await page.locator(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) await inputField.fill(word) } await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) diff --git a/wallets/phantom/src/pages/LockPage/selectors/index.ts b/wallets/phantom/src/pages/LockPage/selectors/index.ts index 79a764285..2e6da5a88 100644 --- a/wallets/phantom/src/pages/LockPage/selectors/index.ts +++ b/wallets/phantom/src/pages/LockPage/selectors/index.ts @@ -29,7 +29,7 @@ const firstTimeFlowPageElements = { const firstTimeFlowImportPage = '.first-time-flow__import'; const newVaultForm = `${firstTimeFlowImportPage} .create-new-vault__form`; -const secretWordsInput = number => +const secretWordsInput = (number: number) => `[data-testid="secret-recovery-phrase-word-input-${number}"]`; const confirmWordsButton = `[data-testid="onboarding-form-submit-button"]`; const passwordInput = `[data-testid="onboarding-form-password-input"]`; diff --git a/wallets/phantom/src/utils/constants.ts b/wallets/phantom/src/utils/constants.ts index 2bd168758..c3fb26259 100644 --- a/wallets/phantom/src/utils/constants.ts +++ b/wallets/phantom/src/utils/constants.ts @@ -1,12 +1,12 @@ -const PROVIDER = 'phantom' +// const PROVIDER = 'phantom' -const extensionInitialUrl = await playwright.windows(PROVIDER).url(); -const extensionId = extensionInitialUrl.match('//(.*?)/')[1]; -const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html`; -const extensionSettingsUrl = `${extensionHomeUrl}#settings`; -const extensionAdvancedSettingsUrl = `${extensionSettingsUrl}/advanced`; -const extensionExperimentalSettingsUrl = `${extensionSettingsUrl}/experimental`; -const extensionAddNetworkUrl = `${extensionSettingsUrl}/networks/add-network`; -const extensionNewAccountUrl = `${extensionHomeUrl}#new-account`; -const extensionImportAccountUrl = `${extensionNewAccountUrl}/import`; -const extensionImportTokenUrl = `${extensionHomeUrl}#import-token`; \ No newline at end of file +// const extensionInitialUrl = await playwright.windows(PROVIDER).url(); +// const extensionId = extensionInitialUrl.match('//(.*?)/')[1]; +// const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html`; +// const extensionSettingsUrl = `${extensionHomeUrl}#settings`; +// const extensionAdvancedSettingsUrl = `${extensionSettingsUrl}/advanced`; +// const extensionExperimentalSettingsUrl = `${extensionSettingsUrl}/experimental`; +// const extensionAddNetworkUrl = `${extensionSettingsUrl}/networks/add-network`; +// const extensionNewAccountUrl = `${extensionHomeUrl}#new-account`; +// const extensionImportAccountUrl = `${extensionNewAccountUrl}/import`; +// const extensionImportTokenUrl = `${extensionHomeUrl}#import-token`; \ No newline at end of file diff --git a/wallets/phantom/src/utils/index.ts b/wallets/phantom/src/utils/index.ts index d6f677629..ee4cdabba 100644 --- a/wallets/phantom/src/utils/index.ts +++ b/wallets/phantom/src/utils/index.ts @@ -1 +1,2 @@ -export * from './selectors/loading' \ No newline at end of file +export * from './selectors/loading' +export * from './constants' \ No newline at end of file diff --git a/wallets/phantom/test/wallet-setup/import.setup.ts b/wallets/phantom/test/wallet-setup/import.setup.ts index e69de29bb..6e9692000 100644 --- a/wallets/phantom/test/wallet-setup/import.setup.ts +++ b/wallets/phantom/test/wallet-setup/import.setup.ts @@ -0,0 +1,19 @@ +import type { BrowserContext, Page } from '@playwright/test' +import { defineWalletSetup } from '@synthetixio/synpress-cache' +import { PhantomWallet } from '../../src' +import { getExtensionId } from '../../src/fixtureActions' + +const PASSWORD = 'Test1234' + +const importPhantomWallet = defineWalletSetup(PASSWORD, async (context: BrowserContext, phantomPage: Page) => { + const extensionId = await getExtensionId(context, 'phantom') + const phantom = new PhantomWallet(phantomPage, context, PASSWORD, extensionId) + + try { + await phantom.importWallet({ secretWords: '', password: PASSWORD }) + } catch (e) { + console.log('Error creating Keplr wallet:', e) + } +}) + +export default importPhantomWallet diff --git a/wallets/phantom/test/wallet-setup/import2.setup.ts b/wallets/phantom/test/wallet-setup/import2.setup.ts new file mode 100644 index 000000000..adfae4e5c --- /dev/null +++ b/wallets/phantom/test/wallet-setup/import2.setup.ts @@ -0,0 +1,19 @@ +import type { BrowserContext, Page } from '@playwright/test' +import { defineWalletSetup } from '@synthetixio/synpress-cache' +import { PhantomWallet } from '../../src' +import { getExtensionId } from '../../src/fixtureActions' + +const PASSWORD = 'Test1234' + +const importPhantomWallet = defineWalletSetup(PASSWORD, async (context: BrowserContext, phantomPage: Page) => { + const extensionId = await getExtensionId(context, 'phantom') + const phantom2 = new PhantomWallet(phantomPage, context, PASSWORD, extensionId) + + try { + await phantom2.importWallet({ secretWords: '', password: PASSWORD }) + } catch (e) { + console.log('Error creating Keplr wallet:', e) + } +}) + +export default importPhantomWallet From 5469d14ce0bbbd36573079a27704529d4b4337de Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Fri, 5 Jul 2024 08:28:59 -0400 Subject: [PATCH 06/16] unzip crx --- packages/cache/package.json | 1 + packages/cache/src/prepareExtension.ts | 43 +++++++++++++------------- packages/cache/src/unzip.d.ts | 1 + pnpm-lock.yaml | 38 +++++++++++++++++++++++ 4 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 packages/cache/src/unzip.d.ts diff --git a/packages/cache/package.json b/packages/cache/package.json index 051030d11..3b06e8010 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -39,6 +39,7 @@ "gradient-string": "2.0.2", "progress": "2.0.3", "tsup": "8.0.2", + "unzip-crx-3": "0.2.0", "unzipper": "0.10.14", "zod": "3.22.4" }, diff --git a/packages/cache/src/prepareExtension.ts b/packages/cache/src/prepareExtension.ts index 1919301f1..fdd4cf8c3 100644 --- a/packages/cache/src/prepareExtension.ts +++ b/packages/cache/src/prepareExtension.ts @@ -1,4 +1,5 @@ -// import download from 'download' +import download from 'download' +import unzipCrx from 'unzip-crx-3'; import { downloadFile, ensureCacheDirExists, unzipArchive } from '.' interface ExtensionConfig { @@ -42,24 +43,24 @@ export async function prepareExtension(extensionName: string) { const cacheDirPath = ensureCacheDirExists() const extensionConfig = await getExtensionConfig(extensionName) // Get config let downloadResult - // if (extensionConfig.name === 'Phantom') { - // downloadResult = await download(extensionConfig.downloadUrl, cacheDirPath, { - // headers: { - // Accept: 'application/octet-stream', - // }, - // }); - // } - // else { - - // } - downloadResult = await downloadFile({ - url: extensionConfig.downloadUrl, - outputDir: cacheDirPath, - fileName: extensionName === 'Phantom' ? 'latest.crx' : `${extensionConfig.name.toLowerCase()}-chrome-${extensionConfig.version}.zip` - }) - const unzipResult = await unzipArchive({ - archivePath: downloadResult.filePath - }) - - return unzipResult.outputPath + if (extensionConfig.name === 'Phantom') { + downloadResult = await download(extensionConfig.downloadUrl, cacheDirPath, { + headers: { + Accept: 'application/octet-stream', + }, + }); + return unzipCrx('.cache-synpress/latest.zip', cacheDirPath) + } + else { + downloadResult = await downloadFile({ + url: extensionConfig.downloadUrl, + outputDir: cacheDirPath, + fileName: `${extensionConfig.name.toLowerCase()}-chrome-${extensionConfig.version}.zip` + }) + const unzipResult = await unzipArchive({ + archivePath: downloadResult.filePath + }) + + return unzipResult.outputPath + } } diff --git a/packages/cache/src/unzip.d.ts b/packages/cache/src/unzip.d.ts new file mode 100644 index 000000000..74f5f100f --- /dev/null +++ b/packages/cache/src/unzip.d.ts @@ -0,0 +1 @@ +declare module 'unzip-crx-3'; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0910748ff..6a23cff6a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -123,6 +123,9 @@ importers: tsup: specifier: 8.0.2 version: 8.0.2(typescript@5.3.3) + unzip-crx-3: + specifier: 0.2.0 + version: 0.2.0 unzipper: specifier: 0.10.14 version: 0.10.14 @@ -5598,6 +5601,10 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + /import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} @@ -6154,6 +6161,15 @@ packages: verror: 1.10.0 dev: true + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: false + /keyv@3.0.0: resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} dependencies: @@ -6195,6 +6211,12 @@ packages: readable-stream: 2.3.8 dev: true + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + dev: false + /lilconfig@3.0.0: resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} engines: {node: '>=14'} @@ -7207,6 +7229,10 @@ packages: - supports-color dev: true + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + /parse-github-url@1.0.2: resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} engines: {node: '>=0.10.0'} @@ -9011,6 +9037,14 @@ packages: engines: {node: '>=8'} dev: true + /unzip-crx-3@0.2.0: + resolution: {integrity: sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==} + dependencies: + jszip: 3.10.1 + mkdirp: 0.5.6 + yaku: 0.16.7 + dev: false + /unzipper@0.10.14: resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} dependencies: @@ -9554,6 +9588,10 @@ packages: engines: {node: '>=10'} dev: true + /yaku@0.16.7: + resolution: {integrity: sha512-Syu3IB3rZvKvYk7yTiyl1bo/jiEFaaStrgv1V2TIJTqYPStSMQVO8EQjg/z+DRzLq/4LIIharNT3iH1hylEIRw==} + dev: false + /yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} dev: true From 5f325fc6a29c410c81717120313abcff1892c4b7 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Mon, 8 Jul 2024 05:33:51 -0400 Subject: [PATCH 07/16] unzip working --- packages/cache/src/prepareExtension.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cache/src/prepareExtension.ts b/packages/cache/src/prepareExtension.ts index fdd4cf8c3..bd2dea080 100644 --- a/packages/cache/src/prepareExtension.ts +++ b/packages/cache/src/prepareExtension.ts @@ -44,12 +44,14 @@ export async function prepareExtension(extensionName: string) { const extensionConfig = await getExtensionConfig(extensionName) // Get config let downloadResult if (extensionConfig.name === 'Phantom') { + const outputPath = `${cacheDirPath}/latest` downloadResult = await download(extensionConfig.downloadUrl, cacheDirPath, { headers: { Accept: 'application/octet-stream', }, }); - return unzipCrx('.cache-synpress/latest.zip', cacheDirPath) + await unzipCrx('.cache-synpress/latest.crx', outputPath) + return outputPath } else { downloadResult = await downloadFile({ From b6330f60cba9a0d9a8683d5573133ba18d38f102 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Mon, 8 Jul 2024 06:03:35 -0400 Subject: [PATCH 08/16] merge and import --- wallets/phantom/package.json | 2 +- .../pages/LockPage/actions/createAccount.ts | 32 +++++++++++++++++++ .../src/pages/LockPage/actions/index.ts | 3 +- wallets/phantom/src/pages/LockPage/page.ts | 6 +++- .../phantom/test/wallet-setup/import.setup.ts | 5 +-- 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 wallets/phantom/src/pages/LockPage/actions/createAccount.ts diff --git a/wallets/phantom/package.json b/wallets/phantom/package.json index 265aafa75..4c537c047 100644 --- a/wallets/phantom/package.json +++ b/wallets/phantom/package.json @@ -15,7 +15,7 @@ ], "scripts": { "build": "pnpm run clean && pnpm run build:dist && pnpm run build:types", - "build:cache": "synpress-cache test/wallet-setup --phantom --debug", + "build:cache": "synpress-cache test/wallet-setup --phantom --debug --force --phantom", "build:dist": "tsup --tsconfig tsconfig.build.json", "build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json", "clean": "rimraf dist types", diff --git a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts new file mode 100644 index 000000000..ac82a3293 --- /dev/null +++ b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts @@ -0,0 +1,32 @@ +import type { Page } from '@playwright/test' +import { lockPageElements } from "../selectors"; + +export const importWallet = async (page: Page, secretWords: string, password: string) => { + await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) + await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) + + for (const [index, word] of secretWords.split(' ').entries()) { + const inputField = await page.locator(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) + await inputField.fill(word) + } + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + + await page.waitForLoadState('domcontentloaded') + + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + + const walletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.passwordInput) + await walletInput.fill(password) + + const confirmWalletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.confirmPasswordInput) + await confirmWalletInput.fill(password) + + const checkbox = await page.locator(lockPageElements.firstTimeFlowImportPageElements.termsCheckbox) + await checkbox.click() + + await page.click(lockPageElements.firstTimeFlowImportPageElements.continueAfterPasswordButton) + + await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/actions/index.ts b/wallets/phantom/src/pages/LockPage/actions/index.ts index 4aaa3d5e9..5fa3aef98 100644 --- a/wallets/phantom/src/pages/LockPage/actions/index.ts +++ b/wallets/phantom/src/pages/LockPage/actions/index.ts @@ -1 +1,2 @@ -export * from './importAccount' \ No newline at end of file +export * from './importAccount' +export * from './createAccount' \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/page.ts b/wallets/phantom/src/pages/LockPage/page.ts index 829a0adfc..a2e5cfc16 100644 --- a/wallets/phantom/src/pages/LockPage/page.ts +++ b/wallets/phantom/src/pages/LockPage/page.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test' import { lockPageElements } from './selectors' -import { importWallet } from './actions' +import { importWallet, createAccount } from './actions' export class LockPage { static readonly selectors = lockPageElements @@ -15,4 +15,8 @@ export class LockPage { async importWallet(secretWords: string, password: string) { await importWallet(this.page, secretWords, password) } + + async createWallet(password: string) { + await createAccount(this.page, password) + } } diff --git a/wallets/phantom/test/wallet-setup/import.setup.ts b/wallets/phantom/test/wallet-setup/import.setup.ts index 6e9692000..610882a3a 100644 --- a/wallets/phantom/test/wallet-setup/import.setup.ts +++ b/wallets/phantom/test/wallet-setup/import.setup.ts @@ -3,14 +3,15 @@ import { defineWalletSetup } from '@synthetixio/synpress-cache' import { PhantomWallet } from '../../src' import { getExtensionId } from '../../src/fixtureActions' -const PASSWORD = 'Test1234' +const PASSWORD = '12345678' +const SECRET_WORDS = 'miss lock clip bicycle once road marble stay stereo bar change home' const importPhantomWallet = defineWalletSetup(PASSWORD, async (context: BrowserContext, phantomPage: Page) => { const extensionId = await getExtensionId(context, 'phantom') const phantom = new PhantomWallet(phantomPage, context, PASSWORD, extensionId) try { - await phantom.importWallet({ secretWords: '', password: PASSWORD }) + await phantom.importWallet({ secretWords: SECRET_WORDS, password: PASSWORD }) } catch (e) { console.log('Error creating Keplr wallet:', e) } From fbbd4926dbba4a40db54b152868385fe70d52ab1 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:30:12 -0400 Subject: [PATCH 09/16] migrating and adapting actions --- .../HomePage/actions/getWalletAddress.ts | 20 ++++++++++ .../pages/LockPage/actions/createAccount.ts | 39 ++++++++++--------- .../src/pages/LockPage/actions/unlock.ts | 18 +++++++++ .../NotificationPage/actions/acceptAccess.ts | 9 +++++ .../pages/NotificationPage/actions/lock.ts | 13 +++++++ .../utils/getNotificationAndWaitForLoads.ts | 26 +++++++++++++ 6 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts create mode 100644 wallets/phantom/src/pages/LockPage/actions/unlock.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/lock.ts create mode 100644 wallets/phantom/src/utils/getNotificationAndWaitForLoads.ts diff --git a/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts b/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts new file mode 100644 index 000000000..dd2bfd072 --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts @@ -0,0 +1,20 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { homePageElements } from "../selectors"; + +export const getWalletAddress = async (page: Page, extensionId: string, chain = 'eth') => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.hover(homePageElements.accountBar.title) + + await new Promise(resolve => setTimeout(resolve, 100)); + await notificationPage.waitForLoadState('domcontentloaded') + + if (chain === 'eth') { + await notificationPage.click(homePageElements.accountBar.ethRow); + } else if (chain === 'solana') { + await notificationPage.click(homePageElements.accountBar.solanaRow); + } + + const walletAddress = await notificationPage.evaluate('navigator.clipboard.readText()') + return walletAddress; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts index ac82a3293..55cfc8fef 100644 --- a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts @@ -1,32 +1,33 @@ import type { Page } from '@playwright/test' import { lockPageElements } from "../selectors"; -export const importWallet = async (page: Page, secretWords: string, password: string) => { - await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) - await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) +export const createAccount = async (page: Page, secretWords: string, password: string) => { + console.log(lockPageElements, page, secretWords, password) + // await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) + // await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) - for (const [index, word] of secretWords.split(' ').entries()) { - const inputField = await page.locator(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) - await inputField.fill(word) - } - await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + // for (const [index, word] of secretWords.split(' ').entries()) { + // const inputField = await page.locator(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) + // await inputField.fill(word) + // } + // await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) - await page.waitForLoadState('domcontentloaded') + // await page.waitForLoadState('domcontentloaded') - await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + // await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) - const walletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.passwordInput) - await walletInput.fill(password) + // const walletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.passwordInput) + // await walletInput.fill(password) - const confirmWalletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.confirmPasswordInput) - await confirmWalletInput.fill(password) + // const confirmWalletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.confirmPasswordInput) + // await confirmWalletInput.fill(password) - const checkbox = await page.locator(lockPageElements.firstTimeFlowImportPageElements.termsCheckbox) - await checkbox.click() + // const checkbox = await page.locator(lockPageElements.firstTimeFlowImportPageElements.termsCheckbox) + // await checkbox.click() - await page.click(lockPageElements.firstTimeFlowImportPageElements.continueAfterPasswordButton) + // await page.click(lockPageElements.firstTimeFlowImportPageElements.continueAfterPasswordButton) - await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); + // await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); - return true; + // return true; } \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/actions/unlock.ts b/wallets/phantom/src/pages/LockPage/actions/unlock.ts new file mode 100644 index 000000000..40fff793a --- /dev/null +++ b/wallets/phantom/src/pages/LockPage/actions/unlock.ts @@ -0,0 +1,18 @@ +import type { Page } from '@playwright/test' +import { lockPageElements } from "../selectors"; + +export const unlock = async (page: Page, password: string, close = false) => { + console.log('close', close) + await page.waitForLoadState('domcontentloaded') + + const inputField = await page.locator(lockPageElements.unlockPageElements.passwordInput) + await inputField.fill(password) + + await page.click(lockPageElements.unlockPageElements.unlockButton); + + // if(close) { + // await module.exports.closePopupAndTooltips(); + // } + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts b/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts new file mode 100644 index 000000000..552c72b31 --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts @@ -0,0 +1,9 @@ +import { notificationPageElements } from "../selectors"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import type { Page } from "@playwright/test"; + +export const acceptAccess = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.click(notificationPageElements.buttons.primaryButton); + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts new file mode 100644 index 000000000..620653d9d --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts @@ -0,0 +1,13 @@ +import type { Page } from '@playwright/test' +import { notificationPageElements } from '../selectors' +import { settingsPageElements } from '../../SettingsPage/selectors' + +export const lock = async (page: Page) => { + await page.waitForLoadState('domcontentloaded') + await page.click(notificationPageElements.menu.buttons.settings); + await page.click(notificationPageElements.menu.buttons.sidebar.settings) + await page.click(settingsPageElements.buttons.lockWallet) + + // await module.exports.closePopupAndTooltips(); + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/utils/getNotificationAndWaitForLoads.ts b/wallets/phantom/src/utils/getNotificationAndWaitForLoads.ts new file mode 100644 index 000000000..2a8951782 --- /dev/null +++ b/wallets/phantom/src/utils/getNotificationAndWaitForLoads.ts @@ -0,0 +1,26 @@ +import type { BrowserContext, Page } from '@playwright/test' + +export async function getNotificationPageAndWaitForLoad(context: BrowserContext, extensionId: string) { + const notificationPageUrl = `chrome-extension://${extensionId}/notification.html` + + const isNotificationPage = (page: Page) => page.url().includes(notificationPageUrl) + + // Check if notification page is already open. + let notificationPage = context.pages().find(isNotificationPage) + + if (!notificationPage) { + notificationPage = await context.waitForEvent('page', { + predicate: isNotificationPage + }) + } + + // Set pop-up window viewport size to resemble the actual MetaMask pop-up window. + await notificationPage.setViewportSize({ + width: 360, + height: 592 + }) + + await notificationPage.waitForLoadState('load') + + return notificationPage +} From cdd98f2f858e9bef93a3bc17655bd1acc6b49f02 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:51:48 -0400 Subject: [PATCH 10/16] migrating more functions --- .../src/pages/HomePage/actions/changeAccount.ts | 8 ++++++++ .../actions/confirmIncorrectNetwork.ts | 10 ++++++++++ .../NotificationPage/actions/confirmSignature.ts | 10 ++++++++++ .../actions/confirmTransaction.ts | 10 ++++++++++ .../NotificationPage/actions/rejectSignature.ts | 10 ++++++++++ .../NotificationPage/actions/rejectTransaction.ts | 11 +++++++++++ .../NotificationPage/actions/selectWallet.ts | 15 +++++++++++++++ 7 files changed, 74 insertions(+) create mode 100644 wallets/phantom/src/pages/HomePage/actions/changeAccount.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts create mode 100644 wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts diff --git a/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts b/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts new file mode 100644 index 000000000..30172fd33 --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts @@ -0,0 +1,8 @@ +import type { Page } from "@playwright/test"; +import { homePageElements } from "../selectors"; + +export const changeAccount = async (page: Page, accountIndex = 1) => { + await page.waitForLoadState('domcontentloaded') + await page.click(homePageElements.settingsMenu.settingsMenuButton); + await page.click(homePageElements.accountMenu.accountButton(accountIndex)) +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts b/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts new file mode 100644 index 000000000..7d70de68a --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts @@ -0,0 +1,10 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { notificationPageElements } from "../selectors"; + +export const confirmIncorrectNetwork = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + await notificationPage.click(notificationPageElements.incorrectModePageElements.buttons.close); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts b/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts new file mode 100644 index 000000000..6c746ec3a --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts @@ -0,0 +1,10 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { notificationPageElements } from "../selectors"; + +export const confirmSignatureRequest = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + await notificationPage.click(notificationPageElements.signaturePageElements.buttons.confirmSign); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts b/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts new file mode 100644 index 000000000..3c507229c --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts @@ -0,0 +1,10 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { notificationPageElements } from "../selectors"; + +export const confirmTransaction = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + await notificationPage.click(notificationPageElements.transactionPageElements.buttons.confirmTransaction); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts b/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts new file mode 100644 index 000000000..dc1982aa9 --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts @@ -0,0 +1,10 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { notificationPageElements } from "../selectors"; + +export const rejectSignatureRequest = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + await notificationPage.click(notificationPageElements.signaturePageElements.buttons.rejectSign); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts b/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts new file mode 100644 index 000000000..016ff2988 --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts @@ -0,0 +1,11 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { notificationPageElements } from "../selectors"; + + +export const rejectTransaction = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + await notificationPage.click(notificationPageElements.transactionPageElements.buttons.rejectTransaction); + + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts b/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts new file mode 100644 index 000000000..b5cf623ed --- /dev/null +++ b/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts @@ -0,0 +1,15 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { notificationPageElements } from "../selectors"; + +export const selectWallet = async (page: Page, extensionId: string, wallet: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + if (wallet === 'metamask') { + await notificationPage.click(notificationPageElements.selectWalletElements.buttons.continueWithMetamask) + } + if (wallet === 'phantom') { + await notificationPage.click(notificationPageElements.selectWalletElements.buttons.continueWithPhantom) + } + + return true; +} \ No newline at end of file From 339fdab0ef7ad890469fbb62d1c6486e4d5a6176 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Mon, 8 Jul 2024 11:00:48 -0400 Subject: [PATCH 11/16] most actions done --- .../HomePage/actions/closePopupAndTooltips.ts | 24 +++++++++++++++++++ .../src/pages/LockPage/actions/unlock.ts | 11 +++++---- .../pages/NotificationPage/actions/index.ts | 8 +++++++ .../pages/NotificationPage/actions/lock.ts | 5 ++-- 4 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts diff --git a/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts b/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts new file mode 100644 index 000000000..cb495cdfd --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts @@ -0,0 +1,24 @@ +import type { Page } from "@playwright/test"; +import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; +import { homePageElements } from "../selectors"; + +export const closePopupAndTooltips = async (page: Page, extensionId: string) => { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + // note: this is required for fast execution of e2e tests to avoid flakiness + // otherwise popup may not be detected properly and not closed + const popupIsVisible = await notificationPage.locator(homePageElements.popup.container).isVisible() + const closeIsVisible = await notificationPage.locator(homePageElements.tippyTooltip.closeButton).isVisible() + const actionableMessageIsVisible = await notificationPage.locator(homePageElements.actionableMessage.closeButton).isVisible() + if (popupIsVisible) { + const popupBackground = await notificationPage.locator(homePageElements.popup.background) + const popupBackgroundBox = await popupBackground.boundingBox(); + await notificationPage.mouse.click(popupBackgroundBox?.x! + 1, popupBackgroundBox?.y! + 1) + } + if (closeIsVisible) { + await page.click(homePageElements.tippyTooltip.closeButton); + } + if (actionableMessageIsVisible) { + await page.click(homePageElements.actionableMessage.closeButton) + } + return true; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/actions/unlock.ts b/wallets/phantom/src/pages/LockPage/actions/unlock.ts index 40fff793a..73a5322bf 100644 --- a/wallets/phantom/src/pages/LockPage/actions/unlock.ts +++ b/wallets/phantom/src/pages/LockPage/actions/unlock.ts @@ -1,8 +1,9 @@ import type { Page } from '@playwright/test' import { lockPageElements } from "../selectors"; +import { closePopupAndTooltips } from '../../HomePage/actions/closePopupAndTooltips'; + +export const unlock = async (page: Page, extensionId: string, password: string, close = false) => { -export const unlock = async (page: Page, password: string, close = false) => { - console.log('close', close) await page.waitForLoadState('domcontentloaded') const inputField = await page.locator(lockPageElements.unlockPageElements.passwordInput) @@ -10,9 +11,9 @@ export const unlock = async (page: Page, password: string, close = false) => { await page.click(lockPageElements.unlockPageElements.unlockButton); - // if(close) { - // await module.exports.closePopupAndTooltips(); - // } + if(close) { + await closePopupAndTooltips(page, extensionId); + } return true; } \ No newline at end of file diff --git a/wallets/phantom/src/pages/NotificationPage/actions/index.ts b/wallets/phantom/src/pages/NotificationPage/actions/index.ts index e69de29bb..ab6dfc22f 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/index.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/index.ts @@ -0,0 +1,8 @@ +export * from './acceptAccess' +export * from './confirmSignature' +export * from './rejectSignature' +export * from './lock' +export * from './selectWallet' +export * from './rejectTransaction' +export * from './confirmTransaction' +export * from './confirmIncorrectNetwork' diff --git a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts index 620653d9d..f3506fded 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts @@ -1,13 +1,14 @@ import type { Page } from '@playwright/test' import { notificationPageElements } from '../selectors' import { settingsPageElements } from '../../SettingsPage/selectors' +import { closePopupAndTooltips } from '../../HomePage/actions/closePopupAndTooltips' -export const lock = async (page: Page) => { +export const lock = async (page: Page, extensionId: string) => { await page.waitForLoadState('domcontentloaded') await page.click(notificationPageElements.menu.buttons.settings); await page.click(notificationPageElements.menu.buttons.sidebar.settings) await page.click(settingsPageElements.buttons.lockWallet) - // await module.exports.closePopupAndTooltips(); + await closePopupAndTooltips(page, extensionId); return true; } \ No newline at end of file From 00eddf5ba25e5c17f56e6340b56a53234214276d Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Mon, 8 Jul 2024 11:45:09 -0400 Subject: [PATCH 12/16] route --- wallets/phantom/src/utils/getExtensionPage.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 wallets/phantom/src/utils/getExtensionPage.ts diff --git a/wallets/phantom/src/utils/getExtensionPage.ts b/wallets/phantom/src/utils/getExtensionPage.ts new file mode 100644 index 000000000..816efd0bb --- /dev/null +++ b/wallets/phantom/src/utils/getExtensionPage.ts @@ -0,0 +1,17 @@ +import type { Page } from "@playwright/test"; + +export const getExtensionPage = async (page: Page, extensionId: string, route: string) => { + const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html`; + + const routes: any = { + advanced: `${extensionHomeUrl}#settings/advanced`, + settings: `${extensionHomeUrl}#settings`, + experimental: `${extensionHomeUrl}#settings/experimental`, + addNetwork: `${extensionHomeUrl}#settings/networks/add-network`, + newAccount: `${extensionHomeUrl}#new-account`, + importAccount: `${extensionHomeUrl}#new-account/import`, + importToken: `${extensionHomeUrl}#import-token`, + } + + page.goto(routes[route]) +} \ No newline at end of file From 769d933d7dbb56ec0c3b417270a19681bf0b06c9 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:58:14 -0400 Subject: [PATCH 13/16] organise pages --- wallets/phantom/src/PhantomWallet.ts | 48 +++++++++++++++---- .../phantom/src/fixtures/phantomFixtures.ts | 2 +- .../HomePage/actions/disconnectFromApp.ts | 28 +++++++++++ .../src/pages/HomePage/actions/index.ts | 4 ++ wallets/phantom/src/pages/HomePage/page.ts | 17 +++++++ .../pages/LockPage/actions/createAccount.ts | 4 +- .../src/pages/LockPage/actions/index.ts | 3 +- wallets/phantom/src/pages/LockPage/page.ts | 9 +++- .../src/pages/NotificationPage/page.ts | 33 +++++++++++++ wallets/phantom/src/utils/constants.ts | 12 ----- wallets/phantom/src/utils/index.ts | 3 +- wallets/phantom/test/synpress.ts | 2 +- .../{import2.setup.ts => create.setup.ts} | 8 ++-- 13 files changed, 138 insertions(+), 35 deletions(-) create mode 100644 wallets/phantom/src/pages/HomePage/actions/disconnectFromApp.ts delete mode 100644 wallets/phantom/src/utils/constants.ts rename wallets/phantom/test/wallet-setup/{import2.setup.ts => create.setup.ts} (63%) diff --git a/wallets/phantom/src/PhantomWallet.ts b/wallets/phantom/src/PhantomWallet.ts index 0095863ec..5eb5a190a 100644 --- a/wallets/phantom/src/PhantomWallet.ts +++ b/wallets/phantom/src/PhantomWallet.ts @@ -32,30 +32,58 @@ export class PhantomWallet { * @param password. The password to set. */ async importWallet({ secretWords, password }: { secretWords: string; password: string }) { - this.lockPage.importWallet(secretWords, password) + await this.lockPage.importWallet(secretWords, password) } async createWallet(password: string) { - console.log(password) + await this.lockPage.createWallet(password) } async getWalletAddress(wallet: string) { - console.log(wallet) + await this.homePage.getWalletAddress(this.extensionId!, wallet) } - async addNewTokensFound() { - console.log('') + async changeAccount(accountIndex: number) { + await this.homePage.changeAccount(accountIndex) } - async disconnectWalletFromDapps() { - console.log('') + async closePopupAndTooltips() { + await this.homePage.closePopupAndTooltips(this.extensionId!) + } + + async disconnectFromApp() { + await this.homePage.disconnectFromApp(this.extensionId!) + } + + async selectWallet(wallet: string) { + await this.notificationPage.selectWallet(this.extensionId!, wallet) + } + + async lock() { + await this.notificationPage.lock(this.extensionId!) } async acceptAccess() { - console.log('') + await this.notificationPage.acceptAccess(this.extensionId!) + } + + async confirmIncorrectNetwork() { + await this.notificationPage.confirmIncorrectNetwork(this.extensionId!) + } + + async confirmSignature() { + await this.notificationPage.confirmSignatureRequest(this.extensionId!) + } + + async confirmTransaction() { + await this.notificationPage.confirmTransaction(this.extensionId!) + } + + async rejectSignature() { + await this.notificationPage.rejectSignatureRequest(this.extensionId!) } - async rejectAccess() { - console.log('') + async rejectTransaction() { + await this.notificationPage.rejectTransaction(this.extensionId!) } } diff --git a/wallets/phantom/src/fixtures/phantomFixtures.ts b/wallets/phantom/src/fixtures/phantomFixtures.ts index 3df589fb9..cbd9dc121 100644 --- a/wallets/phantom/src/fixtures/phantomFixtures.ts +++ b/wallets/phantom/src/fixtures/phantomFixtures.ts @@ -62,7 +62,7 @@ export const phantomFixtures = (walletSetup: ReturnType { + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + + await notificationPage.click(homePageElements.settingsMenu.settingsMenuButton) + await notificationPage.click(homePageElements.settingsMenu.settingsSidebarButton) + await notificationPage.click(homePageElements.settingsMenu.trustedAppsRow) + + const rowButtonLocator = await notificationPage.locator(homePageElements.connectedSites.rowButton) + const hasConnectedSite = await rowButtonLocator.isVisible(); + + let isDisconnected = false; + if (hasConnectedSite) { + await rowButtonLocator.click() + await notificationPage.click(homePageElements.connectedSites.trustedAppsRevokeButton) + isDisconnected = true + } + else { + console.log( + '[disconnectWalletFromDapp] Wallet is not connected to a dapp, skipping...', + ); + } + + return isDisconnected; +} \ No newline at end of file diff --git a/wallets/phantom/src/pages/HomePage/actions/index.ts b/wallets/phantom/src/pages/HomePage/actions/index.ts index e69de29bb..fbc6bf642 100644 --- a/wallets/phantom/src/pages/HomePage/actions/index.ts +++ b/wallets/phantom/src/pages/HomePage/actions/index.ts @@ -0,0 +1,4 @@ +export * from './changeAccount' +export * from './closePopupAndTooltips' +export * from './getWalletAddress' +export * from './disconnectFromApp' \ No newline at end of file diff --git a/wallets/phantom/src/pages/HomePage/page.ts b/wallets/phantom/src/pages/HomePage/page.ts index 8b2424843..f44be3ce8 100644 --- a/wallets/phantom/src/pages/HomePage/page.ts +++ b/wallets/phantom/src/pages/HomePage/page.ts @@ -1,5 +1,6 @@ import type { Page } from '@playwright/test' import { homePageElements } from './selectors' +import { changeAccount, getWalletAddress, closePopupAndTooltips, disconnectFromApp } from './actions' export class HomePage { static readonly selectors = homePageElements @@ -10,4 +11,20 @@ export class HomePage { constructor(page: Page) { this.page = page } + + async changeAccount(accountIndex?: number) { + return await changeAccount(this.page, accountIndex) + } + + async getWalletAddress(extensionId: string, chainId: string){ + return await getWalletAddress(this.page, extensionId, chainId) + } + + async closePopupAndTooltips(extensionId: string) { + await closePopupAndTooltips(this.page, extensionId) + } + + async disconnectFromApp(extensionId: string) { + await disconnectFromApp(this.page, extensionId) + } } diff --git a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts index 55cfc8fef..9274c33ea 100644 --- a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts @@ -1,8 +1,8 @@ import type { Page } from '@playwright/test' import { lockPageElements } from "../selectors"; -export const createAccount = async (page: Page, secretWords: string, password: string) => { - console.log(lockPageElements, page, secretWords, password) +export const createAccount = async (page: Page, password: string) => { + console.log(lockPageElements, page, password) // await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) // await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) diff --git a/wallets/phantom/src/pages/LockPage/actions/index.ts b/wallets/phantom/src/pages/LockPage/actions/index.ts index 5fa3aef98..1110a77a7 100644 --- a/wallets/phantom/src/pages/LockPage/actions/index.ts +++ b/wallets/phantom/src/pages/LockPage/actions/index.ts @@ -1,2 +1,3 @@ export * from './importAccount' -export * from './createAccount' \ No newline at end of file +export * from './createAccount' +export * from './unlock' \ No newline at end of file diff --git a/wallets/phantom/src/pages/LockPage/page.ts b/wallets/phantom/src/pages/LockPage/page.ts index a2e5cfc16..da7326aec 100644 --- a/wallets/phantom/src/pages/LockPage/page.ts +++ b/wallets/phantom/src/pages/LockPage/page.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test' import { lockPageElements } from './selectors' -import { importWallet, createAccount } from './actions' +import { importWallet, createAccount, unlock } from './actions' export class LockPage { static readonly selectors = lockPageElements @@ -16,7 +16,12 @@ export class LockPage { await importWallet(this.page, secretWords, password) } + //@todo: get this written async createWallet(password: string) { await createAccount(this.page, password) - } + } + + async unlock(extensionId: string, password: string) { + await unlock(this.page, extensionId, password, true) + } } diff --git a/wallets/phantom/src/pages/NotificationPage/page.ts b/wallets/phantom/src/pages/NotificationPage/page.ts index c34847eb3..7259d54d9 100644 --- a/wallets/phantom/src/pages/NotificationPage/page.ts +++ b/wallets/phantom/src/pages/NotificationPage/page.ts @@ -1,5 +1,6 @@ import type { Page } from '@playwright/test' import { notificationPageElements } from './selectors' +import { acceptAccess, confirmIncorrectNetwork, confirmSignatureRequest, confirmTransaction, rejectSignatureRequest, rejectTransaction, lock, selectWallet } from './actions' export class NotificationPage { static readonly selectors = notificationPageElements @@ -10,4 +11,36 @@ export class NotificationPage { constructor(page: Page) { this.page = page } + + async lock(extensionId: string) { + await lock(this.page, extensionId) + } + + async acceptAccess(extensionId: string) { + await acceptAccess(this.page, extensionId) + } + + async selectWallet(extensionId: string, wallet: string) { + await selectWallet(this.page, extensionId, wallet) + } + + async confirmIncorrectNetwork(extensionId: string) { + await confirmIncorrectNetwork(this.page, extensionId) + } + + async confirmSignatureRequest(extensionId: string) { + await confirmSignatureRequest(this.page, extensionId) + } + + async confirmTransaction(extensionId: string) { + await confirmTransaction(this.page, extensionId) + } + + async rejectTransaction(extensionId: string) { + await rejectTransaction(this.page, extensionId) + } + + async rejectSignatureRequest(extensionId: string) { + await rejectSignatureRequest(this.page, extensionId) + } } diff --git a/wallets/phantom/src/utils/constants.ts b/wallets/phantom/src/utils/constants.ts deleted file mode 100644 index c3fb26259..000000000 --- a/wallets/phantom/src/utils/constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -// const PROVIDER = 'phantom' - -// const extensionInitialUrl = await playwright.windows(PROVIDER).url(); -// const extensionId = extensionInitialUrl.match('//(.*?)/')[1]; -// const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html`; -// const extensionSettingsUrl = `${extensionHomeUrl}#settings`; -// const extensionAdvancedSettingsUrl = `${extensionSettingsUrl}/advanced`; -// const extensionExperimentalSettingsUrl = `${extensionSettingsUrl}/experimental`; -// const extensionAddNetworkUrl = `${extensionSettingsUrl}/networks/add-network`; -// const extensionNewAccountUrl = `${extensionHomeUrl}#new-account`; -// const extensionImportAccountUrl = `${extensionNewAccountUrl}/import`; -// const extensionImportTokenUrl = `${extensionHomeUrl}#import-token`; \ No newline at end of file diff --git a/wallets/phantom/src/utils/index.ts b/wallets/phantom/src/utils/index.ts index ee4cdabba..d6f677629 100644 --- a/wallets/phantom/src/utils/index.ts +++ b/wallets/phantom/src/utils/index.ts @@ -1,2 +1 @@ -export * from './selectors/loading' -export * from './constants' \ No newline at end of file +export * from './selectors/loading' \ No newline at end of file diff --git a/wallets/phantom/test/synpress.ts b/wallets/phantom/test/synpress.ts index 4fffc0e54..54693c56f 100644 --- a/wallets/phantom/test/synpress.ts +++ b/wallets/phantom/test/synpress.ts @@ -1,5 +1,5 @@ import { testWithSynpress } from '@synthetixio/synpress-core' import { phantomFixtures } from '../src' -import importPhantom from './wallet-setup/import-wallet.setup' +import importPhantom from './wallet-setup/import.setup' export default testWithSynpress(phantomFixtures(importPhantom)) diff --git a/wallets/phantom/test/wallet-setup/import2.setup.ts b/wallets/phantom/test/wallet-setup/create.setup.ts similarity index 63% rename from wallets/phantom/test/wallet-setup/import2.setup.ts rename to wallets/phantom/test/wallet-setup/create.setup.ts index adfae4e5c..28e887a8d 100644 --- a/wallets/phantom/test/wallet-setup/import2.setup.ts +++ b/wallets/phantom/test/wallet-setup/create.setup.ts @@ -5,15 +5,15 @@ import { getExtensionId } from '../../src/fixtureActions' const PASSWORD = 'Test1234' -const importPhantomWallet = defineWalletSetup(PASSWORD, async (context: BrowserContext, phantomPage: Page) => { +const createPhantomWallet = defineWalletSetup(PASSWORD, async (context: BrowserContext, phantomPage: Page) => { const extensionId = await getExtensionId(context, 'phantom') - const phantom2 = new PhantomWallet(phantomPage, context, PASSWORD, extensionId) + const phantom = new PhantomWallet(phantomPage, context, PASSWORD, extensionId) try { - await phantom2.importWallet({ secretWords: '', password: PASSWORD }) + await phantom.createWallet(PASSWORD) } catch (e) { console.log('Error creating Keplr wallet:', e) } }) -export default importPhantomWallet +export default createPhantomWallet From 23279371f00b11b63398aa0d7da7e7ee72685584 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Tue, 9 Jul 2024 10:48:07 -0400 Subject: [PATCH 14/16] lint --- packages/cache/src/prepareExtension.ts | 16 +- packages/cache/src/unzip.d.ts | 2 +- wallets/phantom/src/PhantomWallet.ts | 2 +- wallets/phantom/src/fixtureActions/index.ts | 2 +- wallets/phantom/src/index.ts | 2 +- .../pages/ConfirmationPage/selectors/index.ts | 12 +- .../pages/HomePage/actions/changeAccount.ts | 8 +- .../HomePage/actions/closePopupAndTooltips.ts | 20 +- .../HomePage/actions/disconnectFromApp.ts | 23 +- .../HomePage/actions/getWalletAddress.ts | 16 +- .../src/pages/HomePage/actions/index.ts | 2 +- wallets/phantom/src/pages/HomePage/page.ts | 4 +- .../src/pages/HomePage/selectors/index.ts | 106 +++++---- .../pages/LockPage/actions/createAccount.ts | 4 +- .../pages/LockPage/actions/importAccount.ts | 8 +- .../src/pages/LockPage/actions/index.ts | 2 +- .../src/pages/LockPage/actions/unlock.ts | 19 +- wallets/phantom/src/pages/LockPage/page.ts | 4 +- .../src/pages/LockPage/selectors/index.ts | 104 +++++---- .../NotificationPage/actions/acceptAccess.ts | 12 +- .../actions/confirmIncorrectNetwork.ts | 14 +- .../actions/confirmSignature.ts | 14 +- .../actions/confirmTransaction.ts | 14 +- .../pages/NotificationPage/actions/lock.ts | 12 +- .../actions/rejectSignature.ts | 14 +- .../actions/rejectTransaction.ts | 15 +- .../NotificationPage/actions/selectWallet.ts | 12 +- .../src/pages/NotificationPage/page.ts | 11 +- .../pages/NotificationPage/selectors/index.ts | 202 +++++++++--------- .../src/pages/SettingsPage/selectors/index.ts | 6 +- wallets/phantom/src/utils/getExtensionPage.ts | 8 +- wallets/phantom/src/utils/index.ts | 2 +- .../phantom/src/utils/selectors/loading.ts | 17 +- 33 files changed, 353 insertions(+), 356 deletions(-) diff --git a/packages/cache/src/prepareExtension.ts b/packages/cache/src/prepareExtension.ts index bd2dea080..c98c16016 100644 --- a/packages/cache/src/prepareExtension.ts +++ b/packages/cache/src/prepareExtension.ts @@ -1,5 +1,5 @@ import download from 'download' -import unzipCrx from 'unzip-crx-3'; +import unzipCrx from 'unzip-crx-3' import { downloadFile, ensureCacheDirExists, unzipArchive } from '.' interface ExtensionConfig { @@ -26,8 +26,7 @@ export async function getExtensionConfig(name: string): Promise { name: 'Phantom', version: 'phantom-chrome-latest', - downloadUrl: - 'https://crx-backup.phantom.dev/latest.crx' + downloadUrl: 'https://crx-backup.phantom.dev/latest.crx' } ] } @@ -47,13 +46,12 @@ export async function prepareExtension(extensionName: string) { const outputPath = `${cacheDirPath}/latest` downloadResult = await download(extensionConfig.downloadUrl, cacheDirPath, { headers: { - Accept: 'application/octet-stream', - }, - }); + Accept: 'application/octet-stream' + } + }) await unzipCrx('.cache-synpress/latest.crx', outputPath) return outputPath - } - else { + } else { downloadResult = await downloadFile({ url: extensionConfig.downloadUrl, outputDir: cacheDirPath, @@ -62,7 +60,7 @@ export async function prepareExtension(extensionName: string) { const unzipResult = await unzipArchive({ archivePath: downloadResult.filePath }) - + return unzipResult.outputPath } } diff --git a/packages/cache/src/unzip.d.ts b/packages/cache/src/unzip.d.ts index 74f5f100f..bee17e7ac 100644 --- a/packages/cache/src/unzip.d.ts +++ b/packages/cache/src/unzip.d.ts @@ -1 +1 @@ -declare module 'unzip-crx-3'; \ No newline at end of file +declare module 'unzip-crx-3' diff --git a/wallets/phantom/src/PhantomWallet.ts b/wallets/phantom/src/PhantomWallet.ts index 5eb5a190a..5d2b0145a 100644 --- a/wallets/phantom/src/PhantomWallet.ts +++ b/wallets/phantom/src/PhantomWallet.ts @@ -1,9 +1,9 @@ import { type BrowserContext, type Page } from '@playwright/test' +import { ConfirmationPage } from './pages/ConfirmationPage/page' import { HomePage } from './pages/HomePage/page' import { LockPage } from './pages/LockPage/page' import { NotificationPage } from './pages/NotificationPage/page' import { SettingsPage } from './pages/SettingsPage/page' -import { ConfirmationPage } from './pages/ConfirmationPage/page' export class PhantomWallet { readonly lockPage: LockPage diff --git a/wallets/phantom/src/fixtureActions/index.ts b/wallets/phantom/src/fixtureActions/index.ts index 77a094411..525f21338 100644 --- a/wallets/phantom/src/fixtureActions/index.ts +++ b/wallets/phantom/src/fixtureActions/index.ts @@ -1 +1 @@ -export * from './getExtensionId' \ No newline at end of file +export * from './getExtensionId' diff --git a/wallets/phantom/src/index.ts b/wallets/phantom/src/index.ts index 237c76da9..c67eebaf4 100644 --- a/wallets/phantom/src/index.ts +++ b/wallets/phantom/src/index.ts @@ -1,3 +1,3 @@ export * from './PhantomWallet' export * from './utils' -export * from './fixtures/phantomFixtures' \ No newline at end of file +export * from './fixtures/phantomFixtures' diff --git a/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts b/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts index 224ff168e..106a1ef74 100644 --- a/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts +++ b/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts @@ -1,12 +1,12 @@ -const confirmationPage = '.confirmation-page'; -const confirmationPageFooter = `${confirmationPage} .confirmation-footer`; +const confirmationPage = '.confirmation-page' +const confirmationPageFooter = `${confirmationPage} .confirmation-footer` const footer = { footer: confirmationPageFooter, cancelButton: `${confirmationPageFooter} .btn-secondary`, - approveButton: `${confirmationPageFooter} .btn-primary`, -}; + approveButton: `${confirmationPageFooter} .btn-primary` +} export const confirmationPageElements = { confirmationPage, - footer, -}; \ No newline at end of file + footer +} diff --git a/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts b/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts index 30172fd33..d5a7d1305 100644 --- a/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts +++ b/wallets/phantom/src/pages/HomePage/actions/changeAccount.ts @@ -1,8 +1,8 @@ -import type { Page } from "@playwright/test"; -import { homePageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { homePageElements } from '../selectors' export const changeAccount = async (page: Page, accountIndex = 1) => { await page.waitForLoadState('domcontentloaded') - await page.click(homePageElements.settingsMenu.settingsMenuButton); + await page.click(homePageElements.settingsMenu.settingsMenuButton) await page.click(homePageElements.accountMenu.accountButton(accountIndex)) -} \ No newline at end of file +} diff --git a/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts b/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts index cb495cdfd..06b83ce28 100644 --- a/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts +++ b/wallets/phantom/src/pages/HomePage/actions/closePopupAndTooltips.ts @@ -1,24 +1,26 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { homePageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { homePageElements } from '../selectors' export const closePopupAndTooltips = async (page: Page, extensionId: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) // note: this is required for fast execution of e2e tests to avoid flakiness // otherwise popup may not be detected properly and not closed const popupIsVisible = await notificationPage.locator(homePageElements.popup.container).isVisible() const closeIsVisible = await notificationPage.locator(homePageElements.tippyTooltip.closeButton).isVisible() - const actionableMessageIsVisible = await notificationPage.locator(homePageElements.actionableMessage.closeButton).isVisible() + const actionableMessageIsVisible = await notificationPage + .locator(homePageElements.actionableMessage.closeButton) + .isVisible() if (popupIsVisible) { const popupBackground = await notificationPage.locator(homePageElements.popup.background) - const popupBackgroundBox = await popupBackground.boundingBox(); + const popupBackgroundBox = await popupBackground.boundingBox() await notificationPage.mouse.click(popupBackgroundBox?.x! + 1, popupBackgroundBox?.y! + 1) } if (closeIsVisible) { - await page.click(homePageElements.tippyTooltip.closeButton); + await page.click(homePageElements.tippyTooltip.closeButton) } if (actionableMessageIsVisible) { await page.click(homePageElements.actionableMessage.closeButton) } - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/HomePage/actions/disconnectFromApp.ts b/wallets/phantom/src/pages/HomePage/actions/disconnectFromApp.ts index c8fae57f0..237ac4b02 100644 --- a/wallets/phantom/src/pages/HomePage/actions/disconnectFromApp.ts +++ b/wallets/phantom/src/pages/HomePage/actions/disconnectFromApp.ts @@ -1,6 +1,6 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { homePageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { homePageElements } from '../selectors' export const disconnectFromApp = async (page: Page, extensionId: string) => { const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) @@ -10,19 +10,16 @@ export const disconnectFromApp = async (page: Page, extensionId: string) => { await notificationPage.click(homePageElements.settingsMenu.trustedAppsRow) const rowButtonLocator = await notificationPage.locator(homePageElements.connectedSites.rowButton) - const hasConnectedSite = await rowButtonLocator.isVisible(); + const hasConnectedSite = await rowButtonLocator.isVisible() - let isDisconnected = false; + let isDisconnected = false if (hasConnectedSite) { await rowButtonLocator.click() await notificationPage.click(homePageElements.connectedSites.trustedAppsRevokeButton) isDisconnected = true + } else { + console.log('[disconnectWalletFromDapp] Wallet is not connected to a dapp, skipping...') } - else { - console.log( - '[disconnectWalletFromDapp] Wallet is not connected to a dapp, skipping...', - ); - } - - return isDisconnected; -} \ No newline at end of file + + return isDisconnected +} diff --git a/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts b/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts index dd2bfd072..e7c33c097 100644 --- a/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts +++ b/wallets/phantom/src/pages/HomePage/actions/getWalletAddress.ts @@ -1,20 +1,20 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { homePageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { homePageElements } from '../selectors' export const getWalletAddress = async (page: Page, extensionId: string, chain = 'eth') => { const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) await notificationPage.hover(homePageElements.accountBar.title) - await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise((resolve) => setTimeout(resolve, 100)) await notificationPage.waitForLoadState('domcontentloaded') if (chain === 'eth') { - await notificationPage.click(homePageElements.accountBar.ethRow); + await notificationPage.click(homePageElements.accountBar.ethRow) } else if (chain === 'solana') { - await notificationPage.click(homePageElements.accountBar.solanaRow); + await notificationPage.click(homePageElements.accountBar.solanaRow) } const walletAddress = await notificationPage.evaluate('navigator.clipboard.readText()') - return walletAddress; -} \ No newline at end of file + return walletAddress +} diff --git a/wallets/phantom/src/pages/HomePage/actions/index.ts b/wallets/phantom/src/pages/HomePage/actions/index.ts index fbc6bf642..579f5447a 100644 --- a/wallets/phantom/src/pages/HomePage/actions/index.ts +++ b/wallets/phantom/src/pages/HomePage/actions/index.ts @@ -1,4 +1,4 @@ export * from './changeAccount' export * from './closePopupAndTooltips' export * from './getWalletAddress' -export * from './disconnectFromApp' \ No newline at end of file +export * from './disconnectFromApp' diff --git a/wallets/phantom/src/pages/HomePage/page.ts b/wallets/phantom/src/pages/HomePage/page.ts index f44be3ce8..1219a49ea 100644 --- a/wallets/phantom/src/pages/HomePage/page.ts +++ b/wallets/phantom/src/pages/HomePage/page.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test' +import { changeAccount, closePopupAndTooltips, disconnectFromApp, getWalletAddress } from './actions' import { homePageElements } from './selectors' -import { changeAccount, getWalletAddress, closePopupAndTooltips, disconnectFromApp } from './actions' export class HomePage { static readonly selectors = homePageElements @@ -16,7 +16,7 @@ export class HomePage { return await changeAccount(this.page, accountIndex) } - async getWalletAddress(extensionId: string, chainId: string){ + async getWalletAddress(extensionId: string, chainId: string) { return await getWalletAddress(this.page, extensionId, chainId) } diff --git a/wallets/phantom/src/pages/HomePage/selectors/index.ts b/wallets/phantom/src/pages/HomePage/selectors/index.ts index 0bddd2f03..08ef3f541 100644 --- a/wallets/phantom/src/pages/HomePage/selectors/index.ts +++ b/wallets/phantom/src/pages/HomePage/selectors/index.ts @@ -1,4 +1,4 @@ -const networkSwitcherButtonSelector = '.network-display'; +const networkSwitcherButtonSelector = '.network-display' const networkSwitcher = { button: networkSwitcherButtonSelector, @@ -9,33 +9,29 @@ const networkSwitcher = { goerliNetworkItem: `[data-testid="network-droppo"] [data-testid="goerli-network-item"]`, sepoliaNetworkItem: `[data-testid="network-droppo"] [data-testid="sepolia-network-item"]`, localhostNetworkItem: `[data-testid="network-droppo"] [data-testid="Localhost 8545-network-item"]`, - networkButton: (number: number) => - `[data-testid="network-droppo"] .dropdown-menu-item:nth-child(${ - 3 + number - })`, -}; + networkButton: (number: number) => `[data-testid="network-droppo"] .dropdown-menu-item:nth-child(${3 + number})` +} - -const walletOverview = '.wallet-overview'; +const walletOverview = '.wallet-overview' const tabs = { assetsButton: '[data-testid="home__asset-tab"] button', - activityButton: '[data-testid="home__activity-tab"] button', -}; + activityButton: '[data-testid="home__activity-tab"] button' +} -const transactionList = '.transaction-list__transactions'; -const pendingTransactionsList = `${transactionList} .transaction-list__pending-transactions`; -const completedTransactionsList = `${transactionList} .transaction-list__completed-transactions`; +const transactionList = '.transaction-list__transactions' +const pendingTransactionsList = `${transactionList} .transaction-list__pending-transactions` +const completedTransactionsList = `${transactionList} .transaction-list__completed-transactions` const activityTab = { transactionList, pendingTransactionsList, completedTransactionsList, unconfirmedTransaction: `${pendingTransactionsList} .transaction-list-item--unconfirmed`, - confirmedTransaction: `${completedTransactionsList} .transaction-list-item`, -}; + confirmedTransaction: `${completedTransactionsList} .transaction-list-item` +} -const popupSelector = '.popover-container'; -const sendPopupSelector = `${popupSelector} .transaction-list-item-details`; +const popupSelector = '.popover-container' +const sendPopupSelector = `${popupSelector} .transaction-list-item-details` const popup = { container: popupSelector, closeButton: '.popover-header__button', @@ -45,25 +41,26 @@ const popup = { speedUpButton: `${sendPopupSelector} .btn-primary`, cancelButton: `${sendPopupSelector} .btn-secondary`, transactionStatus: `${sendPopupSelector} .transaction-status`, - copyTxIdButton: `${sendPopupSelector} .transaction-list-item-details__tx-hash .transaction-list-item-details__header-button a`, - }, -}; + copyTxIdButton: `${sendPopupSelector} .transaction-list-item-details__tx-hash .transaction-list-item-details__header-button a` + } +} -const tippyTooltipSelector = '.tippy-popper'; +const tippyTooltipSelector = '.tippy-popper' const tippyTooltip = { container: tippyTooltipSelector, - closeButton: `${tippyTooltipSelector} button`, -}; + closeButton: `${tippyTooltipSelector} button` +} -const actionableMessageSelector = '.actionable-message'; +const actionableMessageSelector = '.actionable-message' const actionableMessage = { container: actionableMessageSelector, - closeButton: `${actionableMessageSelector} button`, -}; + closeButton: `${actionableMessageSelector} button` +} const accountMenu = { - accountButton: (number: number) => `[data-testid="account-menu"] [data-testid="tooltip_interactive-wrapper"]:nth-child(${number})`, -}; + accountButton: (number: number) => + `[data-testid="account-menu"] [data-testid="tooltip_interactive-wrapper"]:nth-child(${number})` +} const settingsMenu = { settingsMenuButton: '[data-testid="settings-menu-open-button"]', @@ -72,58 +69,58 @@ const settingsMenu = { settingsPreferencesButton: '[data-testid="settings-item-preferences"]', trustedAppsRow: '[data-testid="settings-item-trusted-apps"]', developerSettingsRow: '[data-testid="settings-item-developer-settings"]', - defaultAppWalletRow: '[data-testid="settings-item-metamask-override"]', -}; + defaultAppWalletRow: '[data-testid="settings-item-metamask-override"]' +} const whatsNew = { header: '[data-testid="whats_new-header"]', - continueButton: '[data-testid="whats_new-continue_button"]', -}; + continueButton: '[data-testid="whats_new-continue_button"]' +} const welcome = { takeTheTourButton: '[data-testid="welcome-take_the_tour"]', takeTheTourButtonNext: '[data-testid="primary-button"]', - finishSetup: ['data-testid="onboarding-form-submit-button"'], -}; + finishSetup: ['data-testid="onboarding-form-submit-button"'] +} const accountBar = { title: '[data-testid="tooltip_interactive-wrapper"]', ethRow: '[data-testid="account-header-chain-eip155:1"]', - solanaRow: '[data-testid="account-header-chain-solana:101"]', -}; + solanaRow: '[data-testid="account-header-chain-solana:101"]' +} const defaultWallet = { metamask: '[data-testid="metamask-override--USE_METAMASK"]', phantom: '[data-testid="metamask-override--USE_PHANTOM"]', - always_ask: '[data-testid="metamask-override--ALWAYS_ASK"]', -}; + always_ask: '[data-testid="metamask-override--ALWAYS_ASK"]' +} const connectedSites = { trustedAppsRevokeButton: '[data-testid="trusted-apps-revoke-button"]', trustedAppsBackButton: '[data-testid="header--back"]', - rowButton: '[data-testid="trusted_apps_row-button"]', -}; + rowButton: '[data-testid="trusted_apps_row-button"]' +} const accountModal = { walletAddressInput: '.account-modal .qr-code__address', - closeButton: '.account-modal__close', -}; + closeButton: '.account-modal__close' +} -const importAccountSelector = '.new-account'; +const importAccountSelector = '.new-account' const importAccount = { page: importAccountSelector, input: `${importAccountSelector} #private-key-box`, cancelButton: `${importAccountSelector} .new-account-create-form__button:nth-child(1)`, - importButton: `${importAccountSelector} .new-account-create-form__button:nth-child(2)`, -}; + importButton: `${importAccountSelector} .new-account-create-form__button:nth-child(2)` +} const createAccount = { page: importAccountSelector, input: `${importAccountSelector} .new-account-create-form__input`, cancelButton: `${importAccountSelector} .new-account-create-form__button:nth-child(1)`, - createButton: `${importAccountSelector} .new-account-create-form__button:nth-child(2)`, -}; + createButton: `${importAccountSelector} .new-account-create-form__button:nth-child(2)` +} -const importTokenFormSelector = '.import-token__custom-token-form'; +const importTokenFormSelector = '.import-token__custom-token-form' const importToken = { form: importTokenFormSelector, tokenContractAddressInput: `${importTokenFormSelector} #custom-address`, @@ -132,15 +129,14 @@ const importToken = { tokenDecimalInput: `${importTokenFormSelector} #custom-decimals`, addCustomTokenButton: `[data-testid="page-container-footer-next"]`, confirmImportTokenContent: '.confirm-import-token', - importTokensButton: `.btn-primary`, -}; + importTokensButton: `.btn-primary` +} -const assetNavigationSelector = '.asset-navigation'; +const assetNavigationSelector = '.asset-navigation' const asset = { navigation: assetNavigationSelector, - backButton: `${assetNavigationSelector} [data-testid="asset__back"]`, -}; - + backButton: `${assetNavigationSelector} [data-testid="asset__back"]` +} export const homePageElements = { networkSwitcher, @@ -162,4 +158,4 @@ export const homePageElements = { settingsMenu, actionableMessage, tippyTooltip -} \ No newline at end of file +} diff --git a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts index 9274c33ea..fbf801cd2 100644 --- a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts @@ -1,5 +1,5 @@ import type { Page } from '@playwright/test' -import { lockPageElements } from "../selectors"; +import { lockPageElements } from '../selectors' export const createAccount = async (page: Page, password: string) => { console.log(lockPageElements, page, password) @@ -30,4 +30,4 @@ export const createAccount = async (page: Page, password: string) => { // await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); // return true; -} \ No newline at end of file +} diff --git a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts index ac82a3293..b40b6c453 100644 --- a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts @@ -1,5 +1,5 @@ import type { Page } from '@playwright/test' -import { lockPageElements } from "../selectors"; +import { lockPageElements } from '../selectors' export const importWallet = async (page: Page, secretWords: string, password: string) => { await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) @@ -26,7 +26,7 @@ export const importWallet = async (page: Page, secretWords: string, password: st await page.click(lockPageElements.firstTimeFlowImportPageElements.continueAfterPasswordButton) - await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); + await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton) - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/LockPage/actions/index.ts b/wallets/phantom/src/pages/LockPage/actions/index.ts index 1110a77a7..aa79e727b 100644 --- a/wallets/phantom/src/pages/LockPage/actions/index.ts +++ b/wallets/phantom/src/pages/LockPage/actions/index.ts @@ -1,3 +1,3 @@ export * from './importAccount' export * from './createAccount' -export * from './unlock' \ No newline at end of file +export * from './unlock' diff --git a/wallets/phantom/src/pages/LockPage/actions/unlock.ts b/wallets/phantom/src/pages/LockPage/actions/unlock.ts index 73a5322bf..1dd8913a2 100644 --- a/wallets/phantom/src/pages/LockPage/actions/unlock.ts +++ b/wallets/phantom/src/pages/LockPage/actions/unlock.ts @@ -1,19 +1,18 @@ import type { Page } from '@playwright/test' -import { lockPageElements } from "../selectors"; -import { closePopupAndTooltips } from '../../HomePage/actions/closePopupAndTooltips'; +import { closePopupAndTooltips } from '../../HomePage/actions/closePopupAndTooltips' +import { lockPageElements } from '../selectors' export const unlock = async (page: Page, extensionId: string, password: string, close = false) => { - await page.waitForLoadState('domcontentloaded') - + const inputField = await page.locator(lockPageElements.unlockPageElements.passwordInput) await inputField.fill(password) - await page.click(lockPageElements.unlockPageElements.unlockButton); + await page.click(lockPageElements.unlockPageElements.unlockButton) - if(close) { - await closePopupAndTooltips(page, extensionId); + if (close) { + await closePopupAndTooltips(page, extensionId) } - - return true; -} \ No newline at end of file + + return true +} diff --git a/wallets/phantom/src/pages/LockPage/page.ts b/wallets/phantom/src/pages/LockPage/page.ts index da7326aec..e7548166a 100644 --- a/wallets/phantom/src/pages/LockPage/page.ts +++ b/wallets/phantom/src/pages/LockPage/page.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test' +import { createAccount, importWallet, unlock } from './actions' import { lockPageElements } from './selectors' -import { importWallet, createAccount, unlock } from './actions' export class LockPage { static readonly selectors = lockPageElements @@ -19,7 +19,7 @@ export class LockPage { //@todo: get this written async createWallet(password: string) { await createAccount(this.page, password) - } + } async unlock(extensionId: string, password: string) { await unlock(this.page, extensionId, password, true) diff --git a/wallets/phantom/src/pages/LockPage/selectors/index.ts b/wallets/phantom/src/pages/LockPage/selectors/index.ts index 2e6da5a88..065f803d0 100644 --- a/wallets/phantom/src/pages/LockPage/selectors/index.ts +++ b/wallets/phantom/src/pages/LockPage/selectors/index.ts @@ -1,44 +1,42 @@ -const app = '#root'; -const welcomePage = '#root'; -const confirmButton = `${welcomePage} .first-time-flow__button`; +const app = '#root' +const welcomePage = '#root' +const confirmButton = `${welcomePage} .first-time-flow__button` const welcomePageElements = { app, welcomePage, - confirmButton, -}; + confirmButton +} -const metametricsPage = '.metametrics-opt-in'; -const optOutAnalyticsButton = `${metametricsPage} [data-testid="page-container-footer-cancel"]`; +const metametricsPage = '.metametrics-opt-in' +const optOutAnalyticsButton = `${metametricsPage} [data-testid="page-container-footer-cancel"]` const metametricsPageElements = { metametricsPage, - optOutAnalyticsButton, -}; + optOutAnalyticsButton +} -const firstTimeFlowPage = '.first-time-flow'; -const importWalletButton = `[data-testid="import-wallet-button"]`; -const importRecoveryPhraseButton = `[data-testid="import-seed-phrase-button"]`; -const createWalletButton = `${firstTimeFlowPage} [data-testid="create-wallet-button"]`; +const firstTimeFlowPage = '.first-time-flow' +const importWalletButton = `[data-testid="import-wallet-button"]` +const importRecoveryPhraseButton = `[data-testid="import-seed-phrase-button"]` +const createWalletButton = `${firstTimeFlowPage} [data-testid="create-wallet-button"]` const firstTimeFlowPageElements = { firstTimeFlowPage, importWalletButton, importRecoveryPhraseButton, - createWalletButton, -}; - -const firstTimeFlowImportPage = '.first-time-flow__import'; -const newVaultForm = `${firstTimeFlowImportPage} .create-new-vault__form`; -const secretWordsInput = (number: number) => - `[data-testid="secret-recovery-phrase-word-input-${number}"]`; -const confirmWordsButton = `[data-testid="onboarding-form-submit-button"]`; -const passwordInput = `[data-testid="onboarding-form-password-input"]`; -const confirmPasswordInput = `[data-testid="onboarding-form-confirm-password-input"]`; -const termsCheckbox = `[data-testid="onboarding-form-terms-of-service-checkbox"]`; -const continueAfterPasswordButton = - '[data-testid="onboarding-form-submit-button"]'; -const getStartedButton = '[data-testid="onboarding-form-submit-button"]'; -const importButton = `${newVaultForm} .create-new-vault__submit-button`; + createWalletButton +} + +const firstTimeFlowImportPage = '.first-time-flow__import' +const newVaultForm = `${firstTimeFlowImportPage} .create-new-vault__form` +const secretWordsInput = (number: number) => `[data-testid="secret-recovery-phrase-word-input-${number}"]` +const confirmWordsButton = `[data-testid="onboarding-form-submit-button"]` +const passwordInput = `[data-testid="onboarding-form-password-input"]` +const confirmPasswordInput = `[data-testid="onboarding-form-confirm-password-input"]` +const termsCheckbox = `[data-testid="onboarding-form-terms-of-service-checkbox"]` +const continueAfterPasswordButton = '[data-testid="onboarding-form-submit-button"]' +const getStartedButton = '[data-testid="onboarding-form-submit-button"]' +const importButton = `${newVaultForm} .create-new-vault__submit-button` const firstTimeFlowImportPageElements = { firstTimeFlowImportPage, @@ -50,51 +48,51 @@ const firstTimeFlowImportPageElements = { importButton, confirmWordsButton, continueAfterPasswordButton, - getStartedButton, -}; + getStartedButton +} -const firstTimeFlowCreatePage = '.first-time-flow'; -const newPasswordInput = `${firstTimeFlowCreatePage} [data-testid="create-password"]`; -const confirmNewPasswordInput = `${firstTimeFlowCreatePage} [data-testid="confirm-password"]`; -const newSignupCheckbox = `${firstTimeFlowCreatePage} .first-time-flow__checkbox`; -const createButton = `${firstTimeFlowCreatePage} .first-time-flow__button`; +const firstTimeFlowCreatePage = '.first-time-flow' +const newPasswordInput = `${firstTimeFlowCreatePage} [data-testid="create-password"]` +const confirmNewPasswordInput = `${firstTimeFlowCreatePage} [data-testid="confirm-password"]` +const newSignupCheckbox = `${firstTimeFlowCreatePage} .first-time-flow__checkbox` +const createButton = `${firstTimeFlowCreatePage} .first-time-flow__button` const firstTimeFlowCreatePagePageElements = { firstTimeFlowCreatePage, newPasswordInput, confirmNewPasswordInput, newSignupCheckbox, - createButton, -}; + createButton +} -const secureYourWalletPage = '[data-testid="seed-phrase-intro"]'; -const nextButton = `${secureYourWalletPage} button`; +const secureYourWalletPage = '[data-testid="seed-phrase-intro"]' +const nextButton = `${secureYourWalletPage} button` const secureYourWalletPageElements = { secureYourWalletPage, - nextButton, -}; + nextButton +} -const revealSeedPage = '[data-testid="reveal-seed-phrase"]'; -const remindLaterButton = `${revealSeedPage} .first-time-flow__button`; +const revealSeedPage = '[data-testid="reveal-seed-phrase"]' +const remindLaterButton = `${revealSeedPage} .first-time-flow__button` const revealSeedPageElements = { revealSeedPage, - remindLaterButton, -}; + remindLaterButton +} -const endOfFlowPage = '[data-testid="end-of-flow"]'; -const allDoneButton = `${endOfFlowPage} [data-testid="EOF-complete-button"]`; +const endOfFlowPage = '[data-testid="end-of-flow"]' +const allDoneButton = `${endOfFlowPage} [data-testid="EOF-complete-button"]` const endOfFlowPageElements = { endOfFlowPage, - allDoneButton, -}; + allDoneButton +} const unlockPageElements = { passwordInput: '[data-testid="unlock-form-password-input"]', - unlockButton: '[data-testid="unlock-form-submit-button"]', -}; + unlockButton: '[data-testid="unlock-form-submit-button"]' +} export const lockPageElements = { endOfFlowPageElements, @@ -105,5 +103,5 @@ export const lockPageElements = { firstTimeFlowPageElements, metametricsPageElements, welcomePageElements, - unlockPageElements, -} \ No newline at end of file + unlockPageElements +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts b/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts index 552c72b31..2326d7bc0 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/acceptAccess.ts @@ -1,9 +1,9 @@ -import { notificationPageElements } from "../selectors"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import type { Page } from "@playwright/test"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const acceptAccess = async (page: Page, extensionId: string) => { const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) - await notificationPage.click(notificationPageElements.buttons.primaryButton); - return true; -} \ No newline at end of file + await notificationPage.click(notificationPageElements.buttons.primaryButton) + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts b/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts index 7d70de68a..dd1d5d079 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/confirmIncorrectNetwork.ts @@ -1,10 +1,10 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { notificationPageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const confirmIncorrectNetwork = async (page: Page, extensionId: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); - await notificationPage.click(notificationPageElements.incorrectModePageElements.buttons.close); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.click(notificationPageElements.incorrectModePageElements.buttons.close) - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts b/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts index 6c746ec3a..95a6dc645 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/confirmSignature.ts @@ -1,10 +1,10 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { notificationPageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const confirmSignatureRequest = async (page: Page, extensionId: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); - await notificationPage.click(notificationPageElements.signaturePageElements.buttons.confirmSign); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.click(notificationPageElements.signaturePageElements.buttons.confirmSign) - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts b/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts index 3c507229c..033ff1d74 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/confirmTransaction.ts @@ -1,10 +1,10 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { notificationPageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const confirmTransaction = async (page: Page, extensionId: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); - await notificationPage.click(notificationPageElements.transactionPageElements.buttons.confirmTransaction); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.click(notificationPageElements.transactionPageElements.buttons.confirmTransaction) - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts index f3506fded..bac64ce15 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts @@ -1,14 +1,14 @@ import type { Page } from '@playwright/test' -import { notificationPageElements } from '../selectors' -import { settingsPageElements } from '../../SettingsPage/selectors' import { closePopupAndTooltips } from '../../HomePage/actions/closePopupAndTooltips' +import { settingsPageElements } from '../../SettingsPage/selectors' +import { notificationPageElements } from '../selectors' export const lock = async (page: Page, extensionId: string) => { await page.waitForLoadState('domcontentloaded') - await page.click(notificationPageElements.menu.buttons.settings); + await page.click(notificationPageElements.menu.buttons.settings) await page.click(notificationPageElements.menu.buttons.sidebar.settings) await page.click(settingsPageElements.buttons.lockWallet) - await closePopupAndTooltips(page, extensionId); - return true; -} \ No newline at end of file + await closePopupAndTooltips(page, extensionId) + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts b/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts index dc1982aa9..505e495e6 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/rejectSignature.ts @@ -1,10 +1,10 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { notificationPageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const rejectSignatureRequest = async (page: Page, extensionId: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); - await notificationPage.click(notificationPageElements.signaturePageElements.buttons.rejectSign); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.click(notificationPageElements.signaturePageElements.buttons.rejectSign) - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts b/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts index 016ff2988..78f7ca9d6 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/rejectTransaction.ts @@ -1,11 +1,10 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { notificationPageElements } from "../selectors"; - +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const rejectTransaction = async (page: Page, extensionId: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); - await notificationPage.click(notificationPageElements.transactionPageElements.buttons.rejectTransaction); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + await notificationPage.click(notificationPageElements.transactionPageElements.buttons.rejectTransaction) - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts b/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts index b5cf623ed..b57e22e5b 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/selectWallet.ts @@ -1,9 +1,9 @@ -import type { Page } from "@playwright/test"; -import { getNotificationPageAndWaitForLoad } from "../../../utils/getNotificationAndWaitForLoads"; -import { notificationPageElements } from "../selectors"; +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { notificationPageElements } from '../selectors' export const selectWallet = async (page: Page, extensionId: string, wallet: string) => { - const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId); + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) if (wallet === 'metamask') { await notificationPage.click(notificationPageElements.selectWalletElements.buttons.continueWithMetamask) } @@ -11,5 +11,5 @@ export const selectWallet = async (page: Page, extensionId: string, wallet: stri await notificationPage.click(notificationPageElements.selectWalletElements.buttons.continueWithPhantom) } - return true; -} \ No newline at end of file + return true +} diff --git a/wallets/phantom/src/pages/NotificationPage/page.ts b/wallets/phantom/src/pages/NotificationPage/page.ts index 7259d54d9..f80d42687 100644 --- a/wallets/phantom/src/pages/NotificationPage/page.ts +++ b/wallets/phantom/src/pages/NotificationPage/page.ts @@ -1,6 +1,15 @@ import type { Page } from '@playwright/test' +import { + acceptAccess, + confirmIncorrectNetwork, + confirmSignatureRequest, + confirmTransaction, + lock, + rejectSignatureRequest, + rejectTransaction, + selectWallet +} from './actions' import { notificationPageElements } from './selectors' -import { acceptAccess, confirmIncorrectNetwork, confirmSignatureRequest, confirmTransaction, rejectSignatureRequest, rejectTransaction, lock, selectWallet } from './actions' export class NotificationPage { static readonly selectors = notificationPageElements diff --git a/wallets/phantom/src/pages/NotificationPage/selectors/index.ts b/wallets/phantom/src/pages/NotificationPage/selectors/index.ts index da3521978..efdf02b16 100644 --- a/wallets/phantom/src/pages/NotificationPage/selectors/index.ts +++ b/wallets/phantom/src/pages/NotificationPage/selectors/index.ts @@ -1,11 +1,11 @@ -const notificationPage = '.notification'; -const notificationAppContent = `${notificationPage} #app-content .app`; -const loadingLogo = `${notificationPage} #loading__logo`; -const loadingSpinner = `${notificationPage} #loading__spinner`; -const nextButton = `${notificationPage} .permissions-connect-choose-account__bottom-buttons .btn-primary`; -const allowToSpendButton = `${notificationPage} [data-testid="page-container-footer-next"]`; -const rejectToSpendButton = `${notificationPage} [data-testid="page-container-footer-cancel"]`; -const selectAllCheckbox = `${notificationPage} .choose-account-list__header-check-box`; +const notificationPage = '.notification' +const notificationAppContent = `${notificationPage} #app-content .app` +const loadingLogo = `${notificationPage} #loading__logo` +const loadingSpinner = `${notificationPage} #loading__spinner` +const nextButton = `${notificationPage} .permissions-connect-choose-account__bottom-buttons .btn-primary` +const allowToSpendButton = `${notificationPage} [data-testid="page-container-footer-next"]` +const rejectToSpendButton = `${notificationPage} [data-testid="page-container-footer-cancel"]` +const selectAllCheckbox = `${notificationPage} .choose-account-list__header-check-box` const notificationElements = { notificationPage, @@ -15,76 +15,76 @@ const notificationElements = { nextButton, allowToSpendButton, rejectToSpendButton, - selectAllCheckbox, -}; + selectAllCheckbox +} -const confirmSignatureRequestButton = `${notificationPage} .request-signature__footer__sign-button`; -const rejectSignatureRequestButton = `${notificationPage} .request-signature__footer__cancel-button`; -const signatureRequestScrollDownButton = `${notificationPage} [data-testid="signature-request-scroll-button"]`; +const confirmSignatureRequestButton = `${notificationPage} .request-signature__footer__sign-button` +const rejectSignatureRequestButton = `${notificationPage} .request-signature__footer__cancel-button` +const signatureRequestScrollDownButton = `${notificationPage} [data-testid="signature-request-scroll-button"]` -const confirmDataSignatureRequestButton = `${notificationPage} [data-testid="signature-sign-button"]`; -const rejectDataSignatureRequestButton = `${notificationPage} [data-testid="signature-cancel-button"]`; +const confirmDataSignatureRequestButton = `${notificationPage} [data-testid="signature-sign-button"]` +const rejectDataSignatureRequestButton = `${notificationPage} [data-testid="signature-cancel-button"]` const dataSignaturePageElements = { confirmDataSignatureRequestButton, rejectDataSignatureRequestButton, - signatureRequestScrollDownButton, -}; + signatureRequestScrollDownButton +} -const permissionsPage = '.permissions-connect'; -const connectButton = `${permissionsPage} .permission-approval-container__footers .btn-primary`; +const permissionsPage = '.permissions-connect' +const connectButton = `${permissionsPage} .permission-approval-container__footers .btn-primary` const permissionsPageElements = { permissionsPage, - connectButton, -}; + connectButton +} -const popupContainer = '.popover-container'; -const popupCloseButton = `${popupContainer} .popover-header__button`; -const popupCopyRecipientPublicAddressButton = `${popupContainer} .nickname-popover__public-address button`; -const recipientPublicAddress = `${popupContainer} .nickname-popover__public-address__constant`; +const popupContainer = '.popover-container' +const popupCloseButton = `${popupContainer} .popover-header__button` +const popupCopyRecipientPublicAddressButton = `${popupContainer} .nickname-popover__public-address button` +const recipientPublicAddress = `${popupContainer} .nickname-popover__public-address__constant` const recipientPopupElements = { popupContainer, popupCloseButton, popupCopyRecipientPublicAddressButton, - recipientPublicAddress, -}; - -const confirmPageHeader = `${notificationPage} .confirm-page-container-header`; -const confirmPageContent = `${notificationPage} .confirm-page-container-content`; -const networkLabel = `${confirmPageHeader} .network-display`; -const senderButton = `${confirmPageHeader} .sender-to-recipient__party--sender`; -const recipientButton = `${confirmPageHeader} .sender-to-recipient__party--recipient-with-address`; -const editGasFeeLegacyButton = `${notificationPage} .transaction-detail-edit button`; -const editGasFeeLegacyOverrideAckButton = `${notificationPage} .edit-gas-display .edit-gas-display__dapp-acknowledgement-button`; -const editGasLegacyPopup = `${notificationPage} .edit-gas-popover__wrapper`; -const advancedLegacyGasControls = `${editGasLegacyPopup} .edit-gas-display .advanced-gas-controls`; -const gasLimitLegacyInput = `${advancedLegacyGasControls} .form-field:nth-child(1) input`; -const gasPriceLegacyInput = `${advancedLegacyGasControls} .form-field:nth-child(2) input`; -const saveLegacyButton = `${editGasLegacyPopup} .popover-footer .btn-primary`; -const editGasFeeButton = `${notificationPage} [data-testid="edit-gas-fee-button"]`; -const gasOptionLowButton = `${notificationPage} [data-testid="edit-gas-fee-item-low"]`; -const gasOptionMediumButton = `${notificationPage} [data-testid="edit-gas-fee-item-medium"]`; -const gasOptionHighButton = `${notificationPage} [data-testid="edit-gas-fee-item-high"]`; -const gasOptionDappSuggestedButton = `${notificationPage} [data-testid="edit-gas-fee-item-dappSuggested"]`; -const gasOptionCustomButton = `${notificationPage} [data-testid="edit-gas-fee-item-custom"]`; -const baseFeeInput = `${notificationPage} [data-testid="base-fee-input"]`; -const priorityFeeInput = `${notificationPage} [data-testid="priority-fee-input"]`; -const editGasLimitButton = `${notificationPage} [data-testid="advanced-gas-fee-edit"]`; -const gasLimitInput = `${notificationPage} [data-testid="gas-limit-input"]`; -const saveCustomGasFeeButton = `${notificationPage} .popover-container .btn-primary`; -const totalLabel = `${confirmPageContent} .transaction-detail-item:nth-child(2) .transaction-detail-item__detail-values h6:nth-child(2)`; -const customNonceInput = `${confirmPageContent} .custom-nonce-input input`; -const tabs = `${confirmPageContent} .tabs`; -const detailsButton = `${tabs} .tab:nth-child(1) button`; -const dataButton = `${tabs} .tab:nth-child(2) button`; -const dataTab = `${tabs} .confirm-page-container-content__data`; -const originValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(1) .confirm-page-container-content__data-field:nth-child(1) div:nth-child(2)`; -const bytesValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(1) .confirm-page-container-content__data-field:nth-child(2) div:nth-child(2)`; -const hexDataValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(3)`; -const rejectButton = `${confirmPageContent} [data-testid="page-container-footer-cancel"]`; -const confirmButton = `${confirmPageContent} [data-testid="page-container-footer-next"]`; + recipientPublicAddress +} + +const confirmPageHeader = `${notificationPage} .confirm-page-container-header` +const confirmPageContent = `${notificationPage} .confirm-page-container-content` +const networkLabel = `${confirmPageHeader} .network-display` +const senderButton = `${confirmPageHeader} .sender-to-recipient__party--sender` +const recipientButton = `${confirmPageHeader} .sender-to-recipient__party--recipient-with-address` +const editGasFeeLegacyButton = `${notificationPage} .transaction-detail-edit button` +const editGasFeeLegacyOverrideAckButton = `${notificationPage} .edit-gas-display .edit-gas-display__dapp-acknowledgement-button` +const editGasLegacyPopup = `${notificationPage} .edit-gas-popover__wrapper` +const advancedLegacyGasControls = `${editGasLegacyPopup} .edit-gas-display .advanced-gas-controls` +const gasLimitLegacyInput = `${advancedLegacyGasControls} .form-field:nth-child(1) input` +const gasPriceLegacyInput = `${advancedLegacyGasControls} .form-field:nth-child(2) input` +const saveLegacyButton = `${editGasLegacyPopup} .popover-footer .btn-primary` +const editGasFeeButton = `${notificationPage} [data-testid="edit-gas-fee-button"]` +const gasOptionLowButton = `${notificationPage} [data-testid="edit-gas-fee-item-low"]` +const gasOptionMediumButton = `${notificationPage} [data-testid="edit-gas-fee-item-medium"]` +const gasOptionHighButton = `${notificationPage} [data-testid="edit-gas-fee-item-high"]` +const gasOptionDappSuggestedButton = `${notificationPage} [data-testid="edit-gas-fee-item-dappSuggested"]` +const gasOptionCustomButton = `${notificationPage} [data-testid="edit-gas-fee-item-custom"]` +const baseFeeInput = `${notificationPage} [data-testid="base-fee-input"]` +const priorityFeeInput = `${notificationPage} [data-testid="priority-fee-input"]` +const editGasLimitButton = `${notificationPage} [data-testid="advanced-gas-fee-edit"]` +const gasLimitInput = `${notificationPage} [data-testid="gas-limit-input"]` +const saveCustomGasFeeButton = `${notificationPage} .popover-container .btn-primary` +const totalLabel = `${confirmPageContent} .transaction-detail-item:nth-child(2) .transaction-detail-item__detail-values h6:nth-child(2)` +const customNonceInput = `${confirmPageContent} .custom-nonce-input input` +const tabs = `${confirmPageContent} .tabs` +const detailsButton = `${tabs} .tab:nth-child(1) button` +const dataButton = `${tabs} .tab:nth-child(2) button` +const dataTab = `${tabs} .confirm-page-container-content__data` +const originValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(1) .confirm-page-container-content__data-field:nth-child(1) div:nth-child(2)` +const bytesValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(1) .confirm-page-container-content__data-field:nth-child(2) div:nth-child(2)` +const hexDataValue = `${dataTab} .confirm-page-container-content__data-box:nth-child(3)` +const rejectButton = `${confirmPageContent} [data-testid="page-container-footer-cancel"]` +const confirmButton = `${confirmPageContent} [data-testid="page-container-footer-next"]` const confirmPageElements = { notificationPage, @@ -121,47 +121,47 @@ const confirmPageElements = { bytesValue, hexDataValue, rejectButton, - confirmButton, -}; + confirmButton +} -const confirmEncryptionPublicKeyButton = `${notificationPage} .request-encryption-public-key__footer__sign-button`; -const rejectEncryptionPublicKeyButton = `${notificationPage} .request-encryption-public-key__footer__cancel-button`; +const confirmEncryptionPublicKeyButton = `${notificationPage} .request-encryption-public-key__footer__sign-button` +const rejectEncryptionPublicKeyButton = `${notificationPage} .request-encryption-public-key__footer__cancel-button` const encryptionPublicKeyPageElements = { confirmEncryptionPublicKeyButton, - rejectEncryptionPublicKeyButton, -}; + rejectEncryptionPublicKeyButton +} -const confirmDecryptionRequestButton = `${notificationPage} .request-decrypt-message__footer__sign-button`; -const rejectDecryptionRequestButton = `${notificationPage} .request-decrypt-message__footer__cancel-button`; +const confirmDecryptionRequestButton = `${notificationPage} .request-decrypt-message__footer__sign-button` +const rejectDecryptionRequestButton = `${notificationPage} .request-decrypt-message__footer__cancel-button` const decryptPageElements = { confirmDecryptionRequestButton, - rejectDecryptionRequestButton, -}; + rejectDecryptionRequestButton +} -const confirmAddTokenButton = `${notificationPage} .btn-primary`; -const rejectAddTokenButton = `${notificationPage} .btn-secondary`; +const confirmAddTokenButton = `${notificationPage} .btn-primary` +const rejectAddTokenButton = `${notificationPage} .btn-secondary` const addTokenPageElements = { confirmAddTokenButton, - rejectAddTokenButton, -}; + rejectAddTokenButton +} /** * ADJUSTED */ -const root = '#root'; +const root = '#root' const app = { - root, -}; + root +} -const primaryButton = '[data-testid="primary-button"]'; +const primaryButton = '[data-testid="primary-button"]' const buttons = { - primaryButton, -}; + primaryButton +} /** * NEW @@ -170,42 +170,42 @@ const signaturePageElements = { buttons: { confirmSign: '[data-testid="primary-button"]', rejectSign: '[data-testid="secondary-button"]', - signatureRequestScrollDownButton, - }, -}; + signatureRequestScrollDownButton + } +} const transactionPageElements = { buttons: { confirmTransaction: '[data-testid="primary-button"]', - rejectTransaction: '[data-testid="secondary-button"]', - }, -}; + rejectTransaction: '[data-testid="secondary-button"]' + } +} const menu = { buttons: { settings: '[data-testid="settings-menu-open-button"]', sidebar: { - settings: '[data-testid="sidebar_menu-button-settings"]', - }, - }, -}; + settings: '[data-testid="sidebar_menu-button-settings"]' + } + } +} const incorrectModePageElements = { buttons: { - close: '[data-testid="incorrect-mode"] button', - }, -}; + close: '[data-testid="incorrect-mode"] button' + } +} const selectWalletElements = { buttons: { continueWithPhantom: '[data-testid="select_wallet--phantom"]', - continueWithMetamask: '[data-testid="select_wallet--metamask"]', - }, -}; + continueWithMetamask: '[data-testid="select_wallet--metamask"]' + } +} export const notificationPageElements = { notificationElements, - incorrectModePageElements, + incorrectModePageElements, menu, transactionPageElements, signaturePageElements, @@ -221,5 +221,5 @@ export const notificationPageElements = { permissionsPageElements, confirmSignatureRequestButton, rejectSignatureRequestButton, - selectWalletElements, -} \ No newline at end of file + selectWalletElements +} diff --git a/wallets/phantom/src/pages/SettingsPage/selectors/index.ts b/wallets/phantom/src/pages/SettingsPage/selectors/index.ts index 0e5207508..5a2c8da0c 100644 --- a/wallets/phantom/src/pages/SettingsPage/selectors/index.ts +++ b/wallets/phantom/src/pages/SettingsPage/selectors/index.ts @@ -1,5 +1,5 @@ export const settingsPageElements = { buttons: { - lockWallet: '[data-testid="lock-menu-item"]', - }, -}; \ No newline at end of file + lockWallet: '[data-testid="lock-menu-item"]' + } +} diff --git a/wallets/phantom/src/utils/getExtensionPage.ts b/wallets/phantom/src/utils/getExtensionPage.ts index 816efd0bb..0a684dcee 100644 --- a/wallets/phantom/src/utils/getExtensionPage.ts +++ b/wallets/phantom/src/utils/getExtensionPage.ts @@ -1,7 +1,7 @@ -import type { Page } from "@playwright/test"; +import type { Page } from '@playwright/test' export const getExtensionPage = async (page: Page, extensionId: string, route: string) => { - const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html`; + const extensionHomeUrl = `chrome-extension://${extensionId}/notification.html` const routes: any = { advanced: `${extensionHomeUrl}#settings/advanced`, @@ -10,8 +10,8 @@ export const getExtensionPage = async (page: Page, extensionId: string, route: s addNetwork: `${extensionHomeUrl}#settings/networks/add-network`, newAccount: `${extensionHomeUrl}#new-account`, importAccount: `${extensionHomeUrl}#new-account/import`, - importToken: `${extensionHomeUrl}#import-token`, + importToken: `${extensionHomeUrl}#import-token` } page.goto(routes[route]) -} \ No newline at end of file +} diff --git a/wallets/phantom/src/utils/index.ts b/wallets/phantom/src/utils/index.ts index d6f677629..77ad67959 100644 --- a/wallets/phantom/src/utils/index.ts +++ b/wallets/phantom/src/utils/index.ts @@ -1 +1 @@ -export * from './selectors/loading' \ No newline at end of file +export * from './selectors/loading' diff --git a/wallets/phantom/src/utils/selectors/loading.ts b/wallets/phantom/src/utils/selectors/loading.ts index 762984e45..68ff4a0ad 100644 --- a/wallets/phantom/src/utils/selectors/loading.ts +++ b/wallets/phantom/src/utils/selectors/loading.ts @@ -1,10 +1,9 @@ -const loadingLogo = '.loading-logo'; -const loadingSpinner = '.loading-spinner'; -const loadingOverlay = '.loading-overlay'; -const loadingOverlaySpinner = '.loading-overlay__spinner'; -const loadingOverlayErrorButtons = '.loading-overlay__error-buttons'; -const loadingOverlayErrorButtonsRetryButton = - '.loading-overlay__error-buttons .btn-primary'; +const loadingLogo = '.loading-logo' +const loadingSpinner = '.loading-spinner' +const loadingOverlay = '.loading-overlay' +const loadingOverlaySpinner = '.loading-overlay__spinner' +const loadingOverlayErrorButtons = '.loading-overlay__error-buttons' +const loadingOverlayErrorButtonsRetryButton = '.loading-overlay__error-buttons .btn-primary' export const loadingElements = { loadingLogo, @@ -12,5 +11,5 @@ export const loadingElements = { loadingOverlay, loadingOverlaySpinner, loadingOverlayErrorButtons, - loadingOverlayErrorButtonsRetryButton, -}; \ No newline at end of file + loadingOverlayErrorButtonsRetryButton +} From 38e2cc4424f7c6e7c0bc36fe15b36dd73873581e Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:02:37 -0400 Subject: [PATCH 15/16] phantom --- wallets/phantom/src/PhantomWallet.ts | 14 ++++++++------ .../src/pages/ConfirmationPage/actions/index.ts | 0 .../phantom/src/pages/ConfirmationPage/page.ts | 13 ------------- .../src/pages/ConfirmationPage/selectors/index.ts | 12 ------------ .../src/pages/HomePage/actions/backToMain.ts | 8 ++++++++ .../phantom/src/pages/HomePage/actions/index.ts | 2 ++ .../pages/HomePage/actions/selectDefaultWallet.ts | 15 +++++++++++++++ wallets/phantom/src/pages/HomePage/page.ts | 10 +++++++++- .../src/pages/NotificationPage/actions/lock.ts | 2 +- .../src/pages/NotificationPage/selectors/index.ts | 7 +++++++ .../src/pages/SettingsPage/actions/index.ts | 0 wallets/phantom/src/pages/SettingsPage/page.ts | 13 ------------- .../src/pages/SettingsPage/selectors/index.ts | 5 ----- 13 files changed, 50 insertions(+), 51 deletions(-) delete mode 100644 wallets/phantom/src/pages/ConfirmationPage/actions/index.ts delete mode 100644 wallets/phantom/src/pages/ConfirmationPage/page.ts delete mode 100644 wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts create mode 100644 wallets/phantom/src/pages/HomePage/actions/backToMain.ts create mode 100644 wallets/phantom/src/pages/HomePage/actions/selectDefaultWallet.ts delete mode 100644 wallets/phantom/src/pages/SettingsPage/actions/index.ts delete mode 100644 wallets/phantom/src/pages/SettingsPage/page.ts delete mode 100644 wallets/phantom/src/pages/SettingsPage/selectors/index.ts diff --git a/wallets/phantom/src/PhantomWallet.ts b/wallets/phantom/src/PhantomWallet.ts index 5d2b0145a..5aa2d7e4c 100644 --- a/wallets/phantom/src/PhantomWallet.ts +++ b/wallets/phantom/src/PhantomWallet.ts @@ -1,16 +1,12 @@ import { type BrowserContext, type Page } from '@playwright/test' -import { ConfirmationPage } from './pages/ConfirmationPage/page' import { HomePage } from './pages/HomePage/page' import { LockPage } from './pages/LockPage/page' import { NotificationPage } from './pages/NotificationPage/page' -import { SettingsPage } from './pages/SettingsPage/page' export class PhantomWallet { readonly lockPage: LockPage readonly homePage: HomePage readonly notificationPage: NotificationPage - readonly settingsPage: SettingsPage - readonly confirmationPage: ConfirmationPage constructor( readonly page: Page, @@ -21,8 +17,6 @@ export class PhantomWallet { this.lockPage = new LockPage(page) this.homePage = new HomePage(page) this.notificationPage = new NotificationPage(page) - this.settingsPage = new SettingsPage(page) - this.confirmationPage = new ConfirmationPage(page) } /** * Does initial setup for the wallet. @@ -86,4 +80,12 @@ export class PhantomWallet { async rejectTransaction() { await this.notificationPage.rejectTransaction(this.extensionId!) } + + async backToMain() { + await this.homePage.backToMain() + } + + async selectDefaultWallet() { + await this.homePage.selectDefaultWallet(this.extensionId!, 'phantom') + } } diff --git a/wallets/phantom/src/pages/ConfirmationPage/actions/index.ts b/wallets/phantom/src/pages/ConfirmationPage/actions/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/wallets/phantom/src/pages/ConfirmationPage/page.ts b/wallets/phantom/src/pages/ConfirmationPage/page.ts deleted file mode 100644 index 52c37d3ec..000000000 --- a/wallets/phantom/src/pages/ConfirmationPage/page.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Page } from '@playwright/test' -import { confirmationPageElements } from './selectors' - -export class ConfirmationPage { - static readonly selectors = confirmationPageElements - readonly selectors = confirmationPageElements - - readonly page: Page - - constructor(page: Page) { - this.page = page - } -} diff --git a/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts b/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts deleted file mode 100644 index 106a1ef74..000000000 --- a/wallets/phantom/src/pages/ConfirmationPage/selectors/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -const confirmationPage = '.confirmation-page' -const confirmationPageFooter = `${confirmationPage} .confirmation-footer` -const footer = { - footer: confirmationPageFooter, - cancelButton: `${confirmationPageFooter} .btn-secondary`, - approveButton: `${confirmationPageFooter} .btn-primary` -} - -export const confirmationPageElements = { - confirmationPage, - footer -} diff --git a/wallets/phantom/src/pages/HomePage/actions/backToMain.ts b/wallets/phantom/src/pages/HomePage/actions/backToMain.ts new file mode 100644 index 000000000..d62dc88da --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/actions/backToMain.ts @@ -0,0 +1,8 @@ +import type { Page } from '@playwright/test' +import { homePageElements } from '../selectors' + +export const backToMain = async (page: Page) => { + await page.waitForLoadState('domcontentloaded') + await page.click(homePageElements.connectedSites.trustedAppsBackButton) + await page.click(homePageElements.settingsMenu.settingsSidebarCloseButton) +} diff --git a/wallets/phantom/src/pages/HomePage/actions/index.ts b/wallets/phantom/src/pages/HomePage/actions/index.ts index 579f5447a..19d12e5c0 100644 --- a/wallets/phantom/src/pages/HomePage/actions/index.ts +++ b/wallets/phantom/src/pages/HomePage/actions/index.ts @@ -2,3 +2,5 @@ export * from './changeAccount' export * from './closePopupAndTooltips' export * from './getWalletAddress' export * from './disconnectFromApp' +export * from './selectDefaultWallet' +export * from './backToMain' \ No newline at end of file diff --git a/wallets/phantom/src/pages/HomePage/actions/selectDefaultWallet.ts b/wallets/phantom/src/pages/HomePage/actions/selectDefaultWallet.ts new file mode 100644 index 000000000..6deccf409 --- /dev/null +++ b/wallets/phantom/src/pages/HomePage/actions/selectDefaultWallet.ts @@ -0,0 +1,15 @@ +import type { Page } from '@playwright/test' +import { getNotificationPageAndWaitForLoad } from '../../../utils/getNotificationAndWaitForLoads' +import { homePageElements } from '../selectors' + +export const selectDefaultWallet = async (page: Page, extensionId: string, wallet: string) => { + console.log(wallet) + const notificationPage = await getNotificationPageAndWaitForLoad(page.context(), extensionId) + const walletSelector = homePageElements.defaultWallet['phantom'] + await notificationPage.click(homePageElements.settingsMenu.settingsMenuButton) + await notificationPage.click(homePageElements.settingsMenu.settingsSidebarButton) + await notificationPage.click(homePageElements.settingsMenu.settingsPreferencesButton) + await notificationPage.click(homePageElements.settingsMenu.defaultAppWalletRow) + await notificationPage.click(walletSelector) + await notificationPage.click(homePageElements.connectedSites.trustedAppsBackButton) +} diff --git a/wallets/phantom/src/pages/HomePage/page.ts b/wallets/phantom/src/pages/HomePage/page.ts index 1219a49ea..94eea1cbf 100644 --- a/wallets/phantom/src/pages/HomePage/page.ts +++ b/wallets/phantom/src/pages/HomePage/page.ts @@ -1,5 +1,5 @@ import type { Page } from '@playwright/test' -import { changeAccount, closePopupAndTooltips, disconnectFromApp, getWalletAddress } from './actions' +import { changeAccount, closePopupAndTooltips, disconnectFromApp, getWalletAddress, selectDefaultWallet, backToMain } from './actions' import { homePageElements } from './selectors' export class HomePage { @@ -27,4 +27,12 @@ export class HomePage { async disconnectFromApp(extensionId: string) { await disconnectFromApp(this.page, extensionId) } + + async selectDefaultWallet(extensionId: string, wallet: string) { + await selectDefaultWallet(this.page, extensionId, wallet) + } + + async backToMain() { + await backToMain(this.page) + } } diff --git a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts index bac64ce15..90a1cc9a3 100644 --- a/wallets/phantom/src/pages/NotificationPage/actions/lock.ts +++ b/wallets/phantom/src/pages/NotificationPage/actions/lock.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test' import { closePopupAndTooltips } from '../../HomePage/actions/closePopupAndTooltips' -import { settingsPageElements } from '../../SettingsPage/selectors' +import { settingsPageElements } from '../selectors' import { notificationPageElements } from '../selectors' export const lock = async (page: Page, extensionId: string) => { diff --git a/wallets/phantom/src/pages/NotificationPage/selectors/index.ts b/wallets/phantom/src/pages/NotificationPage/selectors/index.ts index efdf02b16..5018c4154 100644 --- a/wallets/phantom/src/pages/NotificationPage/selectors/index.ts +++ b/wallets/phantom/src/pages/NotificationPage/selectors/index.ts @@ -174,6 +174,13 @@ const signaturePageElements = { } } +export const settingsPageElements = { + buttons: { + lockWallet: '[data-testid="lock-menu-item"]' + } +} + + const transactionPageElements = { buttons: { confirmTransaction: '[data-testid="primary-button"]', diff --git a/wallets/phantom/src/pages/SettingsPage/actions/index.ts b/wallets/phantom/src/pages/SettingsPage/actions/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/wallets/phantom/src/pages/SettingsPage/page.ts b/wallets/phantom/src/pages/SettingsPage/page.ts deleted file mode 100644 index 3809723cb..000000000 --- a/wallets/phantom/src/pages/SettingsPage/page.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Page } from '@playwright/test' -import { settingsPageElements } from './selectors' - -export class SettingsPage { - static readonly selectors = settingsPageElements - readonly selectors = settingsPageElements - - readonly page: Page - - constructor(page: Page) { - this.page = page - } -} diff --git a/wallets/phantom/src/pages/SettingsPage/selectors/index.ts b/wallets/phantom/src/pages/SettingsPage/selectors/index.ts deleted file mode 100644 index 5a2c8da0c..000000000 --- a/wallets/phantom/src/pages/SettingsPage/selectors/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const settingsPageElements = { - buttons: { - lockWallet: '[data-testid="lock-menu-item"]' - } -} From 5a1092d3c7f93ba7344ef372a6626fd2f3045247 Mon Sep 17 00:00:00 2001 From: Sero <69639595+Seroxdesign@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:47:50 -0400 Subject: [PATCH 16/16] wallet setup and complete all ports --- .../pages/LockPage/actions/createAccount.ts | 33 +++++++------------ .../pages/LockPage/actions/importAccount.ts | 2 ++ .../src/pages/LockPage/selectors/index.ts | 10 ++++-- wallets/phantom/test/synpress.ts | 4 +-- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts index fbf801cd2..c705b352e 100644 --- a/wallets/phantom/src/pages/LockPage/actions/createAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/createAccount.ts @@ -2,32 +2,23 @@ import type { Page } from '@playwright/test' import { lockPageElements } from '../selectors' export const createAccount = async (page: Page, password: string) => { - console.log(lockPageElements, page, password) - // await page.click(lockPageElements.firstTimeFlowPageElements.importWalletButton) - // await page.click(lockPageElements.firstTimeFlowPageElements.importRecoveryPhraseButton) + await page.waitForLoadState('domcontentloaded') + await page.click(lockPageElements.firstTimeFlowPageElements.createWalletButton) - // for (const [index, word] of secretWords.split(' ').entries()) { - // const inputField = await page.locator(lockPageElements.firstTimeFlowImportPageElements.secretWordsInput(index)) - // await inputField.fill(word) - // } - // await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + const walletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.passwordInput) + await walletInput.fill(password) - // await page.waitForLoadState('domcontentloaded') + const confirmWalletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.confirmPasswordInput) + await confirmWalletInput.fill(password) - // await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + const checkbox = await page.locator(lockPageElements.firstTimeFlowImportPageElements.termsCheckbox) + await checkbox.click() - // const walletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.passwordInput) - // await walletInput.fill(password) + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) - // const confirmWalletInput = await page.locator(lockPageElements.firstTimeFlowImportPageElements.confirmPasswordInput) - // await confirmWalletInput.fill(password) + await page.click(lockPageElements.firstTimeFlowImportPageElements.savedWordsCheckbox) - // const checkbox = await page.locator(lockPageElements.firstTimeFlowImportPageElements.termsCheckbox) - // await checkbox.click() + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) - // await page.click(lockPageElements.firstTimeFlowImportPageElements.continueAfterPasswordButton) - - // await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton); - - // return true; + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) } diff --git a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts index b40b6c453..5065eaa88 100644 --- a/wallets/phantom/src/pages/LockPage/actions/importAccount.ts +++ b/wallets/phantom/src/pages/LockPage/actions/importAccount.ts @@ -28,5 +28,7 @@ export const importWallet = async (page: Page, secretWords: string, password: st await page.click(lockPageElements.firstTimeFlowImportPageElements.getStartedButton) + await page.click(lockPageElements.firstTimeFlowImportPageElements.confirmWordsButton) + return true } diff --git a/wallets/phantom/src/pages/LockPage/selectors/index.ts b/wallets/phantom/src/pages/LockPage/selectors/index.ts index 065f803d0..6730fae15 100644 --- a/wallets/phantom/src/pages/LockPage/selectors/index.ts +++ b/wallets/phantom/src/pages/LockPage/selectors/index.ts @@ -16,15 +16,17 @@ const metametricsPageElements = { } const firstTimeFlowPage = '.first-time-flow' -const importWalletButton = `[data-testid="import-wallet-button"]` +const importWalletButton = '[data-testid="import-wallet-button"]' const importRecoveryPhraseButton = `[data-testid="import-seed-phrase-button"]` -const createWalletButton = `${firstTimeFlowPage} [data-testid="create-wallet-button"]` +const createWalletButton = `[data-testid="create-wallet-button"]` +const hiddenXPath = 'xpath=//*[@id="root"]/main/div[2]/form/div[1]/div[2]/div' const firstTimeFlowPageElements = { firstTimeFlowPage, importWalletButton, importRecoveryPhraseButton, - createWalletButton + createWalletButton, + hiddenXPath } const firstTimeFlowImportPage = '.first-time-flow__import' @@ -34,6 +36,7 @@ const confirmWordsButton = `[data-testid="onboarding-form-submit-button"]` const passwordInput = `[data-testid="onboarding-form-password-input"]` const confirmPasswordInput = `[data-testid="onboarding-form-confirm-password-input"]` const termsCheckbox = `[data-testid="onboarding-form-terms-of-service-checkbox"]` +const savedWordsCheckbox = '[data-testid="onboarding-form-saved-secret-recovery-phrase-checkbox"]' const continueAfterPasswordButton = '[data-testid="onboarding-form-submit-button"]' const getStartedButton = '[data-testid="onboarding-form-submit-button"]' const importButton = `${newVaultForm} .create-new-vault__submit-button` @@ -46,6 +49,7 @@ const firstTimeFlowImportPageElements = { confirmPasswordInput, termsCheckbox, importButton, + savedWordsCheckbox, confirmWordsButton, continueAfterPasswordButton, getStartedButton diff --git a/wallets/phantom/test/synpress.ts b/wallets/phantom/test/synpress.ts index 54693c56f..f7ad8643e 100644 --- a/wallets/phantom/test/synpress.ts +++ b/wallets/phantom/test/synpress.ts @@ -1,5 +1,5 @@ import { testWithSynpress } from '@synthetixio/synpress-core' import { phantomFixtures } from '../src' -import importPhantom from './wallet-setup/import.setup' +import createPhantom from './wallet-setup/create.setup' -export default testWithSynpress(phantomFixtures(importPhantom)) +export default testWithSynpress(phantomFixtures(createPhantom))