Skip to content

Commit

Permalink
feat: Phantom support
Browse files Browse the repository at this point in the history
  • Loading branch information
zgz2020 committed Dec 11, 2024
1 parent 21f3e06 commit 306e2a0
Show file tree
Hide file tree
Showing 123 changed files with 4,354 additions and 25 deletions.
29 changes: 29 additions & 0 deletions docs/api/cypress/functions/initPhantom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Function: initPhantom()

```ts
function initPhantom(): Promise<{
"browserArgs": string[];
"extensions": string[];
}>
```

Initializes Phantom for Cypress tests.

This function prepares the Phantom extension for use in Cypress tests.
It sets up the necessary browser arguments and extension paths.

## Returns

`Promise`\<\{
`"browserArgs"`: `string`[];
`"extensions"`: `string`[];
\}\>

An object containing the extension path and browser arguments.

| Member | Type |
| :------ | :------ |
| `browserArgs` | `string`[] |
| `extensions` | `string`[] |

## Async
3 changes: 3 additions & 0 deletions docs/api/cypress/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
| Member | Description |
| :------ | :------ |
| [MetaMask](classes/MetaMask.md) | MetaMask class for interacting with the MetaMask extension in Cypress tests. |
| [Phantom](classes/Phantom.md) | Phantom class for interacting with the Phantom extension in Cypress tests. |
| [configureSynpressForEthereumWalletMock](functions/configureSynpressForEthereumWalletMock.md) | Configures Synpress for use with the Ethereum Wallet Mock. |
| [configureSynpressForMetaMask](functions/configureSynpressForMetaMask.md) | Configures Synpress for use with MetaMask. |
| [configureSynpressForPhantom](functions/configureSynpressForPhantom.md) | Configures Synpress for use with Phantom. |
| [initMetaMask](functions/initMetaMask.md) | Initializes MetaMask for Cypress tests. |
| [initPhantom](functions/initPhantom.md) | Initializes Phantom for Cypress tests. |
94 changes: 78 additions & 16 deletions docs/api/typedoc-sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
{
"text": "Classes",
"collapsed": true,
"items": [{ "text": "MetaMask", "link": "/api/cypress/classes/MetaMask.md" }]
"items": [
{ "text": "MetaMask", "link": "/api/cypress/classes/MetaMask.md" },
{ "text": "Phantom", "link": "/api/cypress/classes/Phantom.md" }
]
},
{
"text": "Functions",
Expand All @@ -17,8 +20,22 @@
"text": "configureSynpressForEthereumWalletMock",
"link": "/api/cypress/functions/configureSynpressForEthereumWalletMock.md"
},
{ "text": "configureSynpressForMetaMask", "link": "/api/cypress/functions/configureSynpressForMetaMask.md" },
{ "text": "initMetaMask", "link": "/api/cypress/functions/initMetaMask.md" }
{
"text": "configureSynpressForMetaMask",
"link": "/api/cypress/functions/configureSynpressForMetaMask.md"
},
{
"text": "configureSynpressForPhantom",
"link": "/api/cypress/functions/configureSynpressForPhantom.md"
},
{
"text": "initMetaMask",
"link": "/api/cypress/functions/initMetaMask.md"
},
{
"text": "initPhanton",
"link": "/api/cypress/functions/initPhantom.md"
}
]
},
{
Expand All @@ -30,14 +47,21 @@
"text": "Functions",
"collapsed": true,
"items": [
{ "text": "mockEthereum", "link": "/api/cypress/support/functions/mockEthereum.md" },
{
"text": "mockEthereum",
"link": "/api/cypress/support/functions/mockEthereum.md"
},
{
"text": "synpressCommandsForEthereumWalletMock",
"link": "/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md"
},
{
"text": "synpressCommandsForMetaMask",
"link": "/api/cypress/support/functions/synpressCommandsForMetaMask.md"
},
{
"text": "synpressCommandsForPhantom",
"link": "/api/cypress/support/functions/synpressCommandsForPhantom.md"
}
]
}
Expand All @@ -54,8 +78,14 @@
"text": "Functions",
"collapsed": true,
"items": [
{ "text": "defineWalletSetup", "link": "/api/index/functions/defineWalletSetup.md" },
{ "text": "testWithSynpress", "link": "/api/index/functions/testWithSynpress.md" }
{
"text": "defineWalletSetup",
"link": "/api/index/functions/defineWalletSetup.md"
},
{
"text": "testWithSynpress",
"link": "/api/index/functions/testWithSynpress.md"
}
]
}
]
Expand All @@ -69,28 +99,60 @@
"text": "Classes",
"collapsed": true,
"items": [
{ "text": "EthereumWalletMock", "link": "/api/playwright/classes/EthereumWalletMock.md" },
{ "text": "MetaMask", "link": "/api/playwright/classes/MetaMask.md" }
{
"text": "EthereumWalletMock",
"link": "/api/playwright/classes/EthereumWalletMock.md"
},
{ "text": "MetaMask", "link": "/api/playwright/classes/MetaMask.md" },
{ "text": "Phantom", "link": "/api/playwright/classes/Phantom.md" }
]
},
{
"text": "Variables",
"collapsed": true,
"items": [
{ "text": "DEFAULT_NETWORK_ID", "link": "/api/playwright/variables/DEFAULT_NETWORK_ID.md" },
{ "text": "PRIVATE_KEY", "link": "/api/playwright/variables/PRIVATE_KEY.md" },
{ "text": "web3MockPath", "link": "/api/playwright/variables/web3MockPath.md" }
{
"text": "DEFAULT_NETWORK_ID",
"link": "/api/playwright/variables/DEFAULT_NETWORK_ID.md"
},
{
"text": "PRIVATE_KEY",
"link": "/api/playwright/variables/PRIVATE_KEY.md"
},
{
"text": "web3MockPath",
"link": "/api/playwright/variables/web3MockPath.md"
}
]
},
{
"text": "Functions",
"collapsed": true,
"items": [
{ "text": "ethereumWalletMockFixtures", "link": "/api/playwright/functions/ethereumWalletMockFixtures.md" },
{ "text": "getExtensionId", "link": "/api/playwright/functions/getExtensionId.md" },
{ "text": "metaMaskFixtures", "link": "/api/playwright/functions/metaMaskFixtures.md" },
{ "text": "mockEthereum", "link": "/api/playwright/functions/mockEthereum.md" },
{ "text": "unlockForFixture", "link": "/api/playwright/functions/unlockForFixture.md" }
{
"text": "ethereumWalletMockFixtures",
"link": "/api/playwright/functions/ethereumWalletMockFixtures.md"
},
{
"text": "getExtensionId",
"link": "/api/playwright/functions/getExtensionId.md"
},
{
"text": "metaMaskFixtures",
"link": "/api/playwright/functions/metaMaskFixtures.md"
},
{
"text": "phantomFixtures",
"link": "/api/playwright/functions/phantomFixtures.md"
},
{
"text": "mockEthereum",
"link": "/api/playwright/functions/mockEthereum.md"
},
{
"text": "unlockForFixture",
"link": "/api/playwright/functions/unlockForFixture.md"
}
]
}
]
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"scripts": {
"build": "turbo build",
"build:cache": "turbo build:cache --filter=@synthetixio/synpress-metamask",
"build:cache:phantom": "turbo build:cache --filter=@synthetixio/synpress-phantom",
"docs:build": "turbo docs:build --filter=docs",
"format": "biome format . --write",
"format:check": "biome format . --error-on-warnings",
Expand All @@ -15,8 +16,8 @@
"sort-package-json": "sort-package-json 'package.json' '{packages,wallets,examples}/*/package.json'",
"sort-package-json:check": "sort-package-json 'package.json' '{packages,wallets,examples}/*/package.json' --check",
"test": "turbo test",
"test:playwright:headful": "turbo test:playwright:headful --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock",
"test:playwright:headless": "turbo test:playwright:headless --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock",
"test:playwright:headful": "turbo test:playwright:headful --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock --filter=@synthetixio/synpress-phantom",
"test:playwright:headless": "turbo test:playwright:headless --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock --filter=@synthetixio/synpress-phantom",
"update:deps": "ncu -u -ws --root"
},
"lint-staged": {
Expand Down
1 change: 1 addition & 0 deletions packages/cache/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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"
},
Expand Down
22 changes: 18 additions & 4 deletions packages/cache/src/cli/cliEntrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { rimraf } from 'rimraf'
import { WALLET_SETUP_DIR_NAME } from '../constants'
import { createCache } from '../createCache'
import { prepareExtension } from '../prepareExtension'
import { prepareExtensionPhantom } from '../prepareExtensionPhantom'
import { compileWalletSetupFunctions } from './compileWalletSetupFunctions'
import { footer } from './footer'

interface CliFlags {
headless: boolean
force: boolean
debug: boolean
phantom: boolean
}

// TODO: Add unit tests for the CLI!
Expand All @@ -30,6 +32,7 @@ export const cliEntrypoint = async () => {
)
.option('-f, --force', 'Force the creation of cache even if it already exists', false)
.option('-d, --debug', 'If this flag is present, the compilation files are not going to be deleted', false)
.option('-p, --phantom', 'If this flag is present, Phantom extension will be installed instead of Metamask', false)
.helpOption(undefined, 'Display help for command')
.addHelpText('afterAll', `\n${footer}\n`)
.parse(process.argv)
Expand All @@ -46,8 +49,15 @@ export const cliEntrypoint = async () => {
}

if (flags.debug) {
console.log('[DEBUG] Running with the following options:')
console.log({ cacheDir: walletSetupDir, ...flags, headless: Boolean(process.env.HEADLESS) ?? false }, '\n')
console.log('[DEBUG] Running with the following options ===:')
console.log(
{
cacheDir: walletSetupDir,
...flags,
headless: Boolean(process.env.HEADLESS) ?? false
},
'\n'
)
}

if (os.platform() === 'win32') {
Expand All @@ -64,8 +74,12 @@ export const cliEntrypoint = async () => {

const compiledWalletSetupDirPath = await compileWalletSetupFunctions(walletSetupDir, flags.debug)

// TODO: We should be using `prepareExtension` function from the wallet itself!
await createCache(compiledWalletSetupDirPath, prepareExtension, flags.force)
// TODO: We should be using `prepareExtension` functions from the wallet itself!
if (flags.phantom) {
await createCache(compiledWalletSetupDirPath, prepareExtensionPhantom, flags.force)
} else {
await createCache(compiledWalletSetupDirPath, prepareExtension, flags.force)
}

if (!flags.debug) {
await rimraf(compiledWalletSetupDirPath)
Expand Down
1 change: 1 addition & 0 deletions packages/cache/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './utils/createTempContextDir'
export * from './utils/removeTempContextDir'
export * from './prepareExtension'
export * from './cli/cliEntrypoint'
export * from './prepareExtensionPhantom'
21 changes: 21 additions & 0 deletions packages/cache/src/prepareExtensionPhantom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { downloadFile, ensureCacheDirExists, unzipArchivePhantom } from '.'

export const DEFAULT_PHANTOM_VERSION = 'latest'
export const PHANTOM_EXTENSION_DOWNLOAD_URL = 'https://crx-backup.phantom.dev/latest.crx'

// NOTE: This function is copied from `wallets/phantom/src/prepareExtensionPhantom.ts` only TEMPORARILY!
export async function prepareExtensionPhantom() {
const cacheDirPath = ensureCacheDirExists()

const downloadResult = await downloadFile({
url: PHANTOM_EXTENSION_DOWNLOAD_URL,
outputDir: cacheDirPath,
fileName: 'phantom-chrome-latest.crx'
})

const unzipResult = await unzipArchivePhantom({
archivePath: downloadResult.filePath
})

return unzipResult.outputPath
}
25 changes: 25 additions & 0 deletions packages/cache/src/unzipArchive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'node:path'
import fs from 'fs-extra'
import unzipCrx from 'unzip-crx-3'
import unzippper from 'unzipper'

type UnzipArchiveOptions = {
Expand Down Expand Up @@ -73,3 +74,27 @@ export async function unzipArchive(options: UnzipArchiveOptions) {
throw new Error(`[UnzipFile] Error unzipping the file - ${error.message}`)
})
}

export async function unzipArchivePhantom(options: UnzipArchiveOptions) {
const { archivePath, overwrite } = options

const archiveFileExtension = archivePath.split('.').slice(-1)
const outputPath = archivePath.replace(`.${archiveFileExtension}`, '')

const fileExists = fs.existsSync(outputPath)
if (fileExists && !overwrite) {
return {
outputPath,
unzipSkipped: true
}
}

// Creates the output directory
fs.mkdirSync(outputPath, { recursive: true })

await unzipCrx(archivePath, outputPath)

// TODO: Handle errors

return { outputPath }
}
2 changes: 1 addition & 1 deletion packages/cache/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"declarationMap": true
},
"include": ["src"],
"files": ["environment.d.ts"]
"files": ["environment.d.ts", "unzip-crx-3.d.ts"]
}
2 changes: 1 addition & 1 deletion packages/cache/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"src",
"test"
],
"files": ["environment.d.ts"]
"files": ["environment.d.ts", "unzip-crx-3.d.ts"]
}
1 change: 1 addition & 0 deletions packages/cache/unzip-crx-3.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'unzip-crx-3'
Loading

0 comments on commit 306e2a0

Please sign in to comment.