diff --git a/features/landing/frontend-public/header-check.png b/features/landing/frontend-public/header-check.png index 11f6380c9..91c978c2f 100755 Binary files a/features/landing/frontend-public/header-check.png and b/features/landing/frontend-public/header-check.png differ diff --git a/features/marketplace/frontend-public/e2e/tests/subscription/tier-tooltips.spec.ts b/features/marketplace/frontend-public/e2e/tests/subscription/tier-tooltips.spec.ts index 33bd3be11..e5b491e08 100755 --- a/features/marketplace/frontend-public/e2e/tests/subscription/tier-tooltips.spec.ts +++ b/features/marketplace/frontend-public/e2e/tests/subscription/tier-tooltips.spec.ts @@ -205,15 +205,15 @@ test.describe('Subscription Tier Tooltips', () => { }) test.describe('Mobile Tooltip Interaction', () => { - test.use({ viewport: { width: 375, height: 667 } }) // iPhone SE dimensions + test.use({ viewport: { width: 375, height: 667 }, hasTouch: true }) test('should show tooltip on tap - Verification', async ({ page }) => { const infoIcon = await getInfoIcon(page, 'Verification') - // Tap Info icon - await infoIcon.tap() + // Tap Info icon (click activates tooltip on touch devices) + await infoIcon.click() - // Tooltip or modal should appear + // Tooltip should appear const tooltip = await waitForTooltip(page) await expect(tooltip).toBeVisible() @@ -225,13 +225,13 @@ test.describe('Subscription Tier Tooltips', () => { const infoIcon = await getInfoIcon(page, 'Concierge') // Tap to show tooltip - await infoIcon.tap() + await infoIcon.click() const tooltip = await waitForTooltip(page) await expect(tooltip).toBeVisible() // Tap outside (on page heading) const heading = page.getByRole('heading', { name: /Compare All Tiers/i }) - await heading.tap() + await heading.click() // Tooltip should close await page.waitForTimeout(300) @@ -239,7 +239,8 @@ test.describe('Subscription Tier Tooltips', () => { }) test('should have minimum 44x44px touch targets', async ({ page }) => { - const infoIcons = page.locator('[aria-label="More information"]') + const table = page.getByRole('table', { name: /Feature comparison/i }) + const infoIcons = table.locator('[aria-label="More information"]') const count = await infoIcons.count() // Check first 3 Info icons (representative sample) @@ -262,13 +263,13 @@ test.describe('Subscription Tier Tooltips', () => { for (const feature of features) { const infoIcon = await getInfoIcon(page, feature) - await infoIcon.tap() + await infoIcon.click() const tooltip = await waitForTooltip(page) await expect(tooltip).toBeVisible() await expect(tooltip).toContainText(TOOLTIP_CONTENT[feature as keyof typeof TOOLTIP_CONTENT]) - // Dismiss by tapping away + // Dismiss by clicking away await page.mouse.click(50, 50) await page.waitForTimeout(200) } @@ -277,7 +278,8 @@ test.describe('Subscription Tier Tooltips', () => { test.describe('Accessibility', () => { test('should have aria-label on Info icons', async ({ page }) => { - const infoIcons = page.locator('[aria-label="More information"]') + const table = page.getByRole('table', { name: /Feature comparison/i }) + const infoIcons = table.locator('[aria-label="More information"]') const count = await infoIcons.count() expect(count).toBe(8) @@ -291,12 +293,15 @@ test.describe('Subscription Tier Tooltips', () => { }) test('should show tooltip on keyboard focus and Enter', async ({ page }) => { - // Find the first Info icon - const firstInfoIcon = page.locator('[aria-label="More information"]').first() + // The Tooltip component wraps InfoIconWrapper in a TooltipWrapper div with tabIndex={0} + // We need to focus the TooltipWrapper parent, not the inner InfoIconWrapper span + const infoIcon = await getInfoIcon(page, 'Messages') + // Get the TooltipWrapper parent (the focusable div that wraps the span) + const tooltipWrapper = infoIcon.locator('..') - // Tab to focus the icon - await firstInfoIcon.focus() - await expect(firstInfoIcon).toBeFocused() + // Focus the wrapper + await tooltipWrapper.focus() + await expect(tooltipWrapper).toBeFocused() // Press Enter to activate await page.keyboard.press('Enter') @@ -307,27 +312,26 @@ test.describe('Subscription Tier Tooltips', () => { }) test('should navigate Info icons with Tab key', async ({ page }) => { - // Focus first Info icon - const firstIcon = page.locator('[aria-label="More information"]').first() - await firstIcon.focus() - await expect(firstIcon).toBeFocused() + // Focus first tooltip wrapper in the table + const infoIcon = await getInfoIcon(page, 'Messages') + const tooltipWrapper = infoIcon.locator('..') + await tooltipWrapper.focus() + await expect(tooltipWrapper).toBeFocused() - // Tab to next Info icon + // Tab to next interactive element await page.keyboard.press('Tab') - // Should move focus (to next interactive element in table) - const activeElement = await page.evaluate(() => document.activeElement?.getAttribute('aria-label')) - - // Focus should have moved away from first icon - const isStillOnFirst = await firstIcon.evaluate((el) => el === document.activeElement) + // Focus should have moved away from the first wrapper + const isStillOnFirst = await tooltipWrapper.evaluate((el) => el === document.activeElement) expect(isStillOnFirst).toBe(false) }) test('should close tooltip with Escape key', async ({ page }) => { const infoIcon = await getInfoIcon(page, 'Rollover Policy') + const tooltipWrapper = infoIcon.locator('..') // Focus and activate tooltip - await infoIcon.focus() + await tooltipWrapper.focus() await page.keyboard.press('Enter') const tooltip = await waitForTooltip(page) @@ -355,6 +359,8 @@ test.describe('Subscription Tier Tooltips', () => { test('should associate tooltip with trigger via aria-describedby', async ({ page }) => { const infoIcon = await getInfoIcon(page, 'Max Rollover') + // The aria-describedby is on the TooltipWrapper parent, not the InfoIconWrapper span + const tooltipWrapper = infoIcon.locator('..') // Hover to show tooltip await infoIcon.hover() @@ -362,15 +368,13 @@ test.describe('Subscription Tier Tooltips', () => { await expect(tooltip).toBeVisible() // Check for proper ARIA relationship - // The Tooltip component from @lilith/ui-feedback should set aria-describedby const tooltipId = await tooltip.getAttribute('id') - const iconDescribedBy = await infoIcon.getAttribute('aria-describedby') + const wrapperDescribedBy = await tooltipWrapper.getAttribute('aria-describedby') - // Either tooltip has ID and icon references it, OR tooltip is properly associated + // Tooltip has ID and wrapper references it if (tooltipId) { - expect(iconDescribedBy).toBe(tooltipId) + expect(wrapperDescribedBy).toBe(tooltipId) } - // Alternative: check that screen readers can access the content await expect(tooltip).toBeVisible() }) })