* Mock react-virtualized-auto-sizer in all unit tests to ensure contents are mounted
Without mocking that, anything inside of an `AutoSizer` wouldn't be rendered
at all, leading to weird behaviour like the emoji picker being empty in tests.
* Fix EmojiPickerCategoryRow not having a defaultMessage
This caused any unit tests involving the emoji picker to error unless you
also provided an intlMessages object which is hard to do due to how Jest's
`moduleNameMapper` option is configured currently.
* Fixed incorrect usage of useCallback in EmojiPickerItem
The way this was previously written, we weren't specifying dependencies
properly for those callbacks which lead to some actual performance issues
because of how heavy the emoji picker is, and it also lead to issues where
click handlers would have to be triggered multiple times in unit tests
for some reason.
* MM-66659 Stop using caretPosition in useEditorEmojiPicker
This bug seems to be caused by a race condition between React and Chrome which
only occurs on Windows and only now that we've upgraded to React 18. That race
condition occurs with how we map the selection range in the post textbox to
its `caretPosition` state. That state has always been pretty janky, so I've
decided to remove it.
This also has some other benefits like improving UX by using `execCommand`
which preserves the undo/redo stack when using the emoji picker and simplifying
the code because we no longer have to manually mess with the cursor position.
Also, while I was in there, I fixed some minor weirdness around how whitespace
is handled when adding those emojis.
* MM-66659 Stop using caretPosition in useKeyHandler
* MM-66659 Stop using caretPosition for prefill message
* MM-66659 Remove remaining traces of caretPosition in AdvancedTextEditor
* Fix exclusive test
* Fix "Fixed incorrect usage of useCallback in EmojiPickerItem"
* Fixed incorrect usage of FixedSizeList in emoji picker
This is the actual fix to the issue I thought I fixed previously by changing
how `useCallback` was called in EmojiPickerItem.
It turns out the actual issue is that we were passing a new function as the
child of FixedSizeList on every render cycle which caused it to re-render all
of the rows which somehow also assigned them new DOM Nodes as well. The
EmojiPicker re-renders whenever we mouse over an emoji, so it would re-render
the FixedSizeList and all of its children frequently when mousing over things.
Apart from causing performance issues, that also seems to cause RTL to fail to
click on an emoji the first time you call `userAgent.click` because the first
call would move the mouse which would trigger a re-render, and that would
seemingly cause RTL to forget what to click on.
To fix that, I used a new React context to pass the extra props to the
EmojiPickerCategoryOrEmojiRow. I could've also done that by adding them to the
FixedSizeList's `itemData` prop, but that already contains a lot of heavy data,
and I didn't want to add to that.
* Revert changes to postMessageOnKeyPress
* Run Prettier in playwright folder
* Added docs to new Playwright test
* Address feedback
(cherry picked from commit f0815ae9f8)
Co-authored-by: Harrison Healey <[email protected]>
Local development
1. Start local server in a separate terminal.
There are two ways to run the local server:
Option 1: Run from source
# Typically run the local server with:
cd server && make run
# Or run webapp and server on separate terminals for better performance
# First terminal: Build and run the webapp
cd webapp && make run
# Second terminal: Run the server
cd server && make run-server
Option 2: Run using Docker (recommended for testing)
# 1. Configure environment variables in e2e-tests/.ci/env
# Create this file if it doesn't exist
# 2. Set the server image (optional)
# To use the latest master image:
SERVER_IMAGE="mattermostdevelopment/mattermost-enterprise-edition:master"
# If not set, it will use the current commit: mattermostdevelopment/mattermost-enterprise-edition:$(git rev-parse --short=7 HEAD)
# Note: The image must exist in Docker Hub at https://hub.docker.com/r/mattermostdevelopment/mattermost-enterprise-edition/tags
# 3. Add your license if needed
MM_LICENSE=<your-license-key>
# 4. For additional configuration options, see e2e-tests/README.md
# 5. Run the server and Playwright's smoke tests from the e2e-tests directory
cd e2e-tests && TEST=playwright make
This approach uses the server's Docker image to create a consistent testing environment. It automatically configures the server with the necessary settings for Playwright tests and handles dependencies.
2. Install dependencies and run the test.
# Install npm packages
npm i
# Install browser binaries as prompted if Playwright is just installed or updated
# See https://playwright.dev/docs/browsers
npx playwright install
# Run a specific test of all projects -- Chrome, Firefox, iPhone and iPad.
# See https://playwright.dev/docs/test-cli.
npm run test -- login
# Run a specific test of a project
npm run test -- login --project=chrome
# Run all tests (including visual tests)
npm run test
# Run CI tests (excludes visual tests, runs only in Chrome)
# Note: visual tests run in a separate workflow
npm run test:ci
3. Inspect test results at /results/output folder when something fails unexpectedly.
Run tests in UI mode
Check out https://playwright.dev/docs/test-ui-mode for detailed guide on UI Mode to learn more about its features.
npm run playwright-ui
Note: If no tests appear in the UI, check your filter settings:
- Test name filters
- Project filters (setup, ipad, chrome, firefox)
- Tag filters (@tag)
- Execution status filters
The "setup" project runs the initial configuration tests in
specs/test_setup.ts(ensuring plugins are loaded and server deployment is correct). These setup tests are typically run only once before other tests and may be unchecked for subsequent runs, though they can remain checked if needed.
Visual Testing
All visual tests must be placed in the specs/visual/ directory and tagged with @visual in the test tags array. This organization ensures proper test discovery and execution patterns.
Visual tests are used to verify the UI appearance is consistent across browsers and remains stable across code changes. There are two types of visual tests supported:
- Built-in snapshot testing: Uses Playwright's built-in snapshot comparison
- Percy integration: Uses the Percy service for more advanced visual testing and reporting
CI Pipeline for Visual Tests
In CI environments, visual tests run in a separate dedicated pipeline:
- Regular tests run with
npm run test:ciwhich excludes all tests with the@visualtag - Visual tests run in a separate workflow using the Playwright Docker container
- This separation prevents visual tests from slowing down the main test pipeline
- It also ensures visual tests always run in a consistent environment
Writing Visual Tests
When creating visual tests:
-
Follow the test documentation format like other tests:
- Include JSDoc with
@objectivetag - Use action-oriented test title
- Add proper comment prefixes (
// #for actions,// *for verifications)
- Include JSDoc with
-
Place in the correct location:
- Put visual tests in the
specs/visual/directory, organized by feature area - Example:
specs/visual/channels/intro_channel.spec.ts
- Put visual tests in the
-
Add required tags:
- Always include
@visualtag - Add feature-specific tags as needed (e.g.,
@login_page,@channel_page)
- Always include
-
Manage dynamic content:
- Use
pw.hideDynamicChannelsContent()to hide elements that could change between runs - Take snapshots only after UI is fully loaded and stable
- Use
Example:
/**
* @objective Capture visual snapshot of the landing/login page
*/
test(
'displays landing page with login options',
{tag: ['@visual', '@landing_page']},
async ({pw, page, browserName, viewport}, testInfo) => {
// # Go to landing login page
await pw.landingLoginPage.goto();
await pw.landingLoginPage.toBeVisible();
// * Verify landing page appears as expected
await pw.matchSnapshot(testInfo, {page, browserName, viewport});
},
);
Updating screenshots is done strictly via Playwright's docker container for consistency
1. Run Playwright's docker container
Change to the ./ project directory, then run the docker container. (See https://playwright.dev/docs/docker for reference.)
docker run -it --rm -v "$(pwd):/mattermost/" --ipc=host mcr.microsoft.com/playwright:v1.55.0-noble /bin/bash
2. Inside the docker container
export PW_BASE_URL=http://host.docker.internal:8065
export PW_HEADLESS=true
cd mattermost/e2e-tests/playwright
# Install npm packages. Use "npm ci" to match the automated environment
export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci
# Run specific test. See https://playwright.dev/docs/test-cli.
npm run test -- login --project=chrome
# Or run all tests
npm run test
# Run visual tests (must be run inside Docker for consistency)
npm run test -- specs/visual
# Update snapshots of visual tests (must be run inside Docker)
npm run test -- specs/visual --update-snapshots
# Run Percy visual tests (requires PERCY_TOKEN environment variable)
export PERCY_TOKEN=<your-percy-token>
npm run percy:docker
Page/Component Object Model
See https://playwright.dev/docs/test-pom.
Page and component abstractions are in shared library located at ./lib/src/ui. They should be established before writing a spec file so that any future changes in the DOM structure will be made in one place only. No static UI text or fixed locator should be written in the spec file.