Add all-in-one desktop wallet with extensive feature set: Infrastructure: - Storage: IPFS-based decentralized file storage with upload/download - Hosting: Domain registration and static site hosting - Compute: GPU/CPU job marketplace for distributed computing - Database: Multi-model database services (KV, Document, Vector, etc.) Financial Features: - Privacy: Confidential transactions with Pedersen commitments - Bridge: Cross-chain transfers (Ethereum, Bitcoin, IBC/Cosmos) - Governance: DAO proposals, voting, and delegation - ZK-Rollup: L2 scaling with deposits, withdrawals, and transfers UI/UX Improvements: - Add ErrorBoundary component for graceful error handling - Add LoadingStates components (spinners, skeletons, overlays) - Add Animation components (FadeIn, SlideIn, CountUp, etc.) - Update navigation with new feature sections Testing: - Add Playwright E2E smoke tests - Test route accessibility and page rendering - Verify build process and asset loading Build: - Fix TypeScript compilation errors - Update Tauri plugin dependencies - Successfully build macOS app bundle and DMG
150 lines
4.2 KiB
TypeScript
150 lines
4.2 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
/**
|
|
* Smoke tests for Synor Desktop Wallet
|
|
*
|
|
* These tests verify the development server is running and serving content.
|
|
* Note: Full E2E testing of Tauri features requires running the complete
|
|
* Tauri application with the Rust backend.
|
|
*
|
|
* For comprehensive E2E testing, use:
|
|
* pnpm tauri:dev (to run full app)
|
|
*
|
|
* These smoke tests verify:
|
|
* - Dev server responds
|
|
* - HTML content is served
|
|
* - React app bundles load
|
|
*/
|
|
|
|
test.describe('Smoke Tests', () => {
|
|
test('dev server should respond', async ({ page }) => {
|
|
const response = await page.goto('/');
|
|
expect(response?.status()).toBe(200);
|
|
});
|
|
|
|
test('should serve HTML content', async ({ page }) => {
|
|
await page.goto('/');
|
|
const html = await page.content();
|
|
// Should have basic HTML structure
|
|
expect(html).toContain('<!DOCTYPE html>');
|
|
expect(html).toContain('<html');
|
|
expect(html).toContain('</html>');
|
|
});
|
|
|
|
test('should have root element for React', async ({ page }) => {
|
|
await page.goto('/');
|
|
const html = await page.content();
|
|
// Should have React root element
|
|
expect(html).toContain('id="root"');
|
|
});
|
|
|
|
test('should load JavaScript bundles', async ({ page }) => {
|
|
await page.goto('/');
|
|
const html = await page.content();
|
|
// Should include script tags
|
|
expect(html).toContain('<script');
|
|
expect(html).toContain('type="module"');
|
|
});
|
|
|
|
test('should load CSS', async ({ page }) => {
|
|
await page.goto('/');
|
|
const html = await page.content();
|
|
// Should include styles (either link stylesheet or style tag)
|
|
const hasStylesheet = html.includes('stylesheet') || html.includes('<style');
|
|
expect(hasStylesheet).toBe(true);
|
|
});
|
|
|
|
test('should have correct title', async ({ page }) => {
|
|
await page.goto('/');
|
|
const title = await page.title();
|
|
// Should have a title set
|
|
expect(title.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test('all routes should return 200', async ({ page }) => {
|
|
const routes = [
|
|
'/',
|
|
'/setup',
|
|
'/dashboard',
|
|
'/send',
|
|
'/receive',
|
|
'/history',
|
|
'/node',
|
|
'/mining',
|
|
'/staking',
|
|
'/swap',
|
|
'/market',
|
|
'/contracts',
|
|
'/tokens',
|
|
'/nfts',
|
|
'/settings',
|
|
'/storage',
|
|
'/hosting',
|
|
'/compute',
|
|
'/database',
|
|
'/privacy',
|
|
'/bridge',
|
|
'/governance',
|
|
'/zk',
|
|
];
|
|
|
|
for (const route of routes) {
|
|
const response = await page.goto(route);
|
|
expect(response?.status(), `Route ${route} should return 200`).toBe(200);
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Build Verification', () => {
|
|
test('should load without unexpected JavaScript errors', async ({ page }) => {
|
|
const errors: string[] = [];
|
|
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error') {
|
|
const text = msg.text();
|
|
// Ignore expected errors when running outside Tauri context:
|
|
// - Tauri API errors (__TAURI__, invoke, etc.)
|
|
// - React error boundary messages (expected when components fail without Tauri)
|
|
// - Window property checks
|
|
const isExpectedError =
|
|
text.includes('__TAURI__') ||
|
|
text.includes('tauri') ||
|
|
text.includes('invoke') ||
|
|
text.includes('window.') ||
|
|
text.includes('error boundary') ||
|
|
text.includes('Error occurred in') ||
|
|
text.includes('TitleBar') ||
|
|
text.includes('getCurrentWindow');
|
|
|
|
if (!isExpectedError) {
|
|
errors.push(text);
|
|
}
|
|
}
|
|
});
|
|
|
|
await page.goto('/');
|
|
await page.waitForTimeout(2000); // Wait for async operations
|
|
|
|
// Log any errors found for debugging
|
|
if (errors.length > 0) {
|
|
console.log('Unexpected console errors found:', errors);
|
|
}
|
|
|
|
// Should have no unexpected errors
|
|
expect(errors).toHaveLength(0);
|
|
});
|
|
|
|
test('should not have network failures for static assets', async ({ page }) => {
|
|
const failedRequests: string[] = [];
|
|
|
|
page.on('requestfailed', (request) => {
|
|
failedRequests.push(`${request.url()} - ${request.failure()?.errorText}`);
|
|
});
|
|
|
|
await page.goto('/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Should have no failed requests
|
|
expect(failedRequests).toHaveLength(0);
|
|
});
|
|
});
|