---
title: End-to-End Testing
sidebar_position: 4
---

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

# End-to-End Testing

Apache Superset uses Playwright for end-to-end testing, migrating from the legacy Cypress tests.

## Running Tests

### Playwright (Recommended)

```bash
cd superset-frontend

# Run all tests
npm run playwright:test
# or: npx playwright test

# Run specific test file
npx playwright test tests/auth/login.spec.ts

# Run with UI mode for debugging
npm run playwright:ui
# or: npx playwright test --ui

# Run in headed mode (see browser)
npm run playwright:headed
# or: npx playwright test --headed

# Debug specific test file
npm run playwright:debug tests/auth/login.spec.ts
# or: npx playwright test --debug tests/auth/login.spec.ts
```

### Cypress (Deprecated)

Cypress tests are being migrated to Playwright. For legacy tests:

```bash
cd superset-frontend/cypress-base
npm run cypress-run-chrome    # Headless
npm run cypress-debug         # Interactive UI
```

## Project Architecture

```
superset-frontend/playwright/
├── components/core/     # Reusable UI components
├── pages/              # Page Object Models
├── tests/              # Test files organized by feature
├── utils/              # Shared constants and utilities
└── playwright.config.ts
```

## Design Principles

We follow **YAGNI** (You Aren't Gonna Need It), **DRY** (Don't Repeat Yourself), and **KISS** (Keep It Simple, Stupid) principles:

- Build only what's needed now
- Reuse existing patterns and components
- Keep solutions simple and maintainable

## Page Object Pattern

Each page object encapsulates:

- **Actions**: What you can do on the page
- **Queries**: Information you can get from the page
- **Selectors**: Centralized in private static SELECTORS constant
- **NO Assertions**: Keep assertions in test files

**Example Page Object:**

```typescript
export class AuthPage {
  // Selectors centralized in the page object
  private static readonly SELECTORS = {
    LOGIN_FORM: '[data-test="login-form"]',
    USERNAME_INPUT: '[data-test="username-input"]',
  } as const;

  // Actions - what you can do
  async loginWithCredentials(username: string, password: string) {}

  // Queries - information you can get
  async getCurrentUrl(): Promise<string> {}

  // NO assertions - those belong in tests
}
```

**Example Test:**

```typescript
import { test, expect } from '@playwright/test';
import { AuthPage } from '../../pages/AuthPage';
import { LOGIN } from '../../utils/urls';

test('should login with correct credentials', async ({ page }) => {
  const authPage = new AuthPage(page);
  await authPage.goto();
  await authPage.loginWithCredentials('admin', 'general');

  // Assertions belong in tests, not page objects
  expect(await authPage.getCurrentUrl()).not.toContain(LOGIN);
});
```

## Core Components

Reusable UI interaction classes for common elements (`components/core/`):

- **Form**: Container with properly scoped child element access
- **Input**: Supports `fill()`, `type()`, and `pressSequentially()` methods
- **Button**: Standard click, hover, focus interactions

**Usage Example:**

```typescript
import { Form } from '../components/core';

const loginForm = new Form(page, '[data-test="login-form"]');
const usernameInput = loginForm.getInput('[data-test="username-input"]');
await usernameInput.fill('admin');
```

## Test Reports

Playwright generates multiple reports for better visibility:

```bash
# View interactive HTML report (opens automatically on failure)
npm run playwright:report
# or: npx playwright show-report

# View test trace for debugging failures
npx playwright show-trace test-results/[test-name]/trace.zip
```

### Report Types

- **List Reporter**: Shows progress and summary table in terminal
- **HTML Report**: Interactive web interface with screenshots, videos, and traces
- **JSON Report**: Machine-readable format in `test-results/results.json`
- **GitHub Actions**: Annotations in CI for failed tests

### Debugging Failed Tests

When tests fail, Playwright automatically captures:

- **Screenshots** at the point of failure
- **Videos** of the entire test run
- **Traces** with timeline and network activity
- **Error context** with detailed debugging information

All debugging artifacts are available in the HTML report for easy analysis.

## Configuration

- **Config**: `playwright.config.ts` - matches Cypress settings
- **Base URL**: `http://localhost:8088` (assumes Superset running)
- **Browsers**: Chrome only for Phase 1 (YAGNI)
- **Retries**: 2 in CI, 0 locally (matches Cypress)

## Contributing Guidelines

### Adding New Tests

1. **Check existing components** before creating new ones
2. **Use page objects** for page interactions
3. **Keep assertions in tests**, not page objects
4. **Follow naming conventions**: `feature.spec.ts`

### Adding New Components

1. **Follow YAGNI**: Only build what's immediately needed
2. **Use Locator-based scoping** for proper element isolation
3. **Support both string selectors and Locator objects** via constructor overloads
4. **Add to `components/core/index.ts`** for easy importing

### Adding New Page Objects

1. **Centralize selectors** in private static SELECTORS constant
2. **Import shared constants** from `utils/urls.ts`
3. **Actions and queries only** - no assertions
4. **Use existing components** for DOM interactions

## Migration from Cypress

When porting Cypress tests:

1. **Port the logic**, not the implementation
2. **Use page objects** instead of inline selectors
3. **Replace `cy.intercept/cy.wait`** with `page.waitForRequest()`
4. **Use shared constants** from `utils/urls.ts`
5. **Follow the established patterns** shown in `tests/auth/login.spec.ts`

## Best Practices

- **Centralize selectors** in page objects
- **Centralize URLs** in `utils/urls.ts`
- **Use meaningful test descriptions**
- **Keep page objects action-focused**
- **Put assertions in tests, not page objects**
- **Follow the existing patterns** for consistency
