This directory contains end-to-end tests for the Freighter wallet extension using Playwright.
Before running the tests, ensure you have:
- Node.js and Yarn: Install dependencies from the root of the extension directory
- Built Extension: The extension must be built before running tests
From the root directory:
yarn installIf you need to test against a specific backend, create an .env file at extension/.env:
INDEXER_URL=INSERT_YOUR_INDEXER_URL_V1
INDEXER_V2_URL=INSERT_YOUR_INDEXER_URL_V2
The tests run against the built extension in the extension/build directory:
yarn build:extensionFrom the root directory:
yarn test:e2eyarn test:e2e sendPayment.test.tsPlaywright provides a UI mode for debugging:
yarn test:e2e --uiTo see the browser while tests run:
yarn test:e2e --headedyarn test:e2e -g "Send doesn't throw error"accountHistory.test.ts- Tests for account history and transaction viewingaddAsset.test.ts- Tests for adding custom assetsaddCollectible.test.ts- Tests for adding NFTs/collectiblesallowList.test.ts- Tests for domain allowlist functionalitybuyWithOnramp.test.ts- Tests for on-ramp integrationloadAccount.test.ts- Tests for loading/importing accountslogin.test.ts- Tests for authentication flowsmemo.test.ts- Tests for memo functionality in transactionsonboarding.test.ts- Tests for user onboarding flowsendCollectible.test.ts- Tests for sending NFTssendPayment.test.ts- Tests for payment functionalitytranslations-pt.test.ts- Tests for Portuguese translations
The test-fixtures.ts file provides custom fixtures for:
- Browser context with extension loaded
- Extension ID extraction
- Service worker access
- Language configuration
The helpers/ directory contains:
login.ts- Authentication helper functionsstubs.ts- API mocking utilitiestest-token.ts- Test token constants
The Playwright configuration is in extension/playwright.config.ts:
- Timeout: 15 seconds per test
- Retries: 5 attempts on failure
- Workers: 8 locally, 4 on CI
- Browser: Chromium only
- Viewport: 1280x720
When tests fail, traces are automatically captured:
npx playwright show-trace test-results/[test-name]/trace.zipRun with the Playwright Inspector:
PWDEBUG=1 npx playwright testScreenshots are automatically captured in the test-results/ directory when tests fail.
For running tests sequentially (useful for tests that modify shared state):
IS_INTEGRATION_MODE=true yarn test:e2ee2e tests are run in CI by this GitHub action workflow: https://github.com/stellar/freighter/blob/master/.github/workflows/runTests.yml
This job runs on every commit on a PR.
This workflow toggles IS_INTEGRATION_MODE on if the branch is pointing at master (indicating that we're getting ready to deploy to production)
In CI, if the tests fail, the GitHub Action will upload an artifact that will allow you to view a recording of what happened in the browser in CI. This link will be visible in the test run in the Run actions/upload-artifact@v5 step. Download this artifact and unzip.
The failed tests can be viewed using the show-trace command:
npx playwright show-trace test-results/[test-name]/trace.zip- Ensure the extension is built:
yarn build - Check that
extension/builddirectory exists
- Tests are marked with
test.slow()for operations that may take longer - Default timeout is 15 seconds, with 5 retries
- Check that stub functions are properly defined in test setup
- Ensure routes are registered before navigation
import { test, expect, expectPageToHaveScreenshot } from "./test-fixtures";
import { loginToTestAccount } from "./helpers/login";
test("My test description", async ({ page, extensionId, context }) => {
test.slow(); // If test needs more time
// loginToTestAccount will automatically stub all API's by default
await loginToTestAccount({ page, extensionId, context });
// Your test code here
await page.getByTestId("my-element").click();
await expect(page.getByText("Expected text")).toBeVisible();
});const stubOverrides = async () => {
await stubAccountBalancesWithUSDC(page);
};
await loginToTestAccount({ page, extensionId, context, stubOverrides });Snapshot tests capture visual or structural baselines of your application and compare future runs against those baselines. This helps catch unintended visual regressions.
Freighter uses the expectPageToHaveScreenshot function for visual snapshot testing:
await expectPageToHaveScreenshot({
page,
screenshot: "my-feature.png",
});Snapshot files are stored in directories alongside test files:
onboarding.test.ts→onboarding.test.ts-snapshots/addAsset.test.ts→addAsset.test.ts-snapshots/
When you intentionally change the UI, update snapshots:
yarn test:e2e --update-snapshotsOr update snapshots for a specific test:
yarn test:e2e onboarding.test.ts --update-snapshotsWhen a snapshot test fails, you can review the differences:
-
In the test results directory:
test-results/[test-name]/ ├── expected.png (baseline snapshot) ├── actual.png (current output) └── diff.png (visual diff highlighting changes) -
In VS Code: Use the "Compare" feature on actual/expected/diff images
-
In CI: Download the test artifacts to review snapshot diffs locally
- Keep snapshots focused: Use snapshots to verify specific UI components or pages
- Review carefully: Always review snapshot diffs before updating to catch unintended changes
- Commit snapshots: Include updated snapshots in your git commits
- Avoid flaky snapshots:
- Mock dates/times if they appear in screenshots
- Ensure consistent asset loading states
- Use fixed viewports (Playwright provides 1280x720)
- Document changes: Add comments when updating snapshots for intentional UI changes
import { test, expect, expectPageToHaveScreenshot } from "./test-fixtures";
test("Send payment review screen matches snapshot", async ({
page,
extensionId,
context,
}) => {
test.slow();
const stubOverrides = async () => {
await stubAccountBalancesWithUSDC(page);
};
await loginToTestAccount({ page, extensionId, context, stubOverrides });
// Navigate to send flow
await page.getByTestId("nav-link-send").click();
await page.getByTestId("send-amount-amount-input").fill("100");
await page.getByTestId("address-tile").click();
await page
.getByTestId("send-to-input")
.fill("GBTYAFHGNZSTE4VBWZYAGB3SRGJEPTI5I4Y22KZ4JTVAN56LESB6JZOF");
await page.getByText("Continue").click();
// Capture the payment review screen
await expectPageToHaveScreenshot({
page,
screenshot: "send-payment-review.png",
});
});Tests run automatically in CI with:
- 4 parallel workers
- 1-hour global timeout
- Fail-fast on first failure after retries
test.onlyforbidden in CI
- Playwright Documentation
- Freighter Extension README
- Test Snapshots - Visual regression test baselines