fix: comprehensive e2e test reliability improvements#33
Conversation
- Document dual logger architecture (serverLogger + httpLogger) - Add LOG_LEVEL environment variable configuration - Update security redaction paths for both loggers - Add comprehensive error handling integration examples - Document server startup logging with environment details - Add logger export and reusability patterns - Update production considerations with conditional stack traces - Enhance formatting configuration documentation - Add clear guidance on when to use each logger type - Rename application from "LFX Projects Self-Service" to "LFX Projects" - Update all references and branding to reflect new name - Update authentication documentation with new application name Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva <asithade@gmail.com>
Signed-off-by: Asitha de Silva <asithade@gmail.com>
- Added data-testid="header-projects-text" for reliable header text targeting - Fixed strict mode violations by replacing getByText with getByTestId selectors - Updated all tests to use consistent "aswf" search instead of flaky "Foundation" search - Fixed project logo visibility assertions using toBeAttached() instead of toBeVisible() - Improved authentication helper with better error handling and retry logic - Updated all project card navigation tests to search for specific projects before clicking - Fixed responsive design test assertions for mobile/tablet viewports - Removed assumptions about project card order in favor of explicit search-based targeting All 86 e2e tests now pass consistently on Chrome, with Firefox showing only intermittent page load timeouts rather than test logic failures. Signed-off-by: Asitha de Silva <asithade@gmail.com>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughE2E tests were refactored to use data-testid selectors and explicit element waits instead of network idle or arbitrary delays. Search and navigation flows were made deterministic. Firefox timeouts and a mobile project name were adjusted in Playwright config. A header span received a data-testid. CI/env, ignore lists, and license script exclusions were updated. Documentation reflects the config rename. Changes
Sequence Diagram(s)sequenceDiagram
participant PW as Playwright Test
participant Browser
participant App as LFX PCC App
PW->>Browser: open homepage
PW->>App: wait for projects-section / first project-card (visible)
PW->>App: fill search "aswf" + Enter
App-->>PW: filtered project cards visible
PW->>App: click "Academy Software Foundation" project card
App-->>PW: navigate to /project/<id>
PW->>App: click Dashboard link
App-->>PW: Dashboard renders (cards, indicators, charts)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing Touches🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Pull Request Overview
This PR addresses Firefox timeout issues and improves the reliability of end-to-end tests by implementing comprehensive fixes across test files and components. The changes focus on making tests more stable through better element targeting and consistent test patterns.
- Fixed strict mode violations by replacing
getByText('Projects')withdata-testidselectors - Enhanced test reliability with proper timeouts and waiting strategies
- Standardized search patterns to use "aswf" for consistent Academy Software Foundation project targeting
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
header.component.html |
Added data-testid="header-projects-text" for reliable test targeting |
project-dashboard.spec.ts |
Updated search patterns to use "aswf" and improved element selectors with proper timeouts |
project-dashboard-robust.spec.ts |
Fixed strict mode violations by replacing text selectors with data-testid attributes |
homepage.spec.ts |
Enhanced test reliability by switching to data-testid selectors and improved waiting strategies |
homepage-robust.spec.ts |
Improved navigation tests and removed unreliable text-based element targeting |
auth.helper.ts |
Minor import ordering cleanup |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (11)
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts (2)
262-268: Remove duplicated assertion for hidden header search on mobileThe hidden-check for the header search input is performed twice. Drop the duplicate to keep tests lean.
- // Search bar should be hidden on mobile (responsive design) - await expect(page.getByPlaceholder('Search projects...')).toBeHidden();
11-16: Prefer test id for hero search input to avoid content-couplingRelying on the full accessible name string is brittle to copy updates. Consider targeting the hero search by test id and then its inner input.
- await expect(page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' })).toBeVisible({ timeout: 10000 }); - await page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }).fill('aswf'); + const heroSearch = page.getByTestId('hero-search-input').locator('input[type="text"]'); + await expect(heroSearch).toBeVisible({ timeout: 10000 }); + await heroSearch.fill('aswf');apps/lfx-pcc/e2e/homepage.spec.ts (2)
137-140: Minor redundancy: duplicate filtered count assertionYou assert the filtered count is less than the initial count inside
toPassand then again right after. Consider removing the second check to avoid duplication.- const filteredCards = page.getByTestId('project-card'); - const filteredCount = await filteredCards.count(); - expect(filteredCount).toBeLessThan(initialCount); + // Count already validated in the toPass block above
228-237: No-results flow is explicitWaiting for initial cards, entering a non-existent query, and asserting zero cards is straightforward. Consider adding an empty-state assertion if the UI provides one.
apps/lfx-pcc/e2e/homepage-robust.spec.ts (3)
248-253: Remove duplicate visibility assertion for projects section
projects-sectionvisibility is checked twice; drop the second one.- // Projects should be filtered (count may change) - await expect(page.locator('[data-testid="projects-section"]')).toBeVisible();
281-303: Tighten URL assertion for ASWF navigationExact string match can fail with trailing slashes or query params. Prefer a regex that allows anchors and query strings.
- await expect(page).toHaveURL('/project/aswf'); + await expect(page).toHaveURL(/\/project\/aswf(?:$|[?#/])/);
237-238: Prefer test id for hero search input when fillingLike in other tests, avoid content-based names. Use the hero search test id and target the inner input.
- const searchInput = page.getByRole('textbox', { name: 'Search projects, committees,' }); - await searchInput.fill('aswf'); + const searchInput = page.getByTestId('hero-search-input').locator('input[type="text"]'); + await searchInput.fill('aswf');apps/lfx-pcc/e2e/project-dashboard.spec.ts (4)
11-16: Reduce duplication by capturing the locator (and consider a data-testid).Good explicit wait. Minor refactor reduces brittleness and duplication.
Apply:
-// Wait for the search input to be available -await expect(page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' })).toBeVisible({ timeout: 10000 }); - -// Perform search for "aswf" to get the Academy Software Foundation project -await page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }).fill('aswf'); +// Wait for the search input to be available +const homeSearch = page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }); +await expect(homeSearch).toBeVisible({ timeout: 10000 }); + +// Perform search for "aswf" to get the Academy Software Foundation project +await homeSearch.fill('aswf');If feasible, prefer a stable test id (e.g., data-testid="homepage-search-input") here for long-term resilience. I can follow up with a PR to add it.
65-68: Add an accessibility-based assertion for the active tab.Visual class check is fine; also assert ARIA state for robustness.
const dashboardTab = page.getByRole('link', { name: 'Dashboard' }); await expect(dashboardTab).toHaveClass(/bg-blue-50/); +await expect(dashboardTab).toHaveAttribute('aria-current', 'page');
81-83: Relax heading text match slightly to reduce brittleness.If the display name varies, matching both long and short forms avoids flakes.
-await expect(page.getByRole('heading', { level: 1 })).toContainText('Academy Software Foundation (ASWF)'); +const h1 = page.getByRole('heading', { level: 1 }); +await expect(h1).toContainText(/Academy Software Foundation/i); +await expect(h1).toContainText(/ASWF/i);
294-306: Assert header “Projects” is hidden on mobile here as well.Mirror the earlier check for consistency.
// Search bar should be hidden on mobile (responsive design) await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); +await expect(page.getByTestId('header-projects-text')).toBeHidden();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/lfx-pcc/e2e/helpers/auth.helper.ts(1 hunks)apps/lfx-pcc/e2e/homepage-robust.spec.ts(12 hunks)apps/lfx-pcc/e2e/homepage.spec.ts(7 hunks)apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts(3 hunks)apps/lfx-pcc/e2e/project-dashboard.spec.ts(5 hunks)apps/lfx-pcc/src/app/shared/components/header/header.component.html(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
apps/**/src/**/*.html
📄 CodeRabbit Inference Engine (CLAUDE.md)
apps/**/src/**/*.html: Always add data-testid attributes when creating new components for reliable test targeting
Use data-testid naming convention - '[section]-[component]-[element]' for hierarchical structure
Files:
apps/lfx-pcc/src/app/shared/components/header/header.component.html
{apps,packages}/**/*.{ts,tsx,js,jsx,css,scss}
📄 CodeRabbit Inference Engine (CLAUDE.md)
License headers are required on all source files
Files:
apps/lfx-pcc/e2e/helpers/auth.helper.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use TypeScript interfaces instead of union types for better maintainability
Files:
apps/lfx-pcc/e2e/helpers/auth.helper.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Do not nest ternary expressions
Files:
apps/lfx-pcc/e2e/helpers/auth.helper.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
**/*{.spec.ts,-robust.spec.ts}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*{.spec.ts,-robust.spec.ts}: E2E tests use dual architecture - both content-based (.spec.ts) and structural (-robust.spec.ts) tests
Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Files:
apps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Run yarn e2e before major changes to ensure all 85+ tests pass consistently
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : E2E tests use dual architecture - both content-based (_.spec.ts) and structural (_-robust.spec.ts) tests
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to apps/**/src/**/*.html : Use data-testid naming convention - '[section]-[component]-[element]' for hierarchical structure
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to apps/**/src/**/*.html : Always add data-testid attributes when creating new components for reliable test targeting
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to apps/**/src/**/*.html : Always add data-testid attributes when creating new components for reliable test targeting
Applied to files:
apps/lfx-pcc/src/app/shared/components/header/header.component.htmlapps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to apps/**/src/**/*.html : Use data-testid naming convention - '[section]-[component]-[element]' for hierarchical structure
Applied to files:
apps/lfx-pcc/src/app/shared/components/header/header.component.htmlapps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: All PrimeNG components are wrapped in LFX components for UI library independence
Applied to files:
apps/lfx-pcc/src/app/shared/components/header/header.component.html
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to packages/shared/src/{interfaces,constants,enums}/**/*.{ts,tsx} : All shared types, interfaces, and constants are centralized in lfx-pcc/shared package
Applied to files:
apps/lfx-pcc/e2e/helpers/auth.helper.tsapps/lfx-pcc/e2e/homepage-robust.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to {apps,packages}/**/index.ts : Always use direct imports for standalone components - no barrel exports
Applied to files:
apps/lfx-pcc/e2e/helpers/auth.helper.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : E2E tests use dual architecture - both content-based (_.spec.ts) and structural (_-robust.spec.ts) tests
Applied to files:
apps/lfx-pcc/e2e/helpers/auth.helper.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Applied to files:
apps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Run yarn e2e before major changes to ensure all 85+ tests pass consistently
Applied to files:
apps/lfx-pcc/e2e/project-dashboard-robust.spec.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/homepage.spec.tsapps/lfx-pcc/e2e/project-dashboard.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Code Quality Checks
🔇 Additional comments (15)
apps/lfx-pcc/src/app/shared/components/header/header.component.html (1)
12-12: Good addition: stable test id on header label
data-testid="header-projects-text"follows the '[section]-[component]-[element]' convention and matches responsive behavior (hidden on mobile). No issues.apps/lfx-pcc/e2e/helpers/auth.helper.ts (1)
4-4: Import reorder is fineNo functional impact; types remain correct and license header present. LGTM.
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts (3)
11-16: Nice: explicit wait for search input before interactingSwitching to an explicit visibility wait reduces flakiness across browsers. Good move.
18-27: Improved synchronization on results and navigationWaiting for first
lfx-project-cardand URL match before clicking Dashboard tightens test determinism. Looks good.
287-288: Consistent selector: tablet check via test idUsing
getByTestId('header-projects-text')on tablet aligns with the new header test id and is robust. Good update.apps/lfx-pcc/e2e/homepage.spec.ts (5)
15-21: Title/subtitle assertions via test idsAsserting hero content through test ids is precise and stable. LGTM.
91-111: Stable project card checks with test ids and attached logo
- Waiting for first card with timeout is solid.
- Using
toBeAttached()for logos handles invalid URLs gracefully.
This should reduce flakiness.
127-132: Good use of expect().toPass for dynamic filteringPolling until the card count drops is a pragmatic way to wait for search filtering without arbitrary timeouts. Nice.
169-186: Deterministic navigation to a specific projectFiltering to CNCF and asserting URL with a slug regex is a solid pattern to keep the test stable. Looks good.
195-214: Responsive checks are crispWaiting for cards, then switching viewports and asserting visibility/hidden states (including header search on mobile) is clear and reliable. LGTM.
apps/lfx-pcc/e2e/homepage-robust.spec.ts (4)
28-28:toBeAttachedfor main container is appropriateAttachment is sufficient for existence checks and can be more tolerant than visibility. Good pick.
106-108: Explicit project load wait
[data-testid="projects-section"]with a timeout is a clear readiness signal. Looks good.
172-174: Logo check viatoBeAttachedAvoids false negatives with hidden or broken images. Good adjustment.
389-390: Project load wait pattern is consistentWaiting for first project card with a timeout helps reduce flakiness across browsers. LGTM.
apps/lfx-pcc/e2e/project-dashboard.spec.ts (1)
51-57: LGTM: desktop/tablet header assertions are robust and aligned with data-testid usage.
✅ E2E Tests PassedBrowser: chromium All E2E tests passed successfully. Test Configuration
|
Signed-off-by: Asitha de Silva <asithade@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts (2)
262-271: Remove duplicate hidden-search assertion in mobile blockThe search hidden check is performed twice (Line 260 and Line 267). Keep one to reduce noise without losing coverage.
Apply this diff:
// Search bar should be hidden on mobile (responsive design) - await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); + await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); // On mobile: "Projects" text is completely hidden from header button // We need to target the specific span that contains "Projects" text await expect(page.getByTestId('header-projects-text')).toBeHidden(); - // Search bar should be hidden on mobile (responsive design) - await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); - // Mobile search toggle should be visible await expect(page.getByTestId('mobile-search-toggle')).toBeVisible();
294-306: Pre-wait for health card and extended indicator timeouts are sensible; consider centralizing timeoutsThe preliminary wait for project-health-card and extended 20s waits for indicator values align with async rendering.
To improve maintainability, define shared constants at the top to avoid scattered magic numbers:
const TIMEOUTS = { default: 10_000, healthCard: 15_000, indicators: 20_000 }; // ... await expect(page.locator('[data-testid="project-health-card"]')).toBeVisible({ timeout: TIMEOUTS.healthCard }); await expect(activityScore).toBeVisible({ timeout: TIMEOUTS.indicators }); // etc.apps/lfx-pcc/e2e/homepage-robust.spec.ts (1)
107-108: Consistent explicit waits improve reliability; consider consolidating timeout constantsThe repeated 10s/20s waits are appropriate for async rendering. To improve readability/maintenance, define a shared constant (e.g., const WAIT = 10_000) or a TIMEOUTS map and reuse across tests.
Example:
const TIMEOUTS = { default: 10_000, slow: 20_000 }; // await expect(locator).toBeVisible({ timeout: TIMEOUTS.default });Also applies to: 124-125, 142-143, 164-165, 197-198, 237-238, 258-259, 359-359, 389-389
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.vscode/settings.json(1 hunks)apps/lfx-pcc/e2e/homepage-robust.spec.ts(12 hunks)apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts(3 hunks)apps/lfx-pcc/playwright.config.ts(1 hunks)check-headers.sh(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .vscode/settings.json
🧰 Additional context used
📓 Path-based instructions (4)
{apps,packages}/**/*.{ts,tsx,js,jsx,css,scss}
📄 CodeRabbit Inference Engine (CLAUDE.md)
License headers are required on all source files
Files:
apps/lfx-pcc/playwright.config.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use TypeScript interfaces instead of union types for better maintainability
Files:
apps/lfx-pcc/playwright.config.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Do not nest ternary expressions
Files:
apps/lfx-pcc/playwright.config.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
**/*{.spec.ts,-robust.spec.ts}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*{.spec.ts,-robust.spec.ts}: E2E tests use dual architecture - both content-based (.spec.ts) and structural (-robust.spec.ts) tests
Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Files:
apps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
🧠 Learnings (2)
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Applied to files:
apps/lfx-pcc/playwright.config.tsapps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : E2E tests use dual architecture - both content-based (_.spec.ts) and structural (_-robust.spec.ts) tests
Applied to files:
apps/lfx-pcc/e2e/homepage-robust.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Code Quality Checks
🔇 Additional comments (7)
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts (4)
11-16: Good switch to explicit waits and standardized search termWaiting for the search input by role and using “aswf” improves determinism across browsers.
18-20: Explicit wait for first project card is appropriateUsing the first card as readiness signal stabilizes subsequent interactions.
24-27: URL and Dashboard readiness checks improve navigation stabilityVerifying URL and link visibility before clicking reduces flakiness.
287-287: Tablet header verification via data-testid is solidChecking header-projects-text by test id avoids brittle text-based selectors.
apps/lfx-pcc/e2e/homepage-robust.spec.ts (3)
28-28: Using toBeAttached for lfx-home reduces false negativesAttachment is a more reliable readiness signal than visibility for container components.
172-174: Switching project logo check to toBeAttached is the right trade-offLogos may not render as visible with invalid/missing URLs; attachment verifies presence without flakiness.
281-303: Robust navigation to ASWF project is well-structuredFiltering by “aswf”, asserting the specific card title, clicking that card, and verifying exact URL provides deterministic navigation.
- Fix flaky Angular signals test with better element-based waiting - Replace networkidle waits with specific element visibility checks - Add Firefox-specific timeout configurations for better stability - Increase timeouts for Firefox browser (20s elements, 45s navigation) - Fix URL pattern to accept hyphenated project slugs ([\w-]+ vs \w+) - Replace flaky .first().click() with text-based targeting - Update check-headers.sh and VS Code settings Addresses intermittent test failures in both Chromium and Firefox by using more reliable waiting strategies and robust element selection. All 86 tests now pass consistently in Chromium. 🤖 Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva <asithade@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
apps/lfx-pcc/e2e/project-dashboard.spec.ts (4)
283-293: DRY: extract the navigation/search flow into a helper.This block repeats; centralize it for maintainability and faster updates.
// Place once near top-level (outside tests) async function gotoASWFProjectDashboard(page: import('@playwright/test').Page) { await page.goto('/'); const homeSearch = page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }); await expect(homeSearch).toBeVisible({ timeout: 10000 }); await homeSearch.fill('aswf'); await page.keyboard.press('Enter'); const aswfCard = page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }); await expect(aswfCard).toBeVisible({ timeout: 10000 }); await aswfCard.click(); await expect(page).toHaveURL(/\/project\/[\w-]+$/, { timeout: 10000 }); await expect(page.getByRole('link', { name: 'Dashboard' })).toBeVisible(); await page.getByRole('link', { name: 'Dashboard' }).click(); } // Then here: await gotoASWFProjectDashboard(page);
300-301: Also assert the “Projects” label is hidden on mobile here.Make the behavior explicit to avoid regressions.
- // On mobile: "Projects" text is completely hidden from header button + // On mobile: "Projects" text is completely hidden from header button + await expect(page.getByTestId('header-projects-text')).toBeHidden();
311-321: Reuse the helper for the tablet flow too.Avoid duplicating the navigation/search steps.
- // Navigate to homepage and search for a project after viewport change - await page.goto('/'); - await expect(page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' })).toBeVisible({ timeout: 10000 }); - await page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }).fill('aswf'); - await page.keyboard.press('Enter'); - await expect(page.locator('lfx-project-card').first()).toBeVisible({ timeout: 10000 }); - await page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }).click(); - await expect(page).toHaveURL(/\/project\/[\w-]+$/, { timeout: 10000 }); - await expect(page.getByRole('link', { name: 'Dashboard' })).toBeVisible(); - await page.getByRole('link', { name: 'Dashboard' }).click(); + await gotoASWFProjectDashboard(page);
322-325: Use data-testid for the “Projects” label on tablet for selector stability.Replace the nested text selector with the header-projects-text test-id.
- await expect(page.getByRole('button', { name: 'Go to home page' }).getByText('Projects', { exact: true })).toBeVisible(); + await expect(page.getByTestId('header-projects-text')).toBeVisible();
🧹 Nitpick comments (7)
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts (3)
21-22: Click target: assert visibility before clicking to reduce flakiness.Add an explicit visibility check on the filtered card before click.
- await page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }).click(); + const aswfCard = page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }); + await expect(aswfCard).toBeVisible({ timeout: 10000 }); + await aswfCard.click();
266-271: Remove duplicate “Search projects…” hidden assertion.This test already asserts the search input is hidden earlier in the same block. Drop the second check to reduce noise and runtime.
- // Search bar should be hidden on mobile (responsive design) - await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); - // Mobile search toggle should be visible await expect(page.getByTestId('mobile-search-toggle')).toBeVisible();Optional: align with PR objective by asserting the logo is attached (less brittle than visibility when src may 404). Outside this hunk:
await expect(page.getByAltText('LFX Logo')).toBeAttached();
294-306: Timeouts: centralize to avoid drift.The explicit 15–20s timeouts are reasonable for Firefox, but consider extracting them to a constant or reading from config to keep them consistent across tests.
Example:
const HEALTH_TIMEOUT = 20_000; await expect(activityScore).toBeVisible({ timeout: HEALTH_TIMEOUT });apps/lfx-pcc/e2e/project-dashboard.spec.ts (4)
18-23: Click target: assert visibility before clicking to reduce flakiness.Mirror the robust spec by asserting the filtered card is visible before clicking.
- await expect(page.locator('lfx-project-card').first()).toBeVisible({ timeout: 10000 }); - await page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }).click(); + await expect(page.locator('lfx-project-card').first()).toBeVisible({ timeout: 10000 }); + const aswfCard = page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }); + await expect(aswfCard).toBeVisible({ timeout: 10000 }); + await aswfCard.click();
45-49: Add the explicit “Projects” label hidden assertion on mobile.You mention it’s hidden; assert it to prevent regressions.
if (isMobile) { // On mobile: "Projects" text is completely hidden from header button // Search should be hidden await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); + await expect(page.getByTestId('header-projects-text')).toBeHidden(); // Mobile search toggle should be visible await expect(page.getByTestId('mobile-search-toggle')).toBeVisible();
67-67: Active tab assertion may be brittle on class names.If available, prefer a semantic state like aria-current="page" or selected attribute to reduce coupling to CSS classes.
81-82: Project heading expectation: LGTM.Note: for logos that can 404, prefer toBeAttached over visibility (outside this hunk).
Example (elsewhere in this file):
await expect(projectImage).toBeAttached();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.github/workflows/e2e-tests.yml(1 hunks)apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts(3 hunks)apps/lfx-pcc/e2e/project-dashboard.spec.ts(5 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
{apps,packages}/**/*.{ts,tsx,js,jsx,css,scss}
📄 CodeRabbit Inference Engine (CLAUDE.md)
License headers are required on all source files
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use TypeScript interfaces instead of union types for better maintainability
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
**/*{.spec.ts,-robust.spec.ts}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*{.spec.ts,-robust.spec.ts}: E2E tests use dual architecture - both content-based (.spec.ts) and structural (-robust.spec.ts) tests
Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Do not nest ternary expressions
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
🧠 Learnings (2)
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Applied to files:
apps/lfx-pcc/e2e/project-dashboard.spec.tsapps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : E2E tests use dual architecture - both content-based (_.spec.ts) and structural (_-robust.spec.ts) tests
Applied to files:
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: E2E Tests / Playwright E2E Tests
🔇 Additional comments (8)
apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts (4)
11-16: Explicit wait + deterministic search: LGTM.Using a named role with an explicit timeout improves stability across browsers. Good change.
24-27: Slug regex + Dashboard readiness: LGTM.Allowing hyphens in the slug and waiting for the Dashboard link is the right trade-off for determinism.
33-34: URL pattern consistency: LGTM.Consistent use of //project/[\w-]+$/ prevents false negatives on hyphenated slugs.
287-287: Prefer test-id for header label: LGTM.Using header-projects-text keeps selectors stable across UI tweaks.
apps/lfx-pcc/e2e/project-dashboard.spec.ts (4)
11-16: Explicit wait + “aswf” search: LGTM.This matches the suite-wide pattern and improves stability.
24-27: Slug regex + Dashboard readiness: LGTM.Consistent with the robust spec.
33-34: URL pattern consistency: LGTM.
51-55: Desktop header checks via test-ids: LGTM.Stable and consistent with the PR direction.
- Add waitUntil: 'domcontentloaded' to all page.goto() calls - Ensures page is ready before proceeding with tests - Reduces flakiness on slower network connections Signed-off-by: Asitha de Silva <asithadesilva@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
apps/lfx-pcc/e2e/project-dashboard.spec.ts (4)
18-23: Make result selection deterministic (avoid relying on first())Wait for and click the ASWF card directly to prevent ordering flakes. Consolidate the wait and click on the same filtered locator.
Apply this diff:
- // Wait for search results to load - await expect(page.locator('lfx-project-card').first()).toBeVisible({ timeout: 10000 }); - - // Click on the Academy Software Foundation project card specifically - await page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }).click(); + // Wait for and click the ASWF card deterministically + const aswfCard = page.locator('lfx-project-card:has-text("Academy Software Foundation")').first(); + await expect(aswfCard).toBeVisible({ timeout: 10000 }); + await aswfCard.click();
45-49: Also assert that the “Projects” label is hidden on mobileThe comment states it’s hidden; enforce it to prevent regressions.
if (isMobile) { // On mobile: "Projects" text is completely hidden from header button // Search should be hidden + await expect(page.getByTestId('header-projects-text')).toBeHidden(); await expect(page.getByPlaceholder('Search projects...')).toBeHidden();
322-324: Use data-testid for the “Projects” label on tabletPrefer the stable test id over nested text-based selectors.
- // All dashboard elements should be visible on tablet (768px = desktop, "Projects" text visible) - await expect(page.getByRole('button', { name: 'Go to home page' }).getByText('Projects', { exact: true })).toBeVisible(); + // All dashboard elements should be visible on tablet (768px = desktop, "Projects" label visible) + await expect(page.getByTestId('header-projects-text')).toBeVisible();
300-306: Assert the header “Projects” label is hidden on mobile (explicitly)Add a concrete assertion for hidden state to match the comment and avoid regressions.
// On mobile: "Projects" text is completely hidden from header button // Search bar should be hidden on mobile (responsive design) await expect(page.getByPlaceholder('Search projects...')).toBeHidden(); + await expect(page.getByTestId('header-projects-text')).toBeHidden();
🧹 Nitpick comments (2)
apps/lfx-pcc/e2e/project-dashboard.spec.ts (2)
283-293: DRY: Extract navigation/search into a helper and reuseThis block duplicates the pre-test flow. Extract once and call it here for maintainability and speedier updates.
- // Navigate to homepage and search for a project after viewport change - await page.goto('/'); - await expect(page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' })).toBeVisible({ timeout: 10000 }); - await page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }).fill('aswf'); - await page.keyboard.press('Enter'); - await expect(page.locator('lfx-project-card').first()).toBeVisible({ timeout: 10000 }); - await page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }).click(); - await expect(page).toHaveURL(/\/project\/[\w-]+$/, { timeout: 10000 }); - await expect(page.getByRole('link', { name: 'Dashboard' })).toBeVisible(); - await page.getByRole('link', { name: 'Dashboard' }).click(); + await gotoASWFProjectDashboard(page);Add once near the top of this file (outside tests):
async function gotoASWFProjectDashboard(page: import('@playwright/test').Page) { await page.goto('/', { waitUntil: 'domcontentloaded' }); const homeSearch = page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }); await expect(homeSearch).toBeVisible({ timeout: 10000 }); await homeSearch.fill('aswf'); await page.keyboard.press('Enter'); const aswfCard = page.locator('lfx-project-card:has-text("Academy Software Foundation")').first(); await expect(aswfCard).toBeVisible({ timeout: 10000 }); await aswfCard.click(); await expect(page).toHaveURL(/\/project\/[\w-]+$/, { timeout: 10000 }); await expect(page.getByRole('link', { name: 'Dashboard' })).toBeVisible(); await page.getByRole('link', { name: 'Dashboard' }).click(); }
311-321: Reuse the helper for the tablet flow tooAvoid duplication; it centralizes waits, deterministic selection, and timeouts.
- // Navigate to homepage and search for a project after viewport change - await page.goto('/'); - await expect(page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' })).toBeVisible({ timeout: 10000 }); - await page.getByRole('textbox', { name: 'Search projects, committees, meetings, or mailing lists...' }).fill('aswf'); - await page.keyboard.press('Enter'); - await expect(page.locator('lfx-project-card').first()).toBeVisible({ timeout: 10000 }); - await page.locator('lfx-project-card').filter({ hasText: 'Academy Software Foundation' }).click(); - await expect(page).toHaveURL(/\/project\/[\w-]+$/, { timeout: 10000 }); - await expect(page.getByRole('link', { name: 'Dashboard' })).toBeVisible(); - await page.getByRole('link', { name: 'Dashboard' }).click(); + await gotoASWFProjectDashboard(page);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/lfx-pcc/e2e/homepage-robust.spec.ts(13 hunks)apps/lfx-pcc/e2e/homepage.spec.ts(7 hunks)apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts(3 hunks)apps/lfx-pcc/e2e/project-dashboard.spec.ts(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/lfx-pcc/e2e/homepage.spec.ts
- apps/lfx-pcc/e2e/project-dashboard-robust.spec.ts
- apps/lfx-pcc/e2e/homepage-robust.spec.ts
🧰 Additional context used
📓 Path-based instructions (4)
{apps,packages}/**/*.{ts,tsx,js,jsx,css,scss}
📄 CodeRabbit Inference Engine (CLAUDE.md)
License headers are required on all source files
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use TypeScript interfaces instead of union types for better maintainability
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.ts
**/*{.spec.ts,-robust.spec.ts}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*{.spec.ts,-robust.spec.ts}: E2E tests use dual architecture - both content-based (.spec.ts) and structural (-robust.spec.ts) tests
Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Do not nest ternary expressions
Files:
apps/lfx-pcc/e2e/project-dashboard.spec.ts
🧠 Learnings (2)
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : Test responsive behavior - validate mobile, tablet, and desktop viewports appropriately
Applied to files:
apps/lfx-pcc/e2e/project-dashboard.spec.ts
📚 Learning: 2025-08-07T16:35:57.360Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.360Z
Learning: Applies to **/*{.spec.ts,-robust.spec.ts} : E2E tests use dual architecture - both content-based (_.spec.ts) and structural (_-robust.spec.ts) tests
Applied to files:
apps/lfx-pcc/e2e/project-dashboard.spec.ts
🔇 Additional comments (8)
apps/lfx-pcc/e2e/project-dashboard.spec.ts (8)
9-10: LGTM: Navigation wait strategy is appropriateUsing domcontentloaded + subsequent element-state waits is fine and keeps the flow stable.
11-13: LGTM: Explicit wait on the search inputElement-state wait with a concrete timeout improves reliability.
14-15: LGTM: Standardized search termUsing "aswf" aligns with the PR’s standardization across tests.
24-26: LGTM: Hyphen-friendly project slug checkThe updated regex //project/[\w-]+$/ is consistent and robust.
33-33: LGTM: Consistent URL assertionHyphenated slug support matches the rest of the file.
51-54: LGTM: Use data-testid for desktop header labelStable and consistent with the PR’s selector strategy.
81-81: LGTM: Heading assertion updated with acronymMatches the new expected text and improves specificity.
295-295: LGTM: Mobile heading checkAsserting the exact title with acronym improves reliability.
- Add playwright-report/ and test-results/ to .prettierignore - Prevents pre-commit hook failures from untracked test files - Also exclude dist/ and .angular/ build directories Resolves pre-commit hook failures when Playwright test artifacts exist. Signed-off-by: Asitha de Silva <asithade@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.prettierignore (1)
4-10: Optional: also ignore coverage output and similar transient dirsIf you generate coverage locally/CI, consider adding it here as well. Prettier already ignores node_modules by default, but having it explicitly listed is fine.
Suggested addition:
# Ignore test and build artifacts playwright-report/ test-results/ dist/ node_modules/ .angular/ +coverage/Also, minor nit: the top comment “Ignore everything” (paired with
*.*) actually ignores files with extensions by default; consider rephrasing to “Ignore most files by default; re-include selected extensions” for clarity.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/weekly-e2e-tests.yml(1 hunks).prettierignore(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: E2E Tests / Playwright E2E Tests
🔇 Additional comments (1)
.prettierignore (1)
4-10: Good call: exclude build/test artifacts from Prettier’s scopeThe added directories are appropriate and will prevent Prettier from traversing large, ephemeral outputs. This should speed up formatting and avoid noisy diffs.
Signed-off-by: Asitha de Silva <asithade@gmail.com>
dealako
left a comment
There was a problem hiding this comment.
A couple minor comments.
Signed-off-by: Asitha de Silva <asithade@gmail.com>
Summary
This PR addresses Firefox timeout issues and improves the reliability of our e2e test suite by implementing comprehensive fixes across all test files.
Key Changes
getByText('Projects')withdata-testidselectors for more reliable element targetingdata-testid="header-projects-text"to header component and updated all tests to use it.toBeVisible()to.toBeAttached()for logo elements with potentially invalid URLsTest Results
Changes Made
Header Component (
header.component.html)data-testid="header-projects-text"for reliable test targetingTest Files Updated
homepage.spec.ts- Fixed search patterns and element selectorshomepage-robust.spec.ts- Enhanced with proper timeouts and navigation fixesproject-dashboard.spec.ts- Updated to use consistent ASWF project targetingproject-dashboard-robust.spec.ts- Fixed strict mode violations and search consistencyServer Configuration (
server.ts)Testing
🤖 Generated with Claude Code