Files
team/e2e-tests/playwright/CLAUDE.OPTIONAL.md
b6e46e1f06 Cherry pick #37570 to release-11.7 (#37733)
* SEC-10179 Integrate test system IO for Playwright and Cypress (#36376)

* change retry to 1, fixed and disabled failed tests

* add v2 templates for Cypress and Playwright E2E tests with test system io integration

* add commenting to pr

* identify more playwrights to fix separately

* disable deletion-report.spec for separate fix

---------

Co-authored-by: Mattermost Build <[email protected]>

* fix: permission required by test-system-io actions (#36477)

* fix: permission required by e2e test-system-io actions (#36478)

Co-authored-by: sabril <[email protected]>

* chore(ci): consolidate openldap runner prep into a composite action (#36563)

Co-authored-by: sabril <[email protected]>

* ci: port test-system-io v2 templates from release-11.9

Bring Playwright/Cypress template-v2 in line with release-11.9 so they
include prepare-run/prep-deps caching, runner-prep-openldap, and pinned
mattermost-test-system-io action SHAs (1631d8fcea24). Bump Playwright
v2 workers to 10 to match 11.8/11.9. Prerequisite for cherry-picking
#37570 (testcontainers) onto release-11.7.

Co-authored-by: sabril <[email protected]>

* E2E/Playwright: Add testcontainers to playwright-lib (#37570)

* add testcontainers to playwright-lib

* include retry mechanism for transient failures

* - Introduced a new command `testcontainers:up` in package.json to run Playwright tests with Testcontainers.
- Created a standalone Playwright configuration file `playwright.testcontainers-up.config.ts` for managing Testcontainers.
- Added a no-op test `testcontainers_up.spec.ts` to ensure the Testcontainers stack is up during the test run.
- Implemented a global setup script `testcontainers_up_global_setup.ts` to start and stop the Testcontainers stack.
- Updated dependencies in package.json, including adding `chalk` for logging.

* fix package-lock

* fix tsc and restore waiting for all migrations to complete

---------

Co-authored-by: Mattermost Build <[email protected]>

* fix(e2e): remove obsolete CRT intro modal dismiss from uiClickSidebarItem

The CRT tutorial modal was removed in MM-66470; dismissing
#genericModalLabel races and flakes MM-T4261_3.

Co-authored-by: sabril <[email protected]>

* fix(e2e): sync Playwright navigations to live testcontainers baseURL

After restartMattermostContainer remaps the host port, relative page.goto
must follow testConfig.baseURL rather than the worker-start config value.

Co-authored-by: sabril <[email protected]>

* fix(e2e): restore eslint-disable for axe empty fixture pattern

Co-authored-by: sabril <[email protected]>

* fix(e2e): ignore webhook assets in eslint; prettier README

Co-authored-by: sabril <[email protected]>

* fix(e2e): prettier-format testcontainers config helpers

Co-authored-by: sabril <[email protected]>

* ci(e2e): fully adopt test-system-io and lighten Playwright services

Port #37413: drop the dual v1/v2 dispatch path, promote the test-system-io
templates to the canonical names, and remove legacy calculate-results / AWS
artifact upload plumbing.

For Playwright testcontainers on this release, leave optional sidecars
(openldap, keycloak, elasticsearch, opensearch, minio, azurite, webhook)
off by default and remove the related service-specific specs that are not
part of the older suite.

Co-authored-by: sabril <[email protected]>

* style(e2e): prettier stack.ts after optional webhook change

Co-authored-by: sabril <[email protected]>

* ci(e2e): grant contents:read to test-system-io workflow callers

Reusable Playwright/Cypress templates require contents:read. Without it
on the caller job, GitHub Actions fails the workflow at startup.

Co-authored-by: sabril <[email protected]>

* ci: retrigger enterprise build after transient npm cache failure

Co-authored-by: sabril <[email protected]>

* test(e2e): align testcontainers feature flags with release docker-compose

Mirror MM_FEATUREFLAGS_* from e2e-tests/.ci/server.generate.sh for each
release, dropping flags that do not exist in that release's FeatureFlags
struct (or were never enabled in the compose stack).

Co-authored-by: sabril <[email protected]>

* ci: retrigger enterprise after flaky message_export Postgres failure

Co-authored-by: sabril <[email protected]>

* e2e(playwright): omit unset Testcontainers env keys; align release docs

When optional webhook/sidecars are off, .env.testcontainers no longer
writes PW_*=undefined. Docs match empty DEFAULT_TESTCONTAINERS_SERVICES.

Co-authored-by: sabril <[email protected]>

* e2e(playwright): prettier-format lib/README.md table

Fixes CI npm run check (prettier) failures from the services table edit.

Co-authored-by: sabril <[email protected]>

* ci: retrigger E2E after Cypress commit-status race

Orchestration reported 1 failed unit before retest; final summary was
100% but commit status stayed failure. Retrigger for a clean green.

Co-authored-by: sabril <[email protected]>

* e2e(cypress): keep tests/support/env import on release-11.7

#36376 switched message_deletion_spec to @/support/env, but this
release has no Cypress webpack @ alias (added later). That caused a
Webpack Module not found failure and a stuck failed commit status.

Co-authored-by: sabril <[email protected]>

---------

Co-authored-by: Mattermost Build <[email protected]>
Co-authored-by: sabril <[email protected]>
Co-authored-by: yasser khan <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-29 16:25:30 +00:00

11 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository Purpose

This is the Playwright E2E testing suite for Mattermost. It contains end-to-end tests for validating the Mattermost web application functionality using the Playwright testing framework.

Key Commands

Installation

# Install npm packages
npm i

# Install browser binaries (if prompted)
npx playwright install

Running Tests

# Run a specific test across all browsers (Chrome, Firefox, iPad)
npm run test -- <test-name>

# Run a specific test for a specific browser
npm run test -- <test-name> --project=chrome
npm run test -- <test-name> --project=firefox
npm run test -- <test-name> --project=ipad

# Run all tests (including visual tests)
npm run test

# Run CI tests (excludes visual tests, runs only in Chrome)
npm run test:ci

# Run tests with UI mode
npm run playwright-ui

# Run tests with slow-motion to debug
npm run test:slomo

# Run visual tests
npm run test -- visual

# Update visual test snapshots
npm run test:update-snapshots

# Visual testing with Percy
npm run percy:docker

Development Commands

# Build the project
npm run build

# Watch mode for development
npm run build:watch

# Type checking
npm run tsc

# Linting
npm run lint

# Format code
npm run prettier:fix

# Verify test documentation format
npm run lint:test-docs

# Run all checks (lint, prettier, typescript, test docs)
npm run check

# Clean the project
npm run clean

# Show test report
npm run show-report

Architecture Overview

Key Components

  1. lib/ Directory: Contains the shared library (@mattermost/playwright-lib) that provides:

    • Page objects for Mattermost UI pages
    • Component abstractions for UI elements
    • Test utilities and fixtures
    • Server setup and management functions
    • Testcontainers orchestration (lib/src/containers/) for testcontainers mode (see Server Setup below)
    • Visual testing support
  2. specs/ Directory: Contains the actual test files organized by type:

    • functional/ - Functional tests for various features
    • visual/ - Visual regression tests
    • accessibility/ - Accessibility tests
    • client/ - Client API tests
  3. Test Fixtures: The main test fixture (pw) provides:

    • Browser context management
    • Page actions and utilities
    • Server API helpers
    • Random data generators
    • Visual testing helpers
  4. Page Object Model: UI abstractions are organized in:

    • lib/src/ui/pages/ - Page objects (Login, Channels, etc.)
    • lib/src/ui/components/ - Component objects (Posts, Menus, etc.)

Test Flow

  1. Tests typically follow this pattern:

    • Initialize test setup with pw.initSetup()
    • Login to a test account with pw.testBrowser.login()
    • Navigate to the relevant page
    • Perform actions and assertions
    • Optionally take visual snapshots
  2. Visual tests also:

    • Hide dynamic content with pw.hideDynamicChannelsContent()
    • Take snapshots with pw.matchSnapshot()

Environment Configuration

Tests can be configured through environment variables:

  • PW_BASE_URL - Mattermost server URL (default: http://localhost:8065)
  • PW_ADMIN_USERNAME - Admin username (default: sysadmin)
  • PW_ADMIN_PASSWORD - Admin password (default: Sys@dmin-sample1)
  • PW_HEADLESS - Run tests headless (default: true)
  • PW_SNAPSHOT_ENABLE - Enable snapshot testing (default: false)
  • PW_SLOWMO - Add delay between actions in ms (default: 0)
  • PW_WORKERS - Number of parallel workers (default: 1)
  • PERCY_TOKEN - Authentication token for Percy visual testing service (required for Percy tests)
  • PW_USE_TESTCONTAINERS - Selects testcontainers mode, see Server Setup below (default: false)
  • PW_TESTCONTAINERS_SERVICES - Comma-separated additional services to start, e.g. minio,openldap (default: none; core stack is Postgres, Inbucket, Mattermost)
  • PW_TESTCONTAINERS_WEBHOOK - Start the webhook sidecar (true to enable; default: off on this release)
  • PW_TESTCONTAINERS_REUSE - Reuse containers across repeated local runs instead of recreating them; tear down explicitly with npm run testcontainers:down (default: true)
  • SERVER_IMAGE - Mattermost server image testcontainers mode starts (default: mattermostdevelopment/mattermost-enterprise-edition:master)
  • MM_ENV - Comma-separated KEY=VALUE server config overrides for testcontainers mode (default: none)

Server Setup

Before running tests, a Mattermost server must be available. Two options:

  1. Run from source:

    cd server && make run
    
  2. Testcontainers (recommended for testing, and what CI uses) — no separate step needed, Playwright starts and tears down the server + dependencies itself:

    PW_USE_TESTCONTAINERS=true npm run test
    # Starts Postgres, Inbucket, Mattermost only by default; set PW_TESTCONTAINERS_SERVICES=... for sidecars and PW_TESTCONTAINERS_WEBHOOK=true for webhook
    # Containers are reused across runs by default; tear down with `npm run testcontainers:down` (or set PW_TESTCONTAINERS_REUSE=false for a self-cleaning one-off run)
    # `npm run testcontainers:up` brings the stack up (or confirms an existing one) without running any tests
    

Best Practices

  1. Page Object Pattern: Always use page/component objects from the library. No static UI selectors should be in test files.

  2. Locator Priority: Follow the Playwright recommended locator strategy (see Playwright Locators Quick Guide). Use locators in this priority order:

    1. getByRole() - Preferred. Locates by accessibility role and accessible name (e.g., getByRole('button', {name: 'Submit'})).
    2. getByText() - Locates by visible text content.
    3. getByLabel() - Locates form controls by their associated label text.
    4. getByPlaceholder() - Locates inputs by placeholder text.
    5. getByAltText() - Locates elements (usually images) by alt text.
    6. getByTitle() - Locates by the title attribute.
    7. getByTestId() - Last resort. Locates by data-testid attribute.
    • Avoid CSS selectors (.class, #id), XPath, and raw locator() calls unless none of the above locators can identify the element.
    • Use {exact: true} when the accessible name might partially match other elements (e.g., getByRole('button', {name: 'Invite', exact: true})).
  3. Visual Testing: For visual tests:

    • Place all visual tests in the specs/visual/ directory
    • Always include the @visual tag in the test tags array
    • Run via Docker container for consistency to maintain screenshot integrity
    • Use pw.hideDynamicChannelsContent() to hide dynamic elements that could cause flaky tests
    • Update snapshots with npm run test:update-snapshots only from within the Docker container
    • For Percy-based visual testing:
      • A valid PERCY_TOKEN environment variable must be set
      • Tests should only be run inside the Playwright Docker container
    • Follow the visual test documentation format like other tests, with proper JSDoc and comments
  4. Test Title Validation with Claude Code: When using Claude:

    • Run claude spec/path/to/file.spec.ts to check your test file
    • Ask: "Check if test titles follow the format in CLAUDE.md"
    • Claude will analyze each test title and suggest improvements
    • Format should be action-oriented, feature-specific, context-aware, and outcome-focused
    • Example: creates scheduled message from channel and posts at scheduled time
  5. Test Structure:

    • Use descriptive test titles that follow this format:
      • Action-oriented: Start with a verb that describes the main action
      • Feature-specific: Include the feature or component being tested
      • Context-aware: Include relevant context (where/how it's being performed)
      • Outcome-focused: Specify the expected outcome or behavior
    • Examples of well-formatted test titles:
      • "creates scheduled message from channel and posts at scheduled time"
      • "edits scheduled message content while preserving send date"
      • "reschedules message to a future date from scheduled posts page"
      • "deletes scheduled message from scheduled posts page"
      • "converts draft message to scheduled message"
    • Test keys (MM-T\d+) in test titles are optional for new tests
      • New tests without keys will automatically be registered in the test management system after merge
      • Test keys will be assigned later through a separate automated process
    • Follow the # Action and * Verification comment pattern
    • Group related tests in the same spec file
    • Keep tests independent and isolated
    • Use tags to categorize tests with {tag: '@feature_name'}
  6. Test Documentation Format:

    • Include JSDoc-style documentation before each test:
      /**
       * @objective Clear description of what the test verifies
       *
       * @precondition
       * Special setup or conditions required for the test
       * Note: Only include preconditions that are not part of the default setup.
       * Standard conditions like "a test server is running" should be omitted.
       */
      test('MM-T1234 descriptive test title', {tag: '@feature_tag'}, async ({pw}) => {
          // Test implementation
      });
      
    • If no special preconditions are needed, omit the @precondition tag entirely:
      /**
       * @objective Clear description of what the test verifies
       */
      test('descriptive test title', {tag: '@feature_tag'}, async ({pw}) => {
          // Test implementation
      });
      
    • For new tests, the MM-T ID is optional and will be assigned later:
      /**
       * @objective Clear description of what the test verifies
       */
      test('descriptive test title', {tag: '@feature_tag'}, async ({pw}) => {
          // Test implementation
      });
      
    • Use comment prefixes to clearly indicate actions and verifications:
      • // # descriptive action - Comments that describe steps being taken (e.g., // # Initialize user and login)
      • // * descriptive verification - Comments that describe assertions/checks (e.g., // * Verify message appears in channel)
  7. Browser Compatibility:

    • Tests run on Chrome, Firefox, and iPad by default
    • Consider browser-specific behaviors for certain features
    • Use test.skip() for browser-specific limitations
  8. Test Documentation Linting:

    • Run npm run lint:test-docs to verify all spec files follow the documentation format
    • The linter checks for proper JSDoc tags, test titles, feature tags, and action/verification comments
    • This is also included in the standard npm run check command
    • See the example in specs/functional/channels/scheduled_messages/scheduled_messages.spec.ts