diff --git a/backend/main.py b/backend/main.py index 7972749..245956c 100644 --- a/backend/main.py +++ b/backend/main.py @@ -49,4 +49,5 @@ app.include_router(invites_routes.admin_router) app.include_router(availability_routes.router) app.include_router(booking_routes.router) app.include_router(booking_routes.appointments_router) +app.include_router(booking_routes.admin_appointments_router) app.include_router(meta_routes.router) diff --git a/backend/routes/booking.py b/backend/routes/booking.py index b94b7e4..2902a17 100644 --- a/backend/routes/booking.py +++ b/backend/routes/booking.py @@ -203,6 +203,13 @@ async def create_booking( appointments_router = APIRouter(prefix="/api/appointments", tags=["appointments"]) +async def _get_user_email(db: AsyncSession, user_id: int) -> str: + """Get user email by ID.""" + result = await db.execute(select(User.email).where(User.id == user_id)) + email = result.scalar_one_or_none() + return email or "unknown" + + @appointments_router.get("", response_model=list[AppointmentResponse]) async def get_my_appointments( db: AsyncSession = Depends(get_db), @@ -278,3 +285,84 @@ async def cancel_my_appointment( cancelled_at=appointment.cancelled_at, ) + +# ============================================================================= +# Admin Appointments Endpoints +# ============================================================================= + +admin_appointments_router = APIRouter(prefix="/api/admin/appointments", tags=["admin-appointments"]) + + +@admin_appointments_router.get("", response_model=list[AppointmentResponse]) +async def get_all_appointments( + db: AsyncSession = Depends(get_db), + _current_user: User = Depends(require_permission(Permission.VIEW_ALL_APPOINTMENTS)), +) -> list[AppointmentResponse]: + """Get all appointments (admin only), sorted by date descending.""" + result = await db.execute( + select(Appointment) + .order_by(Appointment.slot_start.desc()) + ) + appointments = result.scalars().all() + + responses = [] + for apt in appointments: + user_email = await _get_user_email(db, apt.user_id) + responses.append(AppointmentResponse( + id=apt.id, + user_id=apt.user_id, + user_email=user_email, + slot_start=apt.slot_start, + slot_end=apt.slot_end, + note=apt.note, + status=apt.status.value, + created_at=apt.created_at, + cancelled_at=apt.cancelled_at, + )) + + return responses + + +@admin_appointments_router.post("/{appointment_id}/cancel", response_model=AppointmentResponse) +async def admin_cancel_appointment( + appointment_id: int, + db: AsyncSession = Depends(get_db), + _current_user: User = Depends(require_permission(Permission.CANCEL_ANY_APPOINTMENT)), +) -> AppointmentResponse: + """Cancel any appointment (admin only).""" + # Get the appointment + result = await db.execute( + select(Appointment).where(Appointment.id == appointment_id) + ) + appointment = result.scalar_one_or_none() + + if not appointment: + raise HTTPException(status_code=404, detail="Appointment not found") + + # Check if already cancelled + if appointment.status != AppointmentStatus.BOOKED: + raise HTTPException( + status_code=400, + detail=f"Cannot cancel appointment with status '{appointment.status.value}'" + ) + + # Cancel the appointment + appointment.status = AppointmentStatus.CANCELLED_BY_ADMIN + appointment.cancelled_at = datetime.now(timezone.utc) + + await db.commit() + await db.refresh(appointment) + + user_email = await _get_user_email(db, appointment.user_id) + + return AppointmentResponse( + id=appointment.id, + user_id=appointment.user_id, + user_email=user_email, + slot_start=appointment.slot_start, + slot_end=appointment.slot_end, + note=appointment.note, + status=appointment.status.value, + created_at=appointment.created_at, + cancelled_at=appointment.cancelled_at, + ) diff --git a/backend/tests/test_booking.py b/backend/tests/test_booking.py index d3367dc..1e5a65f 100644 --- a/backend/tests/test_booking.py +++ b/backend/tests/test_booking.py @@ -656,3 +656,153 @@ class TestCancelAppointment: ) assert len(slots_response.json()["slots"]) == 2 + +# ============================================================================= +# Admin Appointments Tests +# ============================================================================= + +class TestAdminViewAppointments: + """Test admin viewing all appointments.""" + + @pytest.mark.asyncio + async def test_admin_can_view_all_appointments(self, client_factory, regular_user, admin_user): + """Admin can view all appointments.""" + # Admin sets availability + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + await admin_client.put( + "/api/admin/availability", + json={ + "date": str(tomorrow()), + "slots": [{"start_time": "09:00:00", "end_time": "12:00:00"}], + }, + ) + + # User books + async with client_factory.create(cookies=regular_user["cookies"]) as client: + await client.post( + "/api/booking", + json={"slot_start": f"{tomorrow()}T09:00:00Z", "note": "Test"}, + ) + + # Admin views all appointments + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + response = await admin_client.get("/api/admin/appointments") + + assert response.status_code == 200 + data = response.json() + assert len(data) >= 1 + assert any(apt["note"] == "Test" for apt in data) + + @pytest.mark.asyncio + async def test_regular_user_cannot_view_all_appointments(self, client_factory, regular_user): + """Regular user cannot access admin appointments endpoint.""" + async with client_factory.create(cookies=regular_user["cookies"]) as client: + response = await client.get("/api/admin/appointments") + + assert response.status_code == 403 + + @pytest.mark.asyncio + async def test_unauthenticated_cannot_view_all_appointments(self, client): + """Unauthenticated user cannot view appointments.""" + response = await client.get("/api/admin/appointments") + assert response.status_code == 401 + + +class TestAdminCancelAppointment: + """Test admin cancelling appointments.""" + + @pytest.mark.asyncio + async def test_admin_can_cancel_any_appointment(self, client_factory, regular_user, admin_user): + """Admin can cancel any user's appointment.""" + # Admin sets availability + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + await admin_client.put( + "/api/admin/availability", + json={ + "date": str(tomorrow()), + "slots": [{"start_time": "09:00:00", "end_time": "12:00:00"}], + }, + ) + + # User books + async with client_factory.create(cookies=regular_user["cookies"]) as client: + book_response = await client.post( + "/api/booking", + json={"slot_start": f"{tomorrow()}T09:00:00Z"}, + ) + apt_id = book_response.json()["id"] + + # Admin cancels + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + response = await admin_client.post(f"/api/admin/appointments/{apt_id}/cancel") + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "cancelled_by_admin" + assert data["cancelled_at"] is not None + + @pytest.mark.asyncio + async def test_regular_user_cannot_use_admin_cancel(self, client_factory, regular_user, admin_user): + """Regular user cannot use admin cancel endpoint.""" + # Admin sets availability + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + await admin_client.put( + "/api/admin/availability", + json={ + "date": str(tomorrow()), + "slots": [{"start_time": "09:00:00", "end_time": "12:00:00"}], + }, + ) + + # User books + async with client_factory.create(cookies=regular_user["cookies"]) as client: + book_response = await client.post( + "/api/booking", + json={"slot_start": f"{tomorrow()}T09:00:00Z"}, + ) + apt_id = book_response.json()["id"] + + # User tries to use admin cancel endpoint + response = await client.post(f"/api/admin/appointments/{apt_id}/cancel") + + assert response.status_code == 403 + + @pytest.mark.asyncio + async def test_admin_cancel_nonexistent_appointment(self, client_factory, admin_user): + """Returns 404 for non-existent appointment.""" + async with client_factory.create(cookies=admin_user["cookies"]) as client: + response = await client.post("/api/admin/appointments/99999/cancel") + + assert response.status_code == 404 + + @pytest.mark.asyncio + async def test_admin_cannot_cancel_already_cancelled(self, client_factory, regular_user, admin_user): + """Admin cannot cancel an already cancelled appointment.""" + # Admin sets availability + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + await admin_client.put( + "/api/admin/availability", + json={ + "date": str(tomorrow()), + "slots": [{"start_time": "09:00:00", "end_time": "12:00:00"}], + }, + ) + + # User books + async with client_factory.create(cookies=regular_user["cookies"]) as client: + book_response = await client.post( + "/api/booking", + json={"slot_start": f"{tomorrow()}T09:00:00Z"}, + ) + apt_id = book_response.json()["id"] + + # User cancels their own appointment + await client.post(f"/api/appointments/{apt_id}/cancel") + + # Admin tries to cancel again + async with client_factory.create(cookies=admin_user["cookies"]) as admin_client: + response = await admin_client.post(f"/api/admin/appointments/{apt_id}/cancel") + + assert response.status_code == 400 + assert "cancelled_by_user" in response.json()["detail"] + diff --git a/frontend/app/admin/appointments/page.tsx b/frontend/app/admin/appointments/page.tsx new file mode 100644 index 0000000..3dcebed --- /dev/null +++ b/frontend/app/admin/appointments/page.tsx @@ -0,0 +1,259 @@ +"use client"; + +import { useEffect, useState, useCallback } from "react"; +import { Permission } from "../../auth-context"; +import { api } from "../../api"; +import { sharedStyles } from "../../styles/shared"; +import { Header } from "../../components/Header"; +import { useRequireAuth } from "../../hooks/useRequireAuth"; +import { components } from "../../generated/api"; + +type AppointmentResponse = components["schemas"]["AppointmentResponse"]; + +// Helper to format datetime +function formatDateTime(isoString: string): string { + const d = new Date(isoString); + return d.toLocaleString("en-US", { + weekday: "short", + month: "short", + day: "numeric", + hour: "2-digit", + minute: "2-digit", + hour12: false, + }); +} + +// Helper to get status display +function getStatusDisplay(status: string): { text: string; color: string } { + switch (status) { + case "booked": + return { text: "Booked", color: "#28a745" }; + case "cancelled_by_user": + return { text: "Cancelled by user", color: "#dc3545" }; + case "cancelled_by_admin": + return { text: "Cancelled by admin", color: "#dc3545" }; + default: + return { text: status, color: "#666" }; + } +} + +export default function AdminAppointmentsPage() { + const { user, isLoading, isAuthorized } = useRequireAuth({ + requiredPermission: Permission.VIEW_ALL_APPOINTMENTS, + fallbackRedirect: "/", + }); + + const [appointments, setAppointments] = useState([]); + const [isLoadingAppointments, setIsLoadingAppointments] = useState(true); + const [cancellingId, setCancellingId] = useState(null); + const [confirmCancelId, setConfirmCancelId] = useState(null); + const [error, setError] = useState(null); + const [statusFilter, setStatusFilter] = useState("all"); + + const fetchAppointments = useCallback(async () => { + try { + const data = await api.get("/api/admin/appointments"); + setAppointments(data); + } catch (err) { + console.error("Failed to fetch appointments:", err); + setError("Failed to load appointments"); + } finally { + setIsLoadingAppointments(false); + } + }, []); + + useEffect(() => { + if (user && isAuthorized) { + fetchAppointments(); + } + }, [user, isAuthorized, fetchAppointments]); + + const handleCancel = async (appointmentId: number) => { + setCancellingId(appointmentId); + setError(null); + + try { + await api.post(`/api/admin/appointments/${appointmentId}/cancel`, {}); + await fetchAppointments(); + setConfirmCancelId(null); + } catch (err) { + if (err instanceof Error) { + setError(err.message); + } else { + setError("Failed to cancel appointment"); + } + } finally { + setCancellingId(null); + } + }; + + if (isLoading) { + return ( +
+
+
+

Loading...

+
+
+ ); + } + + if (!isAuthorized) { + return null; + } + + const filteredAppointments = appointments.filter((apt) => { + if (statusFilter === "all") return true; + return apt.status === statusFilter; + }); + + const bookedCount = appointments.filter((a) => a.status === "booked").length; + const cancelledCount = appointments.filter((a) => a.status !== "booked").length; + + return ( +
+
+
+

All Appointments

+

+ View and manage all user appointments +

+ + {error && ( +
+ {error} +
+ )} + + {/* Status Filter */} +
+ + +
+ + {isLoadingAppointments ? ( +

Loading appointments...

+ ) : appointments.length === 0 ? ( +

No appointments yet.

+ ) : filteredAppointments.length === 0 ? ( +

No appointments match the filter.

+ ) : ( +
+ {filteredAppointments.map((apt) => { + const status = getStatusDisplay(apt.status); + const isPast = new Date(apt.slot_start) <= new Date(); + return ( +
+
+
+
+ {formatDateTime(apt.slot_start)} +
+
+ User: {apt.user_email} +
+ {apt.note && ( +
+ "{apt.note}" +
+ )} + + {status.text} + +
+ + {apt.status === "booked" && ( +
+ {confirmCancelId === apt.id ? ( +
+ + +
+ ) : ( + + )} +
+ )} +
+
+ ); + })} +
+ )} +
+
+ ); +} + diff --git a/frontend/app/components/Header.tsx b/frontend/app/components/Header.tsx index 06cf08d..db4cb5b 100644 --- a/frontend/app/components/Header.tsx +++ b/frontend/app/components/Header.tsx @@ -7,7 +7,7 @@ import constants from "../../../shared/constants.json"; const { ADMIN, REGULAR } = constants.roles; -type PageId = "counter" | "sum" | "profile" | "invites" | "booking" | "appointments" | "audit" | "admin-invites" | "admin-availability"; +type PageId = "counter" | "sum" | "profile" | "invites" | "booking" | "appointments" | "audit" | "admin-invites" | "admin-availability" | "admin-appointments"; interface HeaderProps { currentPage: PageId; @@ -34,6 +34,7 @@ const ADMIN_NAV_ITEMS: NavItem[] = [ { id: "audit", label: "Audit", href: "/audit", adminOnly: true }, { id: "admin-invites", label: "Invites", href: "/admin/invites", adminOnly: true }, { id: "admin-availability", label: "Availability", href: "/admin/availability", adminOnly: true }, + { id: "admin-appointments", label: "Appointments", href: "/admin/appointments", adminOnly: true }, ]; export function Header({ currentPage }: HeaderProps) { diff --git a/frontend/app/generated/api.ts b/frontend/app/generated/api.ts index f8ee2c1..3a396d0 100644 --- a/frontend/app/generated/api.ts +++ b/frontend/app/generated/api.ts @@ -436,6 +436,46 @@ export interface paths { patch?: never; trace?: never; }; + "/api/admin/appointments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get All Appointments + * @description Get all appointments (admin only), sorted by date descending. + */ + get: operations["get_all_appointments_api_admin_appointments_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/admin/appointments/{appointment_id}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Admin Cancel Appointment + * @description Cancel any appointment (admin only). + */ + post: operations["admin_cancel_appointment_api_admin_appointments__appointment_id__cancel_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/meta/constants": { parameters: { query?: never; @@ -1575,6 +1615,57 @@ export interface operations { }; }; }; + get_all_appointments_api_admin_appointments_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AppointmentResponse"][]; + }; + }; + }; + }; + admin_cancel_appointment_api_admin_appointments__appointment_id__cancel_post: { + parameters: { + query?: never; + header?: never; + path: { + appointment_id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AppointmentResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; get_constants_api_meta_constants_get: { parameters: { query?: never; diff --git a/frontend/test-results/.last-run.json b/frontend/test-results/.last-run.json index 0dc2013..803548d 100644 --- a/frontend/test-results/.last-run.json +++ b/frontend/test-results/.last-run.json @@ -2,9 +2,6 @@ "status": "failed", "failedTests": [ "647d672ac99574a52088-7123e0baf27b194c0b82", - "647d672ac99574a52088-a2e9f69e9c9ef92dc2bb", - "647d672ac99574a52088-f95d3555fba5395917f0", - "a3a10f2351dcc49e1cb9-ac24d656b0f11d39342d", - "50879ed375f8988ef978-7be9cdef76510785fb98" + "647d672ac99574a52088-a2e9f69e9c9ef92dc2bb" ] } \ No newline at end of file diff --git a/frontend/test-results/availability-Availability--16504-s-can-add-availability-slot/error-context.md b/frontend/test-results/availability-Availability--16504-s-can-add-availability-slot/error-context.md index 76eaba8..9a327b4 100644 --- a/frontend/test-results/availability-Availability--16504-s-can-add-availability-slot/error-context.md +++ b/frontend/test-results/availability-Availability--16504-s-can-add-availability-slot/error-context.md @@ -12,112 +12,116 @@ - link "Invites" [ref=e8] [cursor=pointer]: - /url: /admin/invites - generic [ref=e9]: •Availability - - generic [ref=e10]: - - generic [ref=e11]: admin@example.com - - button "Sign out" [ref=e12] [cursor=pointer] - - generic [ref=e14]: - - generic [ref=e16]: - - heading "Availability" [level=1] [ref=e17] - - paragraph [ref=e18]: Configure your available time slots for the next 30 days - - generic [ref=e19]: - - generic [ref=e20] [cursor=pointer]: - - generic [ref=e21]: - - generic [ref=e22]: Mon, Dec 22 - - button "⎘" [ref=e23] - - generic [ref=e25]: 09:00 - 12:00 - - generic [ref=e26] [cursor=pointer]: - - generic [ref=e28]: Tue, Dec 23 - - generic [ref=e30]: No availability - - generic [ref=e31] [cursor=pointer]: - - generic [ref=e33]: Wed, Dec 24 - - generic [ref=e35]: No availability - - generic [ref=e36] [cursor=pointer]: - - generic [ref=e38]: Thu, Dec 25 - - generic [ref=e40]: No availability - - generic [ref=e41] [cursor=pointer]: - - generic [ref=e43]: Fri, Dec 26 - - generic [ref=e45]: No availability - - generic [ref=e46] [cursor=pointer]: - - generic [ref=e48]: Sat, Dec 27 - - generic [ref=e50]: No availability - - generic [ref=e51] [cursor=pointer]: - - generic [ref=e53]: Sun, Dec 28 - - generic [ref=e55]: No availability - - generic [ref=e56] [cursor=pointer]: - - generic [ref=e58]: Mon, Dec 29 - - generic [ref=e60]: No availability - - generic [ref=e61] [cursor=pointer]: - - generic [ref=e63]: Tue, Dec 30 - - generic [ref=e65]: No availability - - generic [ref=e66] [cursor=pointer]: - - generic [ref=e68]: Wed, Dec 31 - - generic [ref=e70]: No availability - - generic [ref=e71] [cursor=pointer]: - - generic [ref=e73]: Thu, Jan 1 - - generic [ref=e75]: No availability - - generic [ref=e76] [cursor=pointer]: - - generic [ref=e78]: Fri, Jan 2 - - generic [ref=e80]: No availability - - generic [ref=e81] [cursor=pointer]: - - generic [ref=e83]: Sat, Jan 3 - - generic [ref=e85]: No availability - - generic [ref=e86] [cursor=pointer]: - - generic [ref=e88]: Sun, Jan 4 - - generic [ref=e90]: No availability - - generic [ref=e91] [cursor=pointer]: - - generic [ref=e93]: Mon, Jan 5 - - generic [ref=e95]: No availability - - generic [ref=e96] [cursor=pointer]: - - generic [ref=e98]: Tue, Jan 6 - - generic [ref=e100]: No availability - - generic [ref=e101] [cursor=pointer]: - - generic [ref=e103]: Wed, Jan 7 - - generic [ref=e105]: No availability - - generic [ref=e106] [cursor=pointer]: - - generic [ref=e108]: Thu, Jan 8 - - generic [ref=e110]: No availability - - generic [ref=e111] [cursor=pointer]: - - generic [ref=e113]: Fri, Jan 9 - - generic [ref=e115]: No availability - - generic [ref=e116] [cursor=pointer]: - - generic [ref=e118]: Sat, Jan 10 - - generic [ref=e120]: No availability - - generic [ref=e121] [cursor=pointer]: - - generic [ref=e123]: Sun, Jan 11 - - generic [ref=e125]: No availability - - generic [ref=e126] [cursor=pointer]: - - generic [ref=e128]: Mon, Jan 12 - - generic [ref=e130]: No availability - - generic [ref=e131] [cursor=pointer]: - - generic [ref=e133]: Tue, Jan 13 - - generic [ref=e135]: No availability - - generic [ref=e136] [cursor=pointer]: - - generic [ref=e138]: Wed, Jan 14 - - generic [ref=e140]: No availability - - generic [ref=e141] [cursor=pointer]: - - generic [ref=e143]: Thu, Jan 15 - - generic [ref=e145]: No availability - - generic [ref=e146] [cursor=pointer]: - - generic [ref=e148]: Fri, Jan 16 - - generic [ref=e150]: No availability - - generic [ref=e151] [cursor=pointer]: - - generic [ref=e153]: Sat, Jan 17 - - generic [ref=e155]: No availability - - generic [ref=e156] [cursor=pointer]: - - generic [ref=e158]: Sun, Jan 18 - - generic [ref=e160]: No availability - - generic [ref=e161] [cursor=pointer]: - - generic [ref=e163]: Mon, Jan 19 - - generic [ref=e165]: No availability - - generic [ref=e166] [cursor=pointer]: - - generic [ref=e168]: Tue, Jan 20 - - generic [ref=e170]: No availability - - status [ref=e171]: - - generic [ref=e172]: - - img [ref=e174] - - generic [ref=e176]: + - generic [ref=e10]: + - text: • + - link "Appointments" [ref=e11] [cursor=pointer]: + - /url: /admin/appointments + - generic [ref=e12]: + - generic [ref=e13]: admin@example.com + - button "Sign out" [ref=e14] [cursor=pointer] + - generic [ref=e16]: + - generic [ref=e18]: + - heading "Availability" [level=1] [ref=e19] + - paragraph [ref=e20]: Configure your available time slots for the next 30 days + - generic [ref=e21]: + - generic [ref=e22] [cursor=pointer]: + - generic [ref=e23]: + - generic [ref=e24]: Mon, Dec 22 + - button "⎘" [ref=e25] + - generic [ref=e27]: 09:00 - 12:00 + - generic [ref=e28] [cursor=pointer]: + - generic [ref=e30]: Tue, Dec 23 + - generic [ref=e32]: No availability + - generic [ref=e33] [cursor=pointer]: + - generic [ref=e35]: Wed, Dec 24 + - generic [ref=e37]: No availability + - generic [ref=e38] [cursor=pointer]: + - generic [ref=e40]: Thu, Dec 25 + - generic [ref=e42]: No availability + - generic [ref=e43] [cursor=pointer]: + - generic [ref=e45]: Fri, Dec 26 + - generic [ref=e47]: No availability + - generic [ref=e48] [cursor=pointer]: + - generic [ref=e50]: Sat, Dec 27 + - generic [ref=e52]: No availability + - generic [ref=e53] [cursor=pointer]: + - generic [ref=e55]: Sun, Dec 28 + - generic [ref=e57]: No availability + - generic [ref=e58] [cursor=pointer]: + - generic [ref=e60]: Mon, Dec 29 + - generic [ref=e62]: No availability + - generic [ref=e63] [cursor=pointer]: + - generic [ref=e65]: Tue, Dec 30 + - generic [ref=e67]: No availability + - generic [ref=e68] [cursor=pointer]: + - generic [ref=e70]: Wed, Dec 31 + - generic [ref=e72]: No availability + - generic [ref=e73] [cursor=pointer]: + - generic [ref=e75]: Thu, Jan 1 + - generic [ref=e77]: No availability + - generic [ref=e78] [cursor=pointer]: + - generic [ref=e80]: Fri, Jan 2 + - generic [ref=e82]: No availability + - generic [ref=e83] [cursor=pointer]: + - generic [ref=e85]: Sat, Jan 3 + - generic [ref=e87]: No availability + - generic [ref=e88] [cursor=pointer]: + - generic [ref=e90]: Sun, Jan 4 + - generic [ref=e92]: No availability + - generic [ref=e93] [cursor=pointer]: + - generic [ref=e95]: Mon, Jan 5 + - generic [ref=e97]: No availability + - generic [ref=e98] [cursor=pointer]: + - generic [ref=e100]: Tue, Jan 6 + - generic [ref=e102]: No availability + - generic [ref=e103] [cursor=pointer]: + - generic [ref=e105]: Wed, Jan 7 + - generic [ref=e107]: No availability + - generic [ref=e108] [cursor=pointer]: + - generic [ref=e110]: Thu, Jan 8 + - generic [ref=e112]: No availability + - generic [ref=e113] [cursor=pointer]: + - generic [ref=e115]: Fri, Jan 9 + - generic [ref=e117]: No availability + - generic [ref=e118] [cursor=pointer]: + - generic [ref=e120]: Sat, Jan 10 + - generic [ref=e122]: No availability + - generic [ref=e123] [cursor=pointer]: + - generic [ref=e125]: Sun, Jan 11 + - generic [ref=e127]: No availability + - generic [ref=e128] [cursor=pointer]: + - generic [ref=e130]: Mon, Jan 12 + - generic [ref=e132]: No availability + - generic [ref=e133] [cursor=pointer]: + - generic [ref=e135]: Tue, Jan 13 + - generic [ref=e137]: No availability + - generic [ref=e138] [cursor=pointer]: + - generic [ref=e140]: Wed, Jan 14 + - generic [ref=e142]: No availability + - generic [ref=e143] [cursor=pointer]: + - generic [ref=e145]: Thu, Jan 15 + - generic [ref=e147]: No availability + - generic [ref=e148] [cursor=pointer]: + - generic [ref=e150]: Fri, Jan 16 + - generic [ref=e152]: No availability + - generic [ref=e153] [cursor=pointer]: + - generic [ref=e155]: Sat, Jan 17 + - generic [ref=e157]: No availability + - generic [ref=e158] [cursor=pointer]: + - generic [ref=e160]: Sun, Jan 18 + - generic [ref=e162]: No availability + - generic [ref=e163] [cursor=pointer]: + - generic [ref=e165]: Mon, Jan 19 + - generic [ref=e167]: No availability + - generic [ref=e168] [cursor=pointer]: + - generic [ref=e170]: Tue, Jan 20 + - generic [ref=e172]: No availability + - status [ref=e173]: + - generic [ref=e174]: + - img [ref=e176] + - generic [ref=e178]: - text: Static route - - button "Hide static indicator" [ref=e177] [cursor=pointer]: - - img [ref=e178] - - alert [ref=e181] + - button "Hide static indicator" [ref=e179] [cursor=pointer]: + - img [ref=e180] + - alert [ref=e183] ``` \ No newline at end of file diff --git a/frontend/test-results/availability-Availability--5fe6c-cess-can-clear-availability/error-context.md b/frontend/test-results/availability-Availability--5fe6c-cess-can-clear-availability/error-context.md index 76eaba8..9a327b4 100644 --- a/frontend/test-results/availability-Availability--5fe6c-cess-can-clear-availability/error-context.md +++ b/frontend/test-results/availability-Availability--5fe6c-cess-can-clear-availability/error-context.md @@ -12,112 +12,116 @@ - link "Invites" [ref=e8] [cursor=pointer]: - /url: /admin/invites - generic [ref=e9]: •Availability - - generic [ref=e10]: - - generic [ref=e11]: admin@example.com - - button "Sign out" [ref=e12] [cursor=pointer] - - generic [ref=e14]: - - generic [ref=e16]: - - heading "Availability" [level=1] [ref=e17] - - paragraph [ref=e18]: Configure your available time slots for the next 30 days - - generic [ref=e19]: - - generic [ref=e20] [cursor=pointer]: - - generic [ref=e21]: - - generic [ref=e22]: Mon, Dec 22 - - button "⎘" [ref=e23] - - generic [ref=e25]: 09:00 - 12:00 - - generic [ref=e26] [cursor=pointer]: - - generic [ref=e28]: Tue, Dec 23 - - generic [ref=e30]: No availability - - generic [ref=e31] [cursor=pointer]: - - generic [ref=e33]: Wed, Dec 24 - - generic [ref=e35]: No availability - - generic [ref=e36] [cursor=pointer]: - - generic [ref=e38]: Thu, Dec 25 - - generic [ref=e40]: No availability - - generic [ref=e41] [cursor=pointer]: - - generic [ref=e43]: Fri, Dec 26 - - generic [ref=e45]: No availability - - generic [ref=e46] [cursor=pointer]: - - generic [ref=e48]: Sat, Dec 27 - - generic [ref=e50]: No availability - - generic [ref=e51] [cursor=pointer]: - - generic [ref=e53]: Sun, Dec 28 - - generic [ref=e55]: No availability - - generic [ref=e56] [cursor=pointer]: - - generic [ref=e58]: Mon, Dec 29 - - generic [ref=e60]: No availability - - generic [ref=e61] [cursor=pointer]: - - generic [ref=e63]: Tue, Dec 30 - - generic [ref=e65]: No availability - - generic [ref=e66] [cursor=pointer]: - - generic [ref=e68]: Wed, Dec 31 - - generic [ref=e70]: No availability - - generic [ref=e71] [cursor=pointer]: - - generic [ref=e73]: Thu, Jan 1 - - generic [ref=e75]: No availability - - generic [ref=e76] [cursor=pointer]: - - generic [ref=e78]: Fri, Jan 2 - - generic [ref=e80]: No availability - - generic [ref=e81] [cursor=pointer]: - - generic [ref=e83]: Sat, Jan 3 - - generic [ref=e85]: No availability - - generic [ref=e86] [cursor=pointer]: - - generic [ref=e88]: Sun, Jan 4 - - generic [ref=e90]: No availability - - generic [ref=e91] [cursor=pointer]: - - generic [ref=e93]: Mon, Jan 5 - - generic [ref=e95]: No availability - - generic [ref=e96] [cursor=pointer]: - - generic [ref=e98]: Tue, Jan 6 - - generic [ref=e100]: No availability - - generic [ref=e101] [cursor=pointer]: - - generic [ref=e103]: Wed, Jan 7 - - generic [ref=e105]: No availability - - generic [ref=e106] [cursor=pointer]: - - generic [ref=e108]: Thu, Jan 8 - - generic [ref=e110]: No availability - - generic [ref=e111] [cursor=pointer]: - - generic [ref=e113]: Fri, Jan 9 - - generic [ref=e115]: No availability - - generic [ref=e116] [cursor=pointer]: - - generic [ref=e118]: Sat, Jan 10 - - generic [ref=e120]: No availability - - generic [ref=e121] [cursor=pointer]: - - generic [ref=e123]: Sun, Jan 11 - - generic [ref=e125]: No availability - - generic [ref=e126] [cursor=pointer]: - - generic [ref=e128]: Mon, Jan 12 - - generic [ref=e130]: No availability - - generic [ref=e131] [cursor=pointer]: - - generic [ref=e133]: Tue, Jan 13 - - generic [ref=e135]: No availability - - generic [ref=e136] [cursor=pointer]: - - generic [ref=e138]: Wed, Jan 14 - - generic [ref=e140]: No availability - - generic [ref=e141] [cursor=pointer]: - - generic [ref=e143]: Thu, Jan 15 - - generic [ref=e145]: No availability - - generic [ref=e146] [cursor=pointer]: - - generic [ref=e148]: Fri, Jan 16 - - generic [ref=e150]: No availability - - generic [ref=e151] [cursor=pointer]: - - generic [ref=e153]: Sat, Jan 17 - - generic [ref=e155]: No availability - - generic [ref=e156] [cursor=pointer]: - - generic [ref=e158]: Sun, Jan 18 - - generic [ref=e160]: No availability - - generic [ref=e161] [cursor=pointer]: - - generic [ref=e163]: Mon, Jan 19 - - generic [ref=e165]: No availability - - generic [ref=e166] [cursor=pointer]: - - generic [ref=e168]: Tue, Jan 20 - - generic [ref=e170]: No availability - - status [ref=e171]: - - generic [ref=e172]: - - img [ref=e174] - - generic [ref=e176]: + - generic [ref=e10]: + - text: • + - link "Appointments" [ref=e11] [cursor=pointer]: + - /url: /admin/appointments + - generic [ref=e12]: + - generic [ref=e13]: admin@example.com + - button "Sign out" [ref=e14] [cursor=pointer] + - generic [ref=e16]: + - generic [ref=e18]: + - heading "Availability" [level=1] [ref=e19] + - paragraph [ref=e20]: Configure your available time slots for the next 30 days + - generic [ref=e21]: + - generic [ref=e22] [cursor=pointer]: + - generic [ref=e23]: + - generic [ref=e24]: Mon, Dec 22 + - button "⎘" [ref=e25] + - generic [ref=e27]: 09:00 - 12:00 + - generic [ref=e28] [cursor=pointer]: + - generic [ref=e30]: Tue, Dec 23 + - generic [ref=e32]: No availability + - generic [ref=e33] [cursor=pointer]: + - generic [ref=e35]: Wed, Dec 24 + - generic [ref=e37]: No availability + - generic [ref=e38] [cursor=pointer]: + - generic [ref=e40]: Thu, Dec 25 + - generic [ref=e42]: No availability + - generic [ref=e43] [cursor=pointer]: + - generic [ref=e45]: Fri, Dec 26 + - generic [ref=e47]: No availability + - generic [ref=e48] [cursor=pointer]: + - generic [ref=e50]: Sat, Dec 27 + - generic [ref=e52]: No availability + - generic [ref=e53] [cursor=pointer]: + - generic [ref=e55]: Sun, Dec 28 + - generic [ref=e57]: No availability + - generic [ref=e58] [cursor=pointer]: + - generic [ref=e60]: Mon, Dec 29 + - generic [ref=e62]: No availability + - generic [ref=e63] [cursor=pointer]: + - generic [ref=e65]: Tue, Dec 30 + - generic [ref=e67]: No availability + - generic [ref=e68] [cursor=pointer]: + - generic [ref=e70]: Wed, Dec 31 + - generic [ref=e72]: No availability + - generic [ref=e73] [cursor=pointer]: + - generic [ref=e75]: Thu, Jan 1 + - generic [ref=e77]: No availability + - generic [ref=e78] [cursor=pointer]: + - generic [ref=e80]: Fri, Jan 2 + - generic [ref=e82]: No availability + - generic [ref=e83] [cursor=pointer]: + - generic [ref=e85]: Sat, Jan 3 + - generic [ref=e87]: No availability + - generic [ref=e88] [cursor=pointer]: + - generic [ref=e90]: Sun, Jan 4 + - generic [ref=e92]: No availability + - generic [ref=e93] [cursor=pointer]: + - generic [ref=e95]: Mon, Jan 5 + - generic [ref=e97]: No availability + - generic [ref=e98] [cursor=pointer]: + - generic [ref=e100]: Tue, Jan 6 + - generic [ref=e102]: No availability + - generic [ref=e103] [cursor=pointer]: + - generic [ref=e105]: Wed, Jan 7 + - generic [ref=e107]: No availability + - generic [ref=e108] [cursor=pointer]: + - generic [ref=e110]: Thu, Jan 8 + - generic [ref=e112]: No availability + - generic [ref=e113] [cursor=pointer]: + - generic [ref=e115]: Fri, Jan 9 + - generic [ref=e117]: No availability + - generic [ref=e118] [cursor=pointer]: + - generic [ref=e120]: Sat, Jan 10 + - generic [ref=e122]: No availability + - generic [ref=e123] [cursor=pointer]: + - generic [ref=e125]: Sun, Jan 11 + - generic [ref=e127]: No availability + - generic [ref=e128] [cursor=pointer]: + - generic [ref=e130]: Mon, Jan 12 + - generic [ref=e132]: No availability + - generic [ref=e133] [cursor=pointer]: + - generic [ref=e135]: Tue, Jan 13 + - generic [ref=e137]: No availability + - generic [ref=e138] [cursor=pointer]: + - generic [ref=e140]: Wed, Jan 14 + - generic [ref=e142]: No availability + - generic [ref=e143] [cursor=pointer]: + - generic [ref=e145]: Thu, Jan 15 + - generic [ref=e147]: No availability + - generic [ref=e148] [cursor=pointer]: + - generic [ref=e150]: Fri, Jan 16 + - generic [ref=e152]: No availability + - generic [ref=e153] [cursor=pointer]: + - generic [ref=e155]: Sat, Jan 17 + - generic [ref=e157]: No availability + - generic [ref=e158] [cursor=pointer]: + - generic [ref=e160]: Sun, Jan 18 + - generic [ref=e162]: No availability + - generic [ref=e163] [cursor=pointer]: + - generic [ref=e165]: Mon, Jan 19 + - generic [ref=e167]: No availability + - generic [ref=e168] [cursor=pointer]: + - generic [ref=e170]: Tue, Jan 20 + - generic [ref=e172]: No availability + - status [ref=e173]: + - generic [ref=e174]: + - img [ref=e176] + - generic [ref=e178]: - text: Static route - - button "Hide static indicator" [ref=e177] [cursor=pointer]: - - img [ref=e178] - - alert [ref=e181] + - button "Hide static indicator" [ref=e179] [cursor=pointer]: + - img [ref=e180] + - alert [ref=e183] ``` \ No newline at end of file diff --git a/frontend/test-results/availability-Availability--aa4bd-cess-can-add-multiple-slots/error-context.md b/frontend/test-results/availability-Availability--aa4bd-cess-can-add-multiple-slots/error-context.md deleted file mode 100644 index 76eaba8..0000000 --- a/frontend/test-results/availability-Availability--aa4bd-cess-can-add-multiple-slots/error-context.md +++ /dev/null @@ -1,123 +0,0 @@ -# Page snapshot - -```yaml -- generic [active] [ref=e1]: - - main [ref=e2]: - - generic [ref=e3]: - - generic [ref=e4]: - - link "Audit" [ref=e6] [cursor=pointer]: - - /url: /audit - - generic [ref=e7]: - - text: • - - link "Invites" [ref=e8] [cursor=pointer]: - - /url: /admin/invites - - generic [ref=e9]: •Availability - - generic [ref=e10]: - - generic [ref=e11]: admin@example.com - - button "Sign out" [ref=e12] [cursor=pointer] - - generic [ref=e14]: - - generic [ref=e16]: - - heading "Availability" [level=1] [ref=e17] - - paragraph [ref=e18]: Configure your available time slots for the next 30 days - - generic [ref=e19]: - - generic [ref=e20] [cursor=pointer]: - - generic [ref=e21]: - - generic [ref=e22]: Mon, Dec 22 - - button "⎘" [ref=e23] - - generic [ref=e25]: 09:00 - 12:00 - - generic [ref=e26] [cursor=pointer]: - - generic [ref=e28]: Tue, Dec 23 - - generic [ref=e30]: No availability - - generic [ref=e31] [cursor=pointer]: - - generic [ref=e33]: Wed, Dec 24 - - generic [ref=e35]: No availability - - generic [ref=e36] [cursor=pointer]: - - generic [ref=e38]: Thu, Dec 25 - - generic [ref=e40]: No availability - - generic [ref=e41] [cursor=pointer]: - - generic [ref=e43]: Fri, Dec 26 - - generic [ref=e45]: No availability - - generic [ref=e46] [cursor=pointer]: - - generic [ref=e48]: Sat, Dec 27 - - generic [ref=e50]: No availability - - generic [ref=e51] [cursor=pointer]: - - generic [ref=e53]: Sun, Dec 28 - - generic [ref=e55]: No availability - - generic [ref=e56] [cursor=pointer]: - - generic [ref=e58]: Mon, Dec 29 - - generic [ref=e60]: No availability - - generic [ref=e61] [cursor=pointer]: - - generic [ref=e63]: Tue, Dec 30 - - generic [ref=e65]: No availability - - generic [ref=e66] [cursor=pointer]: - - generic [ref=e68]: Wed, Dec 31 - - generic [ref=e70]: No availability - - generic [ref=e71] [cursor=pointer]: - - generic [ref=e73]: Thu, Jan 1 - - generic [ref=e75]: No availability - - generic [ref=e76] [cursor=pointer]: - - generic [ref=e78]: Fri, Jan 2 - - generic [ref=e80]: No availability - - generic [ref=e81] [cursor=pointer]: - - generic [ref=e83]: Sat, Jan 3 - - generic [ref=e85]: No availability - - generic [ref=e86] [cursor=pointer]: - - generic [ref=e88]: Sun, Jan 4 - - generic [ref=e90]: No availability - - generic [ref=e91] [cursor=pointer]: - - generic [ref=e93]: Mon, Jan 5 - - generic [ref=e95]: No availability - - generic [ref=e96] [cursor=pointer]: - - generic [ref=e98]: Tue, Jan 6 - - generic [ref=e100]: No availability - - generic [ref=e101] [cursor=pointer]: - - generic [ref=e103]: Wed, Jan 7 - - generic [ref=e105]: No availability - - generic [ref=e106] [cursor=pointer]: - - generic [ref=e108]: Thu, Jan 8 - - generic [ref=e110]: No availability - - generic [ref=e111] [cursor=pointer]: - - generic [ref=e113]: Fri, Jan 9 - - generic [ref=e115]: No availability - - generic [ref=e116] [cursor=pointer]: - - generic [ref=e118]: Sat, Jan 10 - - generic [ref=e120]: No availability - - generic [ref=e121] [cursor=pointer]: - - generic [ref=e123]: Sun, Jan 11 - - generic [ref=e125]: No availability - - generic [ref=e126] [cursor=pointer]: - - generic [ref=e128]: Mon, Jan 12 - - generic [ref=e130]: No availability - - generic [ref=e131] [cursor=pointer]: - - generic [ref=e133]: Tue, Jan 13 - - generic [ref=e135]: No availability - - generic [ref=e136] [cursor=pointer]: - - generic [ref=e138]: Wed, Jan 14 - - generic [ref=e140]: No availability - - generic [ref=e141] [cursor=pointer]: - - generic [ref=e143]: Thu, Jan 15 - - generic [ref=e145]: No availability - - generic [ref=e146] [cursor=pointer]: - - generic [ref=e148]: Fri, Jan 16 - - generic [ref=e150]: No availability - - generic [ref=e151] [cursor=pointer]: - - generic [ref=e153]: Sat, Jan 17 - - generic [ref=e155]: No availability - - generic [ref=e156] [cursor=pointer]: - - generic [ref=e158]: Sun, Jan 18 - - generic [ref=e160]: No availability - - generic [ref=e161] [cursor=pointer]: - - generic [ref=e163]: Mon, Jan 19 - - generic [ref=e165]: No availability - - generic [ref=e166] [cursor=pointer]: - - generic [ref=e168]: Tue, Jan 20 - - generic [ref=e170]: No availability - - status [ref=e171]: - - generic [ref=e172]: - - img [ref=e174] - - generic [ref=e176]: - - text: Static route - - button "Hide static indicator" [ref=e177] [cursor=pointer]: - - img [ref=e178] - - alert [ref=e181] -``` \ No newline at end of file diff --git a/frontend/test-results/booking-Booking-Page---Wit-0ce9d-ppears-from-available-slots/error-context.md b/frontend/test-results/booking-Booking-Page---Wit-0ce9d-ppears-from-available-slots/error-context.md deleted file mode 100644 index 3a786a0..0000000 --- a/frontend/test-results/booking-Booking-Page---Wit-0ce9d-ppears-from-available-slots/error-context.md +++ /dev/null @@ -1,160 +0,0 @@ -# Page snapshot - -```yaml -- generic [active] [ref=e1]: - - generic [ref=e2]: - - generic [ref=e3]: - - generic [ref=e4]: - - link "Counter" [ref=e6] [cursor=pointer]: - - /url: / - - generic [ref=e7]: - - text: • - - link "Sum" [ref=e8] [cursor=pointer]: - - /url: /sum - - generic [ref=e9]: •Book - - generic [ref=e10]: - - text: • - - link "Appointments" [ref=e11] [cursor=pointer]: - - /url: /appointments - - generic [ref=e12]: - - text: • - - link "My Invites" [ref=e13] [cursor=pointer]: - - /url: /invites - - generic [ref=e14]: - - text: • - - link "My Profile" [ref=e15] [cursor=pointer]: - - /url: /profile - - generic [ref=e16]: - - generic [ref=e17]: user@example.com - - button "Sign out" [ref=e18] [cursor=pointer] - - main [ref=e19]: - - heading "Book an Appointment" [level=1] [ref=e20] - - paragraph [ref=e21]: Select a date to see available 15-minute slots - - generic [ref=e22]: "Request failed: 409" - - generic [ref=e23]: - - heading "Select a Date" [level=2] [ref=e24] - - generic [ref=e25]: - - button "Mon Dec 22" [ref=e26] [cursor=pointer]: - - generic [ref=e27]: Mon - - generic [ref=e28]: Dec 22 - - button "Tue Dec 23" [ref=e29] [cursor=pointer]: - - generic [ref=e30]: Tue - - generic [ref=e31]: Dec 23 - - button "Wed Dec 24" [ref=e32] [cursor=pointer]: - - generic [ref=e33]: Wed - - generic [ref=e34]: Dec 24 - - button "Thu Dec 25" [ref=e35] [cursor=pointer]: - - generic [ref=e36]: Thu - - generic [ref=e37]: Dec 25 - - button "Fri Dec 26" [ref=e38] [cursor=pointer]: - - generic [ref=e39]: Fri - - generic [ref=e40]: Dec 26 - - button "Sat Dec 27" [ref=e41] [cursor=pointer]: - - generic [ref=e42]: Sat - - generic [ref=e43]: Dec 27 - - button "Sun Dec 28" [ref=e44] [cursor=pointer]: - - generic [ref=e45]: Sun - - generic [ref=e46]: Dec 28 - - button "Mon Dec 29" [ref=e47] [cursor=pointer]: - - generic [ref=e48]: Mon - - generic [ref=e49]: Dec 29 - - button "Tue Dec 30" [ref=e50] [cursor=pointer]: - - generic [ref=e51]: Tue - - generic [ref=e52]: Dec 30 - - button "Wed Dec 31" [ref=e53] [cursor=pointer]: - - generic [ref=e54]: Wed - - generic [ref=e55]: Dec 31 - - button "Thu Jan 1" [ref=e56] [cursor=pointer]: - - generic [ref=e57]: Thu - - generic [ref=e58]: Jan 1 - - button "Fri Jan 2" [ref=e59] [cursor=pointer]: - - generic [ref=e60]: Fri - - generic [ref=e61]: Jan 2 - - button "Sat Jan 3" [ref=e62] [cursor=pointer]: - - generic [ref=e63]: Sat - - generic [ref=e64]: Jan 3 - - button "Sun Jan 4" [ref=e65] [cursor=pointer]: - - generic [ref=e66]: Sun - - generic [ref=e67]: Jan 4 - - button "Mon Jan 5" [ref=e68] [cursor=pointer]: - - generic [ref=e69]: Mon - - generic [ref=e70]: Jan 5 - - button "Tue Jan 6" [ref=e71] [cursor=pointer]: - - generic [ref=e72]: Tue - - generic [ref=e73]: Jan 6 - - button "Wed Jan 7" [ref=e74] [cursor=pointer]: - - generic [ref=e75]: Wed - - generic [ref=e76]: Jan 7 - - button "Thu Jan 8" [ref=e77] [cursor=pointer]: - - generic [ref=e78]: Thu - - generic [ref=e79]: Jan 8 - - button "Fri Jan 9" [ref=e80] [cursor=pointer]: - - generic [ref=e81]: Fri - - generic [ref=e82]: Jan 9 - - button "Sat Jan 10" [ref=e83] [cursor=pointer]: - - generic [ref=e84]: Sat - - generic [ref=e85]: Jan 10 - - button "Sun Jan 11" [ref=e86] [cursor=pointer]: - - generic [ref=e87]: Sun - - generic [ref=e88]: Jan 11 - - button "Mon Jan 12" [ref=e89] [cursor=pointer]: - - generic [ref=e90]: Mon - - generic [ref=e91]: Jan 12 - - button "Tue Jan 13" [ref=e92] [cursor=pointer]: - - generic [ref=e93]: Tue - - generic [ref=e94]: Jan 13 - - button "Wed Jan 14" [ref=e95] [cursor=pointer]: - - generic [ref=e96]: Wed - - generic [ref=e97]: Jan 14 - - button "Thu Jan 15" [ref=e98] [cursor=pointer]: - - generic [ref=e99]: Thu - - generic [ref=e100]: Jan 15 - - button "Fri Jan 16" [ref=e101] [cursor=pointer]: - - generic [ref=e102]: Fri - - generic [ref=e103]: Jan 16 - - button "Sat Jan 17" [ref=e104] [cursor=pointer]: - - generic [ref=e105]: Sat - - generic [ref=e106]: Jan 17 - - button "Sun Jan 18" [ref=e107] [cursor=pointer]: - - generic [ref=e108]: Sun - - generic [ref=e109]: Jan 18 - - button "Mon Jan 19" [ref=e110] [cursor=pointer]: - - generic [ref=e111]: Mon - - generic [ref=e112]: Jan 19 - - button "Tue Jan 20" [ref=e113] [cursor=pointer]: - - generic [ref=e114]: Tue - - generic [ref=e115]: Jan 20 - - generic [ref=e116]: - - heading "Available Slots for Monday, December 22" [level=2] [ref=e117] - - generic [ref=e118]: - - button "10:00" [ref=e119] [cursor=pointer] - - button "10:45" [ref=e120] [cursor=pointer] - - button "11:00" [ref=e121] [cursor=pointer] - - button "11:15" [ref=e122] [cursor=pointer] - - button "11:30" [ref=e123] [cursor=pointer] - - button "11:45" [ref=e124] [cursor=pointer] - - button "12:00" [ref=e125] [cursor=pointer] - - button "12:15" [ref=e126] [cursor=pointer] - - button "12:30" [ref=e127] [cursor=pointer] - - button "12:45" [ref=e128] [cursor=pointer] - - generic [ref=e129]: - - heading "Confirm Booking" [level=3] [ref=e130] - - paragraph [ref=e131]: - - strong [ref=e132]: "Time:" - - text: 11:00 - 11:15 - - generic [ref=e133]: - - generic [ref=e134]: Note (optional, max 144 chars) - - textbox "Add a note about your appointment..." [ref=e135] - - generic [ref=e136]: 0/144 - - generic [ref=e137]: - - button "Book Appointment" [ref=e138] [cursor=pointer] - - button "Cancel" [ref=e139] [cursor=pointer] - - status [ref=e140]: - - generic [ref=e141]: - - img [ref=e143] - - generic [ref=e145]: - - text: Static route - - button "Hide static indicator" [ref=e146] [cursor=pointer]: - - img [ref=e147] - - alert [ref=e150] -``` \ No newline at end of file diff --git a/frontend/test-results/counter-Counter---Authenticated-displays-counter-value/error-context.md b/frontend/test-results/counter-Counter---Authenticated-displays-counter-value/error-context.md deleted file mode 100644 index 38ad869..0000000 --- a/frontend/test-results/counter-Counter---Authenticated-displays-counter-value/error-context.md +++ /dev/null @@ -1,46 +0,0 @@ -# Page snapshot - -```yaml -- generic [active] [ref=e1]: - - status [ref=e2]: - - generic [ref=e3]: - - img [ref=e5] - - generic [ref=e7]: - - text: Static route - - button "Hide static indicator" [ref=e8] [cursor=pointer]: - - img [ref=e9] - - alert [ref=e12]: ... - - main [ref=e13]: - - generic [ref=e14]: - - generic [ref=e15]: - - generic [ref=e16]: Counter - - generic [ref=e17]: - - text: • - - link "Sum" [ref=e18] [cursor=pointer]: - - /url: /sum - - generic [ref=e19]: - - text: • - - link "Book" [ref=e20] [cursor=pointer]: - - /url: /booking - - generic [ref=e21]: - - text: • - - link "Appointments" [ref=e22] [cursor=pointer]: - - /url: /appointments - - generic [ref=e23]: - - text: • - - link "My Invites" [ref=e24] [cursor=pointer]: - - /url: /invites - - generic [ref=e25]: - - text: • - - link "My Profile" [ref=e26] [cursor=pointer]: - - /url: /profile - - generic [ref=e27]: - - generic [ref=e28]: counter-1766272960115-d79hw5@example.com - - button "Sign out" [ref=e29] [cursor=pointer] - - generic [ref=e31]: - - generic [ref=e32]: Current Count - - heading "0" [level=1] [ref=e33] - - button "+ Increment" [ref=e34] [cursor=pointer]: - - generic [ref=e35]: + - - text: Increment -``` \ No newline at end of file