Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions frontend/e2e/home-community-rail.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { test, expect } from '@playwright/test';
import { loginAs } from './utils/login';

test.describe('home community rail', () => {
test.beforeEach(async ({ page }) => {
await loginAs(page, 'anderson@dummy.test');
await page.goto('/');
});

test('clicking directly on a family name navigates to their profile', async ({ page }) => {
const name = page.getByText('The Chen Family', { exact: true });
await expect(name).toBeVisible();

const box = await name.boundingBox();
if (!box) throw new Error('Could not measure the family name element');
await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);

await expect(page.getByRole('heading', { name: /Chen/i })).toBeVisible();
});

test('clicking directly on a family avatar navigates to their profile', async ({ page }) => {
const row = page.locator('li', { hasText: 'The Davis Family' });
// Seeded families may render either a real avatar image or the initials
// fallback — match whichever is actually there.
const avatar = row.locator('img, span[aria-hidden="true"]').first();
await expect(avatar).toBeVisible();

const box = await avatar.boundingBox();
if (!box) throw new Error('Could not measure the avatar element');
await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);

await expect(page.getByRole('heading', { name: /Davis/i })).toBeVisible();
});

test('the whole row shows a pointer cursor, including over the name text', async ({ page }) => {
const name = page.getByText('The Brooks Family', { exact: true });
const box = await name.boundingBox();
if (!box) throw new Error('Could not measure the family name element');

const cursor = await page.evaluate(([x, y]) => {
const el = document.elementFromPoint(x, y);
return el ? getComputedStyle(el).cursor : null;
}, [box.x + box.width / 2, box.y + box.height / 2]);

expect(cursor).toBe('pointer');
});
});
8 changes: 4 additions & 4 deletions frontend/src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,17 @@ export default function HomePage() {
<img
src={fam.avatarUrl}
alt=""
className="relative z-0 h-8 w-8 rounded-full object-cover"
className="pointer-events-none h-8 w-8 rounded-full object-cover"
/>
) : (
<span
aria-hidden="true"
className="relative z-0 flex h-8 w-8 items-center justify-center rounded-full bg-surface-warm text-sm font-bold text-brand-primary"
className="pointer-events-none flex h-8 w-8 items-center justify-center rounded-full bg-surface-warm text-sm font-bold text-brand-primary"
>
{initialBadge(fam.name)}
</span>
)}
<span className="relative z-0 min-w-0 flex-1">
<span className="pointer-events-none min-w-0 flex-1">
<span className="block max-w-[24ch] truncate text-sm font-semibold">
{fam.name}
</span>
Expand All @@ -133,7 +133,7 @@ export default function HomePage() {
<Link
to={`/family/${fam.id}?requestSlot=${fam.nextFreeSlotId}`}
title="Open playdate slot — click to request"
className="relative z-10 inline-flex items-center gap-1 rounded-full border border-brand-warm/50 bg-brand-warm/20 px-2 py-0.5 text-[10px] font-bold text-[#8a5a12] hover:bg-brand-warm/30"
className="pointer-events-auto relative z-10 inline-flex items-center gap-1 rounded-full border border-brand-warm/50 bg-brand-warm/20 px-2 py-0.5 text-[10px] font-bold text-[#8a5a12] hover:bg-brand-warm/30"
>
🗓 Playdate
</Link>
Expand Down
Loading