* ci: shard server Postgres tests into 4 parallel runners (#35739) Cherry-pick of00296f9b49from master. * updated go to version 1.25.8 (#35817) Cherry-pick of32a10bac62from master. * Move password hashers from server/v8 to server/public (#35805) Cherry-pick ofcca3f08574from master. * Generate instead of hard-coding test passwords, enforce new minimum for FIPS, shard CI, fix FIPS builds (#35905) Cherry-pick of1bdd985b41from master. * upgrade golangci-lint (#35845) Cherry-pick of157e0400b2from master. On release-11.4 (unlike 11.5), UpdatePostsChannelTypeByChannelId and BackfillPostsChannelType exist in the elasticsearch/opensearch files, so the imports they require (fmt, updatebyquery, scriptlanguage) must be added — they were not in the cherry-pick diff since they already existed on master. Also updates html2text/tablewriter/olekukonko deps to fix a workspace conflict where enterprise's Go 1.25.8 bump pulled in a newer html2text that requires tablewriter ≥ 1.1 (was pinned to 0.0.5 via a replace directive). Matches the subset of866f759e4b(Mm 66662 bump deps) relevant to this incompatibility. * Fix FIPS-incompatible passwords and config in e2e test suites (#36001) Cherry-pick ofb51b4a8937from master. release-11.4 differences vs release-11.5: - demo_plugin_installation.spec.ts also deleted (modify/delete conflict, git rm) - authentication_2_spec.ts conflict: HEAD missing check() call; took incoming (check + FIPS-length passwords) - member_invitation_ui_spec.ts: HEAD has 'Create Account' (capital A) matching release-11.4 button text; kept HEAD's button text with incoming's newTestPassword() * fix(cypress): demo plugin (#36056) Cherry-pick of39f1979aa5from master. demo_plugin_installation.spec.ts was deleted in step 10 (modify/delete); re-created here with both the FIPS-password change and the URL fix. * test: clean up channel store data after TestChannelStore (#36066) TestChannelStore sub-tests create channels, members, and team members using fake TeamIds and UserIds (model.NewId() for non-existent rows). These records are left in the database and cause integrity tests (TestCheck*) running in the same binary to fail their full-table scans. Register a t.Cleanup on TestChannelStore that purges the affected tables entirely. A blanket purge is safe: the schema enforces no FK constraints, and every test suite creates its own data independently. * Fix command injection in server-test-template workflow (#36080) Cherry-pick of9223935f16from master. * fix(ci): restore testname format in sharded gotestsum runs (#36078) run-shard-tests.sh called gotestsum directly without --format, so it fell back to gotestsum's default (pkgname) instead of the testname format set by the Makefile. Pass --format "${GOTESTSUM_FORMAT:-testname}" to match the Makefile default. Co-authored-by: Mattermost Build <[email protected]> * fixup: drop demo_plugin playwright specs — master-only APIs demo_plugin/helpers.ts and demo_plugin_installation.spec.ts use installAndEnablePlugin and isPluginActive which don't exist on release-11.4's PlaywrightExtended type. These files were re-created by the step-11 cherry-pick of39f1979aa5, but they don't compile on this branch (same class of problem as actions.spec.ts in step 10). * fixup: add missing await in PluginLinkTooltip test The test added in39f1979aa5is missing an await on renderWithContext, causing the pointer-events assertion to race. Fix from 0c7d3f27c6 (on a feature branch, not yet on master). * fixup: drop pointer-events test incompatible with jsdom@20 The 'should not block interaction with elements outside the tooltip' test checks getComputedStyle for pointer-events: none, which is set only in SCSS. release-11.4 uses jest-environment-jsdom@29 (jsdom@20), which does not apply stylesheets, so getComputedStyle always returns "". The test passes on release-11.5+ only because they use jest-environment-jsdom@30 (jsdom@25+). Drop the test rather than backport the jsdom upgrade. * fixup: add missing i18n keys for elasticsearch/opensearch functions BackfillPostsChannelType and UpdatePostsChannelTypeByChannelId exist on release-11.4 (unlike release-11.5+). The golangci-lint cherry-pick added new error strings to those functions referencing i18n keys that weren't in en.json. * fixup: run make i18n-extract to reorder keys correctly * fixup: drop terms-and-privacy checkbox from MM-T1774 on release-11.4 The #signup-body-card-form-check-terms-and-privacy element did not exist on release-11.4's signup page. It was added to master after this branch was cut, so the check() call from the incoming cherry-pick causes the test to fail with "element never found". * fixup: remove UpdatePostsChannelTypeByChannelId/BackfillPostsChannelType These functions were introduced by MM-67540 (allow searching public channel messages without channel membership), which never landed on release-11.4. The golangci-lint cherry-pick only modernizes existing code; the rerere resolution incorrectly added the full function bodies from master. Remove both functions and their now-unused imports (fmt, updatebyquery, scriptlanguage) from elasticsearch.go and opensearch.go. Also remove the two i18n keys added to support them. Same treatment as release-11.5, where these functions were also absent. --------- Co-authored-by: Mattermost Build <[email protected]>
@mattermost/playwright-lib
A comprehensive end-to-end testing library for Mattermost web, desktop and plugin applications using Playwright.
Overview
This library provides:
- Pre-built page objects and components for common Mattermost UI elements
- Server configuration and initialization utilities
- Test fixtures and helpers
- Visual testing support with Percy integration
- Accessibility testing support with axe-core
- Browser notification mocking
- File handling utilities
- Common test actions and assertions
Installation
npm install @mattermost/playwright-lib
Usage
Basic example of logging in and posting a message:
import {test, expect} from '@mattermost/playwright-lib';
test('user can post message', async ({pw}) => {
// # Create and login a new user
const {user} = await pw.initSetup();
const {channelsPage} = await pw.testBrowser.login(user);
// # Navigate and post a message
await channelsPage.goto();
const message = 'Hello World!';
await channelsPage.postMessage(message);
// * Verify message appears
const lastPost = await channelsPage.getLastPost();
await expect(lastPost).toHaveText(message);
});
Key Components
Page Objects
Ready-to-use page objects for common Mattermost pages:
- Login
- Signup
- Channels
- System Console
- And more...
UI Components
Reusable component objects for UI elements:
- Headers
- Posts
- Menus
- Modals
- And more...
Test Utilities
Helper functions for common testing needs:
- Server setup and configuration
- User/team creation
- File handling
- Visual testing
- And more...
Configuration
The library can be configured via optional environment variables:
Environment Variables
All environment variables are optional with sensible defaults.
Server Configuration
| Variable | Description | Default |
|---|---|---|
PW_BASE_URL |
Server URL | http://localhost:8065 |
PW_ADMIN_USERNAME |
Admin username | sysadmin |
PW_ADMIN_PASSWORD |
Admin password | Sys@dmin-sample1 |
PW_ADMIN_EMAIL |
Admin email | [email protected] |
PW_ENSURE_PLUGINS_INSTALLED |
Comma-separated list of plugins to install | [] |
PW_RESET_BEFORE_TEST |
Reset server before test | false |
High Availability Cluster Settings
| Variable | Description | Default |
|---|---|---|
PW_HA_CLUSTER_ENABLED |
Enable HA cluster | false |
PW_HA_CLUSTER_NODE_COUNT |
Number of cluster nodes | 2 |
PW_HA_CLUSTER_NAME |
Cluster name | mm_dev_cluster |
Push Notifications
| Variable | Description | Default |
|---|---|---|
PW_PUSH_NOTIFICATION_SERVER |
Push notification server URL | https://push-test.mattermost.com |
Playwright Settings
| Variable | Description | Default |
|---|---|---|
PW_HEADLESS |
Run tests headless | true |
PW_SLOWMO |
Add delay between actions in ms | 0 |
PW_WORKERS |
Number of parallel workers | 1 |
Visual Testing
| Variable | Description | Default |
|---|---|---|
PW_SNAPSHOT_ENABLE |
Enable snapshot testing | false |
PW_PERCY_ENABLE |
Enable Percy visual testing | false |
CI Settings
| Variable | Description | Default |
|---|---|---|
CI |
Set automatically in CI environments | N/A |
Accessibility Testing
The library includes built-in accessibility testing using axe-core:
import {test, expect} from '@mattermost/playwright-lib';
test('verify login page accessibility', async ({page, axe}) => {
// # Navigate to login page
await page.goto('/login');
// # Run accessibility scan
const results = await axe.builder(page).analyze();
// * Verify no accessibility violations
expect(results.violations).toHaveLength(0);
});
The axe-core integration:
- Runs WCAG 2.0 Level A & AA rules by default
- Provides detailed violation reports
- Supports rule customization
- Can be configured per-test or globally
Visual Testing
The library supports visual testing through Playwright's built-in visual comparisons and Percy integration:
import {test, expect} from '@mattermost/playwright-lib';
test('verify channel header appearance', async ({pw, browserName, viewport}, testInfo) => {
// # Setup and login
const {user} = await pw.initSetup();
const {page, channelsPage} = await pw.testBrowser.login(user);
// # Navigate and prepare page
await channelsPage.goto();
await expect(channelsPage.appBar.playbooksIcon).toBeVisible();
await pw.hideDynamicChannelsContent(page);
// * Take and verify snapshot
await pw.matchSnapshot(testInfo, {page, browserName, viewport});
});
Browser Notifications
Mock and verify browser notifications:
import {test, expect} from '@mattermost/playwright-lib';
test('verify notification on mention', async ({pw}) => {
// # Setup users and team
const {team, adminUser, user} = await pw.initSetup();
// # Setup admin browser with notifications
const {page: adminPage, channelsPage: adminChannelsPage} = await pw.testBrowser.login(adminUser);
await adminChannelsPage.goto(team.name, 'town-square');
await pw.stubNotification(adminPage, 'granted');
// # Setup user browser and post mention
const {channelsPage: userChannelsPage} = await pw.testBrowser.login(user);
await userChannelsPage.goto(team.name, 'off-topic');
await userChannelsPage.postMessage(`@ALL good morning, ${team.name}!`);
// * Verify notification received
const notifications = await pw.waitForNotification(adminPage);
expect(notifications.length).toBe(1);
});
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
See LICENSE.txt for license information.