Skip to content

Commit

Permalink
Merge branch 'master' into MonthCountSelector-ts-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Jod929 authored Aug 21, 2023
2 parents 2ed62e5 + 6912c08 commit fdc0828
Show file tree
Hide file tree
Showing 61 changed files with 1,193 additions and 576 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ module.exports = {
'./packages/desktop-client/src/components/settings/index.*',
'./packages/desktop-client/src/components/sidebar.*',
'./packages/desktop-client/src/components/transactions/MobileTransaction.*',
'./packages/desktop-client/src/components/transactions/TransactionsTable.*',
'./packages/desktop-client/src/components/util/AmountInput.*',
'./packages/desktop-client/src/components/util/DisplayId.*',
'./packages/desktop-client/src/components/util/LoadComponent.*',
Expand Down
137 changes: 137 additions & 0 deletions packages/desktop-client/e2e/mobile.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { test, expect } from '@playwright/test';

import { ConfigurationPage } from './page-models/configuration-page';
import { MobileNavigation } from './page-models/mobile-navigation';

test.describe('Mobile', () => {
let page;
let navigation;
let configurationPage;

test.beforeEach(async ({ browser }) => {
page = await browser.newPage();
navigation = new MobileNavigation(page);
configurationPage = new ConfigurationPage(page);

await page.setViewportSize({
width: 350,
height: 600,
});
await page.goto('/');
await configurationPage.createTestFile();
});

test.afterEach(async () => {
await page.close();
});

test('loads the budget page with budgeted amounts', async () => {
const budgetPage = await navigation.goToBudgetPage();

await expect(budgetPage.categoryNames).toHaveText([
'Food',
'Restaurants',
'Entertainment',
'Clothing',
'General',
'Gift',
'Medical',
'Savings',
'Cell',
'Internet',
'Mortgage',
'Water',
'Power',
]);
});

test('opens the accounts page and asserts on balances', async () => {
const accountsPage = await navigation.goToAccountsPage();

const account = await accountsPage.getNthAccount(0);

expect(account.name).toEqual('Ally Savings');
expect(account.balance).toBeGreaterThan(0);
});

test('opens individual account page and checks that filtering is working', async () => {
const accountsPage = await navigation.goToAccountsPage();
const accountPage = await accountsPage.openNthAccount(1);

await expect(accountPage.heading).toHaveText('Bank of America');
expect(await accountPage.getBalance()).toBeGreaterThan(0);

await expect(accountPage.noTransactionsFoundError).not.toBeVisible();

await accountPage.searchByText('nothing should be found');
await expect(accountPage.noTransactionsFoundError).toBeVisible();
await expect(accountPage.transactions).toHaveCount(0);

await accountPage.searchByText('Kroger');
await expect(accountPage.transactions).not.toHaveCount(0);
});

test('creates a transaction via footer button', async () => {
const transactionEntryPage = await navigation.goToTransactionEntryPage();

await expect(transactionEntryPage.header).toHaveText('New Transaction');

await transactionEntryPage.amountField.fill('12.34');
await transactionEntryPage.fillField(
page.getByTestId('payee-field'),
'Kroger',
);
await transactionEntryPage.fillField(
page.getByTestId('category-field'),
'Clothing',
);
await transactionEntryPage.fillField(
page.getByTestId('account-field'),
'Ally Savings',
);

const accountPage = await transactionEntryPage.createTransaction();

await expect(accountPage.transactions.nth(0)).toHaveText(
'KrogerClothing-12.34',
);
});

test('creates a transaction from `/accounts/:id` page', async () => {
const accountsPage = await navigation.goToAccountsPage();
const accountPage = await accountsPage.openNthAccount(1);
const transactionEntryPage = await accountPage.clickCreateTransaction();

await expect(transactionEntryPage.header).toHaveText('New Transaction');

await transactionEntryPage.amountField.fill('12.34');
await transactionEntryPage.fillField(
page.getByTestId('payee-field'),
'Kroger',
);
await transactionEntryPage.fillField(
page.getByTestId('category-field'),
'Clothing',
);

await transactionEntryPage.createTransaction();

await expect(accountPage.transactions.nth(0)).toHaveText(
'KrogerClothing-12.34',
);
});

test('checks that settings page can be opened', async () => {
const settingsPage = await navigation.goToSettingsPage();

const downloadPromise = page.waitForEvent('download');

await settingsPage.exportData();

const download = await downloadPromise;

expect(await download.suggestedFilename()).toMatch(
/^\d{4}-\d{2}-\d{2}-.*.zip$/,
);
});
});
39 changes: 39 additions & 0 deletions packages/desktop-client/e2e/page-models/mobile-account-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { MobileTransactionEntryPage } from './mobile-transaction-entry-page';

export class MobileAccountPage {
constructor(page) {
this.page = page;

this.heading = page.getByRole('heading');
this.balance = page.getByTestId('account-balance');
this.noTransactionsFoundError = page.getByText('No transactions');
this.searchBox = page.getByPlaceholder(/^Search/);
this.transactionList = page.getByLabel('transaction list');
this.transactions = this.transactionList.getByRole('button');
this.createTransactionButton = page.getByRole('button', {
name: 'Add Transaction',
});
}

/**
* Retrieve the balance of the account as a number
*/
async getBalance() {
return parseInt(await this.balance.textContent(), 10);
}

/**
* Search by the given term
*/
async searchByText(term) {
await this.searchBox.fill(term);
}

/**
* Go to transaction creation page
*/
async clickCreateTransaction() {
this.createTransactionButton.click();
return new MobileTransactionEntryPage(this.page);
}
}
33 changes: 33 additions & 0 deletions packages/desktop-client/e2e/page-models/mobile-accounts-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MobileAccountPage } from './mobile-account-page';

export class MobileAccountsPage {
constructor(page) {
this.page = page;

this.accounts = this.page.getByTestId('account');
}

/**
* Get the name and balance of the nth account
*/
async getNthAccount(idx) {
const accountRow = this.accounts.nth(idx);

return {
name: await accountRow.getByTestId('account-name').textContent(),
balance: parseInt(
await accountRow.getByTestId('account-balance').textContent(),
10,
),
};
}

/**
* Click on the n-th account to open it up
*/
async openNthAccount(idx) {
await this.accounts.nth(idx).getByRole('button').click();

return new MobileAccountPage(this.page);
}
}
9 changes: 9 additions & 0 deletions packages/desktop-client/e2e/page-models/mobile-budget-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class MobileBudgetPage {
constructor(page) {
this.page = page;

this.categoryNames = page
.getByTestId('budget-groups')
.getByTestId('category-name');
}
}
38 changes: 38 additions & 0 deletions packages/desktop-client/e2e/page-models/mobile-navigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { MobileAccountsPage } from './mobile-accounts-page';
import { MobileBudgetPage } from './mobile-budget-page';
import { MobileTransactionEntryPage } from './mobile-transaction-entry-page';
import { SettingsPage } from './settings-page';

export class MobileNavigation {
constructor(page) {
this.page = page;
}

async goToBudgetPage() {
const link = this.page.getByRole('link', { name: 'Budget' });
await link.click();

return new MobileBudgetPage(this.page);
}

async goToAccountsPage() {
const link = this.page.getByRole('link', { name: 'Accounts' });
await link.click();

return new MobileAccountsPage(this.page);
}

async goToTransactionEntryPage() {
const link = this.page.getByRole('link', { name: 'Transaction' });
await link.click();

return new MobileTransactionEntryPage(this.page);
}

async goToSettingsPage() {
const link = this.page.getByRole('link', { name: 'Settings' });
await link.click();

return new SettingsPage(this.page);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MobileAccountPage } from './mobile-account-page';

export class MobileTransactionEntryPage {
constructor(page) {
this.page = page;

this.header = page.getByRole('heading');
this.amountField = page.getByTestId('amount-input');
this.add = page.getByRole('button', { name: 'Add transaction' });
}

async fillField(fieldLocator, content) {
await fieldLocator.click();
await this.page.locator('css=[role=combobox] input').fill(content);
await this.page.keyboard.press('Enter');
}

async createTransaction() {
await this.add.click();

return new MobileAccountPage(this.page);
}
}
1 change: 1 addition & 0 deletions packages/desktop-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.2.0",
"react-error-boundary": "^4.0.11",
"react-merge-refs": "^1.1.0",
"react-modal": "3.16.1",
"react-redux": "7.2.1",
Expand Down
Loading

0 comments on commit fdc0828

Please sign in to comment.