Files
universe/e2e/06-wallet.spec.ts
zeekayandHanzo Dev 0604e1da7a fix(e2e): assert public RPC equivalents for firewalled info/health API
/v1/info and /v1/health are firewalled at the gateway by design (404 on the
public endpoint), so specs calling info.getNetworkID / getNodeVersion /
isBootstrapped / peers / health / uptime were asserting facts that are not
publicly observable. Retarget them to the equivalent public C/P/X RPC:

  network ID   -> net_version (C-Chain)
  node version -> web3_clientVersion (C-Chain)
  P bootstrap  -> platform.getCurrentValidators present
  C bootstrap  -> eth_blockNumber advancing
  X bootstrap  -> X-Chain RPC endpoint reachable (200/405)
  peers        -> tolerate firewalled info.peers; assert depth only ENV=local
  uptime       -> validators carry positive stake weight (public RPC returns
                  uptime "0.0000" — it does not attest peer uptime publicly)

helpers: add rpcXChain and per-network ZOO_API_DOMAINS; point the Zoo
cross-chain RPC at api.zoo.network/v1/bc/C/rpc (the api.lux.network/v1/bc/zoo
alias 404s — Zoo is a sovereign network on its own domain).

07-validator is a LOCAL-node suite (its own header says "Run with ENV=local")
whose skip guard only fired on HTTP 0; against production the firewalled
health endpoint returns 404, so it ran the local checks and failed. Gate the
whole suite on isLocal().

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-26 15:46:02 -07:00

98 lines
4.3 KiB
TypeScript

import { test, expect } from '@playwright/test'
import { getUrls, httpStatus, rpcCall, getCurrentValidators, snap } from './helpers'
const urls = getUrls()
// ── Wallet Frontend ─────────────────────────────────────────────────
test.describe('Wallet — Frontend Accessibility', () => {
test('wallet.lux.network loads', async ({ page }) => {
const res = await page.goto(urls.wallet, { timeout: 60_000, waitUntil: 'domcontentloaded' })
const status = res?.status() || 0
console.log(` Wallet HTTP: ${status}`)
expect([200, 301, 302, 307]).toContain(status)
await snap(page, 'wallet-home')
})
test('wallet has visible UI', async ({ page }) => {
await page.goto(urls.wallet, { waitUntil: 'domcontentloaded' })
await page.waitForTimeout(5000)
const title = await page.title()
expect(title.length).toBeGreaterThan(0)
await snap(page, 'wallet-ui')
})
})
// ── Wallet — Access / Create Flow ───────────────────────────────────
test.describe('Wallet — Access Wallet Flow', () => {
test('wallet shows access options', async ({ page }) => {
await page.goto(urls.wallet, { waitUntil: 'domcontentloaded' })
await page.waitForTimeout(5000)
// Look for wallet access UI: mnemonic, keystore, ledger options
const walletUI = page.locator(
'text=/mnemonic/i, text=/keystore/i, text=/ledger/i, text=/create/i, text=/access/i, ' +
'text=/import/i, text=/connect/i, button:has-text("Access"), button:has-text("Create")'
).first()
const visible = await walletUI.isVisible({ timeout: 10_000 }).catch(() => false)
if (visible) {
await snap(page, 'wallet-access-options')
}
expect(await page.title()).toBeTruthy()
})
test('wallet create page accessible', async ({ page }) => {
await page.goto(urls.wallet, { waitUntil: 'domcontentloaded' })
await page.waitForTimeout(3000)
// Try to find create wallet button
const createBtn = page.locator(
'a:has-text("Create"), button:has-text("Create"), a[href*="create"]'
).first()
const visible = await createBtn.isVisible({ timeout: 5_000 }).catch(() => false)
if (visible) {
await createBtn.click()
await page.waitForTimeout(3000)
await snap(page, 'wallet-create')
}
expect(await page.title()).toBeTruthy()
})
})
// ── Wallet — Network Connectivity ───────────────────────────────────
test.describe('Wallet — Network Verification', () => {
test('wallet can derive address from mnemonic (RPC test)', async ({ request }) => {
// Verify the RPC endpoint that wallet connects to is functional
const result = await rpcCall(request, urls.rpc, 'eth_getBalance', [
'0x0000000000000000000000000000000000000000', 'latest',
])
expect(result).toBeTruthy()
})
test('wallet C-Chain endpoint works', async ({ request }) => {
const result = await rpcCall(request, urls.rpc, 'eth_blockNumber')
const block = parseInt(result as string, 16)
expect(block).toBeGreaterThan(0)
})
test('wallet P-Chain endpoint works (for staking)', async ({ request }) => {
const result = await rpcCall(request, urls.rpcPlatform, 'platform.getHeight', {}) as { height: string }
console.log(` P-Chain height: ${result.height}`)
// Height >= 0 means P-Chain is responding (may be 0 during initial bootstrap)
expect(Number(result.height)).toBeGreaterThanOrEqual(0)
})
})
// ── Wallet — Cross-Chain Transfer Readiness ─────────────────────────
test.describe('Wallet — Cross-Chain Readiness', () => {
test('X-Chain is accessible for transfers', async ({ request }) => {
// info.isBootstrapped is firewalled; assert the public X-Chain RPC is served.
const status = await httpStatus(request, urls.rpcXChain)
console.log(` X-Chain RPC: HTTP ${status}`)
expect([200, 405]).toContain(status)
})
test('P-Chain is accessible for staking', async ({ request }) => {
const validators = await getCurrentValidators(request, urls.rpcPlatform)
console.log(` P-Chain validators: ${validators.length}`)
expect(validators.length).toBeGreaterThan(0)
})
})