Compare commits

...

16 Commits

Author SHA1 Message Date
Matiss Janis Aboltins
d796d8ec9b low res :( 2026-01-15 20:39:07 +00:00
Matiss Janis Aboltins
69009ce8ee Merge branch 'master' into matiss/browser-tests 2026-01-14 20:50:31 +00:00
Matiss Janis Aboltins
1e290373e5 Base 2026-01-14 20:49:51 +00:00
Stephen Brown II
f5377ac7b7 chore: migrate from inter-ui to @fontsource-variable/inter (#6436)
* Update inter-ui to latest npm package: ^4.1.1

* chore: migrate from inter-ui to @fontsource-variable/inter

- Replace inter-ui v3.19.3 with @fontsource-variable/inter v5.2.8
- Import variable font CSS directly via @import statements
- Update font-family declarations to use 'Inter Variable' to match Fontsource naming
- Simplifies path resolution and removes custom SCSS overrides

* Add release notes

* Enable Inter font features

Add ss04 to styles.tnum

Remove font feature settings and always apply in tnum style

Always enable alternate digits (ss01) and slashed zero (zero) font features
instead of making them user-configurable preferences.

* Add font feature settings to mobile financial amounts

Apply styles.tnum to mobile components displaying financial amounts
to enable OpenType features (tnum, ss01, ss04) for proper number styling:
- TransactionListItem: transaction amounts and running balance
- BudgetTable: header totals, ToBudget, and Saved amounts
- ExpenseGroupListItem: expense group totals
- BudgetCell, SpentCell, BalanceCell: category amounts
- IncomeGroup: income group amounts
- SchedulesListItem: schedule amounts

This ensures consistent digit rendering with serifs on "1" and open
digit forms across all mobile transaction, budget, and schedule views.

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6436

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6436

* revert VRT changes

* remove lint line

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6436

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6436

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
2026-01-14 20:36:43 +00:00
Matt Fiddaman
826ad86ada ⬆️ mid month dependency bump (#6656)
* @types/node (^22.19.1 → ^22.19.3)

* oxlint (^1.37.0 → ^1.38.0)

* better-sqlite3 (^12.4.1 → ^12.5.0)

* vitest (^4.0.9 → ^4.0.16)

* react-aria-components (^1.13.0 → ^1.14.0)

* @codemirror/autocomplete (^6.19.1 → ^6.20.0)

* @codemirror/language (^6.11.3 → ^6.12.1)

* @codemirror/state (^6.5.2 → ^6.5.3)

* @swc/core (^1.15.2 → ^1.15.8)

* @uiw/react-codemirror (^4.25.3 → ^4.25.4)

* @vitejs/plugin-basic-ssl (^2.1.0 → ^2.1.3)

* @vitejs/plugin-react (^5.1.1 → ^5.1.2)

* hyperformula (^3.1.0 → ^3.1.1)

* i18next (^25.6.2 → ^25.7.4)

* jsdom (^27.2.0 → ^27.4.0)

* react-aria (^3.44.0 → ^3.45.0)

* @swc/helpers (^0.5.17 → ^0.5.18)

* react-error-boundary (^6.0.0 → ^6.0.3)

* react-grid-layout (^1.5.2 → ^1.5.3)

* react-i18next (^16.3.3 → ^16.5.1)

* react-simple-pull-to-refresh (^1.3.3 → ^1.3.4)

* sass (^1.94.0 → ^1.97.2)

* vite (^7.2.2 → ^7.3.1)

* vite-plugin-pwa (^1.1.0 → ^1.2.0)

* fs-extra (^11.3.2 → ^11.3.3)

* @easyops-cn/docusaurus-search-local (^0.52.1 → ^0.52.2)

* react (^19.2.0 → ^19.2.3)

* react-dom (^19.2.0 → ^19.2.3)

* @reduxjs/toolkit (^2.10.1 → ^2.11.2)

* lru-cache (^11.2.2 → ^11.2.4)

* ua-parser-js (^2.0.6 → ^2.0.7)

* workbox-precaching (^7.3.0 → ^7.4.0)

* winston (^3.18.3 → ^3.19.0)

* supertest (^7.1.4 → ^7.2.2)

* playwright (^1.56.0 → ^1.57.0)

* stragglers

* note

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-01-14 20:17:55 +00:00
Will Thomas
c1720f35fd Add Report pages (#6411)
* Adding multiple report pages

* Adding release notes

* Updating release note number

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6411

* Fixing deletion id, allowing empty dashboard name, adding custom report dashboard saving, new dashboard default to empty

* Update VRT snapshots for command bar, payees, and schedules tests

* Update VRT snapshots for payees page visuals and search functionality tests

* Towards move/copy logic (need widget meta copy still!)

* refactor move widget to use add and remove

* Move/Copy modal

* fixes for rename duplicate calls, rename focus issue, and deletion undefined issue

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6411

* some bug/clarity fixes

* better type discipline, dashboard_pages schema, PR review fixes

* re-org of dashboard pages into dropdown, better mobile support, rename moved to title icon

* dashboard spacing fix (even for ridiculously long names), widget type-checking function

* Fix translation interpolation

* Fixing copy vs. move filename, removing old rename modal, minor review tweaks

* overview change simplification, routing error handling, move -> copy migration

* renaming for dashboard pages and error handling

* abstracting out `isWidgetType` function

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6411

* Reorganizing dashboard selector and vertical separator, fix widget tombstoning and undoability

* [autofix.ci] apply automated fixes

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6411

* fix dashboard not found spinner, fix dashboard deletion redirect, add SaveReportWrapper

* fix some deletion navigation issues and idioms

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #6411

* Translate 'modified' status in SaveReport component

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-01-13 22:41:47 +00:00
Stephen Brown II
93cce07542 fix(privacy): hide currency symbols in redacted overlay (#6438)
* fix(privacy): hide currency symbols in redacted overlay

Add RedactedContent component that uses useLayoutEffect to walk the DOM
and replace non-alphanumeric characters (like currency symbols) with spaces.
This ensures characters not rendered by Redacted Script font are hidden,
regardless of how deeply nested they are in the component tree.

* refactor: simplify RedactedContent text node processing loop
2026-01-13 22:19:19 +00:00
Matiss Janis Aboltins
b88feb9336 lint: patch some no-empty-function violations & delete unused code (#6642)
* lint: patch some no-empty-function violations

* docs: update ESLint rules and remove unused loadOwner function in UserAccess component

* refactor: remove getRemoteFile function and associated method from budget file handlers

* chore: disable docstring checks in coderabbit configuration
2026-01-13 22:05:24 +00:00
Matiss Janis Aboltins
0c3a515e29 Update linting rules and replace @ts-ignore with @ts-expect-error (#6636)
* Update linting rules and replace @ts-ignore with @ts-expect-error

* Add release notes for PR #6636

* Fix TypeScript linting issue by adding @ts-ignore for electron types in server start message

* Change category to Maintenance and update linting rules

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 21:53:14 +00:00
Copilot
5d82435700 Restrict AI-generated release notes workflow to PRs targeting master branch (#6622)
* Initial plan

* Add release notes for PR #6622

* Update release-notes workflow to only trigger for PRs against master

Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com>

* Fix: Apply branch filter to AI release notes workflow instead of check workflow

Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com>
2026-01-13 21:27:42 +00:00
Copilot
bcf53007ca Fix missing final newline in generated release notes (#6641)
* Initial plan

* Add release notes for PR #6641

* Fix release-note-generator to add final newline to generated files

Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com>
2026-01-13 21:13:50 +00:00
Matiss Janis Aboltins
64aa88aa22 Add ACTIONS_UPDATE_TOKEN to GitHub Actions workflows (#6530)
* Add ACTIONS_UPDATE_TOKEN to GitHub Actions workflows

* Add release notes for PR #6530

* Update category for release notes

Changed category from Enhancements to Maintenance.

* Remove ACTIONS_UPDATE_TOKEN from GitHub Actions workflows for release notes generation

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 20:58:54 +00:00
Jonathon Jongsma
6d8cba1564 Crossover report: Remove leftover help text referring to linear trend. (#6638)
Accidentally forgotten in https://github.com/actualbudget/actual/pull/6589

Signed-off-by: Jonathon Jongsma <jonathon@quotidian.org>
2026-01-13 20:24:00 +00:00
Joel Jeremy Marquez
914074d4b6 Fix transactions table payee schedule icon not showing if linked schedule has a different account configured (#6561)
* Fix transactions table payee schedule icon not showing if linked schedule has a different account configured

* [autofix.ci] apply automated fixes

* Move SchedulesProvider higher in component tree

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-01-13 20:21:48 +00:00
lif
2b8a15f51c fix: skip schedule prompt for transactions already linked to schedule (#6569)
* fix: skip schedule prompt for transactions already linked to schedule

When editing a future-dated transaction on mobile that is already linked
to a schedule, the app was incorrectly showing the "convert to schedule"
prompt. This was confusing since the transaction was already associated
with a schedule.

This change adds a check for `unserializedTransaction.schedule` to skip
showing the schedule prompt if the transaction is already linked to a
schedule.

Fixes #6357

Signed-off-by: majiayu000 <1835304752@qq.com>

* fix: resolve build and lint issues in TransactionEdit.tsx

* docs: add release notes for PR #6569

* chore: remove duplicate release note file

Signed-off-by: majiayu000 <1835304752@qq.com>

* chore: rename release note file to match PR number

Signed-off-by: majiayu000 <1835304752@qq.com>

* fix: apply schedule prompt fix to desktop version

Signed-off-by: majiayu000 <1835304752@qq.com>

---------

Signed-off-by: majiayu000 <1835304752@qq.com>
2026-01-13 20:20:29 +00:00
Jonathon Jongsma
0467b13848 Update the projection types in crossover report (#6589)
* Add unfiltered median projection type to crossover report

Signed-off-by: Jonathon Jongsma <jonathon@quotidian.org>

* Add a new 'mean' projection type to crossover report

Some people may want to use the average monthly expenses rather than
median expenses.

Signed-off-by: Jonathon Jongsma <jonathon@quotidian.org>

* Remove 'linear trend' from crossover report

The linear projection type almost never provides any useful information
for projecting future expenses. For example, if my expenses have been
declining for the past several months, that doesn't mean that they will
continue to decline until they reach 0 in retirement. It's way too easy
to receive a nonsense projection with the linear projection type. Just
remove it.

Signed-off-by: Jonathon Jongsma <jonathon@quotidian.org>

* Add release notes for crossover point projections

Signed-off-by: Jonathon Jongsma <jonathon@quotidian.org>

* [autofix.ci] apply automated fixes

---------

Signed-off-by: Jonathon Jongsma <jonathon@quotidian.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-01-13 16:34:19 +00:00
493 changed files with 3676 additions and 1727 deletions

View File

@@ -10,6 +10,7 @@ reviews:
enabled: false
pre_merge_checks:
docstrings:
mode: off
enabled: false
custom_checks:
- mode: error

View File

@@ -36,11 +36,13 @@ async function getPRDetails() {
console.log('- PR Number:', pr.number);
console.log('- PR Author:', pr.user.login);
console.log('- PR Title:', pr.title);
console.log('- Base Branch:', pr.base.ref);
const result = {
number: pr.number,
author: pr.user.login,
title: pr.title,
baseBranch: pr.base.ref,
};
setOutput('result', JSON.stringify(result));

View File

@@ -41,8 +41,21 @@ jobs:
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
- name: Check if release notes file already exists
- name: Check if PR targets master branch
if: steps.check-first-comment.outputs.result == 'true' && steps.pr-details.outputs.result != 'null'
id: check-base-branch
run: |
BASE_BRANCH=$(echo '${{ steps.pr-details.outputs.result }}' | jq -r '.baseBranch')
echo "Base branch: $BASE_BRANCH"
if [ "$BASE_BRANCH" = "master" ]; then
echo "targets_master=true" >> $GITHUB_OUTPUT
else
echo "targets_master=false" >> $GITHUB_OUTPUT
echo "PR does not target master branch, skipping release notes generation"
fi
- name: Check if release notes file already exists
if: steps.check-first-comment.outputs.result == 'true' && steps.pr-details.outputs.result != 'null' && steps.check-base-branch.outputs.targets_master == 'true'
id: check-release-notes-exists
run: node .github/actions/ai-generated-release-notes/check-release-notes-exists.js
env:

View File

@@ -30,7 +30,7 @@ jobs:
matrix:
shard: [1, 2, 3, 4, 5]
container:
image: mcr.microsoft.com/playwright:v1.56.0-jammy
image: mcr.microsoft.com/playwright:v1.57.0-jammy
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up environment
@@ -53,7 +53,7 @@ jobs:
name: Functional Desktop App
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.56.0-jammy
image: mcr.microsoft.com/playwright:v1.57.0-jammy
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up environment
@@ -81,7 +81,7 @@ jobs:
matrix:
shard: [1, 2, 3, 4, 5]
container:
image: mcr.microsoft.com/playwright:v1.56.0-jammy
image: mcr.microsoft.com/playwright:v1.57.0-jammy
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up environment
@@ -104,7 +104,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ !cancelled() }}
container:
image: mcr.microsoft.com/playwright:v1.56.0-jammy
image: mcr.microsoft.com/playwright:v1.57.0-jammy
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up environment

View File

@@ -50,6 +50,7 @@ jobs:
- name: Create PR
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ secrets.ACTIONS_UPDATE_TOKEN }}
commit-message: '🔖 (${{ steps.bump_package_versions.outputs.version }})'
title: '🔖 (${{ steps.bump_package_versions.outputs.version }})'
body: 'Generated by [generate-release-pr.yml](../tree/master/.github/workflows/generate-release-pr.yml)'

View File

@@ -44,7 +44,7 @@ jobs:
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/update-vrt')
container:
image: mcr.microsoft.com/playwright:v1.56.0-jammy
image: mcr.microsoft.com/playwright:v1.57.0-jammy
steps:
- name: Get PR details
id: pr

View File

@@ -15,7 +15,7 @@
"vi": "readonly",
"backend": "readonly",
"importScripts": "readonly",
"FS": "readonly" // TODO: remove this
"FS": "readonly"
},
"rules": {
// TODO fix all these and re-enable
@@ -103,13 +103,7 @@
"jsx-a11y/scope": "warn",
// Typescript rules
"typescript/ban-ts-comment": [
"warn",
{
// TODO: remove this
"ts-ignore": "allow-with-description"
}
],
"typescript/ban-ts-comment": ["warn"],
"typescript/consistent-type-definitions": ["warn", "type"],
"typescript/consistent-type-imports": [
"warn",
@@ -190,7 +184,7 @@
// ESLint rules
"eslint/array-callback-return": "warn",
// "eslint/curly": ["warn", "multi-line", "consistent"], // TODO: re-enable? this rule is really slow
"eslint/curly": ["warn", "multi-line", "consistent"],
"eslint/default-case": [
"warn",
{
@@ -470,16 +464,9 @@
// TODO: enable these
{
"files": [
"packages/desktop-client/src/components/admin/UserAccess/UserAccess.tsx",
"packages/desktop-client/src/components/admin/UserDirectory/UserDirectory.tsx",
"packages/desktop-client/src/components/budget/BudgetCategories.tsx",
"packages/desktop-client/src/components/budget/envelope/BalanceMovementMenu.tsx",
"packages/desktop-client/src/components/ManageRules.tsx",
"packages/desktop-client/src/components/mobile/budget/ExpenseGroupList.tsx",
"packages/desktop-client/src/components/modals/EditFieldModal.tsx",
"packages/desktop-client/src/components/reports/reports/Calendar.tsx",
"packages/desktop-client/src/components/schedules/ScheduleLink.tsx",
"packages/desktop-client/src/components/ServerContext.tsx",
"packages/desktop-client/src/components/table.tsx"
],
"rules": {

View File

@@ -169,7 +169,7 @@ Custom ESLint rules specific to Actual.
- `no-untranslated-strings`: Enforces i18n usage
- `prefer-trans-over-t`: Prefers Trans component over t() function
- `prefer-logger-over-console`: Enforces using logger instead of console
- `prefer-logger-over-console`: Enforces using logger instead of console in `packages/loot-core/`
- `typography`: Typography rules
- `prefer-if-statement`: Prefers explicit if statements
@@ -328,7 +328,6 @@ Always maintain newlines between import groups.
**Never:**
- Use `console.*` (use logger instead - enforced by ESLint)
- Import from `uuid` without destructuring: use `import { v4 as uuidv4 } from 'uuid'`
- Import colors directly - use theme instead
- Import `@actual-app/web/*` in `loot-core`
@@ -541,7 +540,6 @@ Before committing changes, ensure:
- [ ] `yarn typecheck` passes
- [ ] `yarn lint:fix` has been run
- [ ] Relevant tests pass
- [ ] No new console.\* usage (use logger)
- [ ] User-facing strings are translated
- [ ] Prefer `type` over `interface`
- [ ] Named exports used (not default exports)

View File

@@ -160,7 +160,8 @@ category: ${type}
authors: [${username}]
---
${summary}`;
${summary}
`;
}
// simple exec that fails silently and returns an empty string on failure

29
bin/run-browser-tests Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/sh
# Run browser tests (vitest browser mode) in Docker for consistent screenshot quality
# Browser tests generate screenshots that vary by environment (fonts, rendering, etc.)
# Running in Docker ensures consistent results across different machines
#
# Usage:
# yarn test:browser # Run all browser tests
# yarn test:browser AuthSettings.browser # Run specific test file
# yarn test:browser --update # Update snapshots
if [ ! -d "node_modules" ] || [ "$(ls -A node_modules)" = "" ]; then
yarn
fi
TEST_ARGS=""
# Loop through all arguments
while [ $# -gt 0 ]; do
TEST_ARGS="$TEST_ARGS $1"
shift
done
echo "Running browser tests in Docker for consistent screenshot quality..."
echo "Test args: $TEST_ARGS"
echo ""
MSYS_NO_PATHCONV=1 docker run --rm --network host -v "$(pwd)":/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.57.0-jammy /bin/bash \
-c "yarn workspace @actual-app/web test --project=browser $TEST_ARGS"

View File

@@ -28,5 +28,5 @@ echo "Running VRT tests with the following parameters:"
echo "E2E_START_URL: $E2E_START_URL"
echo "VRT_ARGS: $VRT_ARGS"
MSYS_NO_PATHCONV=1 docker run --rm --network host -v "$(pwd)":/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.56.0-jammy /bin/bash \
MSYS_NO_PATHCONV=1 docker run --rm --network host -v "$(pwd)":/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.57.0-jammy /bin/bash \
-c "E2E_START_URL=$E2E_START_URL yarn vrt $VRT_ARGS"

View File

@@ -44,6 +44,7 @@
"generate:i18n": "yarn workspace @actual-app/web generate:i18n",
"generate:release-notes": "ts-node ./bin/release-note-generator.ts",
"test": "lage test --continue",
"test:browser": "./bin/run-browser-tests",
"test:debug": "lage test --no-cache --continue",
"e2e": "yarn workspace @actual-app/web run e2e",
"e2e:desktop": "yarn build:desktop --skip-exe-build --skip-translations && yarn workspace desktop-electron e2e",
@@ -61,7 +62,7 @@
},
"devDependencies": {
"@octokit/rest": "^22.0.1",
"@types/node": "^22.19.1",
"@types/node": "^22.19.3",
"@types/prompts": "^2.4.9",
"cross-env": "^10.1.0",
"eslint": "^9.39.2",
@@ -75,7 +76,7 @@
"node-jq": "^6.3.1",
"npm-run-all": "^4.1.5",
"oxfmt": "^0.22.0",
"oxlint": "^1.37.0",
"oxlint": "^1.38.0",
"p-limit": "^7.2.0",
"prompts": "^2.4.2",
"source-map-support": "^0.5.21",

View File

@@ -6,6 +6,7 @@ import type {
// loot-core types
import type { InitConfig } from 'loot-core/server/main';
// oxlint-disable-next-line typescript/ban-ts-comment
// @ts-ignore: bundle not available until we build it
import * as bundle from './app/bundle.api.js';
import * as injected from './injected';

View File

@@ -21,7 +21,7 @@
},
"dependencies": {
"@actual-app/crdt": "workspace:^",
"better-sqlite3": "^12.4.1",
"better-sqlite3": "^12.5.0",
"compare-versions": "^6.1.1",
"node-fetch": "^3.3.2",
"uuid": "^13.0.0"
@@ -29,7 +29,7 @@
"devDependencies": {
"tsc-alias": "^1.8.16",
"typescript": "^5.9.3",
"vitest": "^4.0.9"
"vitest": "^4.0.16"
},
"engines": {
"node": ">=20"

View File

@@ -1,3 +1,4 @@
// oxlint-disable-next-line typescript/ban-ts-comment
// @ts-ignore: bundle not available until we build it
import * as bundle from './app/bundle.api.js';

View File

@@ -6,6 +6,6 @@
"test": "vitest --run"
},
"devDependencies": {
"vitest": "^4.0.9"
"vitest": "^4.0.16"
}
}

View File

@@ -41,7 +41,7 @@
},
"dependencies": {
"@emotion/css": "^11.13.5",
"react-aria-components": "^1.13.0",
"react-aria-components": "^1.14.0",
"usehooks-ts": "^3.1.1"
},
"devDependencies": {
@@ -49,7 +49,7 @@
"@types/react": "^19.2.5",
"react": "19.2.0",
"react-dom": "19.2.0",
"vitest": "^4.0.9"
"vitest": "^4.0.16"
},
"peerDependencies": {
"react": ">=18.2",

View File

@@ -91,7 +91,10 @@ export const styles: Record<string, any> = {
},
shadowLarge,
tnum: {
fontFeatureSettings: '"tnum"',
// tnum: Tabular numbers
// ss01: Open digits
// ss04: Disambiguation w/o zero
fontFeatureSettings: '"tnum", "ss01", "ss04"',
},
notFixed: { fontFeatureSettings: '' },
text: {

View File

@@ -24,6 +24,6 @@
"protoc-gen-js": "3.21.4-4",
"ts-protoc-gen": "0.15.0",
"typescript": "^5.9.3",
"vitest": "^4.0.9"
"vitest": "^4.0.16"
}
}

View File

@@ -8,6 +8,7 @@ coverage
test-results
playwright-report
blob-report
.vitest-attachments/
# production
build

View File

@@ -65,10 +65,10 @@ Run manually:
```sh
# Run docker container
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.56.0-jammy /bin/bash
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.57.0-jammy /bin/bash
# If you receive an error such as "docker: invalid reference format", please instead use the following command:
docker run --rm --network host -v ${pwd}:/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.56.0-jammy /bin/bash
docker run --rm --network host -v ${pwd}:/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.57.0-jammy /bin/bash
# Once inside the docker container, run the VRT tests: important - they MUST be ran against a HTTPS server.
# Use the ip and port noted earlier
@@ -96,3 +96,48 @@ Run locally:
```sh
E2E_START_URL=https://my-remote-server.com yarn vrt
```
## Browser Tests (Vitest Browser Mode)
Browser tests (`.browser.test.tsx` files) use Vitest's browser mode to test React components with visual regression screenshots. These tests generate screenshots that can vary significantly by environment (fonts, rendering, DPI, etc.).
**IMPORTANT: For consistent screenshot quality, always run browser tests in Docker.**
### Running Browser Tests in Docker
From the project root:
```sh
# Run all browser tests
yarn test:browser:docker
# Run a specific browser test file
yarn test:browser:docker AuthSettings.browser
# Run with update flag to update snapshots
yarn test:browser:docker AuthSettings.browser --update
```
From the `packages/desktop-client` directory:
```sh
# Run all browser tests
yarn test:browser:docker
# Run a specific browser test file
yarn test:browser:docker AuthSettings.browser
# Run with update flag
yarn test:browser:docker AuthSettings.browser --update
```
### Why Docker?
Running browser tests locally will produce inconsistent screenshots due to:
- System-specific font rendering
- Different DPI/display scaling
- OS-specific rendering differences
- Font availability variations
Docker ensures all tests run in the same standardized environment (`mcr.microsoft.com/playwright:v1.56.0-jammy`), producing consistent, reproducible screenshots.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Some files were not shown because too many files have changed in this diff Show More