88 lines
4.7 KiB
TypeScript
88 lines
4.7 KiB
TypeScript
/**
|
|
* Explorer Frontend E2E Tests
|
|
* Tests live SPA links, route coverage, and detail-page navigation on explorer.d-bis.org.
|
|
* Run: npx playwright test explorer-monorepo/scripts/e2e-explorer-frontend.spec.ts --project=chromium
|
|
*/
|
|
|
|
import { expect, test } from '@playwright/test'
|
|
|
|
const EXPLORER_URL = process.env.EXPLORER_URL || 'https://explorer.d-bis.org'
|
|
const ADDRESS_TEST = '0x99b3511a2d315a497c8112c1fdd8d508d4b1e506'
|
|
|
|
async function expectBodyToContain(page: Parameters<typeof test>[0], pattern: RegExp) {
|
|
const bodyText = await page.locator('body').textContent().catch(() => '') || ''
|
|
expect(bodyText).toMatch(pattern)
|
|
}
|
|
|
|
test.describe('Explorer Frontend - Path Coverage', () => {
|
|
for (const route of [
|
|
{ path: '/', matcher: /SolaceScanScout|Latest Blocks|Explorer/i },
|
|
{ path: '/blocks', matcher: /Blocks|Block/i },
|
|
{ path: '/transactions', matcher: /Transactions|Transaction/i },
|
|
{ path: '/addresses', matcher: /Addresses|Address/i },
|
|
{ path: '/watchlist', matcher: /Watchlist|Explorer/i },
|
|
{ path: '/pools', matcher: /Pools|Liquidity/i },
|
|
{ path: '/liquidity', matcher: /Liquidity|Route|Pool/i },
|
|
{ path: '/bridge', matcher: /Bridge|Explorer/i },
|
|
{ path: '/weth', matcher: /WETH|Explorer/i },
|
|
]) {
|
|
test(`${route.path} loads`, async ({ page }) => {
|
|
await page.goto(`${EXPLORER_URL}${route.path}`, { waitUntil: 'networkidle', timeout: 20000 })
|
|
await expect(page).toHaveURL(new RegExp(route.path === '/' ? '/?$' : route.path.replace('/', '\\/')), { timeout: 8000 })
|
|
await expectBodyToContain(page, route.matcher)
|
|
})
|
|
}
|
|
|
|
test('/address/:address loads address detail', async ({ page }) => {
|
|
await page.goto(`${EXPLORER_URL}/address/${ADDRESS_TEST}`, { waitUntil: 'networkidle', timeout: 20000 })
|
|
await page.waitForSelector('#addressDetailBreadcrumb', { state: 'attached', timeout: 15000 })
|
|
await expectBodyToContain(page, /Address|Balance|Transaction|Explorer/i)
|
|
})
|
|
})
|
|
|
|
test.describe('Explorer Frontend - Nav and Detail Links', () => {
|
|
test('MetaMask Snap link is present', async ({ page }) => {
|
|
await page.goto(EXPLORER_URL, { waitUntil: 'domcontentloaded', timeout: 20000 })
|
|
const snapLink = page.locator('a[href="/snap/"]').first()
|
|
await expect(snapLink).toBeVisible({ timeout: 8000 })
|
|
await expect(snapLink).toHaveAttribute('href', '/snap/')
|
|
})
|
|
|
|
test('Address breadcrumb home link returns to root', async ({ page }) => {
|
|
await page.goto(`${EXPLORER_URL}/address/${ADDRESS_TEST}`, { waitUntil: 'networkidle', timeout: 20000 })
|
|
await page.waitForSelector('#addressDetailView.active #addressDetailBreadcrumb', { state: 'visible', timeout: 15000 })
|
|
const homeLink = page.locator('#addressDetailView.active #addressDetailBreadcrumb a[href="/"]').first()
|
|
await expect(homeLink).toBeVisible({ timeout: 8000 })
|
|
await homeLink.click()
|
|
await expect(page).toHaveURL(new RegExp(`${EXPLORER_URL.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/?$`), { timeout: 8000 })
|
|
})
|
|
|
|
test('Blocks list opens block detail view', async ({ page }) => {
|
|
await page.goto(`${EXPLORER_URL}/blocks`, { waitUntil: 'networkidle', timeout: 20000 })
|
|
const blockLink = page.locator('#blocksList tbody tr:first-child td:first-child a').first()
|
|
await expect(blockLink).toBeVisible({ timeout: 8000 })
|
|
await blockLink.click()
|
|
await expect(page).toHaveURL(/\/block\/\d+/, { timeout: 8000 })
|
|
await expect(page.locator('#blockDetailView.active #blockDetailBreadcrumb')).toBeVisible({ timeout: 8000 })
|
|
})
|
|
|
|
test('Transactions list opens transaction detail view', async ({ page }) => {
|
|
await page.goto(`${EXPLORER_URL}/transactions`, { waitUntil: 'networkidle', timeout: 20000 })
|
|
const transactionLink = page.locator('#transactionsList tbody tr:first-child td:first-child a').first()
|
|
await expect(transactionLink).toBeVisible({ timeout: 8000 })
|
|
await transactionLink.click()
|
|
await expect(page).toHaveURL(/\/tx\/0x[a-f0-9]+/i, { timeout: 8000 })
|
|
await expect(page.locator('#transactionDetailView.active #transactionDetailBreadcrumb')).toBeVisible({ timeout: 8000 })
|
|
})
|
|
|
|
test('Addresses list opens address detail view', async ({ page }) => {
|
|
await page.goto(`${EXPLORER_URL}/addresses`, { waitUntil: 'networkidle', timeout: 20000 })
|
|
const addressLink = page.locator('#addressesList tbody tr:first-child td:first-child a').first()
|
|
await expect(addressLink).toBeVisible({ timeout: 8000 })
|
|
await expect(page.locator('#addressesList tbody tr').first()).not.toContainText('N/A')
|
|
await addressLink.click()
|
|
await expect(page).toHaveURL(/\/address\/0x[a-f0-9]+/i, { timeout: 8000 })
|
|
await expect(page.locator('#addressDetailView.active #addressDetailBreadcrumb')).toBeVisible({ timeout: 8000 })
|
|
})
|
|
})
|