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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ dist/
.env.*
reference/
*.local
playwright-report/
test-results/
73 changes: 73 additions & 0 deletions e2e/payment-link.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { test, expect } from '@playwright/test';

test.describe('Stellar Payment Link', () => {
test.beforeEach(async ({ context }) => {
// Mock Freighter API so the app thinks a wallet is installed and connected
await context.addInitScript(() => {
(window as any).freighter = {
isConnected: () => Promise.resolve({ isConnected: true }),
getAddress: () => Promise.resolve({ address: 'GATTESTADDRESSYOURSFREIGHTER123456789' }),
requestAccess: () => Promise.resolve(),
};
(window as any).freighterApi = (window as any).freighter; // Some versions use freighterApi
});
});

test('should generate a link, pre-fill the send form, and disable inputs', async ({ page, context }) => {
// 1. Go to Receive page
await page.goto('/receive');
await page.locator('select').selectOption('stellar');

// 2. Open generated link in a new context
const testUrl = '/pay?to=st:xlm:test_meta_address&amount=15.5&memo=TestMemo&exp=' + (Math.floor(Date.now() / 1000) + 3600);

const newPage = await context.newPage();
await newPage.goto(testUrl);

// Switch to Stellar network
await newPage.locator('select').selectOption('stellar');

// Click Connect Freighter
await newPage.click('text=Connect Freighter');

// 3. Verify Send page pre-filled inputs
const recipientInput = newPage.locator('input[placeholder="st:xlm:..."]');
await expect(recipientInput).toHaveValue('st:xlm:test_meta_address');
await expect(recipientInput).toBeDisabled();

const amountInput = newPage.locator('input[placeholder="0.0"]');
await expect(amountInput).toHaveValue('15.5');
await expect(amountInput).toBeDisabled();

const memoInput = newPage.locator('input[placeholder="e.g. Coffee"]');
await expect(memoInput).toHaveValue('TestMemo');
await expect(memoInput).toBeDisabled();
});

test('should show expiration error and disable submit for expired link', async ({ page }) => {
const expiredExp = Math.floor(Date.now() / 1000) - 3600; // 1 hour ago
const testUrl = `/pay?to=st:xlm:test_meta_address&amount=10&exp=${expiredExp}`;

await page.goto(testUrl);

// Switch to Stellar network
await page.locator('select').selectOption('stellar');

// Click Connect Freighter
await page.click('text=Connect Freighter');

// Check for error message
const errorText = page.locator('text=This payment link has expired');
await expect(errorText).toBeVisible();

// The recipient and amount should still be pre-filled and disabled
const recipientInput = page.locator('input[placeholder="st:xlm:..."]');
await expect(recipientInput).toHaveValue('st:xlm:test_meta_address');
await expect(recipientInput).toBeDisabled();

// Verify submit button is disabled
const submitButton = page.locator('button:has-text("Send Privately")');
// Button might also say "Confirm in wallet..." but the text says "Send Privately" initially
await expect(submitButton).toBeDisabled();
});
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@wraith-protocol/sdk": "^1.4.5",
"bs58": "^6.0.0",
"buffer": "^6.0.3",
"qrcode.react": "^4.2.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.6.0",
Expand All @@ -37,6 +38,8 @@
"devDependencies": {
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0",
"@playwright/test": "^1.60.0",
"@types/node": "^25.9.1",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.5.0",
Expand Down
25 changes: 25 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:5173',
trace: 'on-first-retry',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:5173',
reuseExistingServer: !process.env.CI,
},
});
Loading