fix: Dozens of bare waitForTimeout() calls remain throughout e2e tests (#418)
Replace all 10 bare waitForTimeout() calls in tests/e2e/usertest/helpers.ts with proper event-driven Playwright waits per AGENTS.md Engineering Principle #3 ("replace when touched"): connectWallet(): - Remove 500ms resize-event sleep: connectButton.isVisible({ timeout: 5_000 }) already waits for the layout to settle after the resize event - Remove 2000ms "connector init" sleep: the subsequent isVisible check was already event-driven - Replace 2x 1000ms panel-animation sleeps with injectedConnector.waitFor({ state: 'visible' }) — the .connectors-element appearing is the exact observable DOM event - Remove 2x 2000ms "handshake" sleeps: walletDisplay.waitFor() at the end of the function is the correct gate for connection completion attemptStake(): - Remove 3000ms post-goto sleep: tokenAmountSlider.waitFor() at the next line is the correct page-load gate - Remove 2x 500ms debounce sleeps after fill/select: stakeButton.waitFor() downstream is the correct reactive-state gate - Remove 3000ms post-transaction sleep: the button returning to "Stake" text (waitFor at line 619) is already the correct transaction-completion gate Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
92fa38e328
commit
3507538fce
1 changed files with 8 additions and 36 deletions
|
|
@ -143,16 +143,10 @@ export async function connectWallet(page: Page): Promise<void> {
|
||||||
const navbarTitle = page.locator('.navbar-title').first();
|
const navbarTitle = page.locator('.navbar-title').first();
|
||||||
await navbarTitle.waitFor({ state: 'visible', timeout: 60_000 });
|
await navbarTitle.waitFor({ state: 'visible', timeout: 60_000 });
|
||||||
|
|
||||||
// Trigger resize event for mobile detection
|
// Trigger resize event for mobile detection; connectButton.isVisible below waits for layout
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Vue's useMobile composable to recalculate after a resize event in E2E tests. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(500);
|
|
||||||
|
|
||||||
// Give time for wallet connectors to initialize
|
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for wallet connector initialization; connectors load asynchronously with no observable DOM event. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(2_000);
|
|
||||||
|
|
||||||
// Try desktop Connect button first
|
// Try desktop Connect button first
|
||||||
const connectButton = page.locator('.connect-button--disconnected').first();
|
const connectButton = page.locator('.connect-button--disconnected').first();
|
||||||
|
|
@ -160,32 +154,20 @@ export async function connectWallet(page: Page): Promise<void> {
|
||||||
if (await connectButton.isVisible({ timeout: 5_000 })) {
|
if (await connectButton.isVisible({ timeout: 5_000 })) {
|
||||||
console.log('[HELPER] Found desktop Connect button');
|
console.log('[HELPER] Found desktop Connect button');
|
||||||
await connectButton.click();
|
await connectButton.click();
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for the wallet connector slideout panel animation to settle. See AGENTS.md #Engineering Principles.
|
// Wait for the connector panel to open — .connectors-element appearing is the observable event
|
||||||
await page.waitForTimeout(1_000);
|
|
||||||
|
|
||||||
// Click the first wallet connector
|
|
||||||
const injectedConnector = page.locator('.connectors-element').first();
|
const injectedConnector = page.locator('.connectors-element').first();
|
||||||
if (await injectedConnector.isVisible({ timeout: 5_000 })) {
|
await injectedConnector.waitFor({ state: 'visible', timeout: 10_000 });
|
||||||
console.log('[HELPER] Clicking wallet connector...');
|
console.log('[HELPER] Clicking wallet connector...');
|
||||||
await injectedConnector.click();
|
await injectedConnector.click();
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for the injected wallet provider to complete connection handshake. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(2_000);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Try mobile fallback
|
// Try mobile fallback
|
||||||
const mobileLoginIcon = page.locator('.navbar-end svg').first();
|
const mobileLoginIcon = page.locator('.navbar-end svg').first();
|
||||||
if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) {
|
if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) {
|
||||||
console.log('[HELPER] Using mobile login icon');
|
console.log('[HELPER] Using mobile login icon');
|
||||||
await mobileLoginIcon.click();
|
await mobileLoginIcon.click();
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for the wallet connector slideout panel animation to settle. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(1_000);
|
|
||||||
|
|
||||||
const injectedConnector = page.locator('.connectors-element').first();
|
const injectedConnector = page.locator('.connectors-element').first();
|
||||||
if (await injectedConnector.isVisible({ timeout: 5_000 })) {
|
await injectedConnector.waitFor({ state: 'visible', timeout: 10_000 });
|
||||||
await injectedConnector.click();
|
await injectedConnector.click();
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for the injected wallet provider to complete connection handshake. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(2_000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -520,10 +502,6 @@ export async function attemptStake(
|
||||||
const baseUrl = page.url().split('#')[0];
|
const baseUrl = page.url().split('#')[0];
|
||||||
await page.goto(`${baseUrl}stake`);
|
await page.goto(`${baseUrl}stake`);
|
||||||
|
|
||||||
// Wait longer for page to load and stats to initialize
|
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(3_000);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Wait for stake form to fully load
|
// Wait for stake form to fully load
|
||||||
const tokenAmountSlider = page.getByRole('slider', { name: 'Token Amount' });
|
const tokenAmountSlider = page.getByRole('slider', { name: 'Token Amount' });
|
||||||
|
|
@ -549,14 +527,10 @@ export async function attemptStake(
|
||||||
const stakeAmountInput = page.getByLabel('Staking Amount');
|
const stakeAmountInput = page.getByLabel('Staking Amount');
|
||||||
await stakeAmountInput.waitFor({ state: 'visible', timeout: 10_000 });
|
await stakeAmountInput.waitFor({ state: 'visible', timeout: 10_000 });
|
||||||
await stakeAmountInput.fill(amount);
|
await stakeAmountInput.fill(amount);
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for debounced input handlers to settle after programmatic fill. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(500);
|
|
||||||
|
|
||||||
// Select tax rate
|
// Select tax rate
|
||||||
const taxSelect = page.getByRole('combobox', { name: 'Tax' });
|
const taxSelect = page.getByRole('combobox', { name: 'Tax' });
|
||||||
await taxSelect.selectOption({ value: taxRateIndex });
|
await taxSelect.selectOption({ value: taxRateIndex });
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for debounced form state to update after select option change. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(500);
|
|
||||||
|
|
||||||
// Take screenshot before attempting to click
|
// Take screenshot before attempting to click
|
||||||
const screenshotDir = join('test-results', 'usertest', personaName.toLowerCase().replace(/\s+/g, '-'));
|
const screenshotDir = join('test-results', 'usertest', personaName.toLowerCase().replace(/\s+/g, '-'));
|
||||||
|
|
@ -621,8 +595,6 @@ export async function attemptStake(
|
||||||
// May complete instantly
|
// May complete instantly
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles.
|
|
||||||
await page.waitForTimeout(3_000);
|
|
||||||
recordAction(`Stake ${amount} KRK at ${taxRateIndex}% tax`, true, undefined, report);
|
recordAction(`Stake ${amount} KRK at ${taxRateIndex}% tax`, true, undefined, report);
|
||||||
console.log(`[${personaName}] Stake successful`);
|
console.log(`[${personaName}] Stake successful`);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue