Skip to content

Commit 6d0ca8f

Browse files
committed
Phantom support for Playwright
1 parent 21f3e06 commit 6d0ca8f

File tree

116 files changed

+3218
-35
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+3218
-35
lines changed

docs/api/typedoc-sidebar.json

+62-15
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717
"text": "configureSynpressForEthereumWalletMock",
1818
"link": "/api/cypress/functions/configureSynpressForEthereumWalletMock.md"
1919
},
20-
{ "text": "configureSynpressForMetaMask", "link": "/api/cypress/functions/configureSynpressForMetaMask.md" },
21-
{ "text": "initMetaMask", "link": "/api/cypress/functions/initMetaMask.md" }
20+
{
21+
"text": "configureSynpressForMetaMask",
22+
"link": "/api/cypress/functions/configureSynpressForMetaMask.md"
23+
},
24+
{
25+
"text": "initMetaMask",
26+
"link": "/api/cypress/functions/initMetaMask.md"
27+
}
2228
]
2329
},
2430
{
@@ -30,7 +36,10 @@
3036
"text": "Functions",
3137
"collapsed": true,
3238
"items": [
33-
{ "text": "mockEthereum", "link": "/api/cypress/support/functions/mockEthereum.md" },
39+
{
40+
"text": "mockEthereum",
41+
"link": "/api/cypress/support/functions/mockEthereum.md"
42+
},
3443
{
3544
"text": "synpressCommandsForEthereumWalletMock",
3645
"link": "/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md"
@@ -54,8 +63,14 @@
5463
"text": "Functions",
5564
"collapsed": true,
5665
"items": [
57-
{ "text": "defineWalletSetup", "link": "/api/index/functions/defineWalletSetup.md" },
58-
{ "text": "testWithSynpress", "link": "/api/index/functions/testWithSynpress.md" }
66+
{
67+
"text": "defineWalletSetup",
68+
"link": "/api/index/functions/defineWalletSetup.md"
69+
},
70+
{
71+
"text": "testWithSynpress",
72+
"link": "/api/index/functions/testWithSynpress.md"
73+
}
5974
]
6075
}
6176
]
@@ -69,28 +84,60 @@
6984
"text": "Classes",
7085
"collapsed": true,
7186
"items": [
72-
{ "text": "EthereumWalletMock", "link": "/api/playwright/classes/EthereumWalletMock.md" },
73-
{ "text": "MetaMask", "link": "/api/playwright/classes/MetaMask.md" }
87+
{
88+
"text": "EthereumWalletMock",
89+
"link": "/api/playwright/classes/EthereumWalletMock.md"
90+
},
91+
{ "text": "MetaMask", "link": "/api/playwright/classes/MetaMask.md" },
92+
{ "text": "Phantom", "link": "/api/playwright/classes/Phantom.md" }
7493
]
7594
},
7695
{
7796
"text": "Variables",
7897
"collapsed": true,
7998
"items": [
80-
{ "text": "DEFAULT_NETWORK_ID", "link": "/api/playwright/variables/DEFAULT_NETWORK_ID.md" },
81-
{ "text": "PRIVATE_KEY", "link": "/api/playwright/variables/PRIVATE_KEY.md" },
82-
{ "text": "web3MockPath", "link": "/api/playwright/variables/web3MockPath.md" }
99+
{
100+
"text": "DEFAULT_NETWORK_ID",
101+
"link": "/api/playwright/variables/DEFAULT_NETWORK_ID.md"
102+
},
103+
{
104+
"text": "PRIVATE_KEY",
105+
"link": "/api/playwright/variables/PRIVATE_KEY.md"
106+
},
107+
{
108+
"text": "web3MockPath",
109+
"link": "/api/playwright/variables/web3MockPath.md"
110+
}
83111
]
84112
},
85113
{
86114
"text": "Functions",
87115
"collapsed": true,
88116
"items": [
89-
{ "text": "ethereumWalletMockFixtures", "link": "/api/playwright/functions/ethereumWalletMockFixtures.md" },
90-
{ "text": "getExtensionId", "link": "/api/playwright/functions/getExtensionId.md" },
91-
{ "text": "metaMaskFixtures", "link": "/api/playwright/functions/metaMaskFixtures.md" },
92-
{ "text": "mockEthereum", "link": "/api/playwright/functions/mockEthereum.md" },
93-
{ "text": "unlockForFixture", "link": "/api/playwright/functions/unlockForFixture.md" }
117+
{
118+
"text": "ethereumWalletMockFixtures",
119+
"link": "/api/playwright/functions/ethereumWalletMockFixtures.md"
120+
},
121+
{
122+
"text": "getExtensionId",
123+
"link": "/api/playwright/functions/getExtensionId.md"
124+
},
125+
{
126+
"text": "metaMaskFixtures",
127+
"link": "/api/playwright/functions/metaMaskFixtures.md"
128+
},
129+
{
130+
"text": "phantomFixtures",
131+
"link": "/api/playwright/functions/phantomFixtures.md"
132+
},
133+
{
134+
"text": "mockEthereum",
135+
"link": "/api/playwright/functions/mockEthereum.md"
136+
},
137+
{
138+
"text": "unlockForFixture",
139+
"link": "/api/playwright/functions/unlockForFixture.md"
140+
}
94141
]
95142
}
96143
]

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"scripts": {
44
"build": "turbo build",
55
"build:cache": "turbo build:cache --filter=@synthetixio/synpress-metamask",
6+
"build:cache:phantom": "turbo build:cache --filter=@synthetixio/synpress-phantom",
67
"docs:build": "turbo docs:build --filter=docs",
78
"format": "biome format . --write",
89
"format:check": "biome format . --error-on-warnings",
@@ -15,8 +16,8 @@
1516
"sort-package-json": "sort-package-json 'package.json' '{packages,wallets,examples}/*/package.json'",
1617
"sort-package-json:check": "sort-package-json 'package.json' '{packages,wallets,examples}/*/package.json' --check",
1718
"test": "turbo test",
18-
"test:playwright:headful": "turbo test:playwright:headful --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock",
19-
"test:playwright:headless": "turbo test:playwright:headless --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock",
19+
"test:playwright:headful": "turbo test:playwright:headful --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock --filter=@synthetixio/synpress-phantom",
20+
"test:playwright:headless": "turbo test:playwright:headless --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock --filter=@synthetixio/synpress-phantom",
2021
"update:deps": "ncu -u -ws --root"
2122
},
2223
"lint-staged": {

packages/cache/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"gradient-string": "2.0.2",
3939
"progress": "2.0.3",
4040
"tsup": "8.0.2",
41+
"unzip-crx-3": "0.2.0",
4142
"unzipper": "0.10.14",
4243
"zod": "3.22.4"
4344
},

packages/cache/src/cli/cliEntrypoint.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import { rimraf } from 'rimraf'
66
import { WALLET_SETUP_DIR_NAME } from '../constants'
77
import { createCache } from '../createCache'
88
import { prepareExtension } from '../prepareExtension'
9+
import { prepareExtensionPhantom } from '../prepareExtensionPhantom'
910
import { compileWalletSetupFunctions } from './compileWalletSetupFunctions'
1011
import { footer } from './footer'
1112

1213
interface CliFlags {
1314
headless: boolean
1415
force: boolean
1516
debug: boolean
17+
phantom: boolean
1618
}
1719

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

4851
if (flags.debug) {
4952
console.log('[DEBUG] Running with the following options:')
50-
console.log({ cacheDir: walletSetupDir, ...flags, headless: Boolean(process.env.HEADLESS) ?? false }, '\n')
53+
console.log(
54+
{
55+
cacheDir: walletSetupDir,
56+
...flags,
57+
headless: Boolean(process.env.HEADLESS) ?? false
58+
},
59+
'\n'
60+
)
5161
}
5262

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

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

67-
// TODO: We should be using `prepareExtension` function from the wallet itself!
68-
await createCache(compiledWalletSetupDirPath, prepareExtension, flags.force)
77+
// TODO: We should be using `prepareExtension` functions from the wallet itself!
78+
if (flags.phantom) {
79+
await createCache(compiledWalletSetupDirPath, prepareExtensionPhantom, flags.force)
80+
} else {
81+
await createCache(compiledWalletSetupDirPath, prepareExtension, flags.force)
82+
}
6983

7084
if (!flags.debug) {
7185
await rimraf(compiledWalletSetupDirPath)

packages/cache/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from './utils/createTempContextDir'
88
export * from './utils/removeTempContextDir'
99
export * from './prepareExtension'
1010
export * from './cli/cliEntrypoint'
11+
export * from './prepareExtensionPhantom'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { downloadFile, ensureCacheDirExists, unzipArchivePhantom } from '.'
2+
3+
export const DEFAULT_PHANTOM_VERSION = 'latest'
4+
export const PHANTOM_EXTENSION_DOWNLOAD_URL = 'https://crx-backup.phantom.dev/latest.crx'
5+
6+
// NOTE: This function is copied from `wallets/phantom/src/prepareExtensionPhantom.ts` only TEMPORARILY!
7+
export async function prepareExtensionPhantom() {
8+
const cacheDirPath = ensureCacheDirExists()
9+
10+
const downloadResult = await downloadFile({
11+
url: PHANTOM_EXTENSION_DOWNLOAD_URL,
12+
outputDir: cacheDirPath,
13+
fileName: 'phantom-chrome-latest.crx'
14+
})
15+
16+
const unzipResult = await unzipArchivePhantom({
17+
archivePath: downloadResult.filePath
18+
})
19+
20+
return unzipResult.outputPath
21+
}

packages/cache/src/unzipArchive.ts

+25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from 'node:path'
22
import fs from 'fs-extra'
3+
import unzipCrx from 'unzip-crx-3'
34
import unzippper from 'unzipper'
45

56
type UnzipArchiveOptions = {
@@ -73,3 +74,27 @@ export async function unzipArchive(options: UnzipArchiveOptions) {
7374
throw new Error(`[UnzipFile] Error unzipping the file - ${error.message}`)
7475
})
7576
}
77+
78+
export async function unzipArchivePhantom(options: UnzipArchiveOptions) {
79+
const { archivePath, overwrite } = options
80+
81+
const archiveFileExtension = archivePath.split('.').slice(-1)
82+
const outputPath = archivePath.replace(`.${archiveFileExtension}`, '')
83+
84+
const fileExists = fs.existsSync(outputPath)
85+
if (fileExists && !overwrite) {
86+
return {
87+
outputPath,
88+
unzipSkipped: true
89+
}
90+
}
91+
92+
// Creates the output directory
93+
fs.mkdirSync(outputPath, { recursive: true })
94+
95+
await unzipCrx(archivePath, outputPath)
96+
97+
// TODO: Handle errors
98+
99+
return { outputPath }
100+
}

packages/cache/tsconfig.build.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
"declarationMap": true
99
},
1010
"include": ["src"],
11-
"files": ["environment.d.ts"]
11+
"files": ["environment.d.ts", "unzip-crx-3.d.ts"]
1212
}

packages/cache/tsconfig.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
"rootDir": ".",
55
"lib": ["DOM"]
66
},
7-
"include": [
8-
"src",
9-
"test"
10-
],
11-
"files": ["environment.d.ts"]
7+
"include": ["src", "test"],
8+
"files": ["environment.d.ts", "unzip-crx-3.d.ts"]
129
}

packages/cache/unzip-crx-3.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'unzip-crx-3'

0 commit comments

Comments
 (0)