harb/tests/e2e/03-verify-graphql-url.spec.ts
johba a87eb7ed56 fix: use button role for landing CTA, revert risky test changes
Root cause: landing page CTA uses <KButton> (renders <button>), not <a>.
Test 07 was using getByRole('link') which never matched.

- Fix CTA locator: getByRole('button', { name: /get.*krk|get.*edge/i })
- Revert viewport-passing changes in tests 03, 06, and wallet-provider
  to match master — these were untested and added risk
- Cross-browser now only runs test 07 (landing pages) which uses the
  default { page } fixture — no wallet context needed
- Filter net::ERR_ from console error assertions (CI network noise)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:03:25 +00:00

126 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { test, expect } from '@playwright/test';
import { Wallet } from 'ethers';
import { createWalletContext } from '../setup/wallet-provider';
import { getStackConfig, validateStackHealthy } from '../setup/stack';
const ACCOUNT_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
const STACK_CONFIG = getStackConfig();
const STACK_RPC_URL = STACK_CONFIG.rpcUrl;
const STACK_WEBAPP_URL = STACK_CONFIG.webAppUrl;
const STACK_GRAPHQL_URL = STACK_CONFIG.graphqlUrl;
test.describe('GraphQL URL Verification', () => {
test.beforeAll(async () => {
await validateStackHealthy(STACK_CONFIG);
});
test('should load staking page without errors and use correct GraphQL endpoint', async ({ browser }) => {
console.log('[TEST] Creating wallet context...');
const context = await createWalletContext(browser, {
privateKey: ACCOUNT_PRIVATE_KEY,
rpcUrl: STACK_RPC_URL,
});
const page = await context.newPage();
const consoleErrors: string[] = [];
const consoleWarnings: string[] = [];
const consoleLogs: string[] = [];
const networkRequests: Array<{ url: string; status: number }> = [];
const allNetworkActivity: Array<{ url: string; status: number }> = [];
// Capture all console messages
page.on('console', msg => {
const text = msg.text();
if (msg.type() === 'error') {
consoleErrors.push(text);
} else if (msg.type() === 'warning') {
consoleWarnings.push(text);
} else if (text.includes('load') || text.includes('graphql') || text.includes('chain') || text.includes('DEBUG')) {
consoleLogs.push(text);
}
});
// Capture all network requests
page.on('response', response => {
const url = response.url();
const status = response.status();
allNetworkActivity.push({ url, status });
if (url.includes('graphql')) {
networkRequests.push({ url, status });
}
});
try {
console.log('[TEST] Navigating to staking page...');
await page.goto(`${STACK_WEBAPP_URL}/app/stake`, { waitUntil: 'domcontentloaded' });
// Wait for page to fully load and settle
await page.waitForLoadState('networkidle');
// Give more time for Vue components to mount and composables to initialize
console.log('[TEST] Waiting for composables to initialize...');
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source for Ponder/chain indexing delay in CI cold-start. See AGENTS.md #Engineering Principles.
await page.waitForTimeout(5000);
// Log findings
console.log('\n=== Console Errors ===');
if (consoleErrors.length === 0) {
console.log('✅ No console errors');
} else {
console.log('❌ Found console errors:');
consoleErrors.forEach(err => console.log(` - ${err}`));
}
console.log('\n=== Console Warnings ===');
if (consoleWarnings.length > 0) {
consoleWarnings.slice(0, 5).forEach(warn => console.log(` - ${warn}`));
}
console.log('\n=== Relevant Console Logs ===');
if (consoleLogs.length > 0) {
consoleLogs.forEach(log => console.log(` - ${log}`));
}
console.log('\n=== GraphQL Requests ===');
if (networkRequests.length === 0) {
console.log('⚠️ No GraphQL requests detected');
} else {
networkRequests.forEach(req => {
const isCorrect = req.url === STACK_GRAPHQL_URL;
const icon = isCorrect ? '✅' : '❌';
console.log(`${icon} ${req.url} (Status: ${req.status})`);
});
}
console.log('\n=== Sample Network Activity ===');
allNetworkActivity.slice(0, 10).forEach(req => {
console.log(` ${req.status} ${req.url}`);
});
// Assertions
const incorrectRequests = networkRequests.filter(
req => req.url.includes('/app/graphql')
);
// No console errors
expect(consoleErrors.length).toBe(0);
// No requests to /app/graphql
expect(incorrectRequests.length).toBe(0);
// If there were GraphQL requests, they should go to the correct endpoint
if (networkRequests.length > 0) {
const correctRequests = networkRequests.filter(req => req.url === STACK_GRAPHQL_URL);
expect(correctRequests.length).toBeGreaterThan(0);
} else {
console.log('\n⚠ WARNING: No GraphQL requests detected - composables may not be initializing');
}
} finally {
await page.close();
await context.close();
}
});
});