diff --git a/.eslintignore b/.eslintignore index 3f2b2e49..a9ea1674 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,6 +4,8 @@ **/*.test.tsx **/*.test.js **/*.test.jsx +**/*.spec.ts +**/*.spec.tsx app/api/gift-exchanges/\[id\]/draw/route.ts app/api/gift-exchanges/\[id\]/giftSuggestions/route.ts app/api/gift-exchanges/\[id\]/members/route.ts diff --git a/app/onboarding/page.tsx b/app/onboarding/page.tsx index ba4cbe5e..c315c877 100644 --- a/app/onboarding/page.tsx +++ b/app/onboarding/page.tsx @@ -264,7 +264,7 @@ function Onboarding() { value={isSubmitted ? 100 : (currentStep / steps.length) * 100} className="my-4" /> - + {steps[currentStep].title} diff --git a/app/page.tsx b/app/page.tsx index 44bccb08..37a68320 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -63,7 +63,10 @@ export default function Home() {
{/* Hero Section */}
-

+

Make Gift-Giving Magical

@@ -76,7 +79,7 @@ export default function Home() { {/* Features Section */}

{features.map((feature) => ( - + {feature.icon} {feature.title} @@ -113,7 +116,7 @@ export default function Home() { description: 'Exchange gifts and spread joy with your group!', }, ].map((step, index) => ( -
+
{step.step}
diff --git a/package.json b/package.json index 01407297..c6254caa 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "cmdk": "^1.0.0", "cross-env": "^7.0.3", "date-fns": "^3.6.0", + "dotenv": "^16.5.0", "eslint-plugin-jsdoc": "^50.6.6", "framer-motion": "^12.6.3", "lucide-react": "^0.464.0", diff --git a/playwright.config.ts b/playwright.config.ts index d9a6bd65..9091a745 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -7,9 +7,9 @@ import { defineConfig, devices } from '@playwright/test'; * Read environment variables from file. * https://github.com/motdotla/dotenv */ -// import dotenv from 'dotenv'; -// import path from 'path'; -// dotenv.config({ path: path.resolve(__dirname, '.env') }); +import dotenv from 'dotenv'; +import path from 'path'; +dotenv.config({ path: path.resolve(__dirname, '.env') }); /** * See https://playwright.dev/docs/test-configuration. @@ -29,7 +29,7 @@ export default defineConfig({ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ - // baseURL: 'http://127.0.0.1:3000', + baseURL: 'http://localhost:4000', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', @@ -74,9 +74,9 @@ export default defineConfig({ ], /* Run your local dev server before starting the tests */ - // webServer: { - // command: 'npm run start', - // url: 'http://127.0.0.1:3000', - // reuseExistingServer: !process.env.CI, - // }, + webServer: { + command: 'pnpm dev --port 4000', + url: 'http://localhost:4000', + reuseExistingServer: !process.env.CI, + }, }); diff --git a/tests/tests-examples/loggedIn.spec.ts b/tests/tests-examples/loggedIn.spec.ts new file mode 100644 index 00000000..2316be27 --- /dev/null +++ b/tests/tests-examples/loggedIn.spec.ts @@ -0,0 +1,16 @@ +// Copyright (c) Gridiron Survivor. +// Licensed under the MIT License. + +import { test, expect } from '@playwright/test'; +import { getSupabaseClient } from '../utils/auth-setup'; +test('Logged in user who hasn’t completed onboarding sees onboarding', async ({ + page, +}) => { + await getSupabaseClient(page, 'playwrightuser@test.com'); + await page.goto('/'); + await expect(page).toHaveURL('/onboarding'); + await expect(page.getByTestId('onboarding-card')).toBeVisible(); + await expect( + page.getByRole('button', { name: 'Next', exact: true }), + ).toBeVisible(); +}); diff --git a/tests/tests-examples/notLoggedIn.spec.ts b/tests/tests-examples/notLoggedIn.spec.ts new file mode 100644 index 00000000..0ae55856 --- /dev/null +++ b/tests/tests-examples/notLoggedIn.spec.ts @@ -0,0 +1,22 @@ +// Copyright (c) Gridiron Survivor. +// Licensed under the MIT License. + +import { test, expect } from '@playwright/test'; + +test('has title', async ({ page }) => { + await page.goto('/'); + + await expect(page.getByTestId('hero-title')).toBeVisible(); +}); + +test('has 4 features', async ({ page }) => { + await page.goto('/'); + + await expect(page.getByTestId('feature')).toHaveCount(4); +}); + +test('has 3 steps', async ({ page }) => { + await page.goto('/'); + + await expect(page.getByTestId('step')).toHaveCount(3); +}); diff --git a/tests/utils/auth-setup.ts b/tests/utils/auth-setup.ts new file mode 100644 index 00000000..67fba026 --- /dev/null +++ b/tests/utils/auth-setup.ts @@ -0,0 +1,52 @@ +// Copyright (c) Gridiron Survivor. +// Licensed under the MIT License. + +import { createClient } from '@supabase/supabase-js'; +import { Page } from '@playwright/test'; + +/** + * Get a Supabase client with authentication set up for Playwright tests + * @param page - The Playwright page object + * @param userEmail - The email of the user to sign in as + * @returns Promise that resolves when authentication is set up + */ +async function getSupabaseClient(page: Page, userEmail: string): Promise { + const supabaseClient = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, + ); + + const { data, error } = await supabaseClient.auth.signInWithPassword({ + email: userEmail, + password: 'password', + }); + if (!data.user) { + throw Error(error?.message); + } + + const projectRef = process.env + .NEXT_PUBLIC_SUPABASE_URL!.split('//')[1] + .split('.')[0]; + await page.context().addCookies([ + { + name: `sb-${projectRef}-auth-token`, + value: JSON.stringify({ + access_token: data.session.access_token, + refresh_token: data.session.refresh_token, + expires_in: 3600, + expires_at: Math.floor(Date.now() / 1000) + 3600, + token_type: 'bearer', + user: { + id: data.user.id, + email: data.user.email, + }, + }), + domain: 'localhost', + path: '/', + httpOnly: false, + secure: false, + }, + ]); +} + +export { getSupabaseClient };