-
Notifications
You must be signed in to change notification settings - Fork 3
fix(e2e): repair failing weekly test suite #696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -191,7 +191,8 @@ test.describe('Website Visits Drawer', () => { | |
| }); | ||
|
|
||
| test('shows stats section with data', async ({ page }) => { | ||
| await openDrawer(page, 'marketing-card-website-visits', 'website-visits-drawer-stats'); | ||
| await openDrawer(page, 'marketing-card-website-visits', 'website-visits-drawer-content'); | ||
| await expect(page.locator('[data-testid="website-visits-drawer-stats"]')).toBeVisible({ timeout: DATA_LOAD_TIMEOUT }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Problem: The fix splits a single "open and wait for data" call into two steps and duplicates the second step at each callsite: await openDrawer(page, 'marketing-card-website-visits', 'website-visits-drawer-content');
await expect(page.locator('[data-testid="website-visits-drawer-stats"]')).toBeVisible({ timeout: DATA_LOAD_TIMEOUT });The same pair appears 5 times in this file (L194-195, L224-225, L248-249, L273-274, L297-298). The reason — drawer-content is always visible once the drawer opens, drawer-stats appears only after Why this is a problem:
Suggested fix: Push the data-load wait back into a helper so each test reads as one intent: /**
* Open a drawer and wait for its data to load (skeleton cleared).
* dataTestId is the element behind the drawer's loading gate (typically `*-drawer-stats`).
*/
async function openDrawerAndWaitForData(
page: Page,
cardTestId: string,
drawerContentTestId: string,
dataTestId: string,
): Promise<void> {
await openDrawer(page, cardTestId, drawerContentTestId);
await expect(page.locator(`[data-testid="${dataTestId}"]`)).toBeVisible({ timeout: DATA_LOAD_TIMEOUT });
}Callsite collapses to: await openDrawerAndWaitForData(
page,
'marketing-card-website-visits',
'website-visits-drawer-content',
'website-visits-drawer-stats',
);The handful of callers that don't need the data wait (the close-button tests, for example) keep using bare Not a blocker for landing this PR — the duplication is small and the tests are correct. Worth a follow-up cleanup so the next person adding a drawer test inherits the right pattern. |
||
| const statCards = page.locator('[data-testid="website-visits-drawer-stats"]').locator('lfx-card'); | ||
| await expect(statCards).toHaveCount(2); | ||
| }); | ||
|
|
@@ -220,8 +221,9 @@ test.describe('Email CTR Drawer', () => { | |
| }); | ||
|
|
||
| test('shows stats and chart sections', async ({ page }) => { | ||
| await openDrawer(page, 'marketing-card-email-ctr', 'email-ctr-drawer-stats'); | ||
| await expect(page.locator('[data-testid="email-ctr-drawer-chart-section"]')).toBeVisible(); | ||
| await openDrawer(page, 'marketing-card-email-ctr', 'email-ctr-drawer-content'); | ||
| await expect(page.locator('[data-testid="email-ctr-drawer-stats"]')).toBeVisible({ timeout: DATA_LOAD_TIMEOUT }); | ||
| await expect(page.locator('[data-testid="email-ctr-drawer-email-section"]')).toBeVisible(); | ||
| }); | ||
|
Comment on lines
223
to
227
|
||
|
|
||
| test('closes when close button is clicked', async ({ page }) => { | ||
|
|
@@ -243,7 +245,8 @@ test.describe('Paid Social Reach Drawer', () => { | |
| }); | ||
|
|
||
| test('shows ROAS and impressions charts', async ({ page }) => { | ||
| await openDrawer(page, 'marketing-card-paid-social-reach', 'paid-social-reach-drawer-stats'); | ||
| await openDrawer(page, 'marketing-card-paid-social-reach', 'paid-social-reach-drawer-content'); | ||
| await expect(page.locator('[data-testid="paid-social-reach-drawer-stats"]')).toBeVisible({ timeout: DATA_LOAD_TIMEOUT }); | ||
| await expect(page.locator('[data-testid="paid-social-reach-drawer-roas-chart-section"]')).toBeVisible(); | ||
| await expect(page.locator('[data-testid="paid-social-reach-drawer-chart-section"]')).toBeVisible(); | ||
| }); | ||
|
|
@@ -267,7 +270,8 @@ test.describe('Social Media Drawer', () => { | |
| }); | ||
|
|
||
| test('shows stats and platform breakdown', async ({ page }) => { | ||
| await openDrawer(page, 'marketing-card-social-media', 'social-media-drawer-stats'); | ||
| await openDrawer(page, 'marketing-card-social-media', 'social-media-drawer-content'); | ||
| await expect(page.locator('[data-testid="social-media-drawer-stats"]')).toBeVisible({ timeout: DATA_LOAD_TIMEOUT }); | ||
| await expect(page.locator('[data-testid="social-media-drawer-platforms-section"]')).toBeVisible(); | ||
| }); | ||
|
|
||
|
|
@@ -290,7 +294,8 @@ test.describe('Member Growth Drawer', () => { | |
| }); | ||
|
|
||
| test('shows stats section', async ({ page }) => { | ||
| await openDrawer(page, 'flywheel-pulse-member-growth', 'member-acquisition-drawer-stats'); | ||
| await openDrawer(page, 'flywheel-pulse-member-growth', 'member-acquisition-drawer-content'); | ||
| await expect(page.locator('[data-testid="member-acquisition-drawer-stats"]')).toBeVisible({ timeout: DATA_LOAD_TIMEOUT }); | ||
| const statCards = page.locator('[data-testid="member-acquisition-drawer-stats"]').locator('lfx-card'); | ||
| await expect(statCards).toHaveCount(3); | ||
| }); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem:
domain: 'localhost'is hard-coded against the dev server's host.playwright.config.tscurrently setsbaseURL: 'http://localhost:4200'so this works today, but the cookie is only attached for requests whose host islocalhost— it will not be set when the same suite runs against an override target (preview deployment, staging, a remote CI runner using a different hostname). When that happens thelensRedirectGuardredirect kicks back in and the suite regresses, with the failure looking identical to the bug this PR fixes.Why this is a problem:
BASE_URL=https://preview-xyz.lfx.dev ...(or a similar override) silently loses the cookie protection without a clear error. The next "these tests flake again" investigation has to rediscover what this PR just rediscovered.LENS_COOKIE_KEYandDEFAULT_LENSare already imported from shared — only the domain is environment-specific. Deriving it from the runtime URL keeps the rest of the cookie definition pinned to the same source of truth.page.goto('/me/events', ...)is the same vulnerability. If a future test bypassesopenDialogWithEmptyEvents()and callspage.gotodirectly, the cookie won't be set and the flake returns. (Today, all 19 callers go through this helper — confirmed bygrep. But that's a constraint the future has to remember to honor.)Suggested fix: Derive the domain from Playwright's resolved
baseURLinstead of hard-coding'localhost'. Two reasonable shapes:Option A — beforeEach (or fixture)-level cookie setup, so every test in the file is covered, not just ones that go through
openDialogWithEmptyEvents():Option B — keep the per-helper call but derive the domain from
baseURL:A fixture (Option A) is the cleaner long-term shape — it also stops covers-only-this-helper from being a hidden constraint the file enforces.