Skip to content

Playwright End-to-End Testing Guide

This guide covers the Playwright end-to-end testing setup for the Bartendie application.

We’ve replaced Cypress with Playwright for better performance, reliability, and modern testing capabilities. Playwright provides:

  • Multi-browser support: Chrome, Firefox, Safari, and Edge
  • Better CI/CD integration: More reliable in headless environments
  • Modern architecture: Better handling of modern web apps
  • Powerful API mocking: Superior network interception capabilities
  • TypeScript-first approach: Better developer experience
frontend/
├── playwright.config.js # Main Playwright configuration
├── tests/ # Test files directory
│ ├── global-setup.js # Global test setup
│ ├── global-teardown.js # Global test cleanup
│ ├── fixtures/ # Test data and fixtures
│ │ └── test-data.js # Shared test data
│ ├── helpers/ # Test helper functions
│ │ ├── auth-helper.js # Authentication utilities
│ │ └── graphql-helper.js # GraphQL testing utilities
│ ├── auth.spec.js # Authentication flow tests
│ ├── events.spec.js # Event management tests
│ ├── venues.spec.js # Venue management tests
│ ├── inventory.spec.js # Inventory management tests
│ └── recipes.spec.js # Recipe management tests
└── package.json # Updated with Playwright scripts

Key configuration features:

  • Base URL: http://localhost:5173 (Vite dev server)
  • Multi-browser testing: Chrome, Firefox, Safari, Mobile
  • Automatic server startup: Both frontend and backend
  • Test artifacts: Screenshots, videos, traces on failure
  • Parallel execution: Optimized for CI/CD

The configuration automatically starts:

  1. Frontend: pnpm dev on http://localhost:5173
  2. Backend: mix phx.server on http://localhost:4000
Terminal window
# Run all tests
pnpm e2e
# Run tests with UI (interactive mode)
pnpm e2e:open
# Run tests in headed mode (see browser)
pnpm e2e:headed
# Debug tests step by step
pnpm e2e:debug
# View test report
pnpm e2e:report
# Install/update browsers
pnpm e2e:install
  • Login with valid/invalid credentials
  • Registration flow
  • Password reset
  • Logout functionality
  • Field validation
  • Event list display
  • Event creation and validation
  • Event details and editing
  • Event deletion
  • Menu creation for events
  • Venue list and creation
  • Bar management (add/edit/remove)
  • Equipment management
  • Validation and error handling
  • Product management
  • Inventory level updates
  • Low stock alerts
  • Inventory history
  • Recipe creation and editing
  • Ingredient management
  • Recipe search and filtering
  • Category filtering
import { login, logout, register, isLoggedIn } from './helpers/auth-helper.js';
// Login as different user types
await login(page, 'admin'); // or 'user', 'manager'
// Check login status
const loggedIn = await isLoggedIn(page);
// Register new user
await register(page, userData);
import { createTestEvent, waitForGraphQLRequest } from './helpers/graphql-helper.js';
// Create test data
const event = await createTestEvent(eventData);
// Wait for GraphQL operations
await waitForGraphQLRequest(page, 'createEvent');

Centralized test data for:

  • Test users (admin, user, manager)
  • Sample events, venues, products
  • Recipe templates
  • Global Setup: Ensures clean database state
  • Test Isolation: Each test starts with clean state
  • Cleanup: Automatic cleanup after test runs
<button data-testid="create-event-button">Create Event</button>
await page.click('[data-testid="create-event-button"]');
const responsePromise = waitForGraphQLRequest(page, 'createEvent');
await page.click('[data-testid="submit-button"]');
await responsePromise;
// Instead of repeating login steps
await login(page, 'admin');
// Instead of manual GraphQL calls
const event = await createTestEvent(eventData);
// Wait for elements to be visible
await expect(page.locator('[data-testid="success-message"]')).toBeVisible();
// Check text content
await expect(page.locator('[data-testid="event-name"]')).toContainText(eventName);
// Verify URL changes
await expect(page).toHaveURL(/\/events\/[a-zA-Z0-9-]+/);
Terminal window
# Start both servers manually (optional - auto-started by Playwright)
pnpm dev # Frontend
cd .. && mix phx.server # Backend
# Run tests
pnpm e2e # All tests
pnpm e2e auth.spec.js # Specific test file
pnpm e2e:open # Interactive mode
Terminal window
# Headless mode for CI
pnpm e2e
# Generate reports
pnpm e2e:report
Terminal window
pnpm e2e:open
Terminal window
pnpm e2e:debug
  • Screenshots: Captured on failure
  • Videos: Recorded for failed tests
  • Traces: Full execution traces for debugging
  1. Import syntax: import { test, expect } from '@playwright/test'
  2. Selectors: Same data-testid approach
  3. Assertions: expect(locator).toBeVisible() vs cy.should('be.visible')
  4. Network waiting: waitForGraphQLRequest() helper
  5. Page object: Explicit page parameter
  • Faster execution: Better performance
  • More reliable: Less flaky tests
  • Better CI/CD: Improved headless mode
  • Multi-browser: Built-in cross-browser testing
  • Modern API: Better async/await support
  1. Server startup timeout: Increase timeout in config
  2. Element not found: Add proper waits
  3. GraphQL timing: Use waitForGraphQLRequest()
  4. Authentication state: Use login() helper
  1. Use page.pause() to debug interactively
  2. Check test artifacts in test-results/
  3. Use --headed flag to see browser actions
  4. Add console.log() in helper functions

This Playwright setup provides a solid foundation for comprehensive end-to-end testing. The test coverage includes all major user flows and can be extended as new features are added to the application.