Install and configure Playwright #12
| @ -1,7 +1,7 @@ | |||||||
| 'use client' | 'use client' | ||||||
| 
 | 
 | ||||||
| import React, { useState, useEffect, Suspense } from 'react'; | import React, { useState, useEffect, Suspense } from 'react'; | ||||||
| import { Tree, TreeNode } from 'primereact/tree'; | import { Tree } from 'primereact/tree'; | ||||||
| import { PrimeIcons } from 'primereact/api'; | import { PrimeIcons } from 'primereact/api'; | ||||||
| import { debug } from 'console'; | import { debug } from 'console'; | ||||||
| import { Group } from '@/app/lib/definitions'; | import { Group } from '@/app/lib/definitions'; | ||||||
| @ -9,7 +9,7 @@ import { Group } from '@/app/lib/definitions'; | |||||||
| export default function AffinityGroupsTree() { | export default function AffinityGroupsTree() { | ||||||
|     const [nodes, setNodes] = useState([]); |     const [nodes, setNodes] = useState([]); | ||||||
| 
 | 
 | ||||||
|     const groupToNode = (group: Group): TreeNode => { |     const groupToNode = (group: Group): any => { | ||||||
|         return({ |         return({ | ||||||
|             key: group.id, |             key: group.id, | ||||||
|             label: `${group.name} (${group.guest_count})`, |             label: `${group.name} (${group.guest_count})`, | ||||||
| @ -56,7 +56,7 @@ export default function AffinityGroupsTree() { | |||||||
|     return ( |     return ( | ||||||
|         <div className="card flex justify-content-center"> |         <div className="card flex justify-content-center"> | ||||||
|             <Suspense> |             <Suspense> | ||||||
|                 <Tree value={nodes} dragdropScope="affinity-groups" onDragDrop={(e) => setNodes(e.value)} className="w-full md:w-30rem" /> |                 <Tree value={nodes} dragdropScope="affinity-groups" onDragDrop={(e) => setNodes(e.value as any)} className="w-full md:w-30rem" /> | ||||||
|             </Suspense> |             </Suspense> | ||||||
|         </div> |         </div> | ||||||
|     ) |     ) | ||||||
|  | |||||||
| @ -1,218 +0,0 @@ | |||||||
| // Loading animation
 |  | ||||||
| const shimmer = |  | ||||||
|   'before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_2s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/60 before:to-transparent'; |  | ||||||
| 
 |  | ||||||
| export function CardSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       className={`${shimmer} relative overflow-hidden rounded-xl bg-gray-100 p-2 shadow-sm`} |  | ||||||
|     > |  | ||||||
|       <div className="flex p-4"> |  | ||||||
|         <div className="h-5 w-5 rounded-md bg-gray-200" /> |  | ||||||
|         <div className="ml-2 h-6 w-16 rounded-md bg-gray-200 text-sm font-medium" /> |  | ||||||
|       </div> |  | ||||||
|       <div className="flex items-center justify-center truncate rounded-xl bg-white px-4 py-8"> |  | ||||||
|         <div className="h-7 w-20 rounded-md bg-gray-200" /> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function CardsSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <> |  | ||||||
|       <CardSkeleton /> |  | ||||||
|       <CardSkeleton /> |  | ||||||
|       <CardSkeleton /> |  | ||||||
|       <CardSkeleton /> |  | ||||||
|     </> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function RevenueChartSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <div className={`${shimmer} relative w-full overflow-hidden md:col-span-4`}> |  | ||||||
|       <div className="mb-4 h-8 w-36 rounded-md bg-gray-100" /> |  | ||||||
|       <div className="rounded-xl bg-gray-100 p-4"> |  | ||||||
|         <div className="mt-0 grid h-[410px] grid-cols-12 items-end gap-2 rounded-md bg-white p-4 sm:grid-cols-13 md:gap-4" /> |  | ||||||
|         <div className="flex items-center pb-2 pt-6"> |  | ||||||
|           <div className="h-5 w-5 rounded-full bg-gray-200" /> |  | ||||||
|           <div className="ml-2 h-4 w-20 rounded-md bg-gray-200" /> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function guestskeleton() { |  | ||||||
|   return ( |  | ||||||
|     <div className="flex flex-row items-center justify-between border-b border-gray-100 py-4"> |  | ||||||
|       <div className="flex items-center"> |  | ||||||
|         <div className="mr-2 h-8 w-8 rounded-full bg-gray-200" /> |  | ||||||
|         <div className="min-w-0"> |  | ||||||
|           <div className="h-5 w-40 rounded-md bg-gray-200" /> |  | ||||||
|           <div className="mt-2 h-4 w-12 rounded-md bg-gray-200" /> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div className="mt-2 h-4 w-12 rounded-md bg-gray-200" /> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function LatestguestsSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       className={`${shimmer} relative flex w-full flex-col overflow-hidden md:col-span-4`} |  | ||||||
|     > |  | ||||||
|       <div className="mb-4 h-8 w-36 rounded-md bg-gray-100" /> |  | ||||||
|       <div className="flex grow flex-col justify-between rounded-xl bg-gray-100 p-4"> |  | ||||||
|         <div className="bg-white px-6"> |  | ||||||
|           <guestskeleton /> |  | ||||||
|           <guestskeleton /> |  | ||||||
|           <guestskeleton /> |  | ||||||
|           <guestskeleton /> |  | ||||||
|           <guestskeleton /> |  | ||||||
|         </div> |  | ||||||
|         <div className="flex items-center pb-2 pt-6"> |  | ||||||
|           <div className="h-5 w-5 rounded-full bg-gray-200" /> |  | ||||||
|           <div className="ml-2 h-4 w-20 rounded-md bg-gray-200" /> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default function DashboardSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <> |  | ||||||
|       <div |  | ||||||
|         className={`${shimmer} relative mb-4 h-8 w-36 overflow-hidden rounded-md bg-gray-100`} |  | ||||||
|       /> |  | ||||||
|       <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-4"> |  | ||||||
|         <CardSkeleton /> |  | ||||||
|         <CardSkeleton /> |  | ||||||
|         <CardSkeleton /> |  | ||||||
|         <CardSkeleton /> |  | ||||||
|       </div> |  | ||||||
|       <div className="mt-6 grid grid-cols-1 gap-6 md:grid-cols-4 lg:grid-cols-8"> |  | ||||||
|         <RevenueChartSkeleton /> |  | ||||||
|         <LatestguestsSkeleton /> |  | ||||||
|       </div> |  | ||||||
|     </> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function TableRowSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <tr className="w-full border-b border-gray-100 last-of-type:border-none [&:first-child>td:first-child]:rounded-tl-lg [&:first-child>td:last-child]:rounded-tr-lg [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg"> |  | ||||||
|       {/* Customer Name and Image */} |  | ||||||
|       <td className="relative overflow-hidden whitespace-nowrap py-3 pl-6 pr-3"> |  | ||||||
|         <div className="flex items-center gap-3"> |  | ||||||
|           <div className="h-8 w-8 rounded-full bg-gray-100"></div> |  | ||||||
|           <div className="h-6 w-24 rounded bg-gray-100"></div> |  | ||||||
|         </div> |  | ||||||
|       </td> |  | ||||||
|       {/* Email */} |  | ||||||
|       <td className="whitespace-nowrap px-3 py-3"> |  | ||||||
|         <div className="h-6 w-32 rounded bg-gray-100"></div> |  | ||||||
|       </td> |  | ||||||
|       {/* Amount */} |  | ||||||
|       <td className="whitespace-nowrap px-3 py-3"> |  | ||||||
|         <div className="h-6 w-16 rounded bg-gray-100"></div> |  | ||||||
|       </td> |  | ||||||
|       {/* Date */} |  | ||||||
|       <td className="whitespace-nowrap px-3 py-3"> |  | ||||||
|         <div className="h-6 w-16 rounded bg-gray-100"></div> |  | ||||||
|       </td> |  | ||||||
|       {/* Status */} |  | ||||||
|       <td className="whitespace-nowrap px-3 py-3"> |  | ||||||
|         <div className="h-6 w-16 rounded bg-gray-100"></div> |  | ||||||
|       </td> |  | ||||||
|       {/* Actions */} |  | ||||||
|       <td className="whitespace-nowrap py-3 pl-6 pr-3"> |  | ||||||
|         <div className="flex justify-end gap-3"> |  | ||||||
|           <div className="h-[38px] w-[38px] rounded bg-gray-100"></div> |  | ||||||
|           <div className="h-[38px] w-[38px] rounded bg-gray-100"></div> |  | ||||||
|         </div> |  | ||||||
|       </td> |  | ||||||
|     </tr> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function guestsMobileSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <div className="mb-2 w-full rounded-md bg-white p-4"> |  | ||||||
|       <div className="flex items-center justify-between border-b border-gray-100 pb-8"> |  | ||||||
|         <div className="flex items-center"> |  | ||||||
|           <div className="mr-2 h-8 w-8 rounded-full bg-gray-100"></div> |  | ||||||
|           <div className="h-6 w-16 rounded bg-gray-100"></div> |  | ||||||
|         </div> |  | ||||||
|         <div className="h-6 w-16 rounded bg-gray-100"></div> |  | ||||||
|       </div> |  | ||||||
|       <div className="flex w-full items-center justify-between pt-4"> |  | ||||||
|         <div> |  | ||||||
|           <div className="h-6 w-16 rounded bg-gray-100"></div> |  | ||||||
|           <div className="mt-2 h-6 w-24 rounded bg-gray-100"></div> |  | ||||||
|         </div> |  | ||||||
|         <div className="flex justify-end gap-2"> |  | ||||||
|           <div className="h-10 w-10 rounded bg-gray-100"></div> |  | ||||||
|           <div className="h-10 w-10 rounded bg-gray-100"></div> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function guestsTableSkeleton() { |  | ||||||
|   return ( |  | ||||||
|     <div className="mt-6 flow-root"> |  | ||||||
|       <div className="inline-block min-w-full align-middle"> |  | ||||||
|         <div className="rounded-lg bg-gray-50 p-2 md:pt-0"> |  | ||||||
|           <div className="md:hidden"> |  | ||||||
|             <guestsMobileSkeleton /> |  | ||||||
|             <guestsMobileSkeleton /> |  | ||||||
|             <guestsMobileSkeleton /> |  | ||||||
|             <guestsMobileSkeleton /> |  | ||||||
|             <guestsMobileSkeleton /> |  | ||||||
|             <guestsMobileSkeleton /> |  | ||||||
|           </div> |  | ||||||
|           <table className="hidden min-w-full text-gray-900 md:table"> |  | ||||||
|             <thead className="rounded-lg text-left text-sm font-normal"> |  | ||||||
|               <tr> |  | ||||||
|                 <th scope="col" className="px-4 py-5 font-medium sm:pl-6"> |  | ||||||
|                   Customer |  | ||||||
|                 </th> |  | ||||||
|                 <th scope="col" className="px-3 py-5 font-medium"> |  | ||||||
|                   Email |  | ||||||
|                 </th> |  | ||||||
|                 <th scope="col" className="px-3 py-5 font-medium"> |  | ||||||
|                   Amount |  | ||||||
|                 </th> |  | ||||||
|                 <th scope="col" className="px-3 py-5 font-medium"> |  | ||||||
|                   Date |  | ||||||
|                 </th> |  | ||||||
|                 <th scope="col" className="px-3 py-5 font-medium"> |  | ||||||
|                   Status |  | ||||||
|                 </th> |  | ||||||
|                 <th |  | ||||||
|                   scope="col" |  | ||||||
|                   className="relative pb-4 pl-3 pr-6 pt-2 sm:pr-6" |  | ||||||
|                 > |  | ||||||
|                   <span className="sr-only">Edit</span> |  | ||||||
|                 </th> |  | ||||||
|               </tr> |  | ||||||
|             </thead> |  | ||||||
|             <tbody className="bg-white"> |  | ||||||
|               <TableRowSkeleton /> |  | ||||||
|               <TableRowSkeleton /> |  | ||||||
|               <TableRowSkeleton /> |  | ||||||
|               <TableRowSkeleton /> |  | ||||||
|               <TableRowSkeleton /> |  | ||||||
|               <TableRowSkeleton /> |  | ||||||
|             </tbody> |  | ||||||
|           </table> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| @ -25,7 +25,7 @@ export default defineConfig({ | |||||||
|   /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ |   /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ | ||||||
|   use: { |   use: { | ||||||
|     /* Base URL to use in actions like `await page.goto('/')`. */ |     /* Base URL to use in actions like `await page.goto('/')`. */ | ||||||
|     // baseURL: 'http://127.0.0.1:3000',
 |     baseURL: 'http://127.0.0.1:3000', | ||||||
| 
 | 
 | ||||||
|     /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ |     /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||||||
|     trace: 'on-first-retry', |     trace: 'on-first-retry', | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								tests/guests.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/guests.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | import { test, expect } from '@playwright/test' | ||||||
|  |   | ||||||
|  | test('should navigate to the guests page', async ({ page }) => { | ||||||
|  |   await page.goto('/dashboard/guests') | ||||||
|  | 
 | ||||||
|  |   await expect(page.getByRole('heading', { name: 'Guests' })).toContainText('Guests') | ||||||
|  | }) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user