Compare commits
7 Commits
v25.1.0
...
react-aria
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2bf2e9cc9 | ||
|
|
7e1cc49478 | ||
|
|
e6a49b1d99 | ||
|
|
db7d890e79 | ||
|
|
46977b59ca | ||
|
|
b3d0348493 | ||
|
|
b78f1fd575 |
@@ -7,7 +7,6 @@ packages/crdt/dist
|
||||
|
||||
packages/desktop-client/bundle.browser.js
|
||||
packages/desktop-client/build/
|
||||
packages/desktop-client/build-electron/
|
||||
packages/desktop-client/build-stats/
|
||||
packages/desktop-client/public/kcab/
|
||||
packages/desktop-client/public/data/
|
||||
@@ -17,7 +16,6 @@ packages/desktop-client/src/icons/**/*
|
||||
packages/desktop-client/test-results/
|
||||
packages/desktop-client/playwright-report/
|
||||
|
||||
packages/desktop-electron/build/
|
||||
packages/desktop-electron/client-build/
|
||||
packages/desktop-electron/dist/
|
||||
|
||||
|
||||
@@ -161,12 +161,7 @@ module.exports = {
|
||||
],
|
||||
'no-with': 'warn',
|
||||
'no-whitespace-before-property': 'warn',
|
||||
'react-hooks/exhaustive-deps': [
|
||||
'warn',
|
||||
{
|
||||
additionalHooks: '(useQuery)',
|
||||
},
|
||||
],
|
||||
'react-hooks/exhaustive-deps': 'warn',
|
||||
'require-yield': 'warn',
|
||||
'rest-spread-spacing': ['warn', 'never'],
|
||||
strict: ['warn', 'never'],
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -23,6 +23,8 @@ body:
|
||||
options:
|
||||
- label: 'I have searched and found no existing issue'
|
||||
required: true
|
||||
- label: 'I will be providing steps how to reproduce the bug (in most cases this will also mean uploading a demo budget file)'
|
||||
required: true
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -34,14 +36,6 @@ body:
|
||||
value: 'A bug happened!'
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: How can we reproduce the issue?
|
||||
description: Please give step-by-step instructions on how to reproduce the issue. In most cases this might also require uploading a sample budget/import file.
|
||||
value: 'How can we reproduce the issue?'
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
id: env-info
|
||||
attributes:
|
||||
|
||||
4
.github/actions/setup/action.yml
vendored
@@ -7,10 +7,6 @@ runs:
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.16.0
|
||||
- name: Install yarn
|
||||
run: npm install -g yarn
|
||||
shell: bash
|
||||
if: ${{ env.ACT }}
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
id: cache
|
||||
|
||||
36
.github/workflows/i18n-string-extract-master.yml
vendored
@@ -1,36 +0,0 @@
|
||||
name: Extract and upload i18n strings
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
extract-and-upload-i18n-strings:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up environment
|
||||
uses: ./.github/actions/setup
|
||||
- name: Configure i18n client
|
||||
run: |
|
||||
pip install wlc
|
||||
- name: Generate i18n strings
|
||||
run: yarn generate:i18n
|
||||
- name: Upload i18n strings
|
||||
run: |
|
||||
if [[ ! -f packages/desktop-client/locale/en.json ]]; then
|
||||
echo "File packages/desktop-client/locale/en.json not found. Ensure the file was generated correctly."
|
||||
exit 1
|
||||
fi
|
||||
wlc \
|
||||
--url https://hosted.weblate.org/api/ \
|
||||
--key "${{ secrets.WEBLATE_API_KEY_CI_STRINGS }}" \
|
||||
upload \
|
||||
--author-name "Actual Budget" \
|
||||
--author-email "dev@actualbudget.org" \
|
||||
--method add \
|
||||
--input packages/desktop-client/locale/en.json \
|
||||
actualbudget/actual/en
|
||||
echo "Translations uploaded"
|
||||
66
.github/workflows/update-vrt.yml
vendored
@@ -4,11 +4,11 @@ on:
|
||||
types: [ created ]
|
||||
|
||||
permissions:
|
||||
pull-requests: read
|
||||
contents: read
|
||||
pull-requests: write
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.issue.number }}-${{ contains(github.event.comment.body, '/update-vrt') }}
|
||||
group: ${{ github.workflow }}-${{ github.event.issue.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -41,48 +41,11 @@ jobs:
|
||||
run: yarn vrt --update-snapshots
|
||||
env:
|
||||
E2E_START_URL: ${{ steps.netlify.outputs.url }}
|
||||
- name: Create patch
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
git config --system --add safe.directory "*"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git reset
|
||||
git add "**/*.png"
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "Update VRT"
|
||||
git format-patch -1 HEAD --stdout > Update-VRT.patch
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: patch
|
||||
path: Update-VRT.patch
|
||||
|
||||
push-patch:
|
||||
runs-on: ubuntu-latest
|
||||
needs: update-vrt
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Get PR branch
|
||||
# Until https://github.com/xt0rted/pull-request-comment-branch/issues/322 is resolved we use the forked version
|
||||
uses: gotson/pull-request-comment-branch@head-repo-owner-dist
|
||||
id: comment-branch
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ steps.comment-branch.outputs.head_owner }}/${{ steps.comment-branch.outputs.head_repo }}
|
||||
ref: ${{ steps.comment-branch.outputs.head_ref }}
|
||||
- uses: actions/download-artifact@v4
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: patch
|
||||
- name: Apply patch and push
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git apply Update-VRT.patch
|
||||
git add "**/*.png"
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
@@ -90,24 +53,3 @@ jobs:
|
||||
fi
|
||||
git commit -m "Update VRT"
|
||||
git push origin HEAD:${{ steps.comment-branch.outputs.head_ref }}
|
||||
- name: Add finished reaction
|
||||
uses: dkershner6/reaction-action@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commentId: ${{ github.event.comment.id }}
|
||||
reaction: "rocket"
|
||||
|
||||
add-starting-reaction:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event.issue.pull_request &&
|
||||
contains(github.event.comment.body, '/update-vrt')
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: React to comment
|
||||
uses: dkershner6/reaction-action@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commentId: ${{ github.event.comment.id }}
|
||||
reaction: "+1"
|
||||
|
||||
@@ -36,7 +36,7 @@ fi
|
||||
|
||||
yarn workspace loot-core build:node
|
||||
|
||||
yarn workspace @actual-app/web build --mode=desktop # electron specific build
|
||||
yarn workspace @actual-app/web build --mode=desktop
|
||||
|
||||
yarn workspace desktop-electron update-client
|
||||
|
||||
|
||||
@@ -86,10 +86,7 @@ export function addTransactions(
|
||||
}
|
||||
|
||||
export function importTransactions(accountId, transactions) {
|
||||
return send('api/transactions-import', {
|
||||
accountId,
|
||||
transactions,
|
||||
});
|
||||
return send('api/transactions-import', { accountId, transactions });
|
||||
}
|
||||
|
||||
export function getTransactions(accountId, startDate, endDate) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@actual-app/api",
|
||||
"version": "25.1.0",
|
||||
"version": "24.11.0",
|
||||
"license": "MIT",
|
||||
"description": "An API for Actual",
|
||||
"engines": {
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@actual-app/crdt": "workspace:^",
|
||||
"better-sqlite3": "^11.7.0",
|
||||
"better-sqlite3": "^9.6.0",
|
||||
"compare-versions": "^6.1.0",
|
||||
"node-fetch": "^3.3.2",
|
||||
"uuid": "^9.0.1"
|
||||
|
||||
4
packages/desktop-client/.gitignore
vendored
@@ -10,7 +10,6 @@ playwright-report
|
||||
|
||||
# production
|
||||
build
|
||||
build-electron
|
||||
build-stats
|
||||
stats.json
|
||||
|
||||
@@ -25,6 +24,3 @@ public/kcab
|
||||
public/data
|
||||
public/data-file-index.txt
|
||||
public/*.wasm
|
||||
|
||||
# translations
|
||||
locale/
|
||||
|
||||
@@ -27,7 +27,6 @@ test.describe('Mobile Accounts', () => {
|
||||
|
||||
test('opens the accounts page and asserts on balances', async () => {
|
||||
const accountsPage = await navigation.goToAccountsPage();
|
||||
await accountsPage.waitFor();
|
||||
|
||||
const account = await accountsPage.getNthAccount(1);
|
||||
|
||||
@@ -38,10 +37,7 @@ test.describe('Mobile Accounts', () => {
|
||||
|
||||
test('opens individual account page and checks that filtering is working', async () => {
|
||||
const accountsPage = await navigation.goToAccountsPage();
|
||||
await accountsPage.waitFor();
|
||||
|
||||
const accountPage = await accountsPage.openNthAccount(0);
|
||||
await accountPage.waitFor();
|
||||
|
||||
await expect(accountPage.heading).toHaveText('Bank of America');
|
||||
await expect(accountPage.transactionList).toBeVisible();
|
||||
@@ -54,9 +50,6 @@ test.describe('Mobile Accounts', () => {
|
||||
await expect(accountPage.transactions).toHaveCount(0);
|
||||
await expect(page).toMatchThemeScreenshots();
|
||||
|
||||
await accountPage.clearSearch();
|
||||
await expect(accountPage.transactions).not.toHaveCount(0);
|
||||
|
||||
await accountPage.searchByText('Kroger');
|
||||
await expect(accountPage.transactions).not.toHaveCount(0);
|
||||
await expect(page).toMatchThemeScreenshots();
|
||||
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 35 KiB |
@@ -54,17 +54,15 @@ test.describe('Accounts', () => {
|
||||
await expect(page).toMatchThemeScreenshots();
|
||||
});
|
||||
|
||||
test.describe('On Budget Accounts', () => {
|
||||
test.describe('Budgeted Accounts', () => {
|
||||
// Reset filters
|
||||
test.afterEach(async () => {
|
||||
await accountPage.removeFilter(0);
|
||||
});
|
||||
|
||||
test('creates a transfer from two existing transactions', async () => {
|
||||
accountPage = await navigation.goToAccountPage('On budget');
|
||||
await accountPage.waitFor();
|
||||
|
||||
await expect(accountPage.accountName).toHaveText('On Budget Accounts');
|
||||
accountPage = await navigation.goToAccountPage('For budget');
|
||||
await expect(accountPage.accountName).toHaveText('Budgeted Accounts');
|
||||
|
||||
await accountPage.filterByNote('Test Acc Transfer');
|
||||
|
||||
@@ -111,7 +109,6 @@ test.describe('Accounts', () => {
|
||||
offBudget: false,
|
||||
balance: 0,
|
||||
});
|
||||
await accountPage.waitFor();
|
||||
});
|
||||
|
||||
async function importCsv(screenshot = false) {
|
||||
|
||||
|
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
@@ -27,12 +27,12 @@ test.describe('Budget', () => {
|
||||
test('renders the summary information: available funds, overspent, budgeted and for next month', async () => {
|
||||
const summary = budgetPage.budgetSummary.first();
|
||||
|
||||
await expect(summary.getByText('Available funds')).toBeVisible({
|
||||
await expect(summary.getByText('Available Funds')).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
await expect(summary.getByText(/^Overspent in /)).toBeVisible();
|
||||
await expect(summary.getByText('Budgeted')).toBeVisible();
|
||||
await expect(summary.getByText('For next month')).toBeVisible();
|
||||
await expect(summary.getByText('For Next Month')).toBeVisible();
|
||||
await expect(page).toMatchThemeScreenshots();
|
||||
});
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
@@ -30,10 +30,6 @@ export class AccountPage {
|
||||
this.selectTooltip = this.page.getByTestId('transactions-select-tooltip');
|
||||
}
|
||||
|
||||
async waitFor() {
|
||||
await this.transactionTable.waitFor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter details of a transaction
|
||||
*/
|
||||
|
||||
@@ -15,10 +15,6 @@ export class MobileAccountPage {
|
||||
});
|
||||
}
|
||||
|
||||
async waitFor() {
|
||||
await this.transactionList.waitFor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the balance of the account as a number
|
||||
*/
|
||||
@@ -33,10 +29,6 @@ export class MobileAccountPage {
|
||||
await this.searchBox.fill(term);
|
||||
}
|
||||
|
||||
async clearSearch() {
|
||||
await this.searchBox.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to transaction creation page
|
||||
*/
|
||||
|
||||
@@ -4,14 +4,9 @@ export class MobileAccountsPage {
|
||||
constructor(page) {
|
||||
this.page = page;
|
||||
|
||||
this.accountList = this.page.getByLabel('Account list');
|
||||
this.accounts = this.page.getByTestId('account');
|
||||
}
|
||||
|
||||
async waitFor() {
|
||||
await this.accountList.waitFor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name and balance of the nth account
|
||||
*/
|
||||
|
||||
@@ -34,7 +34,7 @@ export class MobileBudgetPage {
|
||||
name: 'Saved',
|
||||
});
|
||||
this.projectedSavingsButton = this.budgetTableHeader.getByRole('button', {
|
||||
name: 'Projected savings',
|
||||
name: 'Projected Savings',
|
||||
});
|
||||
this.overspentButton = this.budgetTableHeader.getByRole('button', {
|
||||
name: 'Overspent',
|
||||
@@ -294,7 +294,7 @@ export class MobileBudgetPage {
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'None of “Saved”, “Projected savings”, or “Overspent” buttons could be located on the page',
|
||||
'None of “Saved”, “Projected Savings”, or “Overspent” buttons could be located on the page',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { MobileAccountPage } from './mobile-account-page';
|
||||
import { MobileAccountsPage } from './mobile-accounts-page';
|
||||
import { MobileBudgetPage } from './mobile-budget-page';
|
||||
import { MobileTransactionEntryPage } from './mobile-transaction-entry-page';
|
||||
@@ -23,13 +22,6 @@ export class MobileNavigation {
|
||||
return new MobileAccountsPage(this.page);
|
||||
}
|
||||
|
||||
async goToUncategorizedPage() {
|
||||
const button = this.page.getByRole('button', { name: /uncategorized/ });
|
||||
await button.click();
|
||||
|
||||
return new MobileAccountPage(this.page);
|
||||
}
|
||||
|
||||
async goToTransactionEntryPage() {
|
||||
const link = this.page.getByRole('link', { name: 'Transaction' });
|
||||
await link.click();
|
||||
|
||||
@@ -66,7 +66,7 @@ export class Navigation {
|
||||
await this.page.getByLabel('Balance:').fill(String(data.balance));
|
||||
|
||||
if (data.offBudget) {
|
||||
await this.page.getByLabel('Off budget').click();
|
||||
await this.page.getByLabel('Off-budget').click();
|
||||
}
|
||||
|
||||
await this.page
|
||||
|
||||
@@ -22,9 +22,8 @@ export class ReportsPage {
|
||||
|
||||
async goToCustomReportPage() {
|
||||
await this.pageContent
|
||||
.getByRole('button', { name: 'Add new widget' })
|
||||
.getByRole('button', { name: 'Create new custom report' })
|
||||
.click();
|
||||
await this.page.getByRole('button', { name: 'New custom report' }).click();
|
||||
return new CustomReportPage(this.page);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,27 @@ export class SettingsPage {
|
||||
}
|
||||
|
||||
async useBudgetType(budgetType) {
|
||||
await this.enableExperimentalFeature('Budget mode toggle');
|
||||
|
||||
const switchBudgetTypeButton = this.page.getByRole('button', {
|
||||
name: `Switch to ${budgetType} budgeting`,
|
||||
});
|
||||
|
||||
await switchBudgetTypeButton.click();
|
||||
}
|
||||
|
||||
async enableExperimentalFeature(featureName) {
|
||||
const advancedSettingsButton = this.page.getByTestId('advanced-settings');
|
||||
await advancedSettingsButton.click();
|
||||
|
||||
const experimentalSettingsButton = this.page.getByTestId(
|
||||
'experimental-settings',
|
||||
);
|
||||
await experimentalSettingsButton.click();
|
||||
|
||||
const featureCheckbox = this.page.getByRole('checkbox', {
|
||||
name: featureName,
|
||||
});
|
||||
await featureCheckbox.click();
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 112 KiB |