Skip to content
Merged
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
30 changes: 20 additions & 10 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,36 @@ REACT_APP_API_URL=http://localhost:3000 # Local API
# REACT_APP_API_URL=https://api.dfx.swiss # Production API

# === E2E Test Configuration ===
# These are only needed when running Playwright tests
# All variables below are REQUIRED when running Playwright tests

# Test wallet mnemonic (NEVER use for real funds!)
TEST_SEED="your twelve word test seed phrase here"
TEST_SEED="below debris olive author enhance ankle drum angle buyer cruel school milk"

# Second test wallet for dual-wallet/gasless tests
TEST_SEED_2="your second twelve word test seed phrase here"

# Test IBAN for sell/refund operations
TEST_IBAN=CH9300762011623852957

# Test email for mail login flow
TEST_EMAIL=your-test-email@example.com

# Test addresses for signature-based login (derived from test seed)
TEST_ADDRESS_1=0x...
TEST_SIGNATURE_1=0x...
TEST_ADDRESS_2=0x...
TEST_SIGNATURE_2=0x...
# Test addresses for signature-based login (derived from TEST_SEED)
# Generate these by running: npx ts-node e2e/scripts/generate-signatures.ts
TEST_ADDRESS_1=0xd3AD44Bda0158567461D6FA7eC39E53534e686E9
TEST_SIGNATURE_1=0x9f2ab17b008d42b29e085210020962beb0758091866598b7a1a54295d1dec7fa56a6425bd491d31707ef3ee97f6479450a56210ae7408a5c2efde806ac50cf481b
TEST_ADDRESS_2=0xB18f08332eD99e0FBee29B2E09Be166B58e6083b
TEST_SIGNATURE_2=0x76cc51c74e84ad3eb0ca1cfde3465d0621292bf6e4edfa3cf40d0dc715e111d7304fbeaddcfe4df2426e6f101c2b2509301579e93857076a1b3ad32843e23aa91c

# Transaction IDs for refund tests
TEST_TX_ID=11
BUY_CRYPTO_TX_ID=4

# Dev environment URL for E2E tests
DEV_BASE_URL=https://dev.app.dfx.swiss
# Lightning.space API URL
LIGHTNING_API_URL=https://lightning.space/v1

# === Widget Build (optional) ===
# === Widget Build (optional - DO NOT enable for local dev!) ===
# These break the dev server! Only use for production widget builds.
# BUILD_PATH=./widget
# GENERATE_SOURCEMAP=false
# CUSTOM_CHUNK_PATH=/widget/
6 changes: 3 additions & 3 deletions .github/workflows/pr-review-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ jobs:
comments.push(`## ❌ TypeScript: ${tscErrors} errors`);
}

// Security audit
if (auditCritical > 0 || auditHigh > 0) {
comments.push(`## ${auditCritical > 0 ? '❌' : '⚠️'} Security: ${auditCritical} critical, ${auditHigh} high vulnerabilities`);
// Security audit (only report critical vulnerabilities)
if (auditCritical > 0) {
comments.push(`## Security: ${auditCritical} critical vulnerabilities`);
}

// New TODOs
Expand Down
4 changes: 2 additions & 2 deletions e2e/api-timing-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const __dirname = path.dirname(__filename);

dotenv.config({ path: path.join(__dirname, '../.env') });

const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:3000';
const TEST_SEED = process.env.TEST_SEED || '';
const API_URL = process.env.REACT_APP_API_URL!;
const TEST_SEED = process.env.TEST_SEED!;

async function main() {
console.log('=== API Timing Test ===\n');
Expand Down
8 changes: 2 additions & 6 deletions e2e/api/test-gasless-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ import path from 'path';

dotenv.config({ path: path.join(process.cwd(), '.env.test') });

const API_URL = process.env.API_URL || 'http://localhost:3000';
const TEST_SEED = process.env.TEST_SEED_2 || '';
const API_URL = process.env.API_URL!;
const TEST_SEED = process.env.TEST_SEED_2!;

async function test() {
if (!TEST_SEED) {
console.error('ERROR: TEST_SEED_2 not set in .env.test');
process.exit(1);
}

const wallet = ethers.Wallet.fromPhrase(TEST_SEED);
console.log('=== Test Gasless API Response ===');
Expand Down
2 changes: 1 addition & 1 deletion e2e/buy-crypto-fail-refund.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getCachedAuth } from './helpers/auth-cache';
* - BUY_CRYPTO_FAIL: Failed buy crypto transaction (e.g., AML check failed)
*/

const TEST_TX_ID = process.env.BUY_CRYPTO_TX_ID || '4';
const TEST_TX_ID = process.env.BUY_CRYPTO_TX_ID!;

test.describe('BuyCrypto FAIL Refund Flow - Complete E2E Test', () => {
let token: string;
Expand Down
2 changes: 1 addition & 1 deletion e2e/compliance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { createTestCredentials } from './test-wallet';
const TEST_USER_DATA_ID = '1005';
const TEST_SEARCH_QUERY = 'max';

const API_URL = (process.env.REACT_APP_API_URL || 'http://localhost:3000') + '/v1';
const API_URL = process.env.REACT_APP_API_URL! + '/v1';

/**
* Read ADMIN_SEED from the API .env file
Expand Down
18 changes: 9 additions & 9 deletions e2e/debug-session-switch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,33 @@ import { test, expect } from '@playwright/test';
/**
* Test: Session switch when logging in with different address
*
* Required env vars: TEST_ADDRESS_1, TEST_SIGNATURE_1, TEST_ADDRESS_2, TEST_SIGNATURE_2, DEV_BASE_URL
* Required env vars: TEST_ADDRESS_1, TEST_SIGNATURE_1, TEST_ADDRESS_2, TEST_SIGNATURE_2, REACT_APP_PUBLIC_URL
*/

const TEST_ADDRESS_1 = process.env.TEST_ADDRESS_1 || '';
const TEST_SIGNATURE_1 = process.env.TEST_SIGNATURE_1 || '';
const TEST_ADDRESS_2 = process.env.TEST_ADDRESS_2 || '';
const TEST_SIGNATURE_2 = process.env.TEST_SIGNATURE_2 || '';
const DEV_BASE_URL = process.env.DEV_BASE_URL || 'https://dev.app.dfx.swiss';
const TEST_ADDRESS_1 = process.env.TEST_ADDRESS_1!;
const TEST_SIGNATURE_1 = process.env.TEST_SIGNATURE_1!;
const TEST_ADDRESS_2 = process.env.TEST_ADDRESS_2!;
const TEST_SIGNATURE_2 = process.env.TEST_SIGNATURE_2!;
const BASE_URL = process.env.REACT_APP_PUBLIC_URL!;

test('Session switch when logging in with different address', async ({ page, context }) => {
// Clear cookies/storage to start fresh
await context.clearCookies();
await page.goto(DEV_BASE_URL);
await page.goto(BASE_URL);
await page.evaluate(() => {
localStorage.clear();
sessionStorage.clear();
});

// Login with Account 1
await page.goto(DEV_BASE_URL + '/account?address=' + TEST_ADDRESS_1 + '&signature=' + TEST_SIGNATURE_1);
await page.goto(BASE_URL + '/account?address=' + TEST_ADDRESS_1 + '&signature=' + TEST_SIGNATURE_1);
await page.waitForLoadState('networkidle');
await page.waitForTimeout(3000);

await page.screenshot({ path: 'e2e/screenshots/bug-session-1-account1.png', fullPage: true });

// Now login with Account 2
await page.goto(DEV_BASE_URL + '/account?address=' + TEST_ADDRESS_2 + '&signature=' + TEST_SIGNATURE_2);
await page.goto(BASE_URL + '/account?address=' + TEST_ADDRESS_2 + '&signature=' + TEST_SIGNATURE_2);
await page.waitForLoadState('networkidle');
await page.waitForTimeout(3000);

Expand Down
20 changes: 10 additions & 10 deletions e2e/dev-account-screenshots.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { test, expect, Page } from '@playwright/test';

/**
* E2E Test: Account page screenshots on dev environment
* E2E Test: Account page screenshots
*
* Takes screenshots of account pages for two test addresses on dev.app.dfx.swiss
* Takes screenshots of account pages for two test addresses
*
* Required env vars: TEST_ADDRESS_1, TEST_SIGNATURE_1, TEST_ADDRESS_2, TEST_SIGNATURE_2, DEV_BASE_URL
* Required env vars: TEST_ADDRESS_1, TEST_SIGNATURE_1, TEST_ADDRESS_2, TEST_SIGNATURE_2, REACT_APP_PUBLIC_URL
*/

const TEST_ADDRESS_1 = process.env.TEST_ADDRESS_1 || '';
const TEST_SIGNATURE_1 = process.env.TEST_SIGNATURE_1 || '';
const TEST_ADDRESS_2 = process.env.TEST_ADDRESS_2 || '';
const TEST_SIGNATURE_2 = process.env.TEST_SIGNATURE_2 || '';
const DEV_BASE_URL = process.env.DEV_BASE_URL || 'https://dev.app.dfx.swiss';
const TEST_ADDRESS_1 = process.env.TEST_ADDRESS_1!;
const TEST_SIGNATURE_1 = process.env.TEST_SIGNATURE_1!;
const TEST_ADDRESS_2 = process.env.TEST_ADDRESS_2!;
const TEST_SIGNATURE_2 = process.env.TEST_SIGNATURE_2!;
const BASE_URL = process.env.REACT_APP_PUBLIC_URL!;

async function waitForAppLoaded(page: Page, timeout = 30000): Promise<void> {
await page.waitForFunction(
Expand All @@ -31,7 +31,7 @@ async function waitForAppLoaded(page: Page, timeout = 30000): Promise<void> {
test.describe('Dev Account Screenshots', () => {
test('capture account pages for both test addresses', async ({ page }) => {
// Account 1
await page.goto(`${DEV_BASE_URL}/account?address=${TEST_ADDRESS_1}&signature=${TEST_SIGNATURE_1}`);
await page.goto(`${BASE_URL}/account?address=${TEST_ADDRESS_1}&signature=${TEST_SIGNATURE_1}`);
await page.waitForLoadState('networkidle');
await waitForAppLoaded(page);
await page.screenshot({ path: 'e2e/screenshots/dev-account-1.png', fullPage: true });
Expand All @@ -40,7 +40,7 @@ test.describe('Dev Account Screenshots', () => {
expect(bodyText1).toContain('konto');

// Account 2
await page.goto(`${DEV_BASE_URL}/account?address=${TEST_ADDRESS_2}&signature=${TEST_SIGNATURE_2}`);
await page.goto(`${BASE_URL}/account?address=${TEST_ADDRESS_2}&signature=${TEST_SIGNATURE_2}`);
await page.waitForLoadState('networkidle');
await waitForAppLoaded(page);
await page.screenshot({ path: 'e2e/screenshots/dev-account-2.png', fullPage: true });
Expand Down
4 changes: 2 additions & 2 deletions e2e/helpers/auth-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import {
dotenv.config({ path: path.join(__dirname, '../../.env') });

// Use same API URL as the React app (add /v1 path for API calls)
const API_URL = (process.env.REACT_APP_API_URL || 'http://localhost:3000') + '/v1';
const API_URL = process.env.REACT_APP_API_URL! + '/v1';

// Lightning.space API URL for Lightning authentication (prod works, dev has internal SSL issues)
const LIGHTNING_API_URL = process.env.LIGHTNING_API_URL || 'https://lightning.space/v1';
const LIGHTNING_API_URL = process.env.LIGHTNING_API_URL!;

// Global cache for auth tokens to avoid rate limiting
const tokenCache: Map<string, { token: string; expiry: number; lightningAddress?: string }> = new Map();
Expand Down
5 changes: 1 addition & 4 deletions e2e/mail-buy-email-button.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { test } from '@playwright/test';

const TEST_EMAIL = process.env.TEST_EMAIL || '';
const TEST_EMAIL = process.env.TEST_EMAIL!;

test('Send new login email', async ({ page }) => {
if (!TEST_EMAIL) {
throw new Error('TEST_EMAIL environment variable is required');
}

await page.goto('https://dev.app.dfx.swiss/login/mail');
await page.waitForLoadState('networkidle');
Expand Down
5 changes: 1 addition & 4 deletions e2e/mail-login-manual.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { test } from '@playwright/test';

const TEST_EMAIL = process.env.TEST_EMAIL || '';
const TEST_EMAIL = process.env.TEST_EMAIL!;

test('Manual Mail Login Flow', async ({ page }) => {
if (!TEST_EMAIL) {
throw new Error('TEST_EMAIL environment variable is required');
}

// Step 1: Go to mail login page
await page.goto('/login/mail');
Expand Down
7 changes: 1 addition & 6 deletions e2e/mail-login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as dotenv from 'dotenv';
// Load test environment variables
dotenv.config({ path: '.env' });

const TEST_EMAIL = process.env.TEST_EMAIL;
const TEST_EMAIL = process.env.TEST_EMAIL!;

// Helper to remove webpack error overlay (appears due to TS errors in dev mode)
async function removeErrorOverlay(page: Page) {
Expand All @@ -15,11 +15,6 @@ async function removeErrorOverlay(page: Page) {
}

test.describe('Mail Login Flow', () => {
test.beforeEach(async () => {
if (!TEST_EMAIL) {
throw new Error('TEST_EMAIL not set in .env');
}
});

test('should load mail login page', async ({ page }) => {
await page.goto('/login/mail');
Expand Down
5 changes: 1 addition & 4 deletions e2e/mail-only-test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@ import { test } from '@playwright/test';
// WICHTIG: Dieser Test verwendet AUSSCHLIESSLICH Mail-Login (OTP)
// KEINE Wallet-Authentifizierung erlaubt!

const TEST_EMAIL = process.env.TEST_EMAIL || '';
const TEST_EMAIL = process.env.TEST_EMAIL!;

test.describe('Mail-Only Login Tests', () => {
test('Step 1: Send login email', async ({ page }) => {
if (!TEST_EMAIL) {
throw new Error('TEST_EMAIL environment variable is required');
}

await page.goto('https://dev.app.dfx.swiss/login/mail');
await page.waitForLoadState('networkidle');
Expand Down
5 changes: 1 addition & 4 deletions e2e/mail-send-new.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { test } from '@playwright/test';

const TEST_EMAIL = process.env.TEST_EMAIL || '';
const TEST_EMAIL = process.env.TEST_EMAIL!;

test('Send new mail login', async ({ page }) => {
if (!TEST_EMAIL) {
throw new Error('TEST_EMAIL environment variable is required');
}

await page.goto('/login/mail');
await page.waitForLoadState('networkidle');
Expand Down
4 changes: 2 additions & 2 deletions e2e/refund-creditor-full-flow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getCachedAuth } from './helpers/auth-cache';
* that the creditor data flow works correctly end-to-end.
*/

const TEST_TX_ID = process.env.TEST_TX_ID || 'T11';
const TEST_TX_ID = process.env.TEST_TX_ID!;
const SCREENSHOT_DIR = 'e2e/test-results/full-flow-screenshots';

test.describe('Bank Refund - Complete Visual Flow', () => {
Expand All @@ -17,7 +17,7 @@ test.describe('Bank Refund - Complete Visual Flow', () => {
test.beforeAll(async ({ request }) => {
const auth = await getCachedAuth(request, 'evm');
token = auth.token;
console.log(`API: ${process.env.E2E_API_URL || 'dev.api.dfx.swiss'}`);
console.log(`API: ${process.env.REACT_APP_API_URL}`);
console.log(`Transaction: ${TEST_TX_ID}`);
});

Expand Down
2 changes: 1 addition & 1 deletion e2e/refund-flow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { getCachedAuth } from './helpers/auth-cache';
* 7. Verify status changes to "Return pending"
*/

const TEST_TX_ID = process.env.TEST_TX_ID || '11';
const TEST_TX_ID = process.env.TEST_TX_ID!;

test.describe('Bank Refund Flow - Complete E2E Test', () => {
let token: string;
Expand Down
2 changes: 1 addition & 1 deletion e2e/refund-submit-complete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getCachedAuth } from './helpers/auth-cache';
* from the original bank transaction, not as input fields.
*/

const TEST_TX_ID = process.env.TEST_TX_ID || '11';
const TEST_TX_ID = process.env.TEST_TX_ID!;
const SCREENSHOT_DIR = 'e2e/test-results/refund-fixed-display';

test.describe('Bank Refund - Fixed Display Flow', () => {
Expand Down
8 changes: 4 additions & 4 deletions e2e/signature-login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { test, expect, Page } from '@playwright/test';
* Required env vars: TEST_ADDRESS_1, TEST_SIGNATURE_1, TEST_ADDRESS_2, TEST_SIGNATURE_2
*/

const TEST_ADDRESS_1 = process.env.TEST_ADDRESS_1 || '';
const TEST_SIGNATURE_1 = process.env.TEST_SIGNATURE_1 || '';
const TEST_ADDRESS_2 = process.env.TEST_ADDRESS_2 || '';
const TEST_SIGNATURE_2 = process.env.TEST_SIGNATURE_2 || '';
const TEST_ADDRESS_1 = process.env.TEST_ADDRESS_1!;
const TEST_SIGNATURE_1 = process.env.TEST_SIGNATURE_1!;
const TEST_ADDRESS_2 = process.env.TEST_ADDRESS_2!;
const TEST_SIGNATURE_2 = process.env.TEST_SIGNATURE_2!;

// Helper to remove webpack error overlay
async function removeErrorOverlay(page: Page) {
Expand Down
2 changes: 1 addition & 1 deletion e2e/swap-bitcoin-to-lightning.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test.describe('Swap Bitcoin to Lightning', () => {
await getLinkedLightningAuth(apiContext, bitcoinAuth.token);

// Navigate to swap with Bitcoin as source and Lightning as target
const baseUrl = process.env.E2E_BASE_URL ?? 'https://dev.app.dfx.swiss';
const baseUrl = process.env.REACT_APP_PUBLIC_URL!;
const url = `${baseUrl}/swap?session=${bitcoinAuth.token}&asset-in=Bitcoin/BTC&asset-out=Lightning/BTC&amount-in=0.001`;
await page.goto(url);

Expand Down
2 changes: 1 addition & 1 deletion e2e/swap-lightning-to-bitcoin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test.describe('Swap Lightning to Bitcoin Onchain', () => {
await getLinkedLightningAuth(apiContext, bitcoinAuth.token);

// Navigate to swap with Lightning as source and Bitcoin Onchain as target
const baseUrl = process.env.E2E_BASE_URL ?? 'https://dev.app.dfx.swiss';
const baseUrl = process.env.REACT_APP_PUBLIC_URL!;
const url = `${baseUrl}/swap?session=${bitcoinAuth.token}&asset-in=Lightning/BTC&asset-out=Bitcoin/BTC&amount-in=0.001`;
await page.goto(url);

Expand Down
2 changes: 1 addition & 1 deletion e2e/synpress/custom-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const METAMASK_PATH = path.join(process.cwd(), '.cache-synpress/metamask-chrome-

// Test wallet credentials from environment
const WALLET_PASSWORD = 'Tester@1234';
const TEST_SEED_PHRASE = process.env.TEST_SEED || 'test test test test test test test test test test test junk';
const TEST_SEED_PHRASE = process.env.TEST_SEED!;

// Derivation paths
export const EVM_DERIVATION_PATH_WALLET1 = ''; // Default (no derivation, direct from seed)
Expand Down
7 changes: 5 additions & 2 deletions e2e/synpress/eip5792-basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

import { testWithSynpress, defineWalletSetup } from '@synthetixio/synpress';
import { MetaMask, metaMaskFixtures } from '@synthetixio/synpress/playwright';
import * as dotenv from 'dotenv';
import path from 'path';

dotenv.config({ path: path.join(__dirname, '../../.env') });

// Define wallet setup inline to ensure hash matches
const WALLET_PASSWORD = 'Tester@1234';
const TEST_SEED_PHRASE = 'test test test test test test test test test test test junk';
const TEST_SEED_PHRASE = process.env.TEST_SEED!;

const walletSetup = defineWalletSetup(WALLET_PASSWORD, async (context, walletPage) => {
const metamask = new MetaMask(context, walletPage, WALLET_PASSWORD);
Expand Down
3 changes: 0 additions & 3 deletions e2e/synpress/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ export const testWithMetaMask = test.extend<{ metamask: MetaMask }>({

export const { expect } = test;

// Test wallet address (first account from Hardhat's default seed phrase)
export const TEST_WALLET_ADDRESS = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';

// Chain configurations for multi-chain testing
export const SUPPORTED_CHAINS = [
{ name: 'Ethereum', chainId: 1, chainHex: '0x1' },
Expand Down
Loading
Loading