refactor: consolidate blockchain explorer into single app and update backup ignore patterns
- Remove standalone explorer-web app (README, HTML, package files) - Add /web endpoint to blockchain-explorer for web interface access - Update .gitignore to exclude application backup archives (*.tar.gz, *.zip) - Add backup documentation files to .gitignore (BACKUP_INDEX.md, README.md) - Consolidate explorer functionality into main blockchain-explorer application
This commit is contained in:
288
apps/marketplace/e2e/bounty-board.spec.ts
Normal file
288
apps/marketplace/e2e/bounty-board.spec.ts
Normal file
@@ -0,0 +1,288 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Bounty Board', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
test('should display bounty board page correctly', async ({ page }) => {
|
||||
// Navigate to bounty board
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check page title and header
|
||||
await expect(page.locator('h1')).toContainText('Bounty Board');
|
||||
await expect(page.locator('text=Developer Ecosystem')).toBeVisible();
|
||||
|
||||
// Check navigation is active
|
||||
await expect(page.locator('button:has-text("Bounty Board")')).toHaveClass(/variant=default/);
|
||||
});
|
||||
|
||||
test('should display bounty statistics cards', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check stats cards are present
|
||||
await expect(page.locator('text=Active Bounties')).toBeVisible();
|
||||
await expect(page.locator('text=Total Value')).toBeVisible();
|
||||
await expect(page.locator('text=Completed Today')).toBeVisible();
|
||||
await expect(page.locator('text=My Earnings')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display bounty filters', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check filter elements
|
||||
await expect(page.locator('input[placeholder*="Search"]')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Filter")')).toBeVisible();
|
||||
|
||||
// Check status filter dropdown
|
||||
await page.click('button:has-text("Status")');
|
||||
await expect(page.locator('text=Active')).toBeVisible();
|
||||
await expect(page.locator('text=Completed')).toBeVisible();
|
||||
await expect(page.locator('text=Expired')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display bounty list', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Wait for bounties to load
|
||||
await page.waitForSelector('[data-testid="bounty-list"]', { timeout: 10000 });
|
||||
|
||||
// Check bounty items
|
||||
const bountyItems = page.locator('[data-testid="bounty-item"]');
|
||||
const count = await bountyItems.count();
|
||||
|
||||
if (count > 0) {
|
||||
// Check first bounty has required elements
|
||||
const firstBounty = bountyItems.first();
|
||||
await expect(firstBounty.locator('[data-testid="bounty-title"]')).toBeVisible();
|
||||
await expect(firstBounty.locator('[data-testid="bounty-reward"]')).toBeVisible();
|
||||
await expect(firstBounty.locator('[data-testid="bounty-status"]')).toBeVisible();
|
||||
await expect(firstBounty.locator('[data-testid="bounty-deadline"]')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should filter bounties by status', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Wait for bounties to load
|
||||
await page.waitForSelector('[data-testid="bounty-list"]', { timeout: 10000 });
|
||||
|
||||
// Get initial count
|
||||
const initialBounties = page.locator('[data-testid="bounty-item"]');
|
||||
const initialCount = await initialBounties.count();
|
||||
|
||||
if (initialCount > 0) {
|
||||
// Filter by active status
|
||||
await page.click('button:has-text("Status")');
|
||||
await page.click('text=Active');
|
||||
|
||||
// Wait for filter to apply
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Check filtered results
|
||||
const filteredBounties = page.locator('[data-testid="bounty-item"]');
|
||||
const filteredCount = await filteredBounties.count();
|
||||
|
||||
// Should have same or fewer bounties
|
||||
expect(filteredCount).toBeLessThanOrEqual(initialCount);
|
||||
}
|
||||
});
|
||||
|
||||
test('should search bounties', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Wait for bounties to load
|
||||
await page.waitForSelector('[data-testid="bounty-list"]', { timeout: 10000 });
|
||||
|
||||
// Get initial count
|
||||
const initialBounties = page.locator('[data-testid="bounty-item"]');
|
||||
const initialCount = await initialBounties.count();
|
||||
|
||||
if (initialCount > 0) {
|
||||
// Search for specific term
|
||||
await page.fill('input[placeholder*="Search"]', 'test');
|
||||
|
||||
// Wait for search to apply
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Check search results
|
||||
const searchResults = page.locator('[data-testid="bounty-item"]');
|
||||
const searchCount = await searchResults.count();
|
||||
|
||||
// Should have same or fewer bounties
|
||||
expect(searchCount).toBeLessThanOrEqual(initialCount);
|
||||
}
|
||||
});
|
||||
|
||||
test('should display bounty details modal', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Wait for bounties to load
|
||||
await page.waitForSelector('[data-testid="bounty-list"]', { timeout: 10000 });
|
||||
|
||||
const bountyItems = page.locator('[data-testid="bounty-item"]');
|
||||
const count = await bountyItems.count();
|
||||
|
||||
if (count > 0) {
|
||||
// Click on first bounty
|
||||
await bountyItems.first().click();
|
||||
|
||||
// Check modal appears
|
||||
await expect(page.locator('[data-testid="bounty-details-modal"]')).toBeVisible();
|
||||
await expect(page.locator('text=Bounty Details')).toBeVisible();
|
||||
|
||||
// Check modal content
|
||||
await expect(page.locator('[data-testid="bounty-description"]')).toBeVisible();
|
||||
await expect(page.locator('[data-testid="bounty-requirements"]')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Submit Solution")')).toBeVisible();
|
||||
|
||||
// Close modal
|
||||
await page.click('button:has-text("Close")');
|
||||
await expect(page.locator('[data-testid="bounty-details-modal"]')).not.toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should handle wallet connection', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check wallet connection button
|
||||
await expect(page.locator('button:has-text("Connect Wallet")')).toBeVisible();
|
||||
|
||||
// Click connect wallet
|
||||
await page.click('button:has-text("Connect Wallet")');
|
||||
|
||||
// Check wallet modal appears
|
||||
await expect(page.locator('[data-testid="wallet-modal"]')).toBeVisible();
|
||||
await expect(page.locator('text=Connect Wallet')).toBeVisible();
|
||||
|
||||
// Close wallet modal
|
||||
await page.keyboard.press('Escape');
|
||||
await expect(page.locator('[data-testid="wallet-modal"]')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should display bounty creation form', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check create bounty button
|
||||
await expect(page.locator('button:has-text("Create Bounty")')).toBeVisible();
|
||||
|
||||
// Click create bounty
|
||||
await page.click('button:has-text("Create Bounty")');
|
||||
|
||||
// Check form appears
|
||||
await expect(page.locator('[data-testid="create-bounty-form"]')).toBeVisible();
|
||||
await expect(page.locator('text=Create New Bounty')).toBeVisible();
|
||||
|
||||
// Check form fields
|
||||
await expect(page.locator('input[name="title"]')).toBeVisible();
|
||||
await expect(page.locator('textarea[name="description"]')).toBeVisible();
|
||||
await expect(page.locator('input[name="reward"]')).toBeVisible();
|
||||
await expect(page.locator('select[name="tier"]')).toBeVisible();
|
||||
await expect(page.locator('select[name="difficulty"]')).toBeVisible();
|
||||
|
||||
// Check form buttons
|
||||
await expect(page.locator('button:has-text("Create Bounty")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Cancel")')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should validate bounty creation form', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
await page.click('button:has-text("Create Bounty")');
|
||||
|
||||
// Try to submit empty form
|
||||
await page.click('button:has-text("Create Bounty")');
|
||||
|
||||
// Check validation errors
|
||||
await expect(page.locator('text=Title is required')).toBeVisible();
|
||||
await expect(page.locator('text=Description is required')).toBeVisible();
|
||||
await expect(page.locator('text=Reward amount is required')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle pagination', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Wait for bounties to load
|
||||
await page.waitForSelector('[data-testid="bounty-list"]', { timeout: 10000 });
|
||||
|
||||
// Check pagination controls
|
||||
const pagination = page.locator('[data-testid="pagination"]');
|
||||
const isVisible = await pagination.isVisible();
|
||||
|
||||
if (isVisible) {
|
||||
// Check page buttons
|
||||
await expect(page.locator('button:has-text("Previous")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Next")')).toBeVisible();
|
||||
|
||||
// Check page numbers
|
||||
const pageNumbers = page.locator('[data-testid="page-number"]');
|
||||
const pageCount = await pageNumbers.count();
|
||||
|
||||
if (pageCount > 1) {
|
||||
// Click next page
|
||||
await page.click('button:has-text("Next")');
|
||||
|
||||
// Wait for page to load
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Check URL or content changed
|
||||
const currentUrl = page.url();
|
||||
expect(currentUrl).toContain('page=');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('should be responsive on mobile', async ({ page }) => {
|
||||
// Set mobile viewport
|
||||
await page.setViewportSize({ width: 375, height: 667 });
|
||||
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check mobile layout
|
||||
await expect(page.locator('h1')).toContainText('Bounty Board');
|
||||
|
||||
// Check mobile navigation
|
||||
await expect(page.locator('button:has-text("☰")')).toBeVisible();
|
||||
|
||||
// Open mobile menu
|
||||
await page.click('button:has-text("☰")');
|
||||
await expect(page.locator('text=Staking')).toBeVisible();
|
||||
await expect(page.locator('text=Leaderboard')).toBeVisible();
|
||||
await expect(page.locator('text=Ecosystem')).toBeVisible();
|
||||
|
||||
// Close mobile menu
|
||||
await page.click('button:has-text("☰")');
|
||||
});
|
||||
|
||||
test('should handle loading states', async ({ page }) => {
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check loading skeleton
|
||||
await expect(page.locator('[data-testid="loading-skeleton"]')).toBeVisible();
|
||||
|
||||
// Wait for content to load
|
||||
await page.waitForSelector('[data-testid="bounty-list"]', { timeout: 10000 });
|
||||
|
||||
// Check loading skeleton is gone
|
||||
await expect(page.locator('[data-testid="loading-skeleton"]')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle error states', async ({ page }) => {
|
||||
// Mock API error
|
||||
await page.route('**/api/v1/bounties*', route => {
|
||||
route.fulfill({
|
||||
status: 500,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: 'Internal server error' })
|
||||
});
|
||||
});
|
||||
|
||||
await page.click('text=Bounty Board');
|
||||
|
||||
// Check error message
|
||||
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
|
||||
await expect(page.locator('text=Failed to load bounties')).toBeVisible();
|
||||
|
||||
// Check retry button
|
||||
await expect(page.locator('button:has-text("Retry")')).toBeVisible();
|
||||
});
|
||||
});
|
||||
351
apps/marketplace/e2e/staking-dashboard.spec.ts
Normal file
351
apps/marketplace/e2e/staking-dashboard.spec.ts
Normal file
@@ -0,0 +1,351 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Staking Dashboard', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
test('should display staking dashboard page correctly', async ({ page }) => {
|
||||
// Navigate to staking dashboard
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check page title and header
|
||||
await expect(page.locator('h1')).toContainText('Staking Dashboard');
|
||||
await expect(page.locator('text=Developer Ecosystem')).toBeVisible();
|
||||
|
||||
// Check navigation is active
|
||||
await expect(page.locator('button:has-text("Staking")')).toHaveClass(/variant=default/);
|
||||
});
|
||||
|
||||
test('should display staking overview cards', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check overview cards are present
|
||||
await expect(page.locator('text=Total Staked')).toBeVisible();
|
||||
await expect(page.locator('text=My Stakes')).toBeVisible();
|
||||
await expect(page.locator('text=Available Rewards')).toBeVisible();
|
||||
await expect(page.locator('text=Average APY')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display staking tabs', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check tab navigation
|
||||
await expect(page.locator('button:has-text("My Stakes")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Available Agents")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Staking Pools")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Rewards")')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display my stakes tab', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// My Stakes tab should be active by default
|
||||
await expect(page.locator('button:has-text("My Stakes")')).toHaveClass(/data-state=active/);
|
||||
|
||||
// Check stakes table
|
||||
await expect(page.locator('[data-testid="stakes-table"]')).toBeVisible();
|
||||
|
||||
// Check table headers
|
||||
await expect(page.locator('text=Agent')).toBeVisible();
|
||||
await expect(page.locator('text=Amount Staked')).toBeVisible();
|
||||
await expect(page.locator('text=APY')).toBeVisible();
|
||||
await expect(page.locator('text=Rewards')).toBeVisible();
|
||||
await expect(page.locator('text=Actions')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display available agents tab', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Available Agents")');
|
||||
|
||||
// Check agents list
|
||||
await expect(page.locator('[data-testid="agents-list"]')).toBeVisible();
|
||||
|
||||
// Check agent cards
|
||||
const agentCards = page.locator('[data-testid="agent-card"]');
|
||||
const count = await agentCards.count();
|
||||
|
||||
if (count > 0) {
|
||||
// Check first agent card elements
|
||||
const firstAgent = agentCards.first();
|
||||
await expect(firstAgent.locator('[data-testid="agent-name"]')).toBeVisible();
|
||||
await expect(firstAgent.locator('[data-testid="agent-performance"]')).toBeVisible();
|
||||
await expect(firstAgent.locator('[data-testid="agent-apy"]')).toBeVisible();
|
||||
await expect(firstAgent.locator('button:has-text("Stake")')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should display staking pools tab', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Staking Pools")');
|
||||
|
||||
// Check pools table
|
||||
await expect(page.locator('[data-testid="pools-table"]')).toBeVisible();
|
||||
|
||||
// Check table headers
|
||||
await expect(page.locator('text=Agent Address')).toBeVisible();
|
||||
await expect(page.locator('text=Total Staked')).toBeVisible();
|
||||
await expect(page.locator('text=Stakers')).toBeVisible();
|
||||
await expect(page.locator('text=APY')).toBeVisible();
|
||||
await expect(page.locator('text=Utilization')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display rewards tab', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Rewards")');
|
||||
|
||||
// Check rewards section
|
||||
await expect(page.locator('[data-testid="rewards-section"]')).toBeVisible();
|
||||
|
||||
// Check rewards summary
|
||||
await expect(page.locator('text=Total Earned')).toBeVisible();
|
||||
await expect(page.locator('text=Pending Rewards')).toBeVisible();
|
||||
await expect(page.locator('text=Claim History')).toBeVisible();
|
||||
|
||||
// Check claim button
|
||||
await expect(page.locator('button:has-text("Claim Rewards")')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle staking modal', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Available Agents")');
|
||||
|
||||
// Wait for agents to load
|
||||
await page.waitForSelector('[data-testid="agents-list"]', { timeout: 10000 });
|
||||
|
||||
const agentCards = page.locator('[data-testid="agent-card"]');
|
||||
const count = await agentCards.count();
|
||||
|
||||
if (count > 0) {
|
||||
// Click stake button on first agent
|
||||
await agentCards.first().locator('button:has-text("Stake")').click();
|
||||
|
||||
// Check staking modal appears
|
||||
await expect(page.locator('[data-testid="staking-modal"]')).toBeVisible();
|
||||
await expect(page.locator('text=Stake Tokens')).toBeVisible();
|
||||
|
||||
// Check modal content
|
||||
await expect(page.locator('input[name="amount"]')).toBeVisible();
|
||||
await expect(page.locator('text=Available Balance')).toBeVisible();
|
||||
await expect(page.locator('text=Estimated APY')).toBeVisible();
|
||||
|
||||
// Check modal buttons
|
||||
await expect(page.locator('button:has-text("Confirm Stake")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Cancel")')).toBeVisible();
|
||||
|
||||
// Close modal
|
||||
await page.click('button:has-text("Cancel")');
|
||||
await expect(page.locator('[data-testid="staking-modal"]')).not.toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should validate staking amount', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Available Agents")');
|
||||
|
||||
await page.waitForSelector('[data-testid="agents-list"]', { timeout: 10000 });
|
||||
|
||||
const agentCards = page.locator('[data-testid="agent-card"]');
|
||||
const count = await agentCards.count();
|
||||
|
||||
if (count > 0) {
|
||||
await agentCards.first().locator('button:has-text("Stake")').click();
|
||||
|
||||
// Try to stake without amount
|
||||
await page.click('button:has-text("Confirm Stake")');
|
||||
|
||||
// Check validation error
|
||||
await expect(page.locator('text=Amount is required')).toBeVisible();
|
||||
|
||||
// Try to stake invalid amount
|
||||
await page.fill('input[name="amount"]', '0');
|
||||
await page.click('button:has-text("Confirm Stake")');
|
||||
|
||||
// Check validation error
|
||||
await expect(page.locator('text=Amount must be greater than 0')).toBeVisible();
|
||||
|
||||
// Try to stake more than available
|
||||
await page.fill('input[name="amount"]', '999999999');
|
||||
await page.click('button:has-text("Confirm Stake")');
|
||||
|
||||
// Check validation error
|
||||
await expect(page.locator('text=Insufficient balance')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should handle unstaking', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Wait for stakes to load
|
||||
await page.waitForSelector('[data-testid="stakes-table"]', { timeout: 10000 });
|
||||
|
||||
const stakeRows = page.locator('[data-testid="stake-row"]');
|
||||
const count = await stakeRows.count();
|
||||
|
||||
if (count > 0) {
|
||||
// Click unstake button on first stake
|
||||
await stakeRows.first().locator('button:has-text("Unstake")').click();
|
||||
|
||||
// Check unstaking modal appears
|
||||
await expect(page.locator('[data-testid="unstaking-modal"]')).toBeVisible();
|
||||
await expect(page.locator('text=Unstake Tokens')).toBeVisible();
|
||||
|
||||
// Check modal content
|
||||
await expect(page.locator('text=Staked Amount')).toBeVisible();
|
||||
await expect(page.locator('text=Unstaking Period')).toBeVisible();
|
||||
await expect(page.locator('text=Early Unstaking Penalty')).toBeVisible();
|
||||
|
||||
// Check modal buttons
|
||||
await expect(page.locator('button:has-text("Confirm Unstake")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Cancel")')).toBeVisible();
|
||||
|
||||
// Close modal
|
||||
await page.click('button:has-text("Cancel")');
|
||||
await expect(page.locator('[data-testid="unstaking-modal"]')).not.toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should display agent performance metrics', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Available Agents")');
|
||||
|
||||
await page.waitForSelector('[data-testid="agents-list"]', { timeout: 10000 });
|
||||
|
||||
const agentCards = page.locator('[data-testid="agent-card"]');
|
||||
const count = await agentCards.count();
|
||||
|
||||
if (count > 0) {
|
||||
const firstAgent = agentCards.first();
|
||||
|
||||
// Check performance metrics
|
||||
await expect(firstAgent.locator('[data-testid="success-rate"]')).toBeVisible();
|
||||
await expect(firstAgent.locator('[data-testid="total-tasks"]')).toBeVisible();
|
||||
await expect(firstAgent.locator('[data-testid="average-accuracy"]')).toBeVisible();
|
||||
await expect(firstAgent.locator('[data-testid="reliability-score"]')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should handle rewards claiming', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
await page.click('button:has-text("Rewards")');
|
||||
|
||||
// Wait for rewards to load
|
||||
await page.waitForSelector('[data-testid="rewards-section"]', { timeout: 10000 });
|
||||
|
||||
// Check if there are claimable rewards
|
||||
const claimButton = page.locator('button:has-text("Claim Rewards")');
|
||||
const isDisabled = await claimButton.isDisabled();
|
||||
|
||||
if (!isDisabled) {
|
||||
// Click claim rewards
|
||||
await claimButton.click();
|
||||
|
||||
// Check confirmation modal
|
||||
await expect(page.locator('[data-testid="claim-modal"]')).toBeVisible();
|
||||
await expect(page.locator('text=Claim Rewards')).toBeVisible();
|
||||
|
||||
// Check claim details
|
||||
await expect(page.locator('text=Total Rewards')).toBeVisible();
|
||||
await expect(page.locator('text=Gas Fee')).toBeVisible();
|
||||
await expect(page.locator('text=Net Amount')).toBeVisible();
|
||||
|
||||
// Confirm claim
|
||||
await page.click('button:has-text("Confirm Claim")');
|
||||
|
||||
// Check success message
|
||||
await expect(page.locator('[data-testid="success-message"]')).toBeVisible();
|
||||
await expect(page.locator('text=Rewards claimed successfully')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should display staking statistics', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check statistics section
|
||||
await expect(page.locator('[data-testid="staking-stats"]')).toBeVisible();
|
||||
|
||||
// Check stat items
|
||||
await expect(page.locator('text=Total Value Locked')).toBeVisible();
|
||||
await expect(page.locator('text=Number of Stakers')).toBeVisible();
|
||||
await expect(page.locator('text=Average Stake Amount')).toBeVisible();
|
||||
await expect(page.locator('text=Total Rewards Distributed')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle wallet connection for staking', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check wallet connection button
|
||||
await expect(page.locator('button:has-text("Connect Wallet")')).toBeVisible();
|
||||
|
||||
// Try to stake without wallet connection
|
||||
await page.click('button:has-text("Available Agents")');
|
||||
|
||||
await page.waitForSelector('[data-testid="agents-list"]', { timeout: 10000 });
|
||||
|
||||
const agentCards = page.locator('[data-testid="agent-card"]');
|
||||
const count = await agentCards.count();
|
||||
|
||||
if (count > 0) {
|
||||
await agentCards.first().locator('button:has-text("Stake")').click();
|
||||
|
||||
// Should show wallet connection required
|
||||
await expect(page.locator('text=Connect wallet to stake')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Connect Wallet")')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('should be responsive on mobile', async ({ page }) => {
|
||||
// Set mobile viewport
|
||||
await page.setViewportSize({ width: 375, height: 667 });
|
||||
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check mobile layout
|
||||
await expect(page.locator('h1')).toContainText('Staking Dashboard');
|
||||
|
||||
// Check mobile navigation
|
||||
await expect(page.locator('button:has-text("☰")')).toBeVisible();
|
||||
|
||||
// Check mobile tabs
|
||||
await expect(page.locator('button:has-text("My Stakes")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Agents")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Pools")')).toBeVisible();
|
||||
await expect(page.locator('button:has-text("Rewards")')).toBeVisible();
|
||||
|
||||
// Check mobile table layout
|
||||
await expect(page.locator('[data-testid="mobile-stakes-table"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle loading states', async ({ page }) => {
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check loading skeleton
|
||||
await expect(page.locator('[data-testid="loading-skeleton"]')).toBeVisible();
|
||||
|
||||
// Wait for content to load
|
||||
await page.waitForSelector('[data-testid="stakes-table"]', { timeout: 10000 });
|
||||
|
||||
// Check loading skeleton is gone
|
||||
await expect(page.locator('[data-testid="loading-skeleton"]')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle error states', async ({ page }) => {
|
||||
// Mock API error
|
||||
await page.route('**/api/v1/staking/**', route => {
|
||||
route.fulfill({
|
||||
status: 500,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: 'Internal server error' })
|
||||
});
|
||||
});
|
||||
|
||||
await page.click('text=Staking');
|
||||
|
||||
// Check error message
|
||||
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
|
||||
await expect(page.locator('text=Failed to load staking data')).toBeVisible();
|
||||
|
||||
// Check retry button
|
||||
await expect(page.locator('button:has-text("Retry")')).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user