Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions e2e/tests/shared/mocked/zcash-blocks.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { BLOCK_3483400 } from "../../../../src/services/adapters/ZcashAdapter/fixtures";
import { expect, test } from "../../../fixtures/test";
import { mockZcashRpc, ZCASH } from "../../../fixtures/zcash";

/**
* Hermetic Zcash blocks list and block detail pages, served from mainnet block 3,483,400.
*/
test.describe("Zcash blocks", () => {
test("lists the latest blocks one call per block and pages to older blocks", async ({
page,
}) => {
const calls = await mockZcashRpc(page);

await page.goto(`/#/${ZCASH.networkSlug}/blocks`);

const table = page.locator("table.blocks-table");
await expect(table).toContainText("3,483,400");
await expect(table).toContainText("3,483,391");
await expect(table.locator("tbody tr")).toHaveCount(10);

const summaryHeights = calls
.filter((call) => call.method === "getblock" && call.params[1] === 1)
.map((call) => call.params[0]);
expect(summaryHeights).toContain("3483391");
expect(calls.map((call) => call.method)).not.toContain("getblockhash");

await page.getByRole("button", { name: "Older →" }).click();
await expect(page).toHaveURL(/fromBlock=3483390/);
await expect(table).toContainText("3,483,381");
});

test("shows Zcash-specific block details", async ({ page }) => {
const calls = await mockZcashRpc(page);

await page.goto(`/#/${ZCASH.networkSlug}/block/${ZCASH.tipHeight}`);

await expect(page.locator(".block-number")).toHaveText("#3,483,400");
await expect(page.getByText(BLOCK_3483400.hash)).toBeVisible();
await expect(page.getByText("t1SqwRAAdSig6dE4EBPLonAait219VmkUjP")).toBeVisible();
await expect(page.getByText("2 Sapling")).toBeVisible();
await expect(page.getByText("2 Ironwood")).toBeVisible();
await expect(page.getByTestId("zcash-value-pools")).toContainText("Value Pools After This Block");

await page.getByRole("button", { name: "+ Show More Details" }).click();
await expect(page.getByText(BLOCK_3483400.nonce)).toBeVisible();
await expect(page.getByText("Equihash Solution:")).toBeVisible();
await expect(page.getByText("Ironwood 318,976")).toBeVisible();

// Only the requested block is fetched with full transactions, by height string. The dev
// server runs React StrictMode, which can issue the same request twice.
const verboseBlockCalls = calls.filter(
(call) => call.method === "getblock" && call.params[1] === 2,
);
expect(new Set(verboseBlockCalls.map((call) => call.params[0]))).toEqual(new Set(["3483400"]));
});
});
6 changes: 6 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import {
LazyTokenDetails,
LazyTx,
LazyTxs,
LazyZcashBlock,
LazyZcashBlocks,
LazyZcashNetwork,
preloadAllRoutes,
} from "./components/LazyComponents";
Expand Down Expand Up @@ -162,8 +164,12 @@ function AppContent() {
<Route path="tbtc/mempool/:filter" element={<LazyBitcoinTx />} />
{/* Zcash Mainnet routes (must come before :networkId catch-all) */}
<Route path="zec" element={<LazyZcashNetwork />} />
<Route path="zec/blocks" element={<LazyZcashBlocks />} />
<Route path="zec/block/:filter" element={<LazyZcashBlock />} />
{/* Zcash Testnet routes */}
<Route path="tzec" element={<LazyZcashNetwork />} />
<Route path="tzec/blocks" element={<LazyZcashBlocks />} />
<Route path="tzec/block/:filter" element={<LazyZcashBlock />} />
{/* Solana Mainnet routes (must come before :networkId catch-all) */}
<Route path="sol" element={<LazySolanaNetwork />} />
<Route path="sol/slots" element={<LazySolanaSlots />} />
Expand Down
6 changes: 6 additions & 0 deletions src/components/LazyComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const BitcoinMempoolPage = lazy(() => import("./pages/bitcoin/BitcoinMempoolPage

// Lazy load page components - Zcash
const ZcashNetwork = lazy(() => import("./pages/zcash"));
const ZcashBlocksPage = lazy(() => import("./pages/zcash/ZcashBlocksPage"));
const ZcashBlockPage = lazy(() => import("./pages/zcash/ZcashBlockPage"));

// Lazy load page components - Solana
const SolanaNetwork = lazy(() => import("./pages/solana"));
Expand Down Expand Up @@ -68,6 +70,8 @@ export const LazyBitcoinTxs = withSuspense(BitcoinTransactionsPage);
export const LazyBitcoinAddress = withSuspense(BitcoinAddressPage);
export const LazyBitcoinMempool = withSuspense(BitcoinMempoolPage);
export const LazyZcashNetwork = withSuspense(ZcashNetwork);
export const LazyZcashBlocks = withSuspense(ZcashBlocksPage);
export const LazyZcashBlock = withSuspense(ZcashBlockPage);
export const LazySolanaNetwork = withSuspense(SolanaNetwork);
export const LazySolanaSlots = withSuspense(SolanaSlotsPage);
export const LazySolanaSlot = withSuspense(SolanaSlotPage);
Expand Down Expand Up @@ -115,6 +119,8 @@ export function preloadAllRoutes() {
import("./pages/bitcoin/BitcoinMempoolPage");
// Zcash pages
import("./pages/zcash");
import("./pages/zcash/ZcashBlocksPage");
import("./pages/zcash/ZcashBlockPage");
// Solana pages
import("./pages/solana");
import("./pages/solana/SolanaSlotsPage");
Expand Down
Loading
Loading