mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-23 02:36:05 +00:00
fix(e2e): stabilize flaky tests with improved waiting strategies
- Increase task creation timeout from 10s to 15s for slow renders - Use force:true on backdrop click to bypass overlay coverage - Replace page.evaluate() with Playwright locators in expandSection() - Add proper condition-based waiting for collapsible panel visibility
This commit is contained in:
parent
c6028b980d
commit
9d21fa1b6e
2 changed files with 35 additions and 26 deletions
|
|
@ -67,19 +67,25 @@ export abstract class BasePage {
|
|||
|
||||
if (!dialogExists) {
|
||||
// Wait for task to be created - check for the specific task
|
||||
const taskLocator = this.page.locator(
|
||||
`task:has-text("${prefixedTaskName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}")`,
|
||||
);
|
||||
const maxWaitTime = 15000; // Increased from 10s to handle slow renders
|
||||
const taskSelector = `task:has-text("${prefixedTaskName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}")`;
|
||||
|
||||
try {
|
||||
await taskLocator.first().waitFor({ state: 'visible', timeout: 10000 });
|
||||
// Primary: wait for the specific task to be visible
|
||||
await this.page.locator(taskSelector).first().waitFor({
|
||||
state: 'visible',
|
||||
timeout: maxWaitTime,
|
||||
});
|
||||
} catch (error) {
|
||||
// If specific task not found, verify count increased
|
||||
// Fallback: verify task count increased (captures edge cases)
|
||||
const finalCount = await this.page.locator('task').count();
|
||||
if (finalCount < expectedCount) {
|
||||
// Get fresh snapshot for error message after DOM settles
|
||||
await this.page.waitForTimeout(500);
|
||||
const tasks = await this.page.locator('task').allTextContents();
|
||||
const currentCount = await this.page.locator('task').count();
|
||||
throw new Error(
|
||||
`Task creation failed. Expected ${expectedCount} tasks, but got ${finalCount}.\n` +
|
||||
`Task creation failed. Expected ${expectedCount} tasks, but got ${currentCount}.\n` +
|
||||
`Task name: "${prefixedTaskName}"\n` +
|
||||
`Existing tasks: ${JSON.stringify(tasks, null, 2)}`,
|
||||
);
|
||||
|
|
@ -88,11 +94,12 @@ export abstract class BasePage {
|
|||
}
|
||||
|
||||
if (!skipClose) {
|
||||
// Close the add task bar if backdrop is visible
|
||||
// Close the add task bar by clicking the backdrop
|
||||
// Use force: true to bypass element coverage checks (overlays may cover backdrop)
|
||||
const backdropVisible = await safeIsVisible(this.backdrop);
|
||||
if (backdropVisible) {
|
||||
await this.backdrop.click();
|
||||
await this.backdrop.waitFor({ state: 'hidden', timeout: 2000 }).catch(() => {
|
||||
await this.backdrop.click({ force: true });
|
||||
await this.backdrop.waitFor({ state: 'hidden', timeout: 3000 }).catch(() => {
|
||||
// Non-fatal: backdrop might auto-hide
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,25 +42,23 @@ export class SettingsPage extends BasePage {
|
|||
* Expand a collapsible section by scrolling to it and clicking header
|
||||
*/
|
||||
async expandSection(sectionSelector: string): Promise<void> {
|
||||
await this.page.evaluate((selector) => {
|
||||
const section = document.querySelector(selector);
|
||||
if (section) {
|
||||
section.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
const section = this.page.locator(sectionSelector);
|
||||
await section.scrollIntoViewIfNeeded();
|
||||
|
||||
const collapsible = section?.querySelector('collapsible');
|
||||
if (collapsible) {
|
||||
const isExpanded = collapsible.classList.contains('isExpanded');
|
||||
if (!isExpanded) {
|
||||
const header = collapsible.querySelector('.collapsible-header');
|
||||
if (header) {
|
||||
(header as HTMLElement).click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, sectionSelector);
|
||||
const collapsible = section.locator('collapsible');
|
||||
const isExpanded = await collapsible.evaluate((el) =>
|
||||
el.classList.contains('isExpanded'),
|
||||
);
|
||||
|
||||
if (!isExpanded) {
|
||||
const header = collapsible.locator('.collapsible-header');
|
||||
await header.click();
|
||||
// Wait for expansion - panel only exists when expanded (@if in template)
|
||||
await collapsible
|
||||
.locator('.collapsible-panel')
|
||||
.waitFor({ state: 'visible', timeout: 5000 });
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500); // Wait for expansion animation
|
||||
await waitForAngularStability(this.page);
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +67,11 @@ export class SettingsPage extends BasePage {
|
|||
*/
|
||||
async expandPluginSection(): Promise<void> {
|
||||
await this.expandSection(PLUGIN_SECTION);
|
||||
// Ensure plugin management component and at least file input are visible
|
||||
await this.pluginManagement.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await this.page
|
||||
.locator(PLUGIN_FILE_INPUT)
|
||||
.waitFor({ state: 'attached', timeout: 5000 });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue