Back to list
LuisDavidTF

smart-recipe-planner-test-ui

by LuisDavidTF

Culina Smart is a menu planning app with integrated AI to suggest recipes to include in your weekly meal plan based on your nutritional goals and the ingredients you have at home.

0🍴 0📅 Jan 21, 2026

SKILL.md


name: smart-recipe-planner-test-ui description: > Smart Recipe Planner UI testing patterns with Playwright. Trigger: When writing E2E tests for the frontend, creating Page Objects, or validating UI flows in Smart Recipe Planner. license: Apache-2.0 metadata: author: ant-gravity version: "1.0" scope: [root, ui] auto_invoke: "Writing Playwright E2E tests" allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task

  • playwright - Generic Playwright patterns (selectors, MCP workflow)
  • smart-recipe-planner-ui - UI component structure

File Structure

e2e/                      # Root level e2e folder (Smart Recipe Planner convention)
├── base-page.ts          # Parent class for ALL pages
├── helpers.ts            # Shared utilities (auth, data gen)
├── auth/                 # Auth feature tests
│   ├── login-page.ts
│   └── login.spec.ts
├── recipes/              # Recipe management tests
│   ├── recipe-page.ts
│   └── recipes.spec.ts
└── planning/             # Meal planning tests
    ├── planner-page.ts
    └── planner.spec.ts

Smart Recipe Planner Page Object Pattern

BasePage

import { Page, Locator, expect } from "@playwright/test";

export class BasePage {
  constructor(protected page: Page) {}

  async goto(path: string): Promise<void> {
    await this.page.goto(path);
    await this.page.waitForLoadState("domcontentloaded");
  }

  // Shared UI components (Header, Footer, Toast)
  async getToastMessage(): Promise<string | null> {
    const toast = this.page.locator('[role="status"]'); // Radix/Sonner toast
    if (await toast.isVisible()) {
      return toast.textContent();
    }
    return null;
  }
}

Feature Page (Example: Recipe)

import { BasePage } from "../base-page";
import { Page, Locator, expect } from "@playwright/test";

export class RecipePage extends BasePage {
  readonly createButton: Locator;
  readonly titleInput: Locator;
  readonly saveButton: Locator;

  constructor(page: Page) {
    super(page);
    this.createButton = page.getByRole("button", { name: "New Recipe" });
    this.titleInput = page.getByLabel("Recipe Title");
    this.saveButton = page.getByRole("button", { name: "Save Recipe" });
  }

  async createRecipe(title: string) {
    await this.createButton.click();
    await this.titleInput.fill(title);
    await this.saveButton.click();
  }
}

Testing Guidelines

Authentication

Tests that require authentication should use a setup state or helper to bypass manual login for every test, unless testing the login flow itself.

// e2e/auth.setup.ts
import { test as setup } from '@playwright/test';

setup('authenticate', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('test@example.com');
  await page.getByLabel('Password').fill('password');
  await page.getByRole('button', { name: 'Sign in' }).click();
  await page.waitForURL('/dashboard');
  await page.context().storageState({ path: 'playwright/.auth/user.json' });
});

Data Test IDs

Prefer accessibility roles (getByRole, getByLabel), but use data-testid for elements that are hard to select otherwise (like specific containers or non-interactive elements).

<!-- Component code -->
<div data-testid="recipe-card-123">...</div>
// Test code
await page.getByTestId("recipe-card-123").click();

Commands

# Run all E2E tests
npx playwright test

# Run UI mode (interactive)
npx playwright test --ui

# Debug tests
npx playwright test --debug

QA Checklist

  • Page Objects are used (no direct locators in spec files)
  • Tests are independent (clean state)
  • Sensitive data is not hardcoded (use env vars)
  • Happy path AND error states are tested
  • Mobile viewports are considered (if configured)

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon