This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CookCLI is a command-line interface for managing Cooklang recipes. It's written in Rust and includes a web server with server-side rendered HTML using Askama templates and Tailwind CSS. The project follows UNIX philosophy where each command does one thing well.
# Full release build (includes CSS compilation)
make release
# Development build
cargo build
make build # Includes CSS compilation
# Build CSS only
make css
npm run build-css
# Build JS only
make js
npm run build-js
# Build specific workspace member
cargo build -p cookcli
# Run without building
cargo run -- [command] [args]# Run all tests
cargo test
# Run specific test
cargo test test_name
# Run tests with output
cargo test -- --nocapture
# Run with debug logging
RUST_LOG=debug cargo run -- [command]
RUST_LOG=trace cargo run -- [command] # More verbose# Start development server with CSS built
make dev_server
# Start development with CSS watch mode
make css-watch # In one terminal
cargo run -- server ./seed # In another terminal
# Install dependencies (first time setup)
npm install
# Build CSS for production
npm run build-css
# Watch CSS changes during development
npm run watch-css
# Build JS for production
npm run build-js
# Watch JS changes during development
npm run watch-jscargo fmt # Format code
cargo clippy # Lint codeThis is a Cargo workspace with multiple crates:
cookcli(this crate) - The CLI application../cooklang-rs- Core Cooklang parser and models../cooklang-find- Recipe discovery and search../cooklang-reports- Template-based report generation../cooklang-import- Recipe import from websites (external dependency)
Each command is a module in src/ with a consistent pattern:
XxxArgsstruct insrc/args.rsor module file - Clap argument definitionspub fn run(ctx: &Context, args: XxxArgs) -> Result<()>- Entry point- Commands receive a
Contextwith base_path, aisle, and pantry configuration
The Context struct (in src/main.rs) provides:
base_path: Current working directory for recipesaisle(): Returns path to aisle.conf (local./config/or global~/.config/cook/)pantry(): Returns path to pantry.conf (same search pattern)
Configuration search order:
./config/[aisle.conf|pantry.conf]- Local to recipe directory~/Library/Application Support/cook/(macOS) or~/.config/cook/(Linux)
recipe: Parse and display recipes (supports multiple output formats)shopping_list: Generate shopping lists with ingredient aggregationserver: Web server using Axum + Askama templates with Tailwind CSSsearch: Full-text recipe searchimport: Import from websites via cooklang-importdoctor: Validate recipes and check configurationsseed: Initialize with example recipesreport: Generate custom outputs using Jinja2 templatesupdate: Self-update the CookCLI binary to the latest version (can be disabled with --no-self-update feature)
util/: Shared utilities for parsing, conversion, and output formatting- Recipe parsing and scaling
- Output format conversions (human, JSON, YAML, Markdown, Cooklang)
- Shopping list generation with aisle/pantry support
- Backend: Axum web framework in
src/server/ - Frontend: Server-side rendered HTML using Askama templates
- Templates: Located in
templates/directory - Styling: Tailwind CSS with custom components
- API handlers in
src/server/handlers/ - Static files served from
static/directory - Shopping list stored as tab-delimited files in
/tmp/
- Recipe discovery via
cooklang-find(handles paths and search) - Parsing via
cooklangparser (lenient mode for validation) - Scaling and conversion in
util/modules - Output formatting based on requested format
- Uses
anyhow::Resultthroughout for error propagation - User-friendly error messages with context
- Special handling for recipe validation (warnings vs errors)
- Scaling notation:
recipe.cook:2(uses colon) - Handled in
util::split_recipe_name_and_scaling_factor() - Applied during parsing before output
- Ingredients with same name are automatically combined
- Unit conversion handled by cooklang crate
- Aisle categorization via aisle.conf
- Pantry filtering via pantry.conf (TOML format with quantities and dates)
validate: Checks syntax, deprecated features, and recipe referencesaisle: Finds ingredients not in aisle configuration- Exit codes: Normal (0) or strict mode (1) for CI/CD
- Uses cooklang-reports with Jinja2 templates
- Config builder pattern for scale, datastore, aisle, pantry
- Falls back to context configurations if not specified
.cookfiles use Cooklang markup- Supports YAML frontmatter or
>>metadata (deprecated) - Output formats: human, json, yaml, markdown, cooklang
The web UI uses server-side rendering with Askama templates:
- Templates located in
templates/directory - Base template (
base.html) provides common layout - Page-specific templates extend the base template
- Template data structures defined in
src/server/templates.rs
- Tailwind CSS for utility-first styling
- Custom components defined in
static/css/input.css - Compiled CSS output in
static/css/output.css - Configuration in
tailwind.config.js
base.html- Common layout with navigation and searchrecipes.html- Recipe listing with directory navigationrecipe.html- Individual recipe display with scalingshopping_list.html- Shopping list managementpreferences.html- User preferences and settings
- Recipe Browsing: Directory-based navigation with breadcrumbs
- Recipe Display: Ingredients, steps, metadata with colorful badges
- Shopping List: Persistent storage in
/tmp/shopping_list.txt - Recipe Scaling: Dynamic scaling with URL parameters
- Search: Real-time recipe search with dropdown results
- Responsive Design: Mobile-friendly layout with Tailwind
Custom Tailwind components for consistent styling:
.recipe-card- Recipe cards with gradient top border.ingredient-badge- Orange gradient badges for ingredients.cookware-badge- Green gradient badges for cookware.timer-badge- Red gradient badges for timers.metadata-pill- Clean outline badges for metadata.nav-pill- Navigation items with hover effects.step-number- Circular step numbers with gradient
Currently no automated tests (as noted in CONTRIBUTING.md). Manual testing approach:
- Use
cook seedto create test recipes - Test each command with various options
- Validate output formats
- Check error handling with invalid inputs
Uses semantic commit messages for automated releases:
feat:- New featuresfix:- Bug fixesdocs:- Documentation changeschore:- Maintenance tasks
Always run these checks before creating a PR:
cargo fmt # Fix formatting
cargo clippy # Check for lint warnings
cargo test # Run testsAll three must pass cleanly with no warnings or errors.
- Add variant to
Commandenum insrc/args.rs - Create module in
src/withXxxArgsstruct andrun()function - Add case in
main.rsmatch statement - Update help text and documentation
Output formatting is centralized in src/util/ modules. Each format has its own module with consistent interface.
- Create new template in
templates/directory - Define data structure in
src/server/templates.rs - Implement handler in
src/server/ui.rs - Add route in the UI router
- Edit component classes in
static/css/input.css - Run
make cssornpm run build-cssto compile - For development, use
npm run watch-cssfor auto-rebuild - Custom colors and utilities can be added to
tailwind.config.js
- Install dependencies:
npm install - Start CSS watch:
npm run watch-css - Run server:
cargo run -- server ./seed - Make changes to templates or styles
- Refresh browser to see changes (templates are recompiled on each request in dev mode)
Use RUST_LOG=trace to see detailed parsing information including:
- File discovery paths
- Configuration loading
- Recipe reference resolution
- Static file serving paths
This document describes the comprehensive UI testing setup for CookCLI using Playwright.
The testing suite provides end-to-end (E2E) testing for the CookCLI web interface, covering:
- Navigation and routing
- Recipe display and scaling
- Shopping list functionality
- Search capabilities
- Pantry management
- User preferences
- Accessibility compliance
- Performance metrics
# Install dependencies
npm install
# Install Playwright browsers
npx playwright install# Run all tests
npm test
# Run tests with UI mode (interactive)
npm run test:ui
# Run tests in debug mode
npm run test:debug
# Run tests with browser visible
npm run test:headed
# Run specific browser tests
npm run test:chrome
npm run test:firefox
npm run test:webkit
# Run mobile tests
npm run test:mobile
# Show test report
npm run test:report
# Generate tests interactively
npm run test:codegentests/
├── e2e/ # End-to-end tests
│ ├── navigation.spec.ts # Navigation and routing tests
│ ├── recipe-display.spec.ts # Recipe rendering tests
│ ├── recipe-scaling.spec.ts # Recipe scaling functionality
│ ├── search.spec.ts # Search functionality
│ ├── shopping-list.spec.ts # Shopping list management
│ ├── preferences.spec.ts # User preferences
│ ├── pantry.spec.ts # Pantry management
│ ├── accessibility.spec.ts # WCAG compliance tests
│ └── performance.spec.ts # Performance metrics
└── fixtures/ # Test utilities
└── test-helpers.ts # Reusable helper functions
The test-helpers.ts file provides reusable utilities:
- TestHelpers: Common navigation and interaction methods
- RecipePage: Recipe-specific page object model
- ShoppingListPage: Shopping list page object model
- Home page display
- Recipe navigation
- Breadcrumb navigation
- Directory browsing
- Navigation menu consistency
- Browser history handling
- Recipe title and description
- Ingredients list
- Cooking steps
- Ingredient/cookware/timer highlighting
- Recipe metadata
- Responsive layout
- Scale input functionality
- URL parameter scaling
- Decimal scaling support
- Scaling persistence
- Shopping list integration
- Search input functionality
- Search results display
- No results handling
- Special character support
- Case-insensitive search
- Search persistence
- Empty state display
- Adding ingredients
- Item completion toggling
- List clearing
- Ingredient aggregation
- Aisle organization
- Session persistence
- Preference display
- Pantry configuration
- Aisle configuration
- File upload handling
- Configuration validation
- Settings persistence
- Pantry navigation
- Item display
- Adding/editing/removing items
- Shopping list filtering
- Recipe integration
- Import/export functionality
- WCAG 2.0 AA compliance
- Keyboard navigation
- Screen reader support
- ARIA labels
- Color contrast
- Focus indicators
- Form labels
- Page load times
- Search performance
- Scaling responsiveness
- Memory usage
- Asset caching
- Cumulative Layout Shift (CLS)
Key settings:
- Base URL:
http://localhost:9080 - Web Server: Automatically starts dev server
- Browsers: Chrome, Firefox, Safari, Mobile
- Parallel Execution: Enabled
- Retries: 2 on CI, 0 locally
- Artifacts: Screenshots, videos, traces on failure
GitHub Actions workflow (ui-tests.yml):
- Runs on push/PR to main branch
- Matrix testing across OS and browsers
- Artifact upload for test results
- Parallel job execution
import { test, expect } from '@playwright/test';
import { TestHelpers } from '../fixtures/test-helpers';
test.describe('Feature Name', () => {
let helpers: TestHelpers;
test.beforeEach(async ({ page }) => {
helpers = new TestHelpers(page);
await helpers.navigateTo('/');
});
test('should do something', async ({ page }) => {
// Test implementation
await expect(page.locator('selector')).toBeVisible();
});
});// Navigate to a page
await helpers.navigateTo('/recipes');
// Search for a recipe
await helpers.searchRecipe('pasta');
// Scale a recipe
await helpers.scaleRecipe(2);
// Add to shopping list
await helpers.addToShoppingList();- Each test should be independent
- Use
beforeEachfor setup - Clean up after tests when necessary
- Prefer semantic selectors (roles, labels)
- Use data attributes for test-specific targeting
- Avoid brittle CSS selectors
- Use explicit waits (
waitForLoadState) - Check visibility before interaction
- Verify both positive and negative cases
- Run tests in parallel when possible
- Use page objects for reusability
- Minimize test data setup
# Run with UI mode
npm run test:ui
# Run with browser visible
npm run test:headed
# Debug specific test
npm run test:debugTraces are automatically captured on failure:
# View trace
npx playwright show-trace trace.zipAvailable in test-results/ directory after failures.
Tests run automatically on:
- Push to main branch
- Pull requests
- Manual workflow dispatch
Results available as GitHub Actions artifacts.
- Server not starting: Ensure
make dev_serverworks locally - Browser installation: Run
npx playwright install - Port conflicts: Check port 9080 is available
- Slow tests: Increase timeouts in config
CI: Set in CI environment for different behaviorDEBUG: Enable Playwright debug output
- Visual regression testing
- API mocking for edge cases
- Load testing with multiple concurrent users
- Internationalization testing
- Cross-browser compatibility matrix