Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TypeScript] Convert playwright config and tests to TS #4217

Merged
merged 12 commits into from
Jan 22, 2025
  •  
  •  
  •  
15 changes: 11 additions & 4 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -588,11 +588,7 @@ export default [
'packages/desktop-client/**/*.{ts,tsx}',
'packages/loot-core/src/client/**/*.{ts,tsx}',
],

rules: {
// enforce type over interface
'@typescript-eslint/consistent-type-definitions': ['warn', 'type'],

// enforce import type
'@typescript-eslint/consistent-type-imports': [
'warn',
Expand Down Expand Up @@ -825,4 +821,15 @@ export default [
'rulesdir/typography': 'off',
},
},
{
files: [
'packages/desktop-client/**/*.{ts,tsx}',
'packages/loot-core/src/client/**/*.{ts,tsx}',
],
ignores: ['**/**/globals.d.ts'],
rules: {
// enforce type over interface
'@typescript-eslint/consistent-type-definitions': ['warn', 'type'],
},
},
];
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

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

test.describe('Mobile Accounts', () => {
let page;
let navigation;
let configurationPage;
let page: Page;
let navigation: MobileNavigation;
let configurationPage: ConfigurationPage;

test.beforeEach(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { join } from 'path';

import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { type AccountPage } from './page-models/account-page';
import { ConfigurationPage } from './page-models/configuration-page';
import { Navigation } from './page-models/navigation';

test.describe('Accounts', () => {
let page;
let navigation;
let configurationPage;
let accountPage;
let page: Page;
let navigation: Navigation;
let configurationPage: ConfigurationPage;
let accountPage: AccountPage;

test.beforeEach(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Original file line number Diff line number Diff line change
@@ -1,48 +1,66 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { amountToCurrency, currencyToAmount } from 'loot-core/shared/util';
import * as monthUtils from 'loot-core/src/shared/months';

import { expect, test } from './fixtures';
import { ConfigurationPage } from './page-models/configuration-page';
import { type MobileBudgetPage } from './page-models/mobile-budget-page';
import { MobileNavigation } from './page-models/mobile-navigation';

const copyLastMonthBudget = async (budgetPage, categoryName) => {
const copyLastMonthBudget = async (
budgetPage: MobileBudgetPage,
categoryName: string,
) => {
const budgetMenuModal = await budgetPage.openBudgetMenu(categoryName);
await budgetMenuModal.copyLastMonthBudget();
await budgetMenuModal.close();
};

const setTo3MonthAverage = async (budgetPage, categoryName) => {
const setTo3MonthAverage = async (
budgetPage: MobileBudgetPage,
categoryName: string,
) => {
const budgetMenuModal = await budgetPage.openBudgetMenu(categoryName);
await budgetMenuModal.setTo3MonthAverage();
await budgetMenuModal.close();
};

const setTo6MonthAverage = async (budgetPage, categoryName) => {
const setTo6MonthAverage = async (
budgetPage: MobileBudgetPage,
categoryName: string,
) => {
const budgetMenuModal = await budgetPage.openBudgetMenu(categoryName);
await budgetMenuModal.setTo6MonthAverage();
await budgetMenuModal.close();
};

const setToYearlyAverage = async (budgetPage, categoryName) => {
const setToYearlyAverage = async (
budgetPage: MobileBudgetPage,
categoryName: string,
) => {
const budgetMenuModal = await budgetPage.openBudgetMenu(categoryName);
await budgetMenuModal.setToYearlyAverage();
await budgetMenuModal.close();
};

async function setBudgetAverage(
budgetPage,
categoryName,
numberOfMonths,
setBudgetAverageFn,
budgetPage: MobileBudgetPage,
categoryName: string,
numberOfMonths: number,
setBudgetAverageFn: (
budgetPage: MobileBudgetPage,
categoryName: string,
numberOfMonths: number,
) => Promise<void>,
) {
let totalSpent = 0;

for (let i = 0; i < numberOfMonths; i++) {
await budgetPage.goToPreviousMonth();
const spentButton = await budgetPage.getButtonForSpent(categoryName);
const spent = await spentButton.textContent();
totalSpent += currencyToAmount(spent);
totalSpent += currencyToAmount(spent) ?? 0;
}

// Calculate average amount
Expand All @@ -62,10 +80,10 @@ const budgetTypes = ['Envelope', 'Tracking'];

budgetTypes.forEach(budgetType => {
test.describe(`Mobile Budget [${budgetType}]`, () => {
let page;
let navigation;
let configurationPage;
let previousGlobalIsTesting;
let page: Page;
let navigation: MobileNavigation;
let configurationPage: ConfigurationPage;
let previousGlobalIsTesting: boolean;

test.beforeAll(() => {
// TODO: Hack, properly mock the currentMonth function
Expand Down Expand Up @@ -270,11 +288,13 @@ budgetTypes.forEach(budgetType => {
await expect(page).toMatchThemeScreenshots();
});

[
[3, setTo3MonthAverage],
[6, setTo6MonthAverage],
[12, setToYearlyAverage],
].forEach(([numberOfMonths, setBudgetAverageFn]) => {
(
[
[3, setTo3MonthAverage],
[6, setTo6MonthAverage],
[12, setToYearlyAverage],
] as const
).forEach(([numberOfMonths, setBudgetAverageFn]) => {
test(`set budget to ${numberOfMonths} month average`, async () => {
const budgetPage = await navigation.goToBudgetPage();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { type BudgetPage } from './page-models/budget-page';
import { ConfigurationPage } from './page-models/configuration-page';

test.describe('Budget', () => {
let page;
let configurationPage;
let budgetPage;
let page: Page;
let configurationPage: ConfigurationPage;
let budgetPage: BudgetPage;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
Expand Down
55 changes: 55 additions & 0 deletions packages/desktop-client/e2e/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { expect as baseExpect, type Locator } from '@playwright/test';

export { test } from '@playwright/test';

export const expect = baseExpect.extend({
async toMatchThemeScreenshots(locator: Locator) {
// Disable screenshot assertions in regular e2e tests;
// only enable them when doing VRT tests
if (!process.env.VRT) {
return {
message: () => 'passed',
pass: true,
};
}

const config = {
// eslint-disable-next-line rulesdir/typography
mask: [locator.locator('[data-vrt-mask="true"]')],
maxDiffPixels: 5,
};

// Get the data-theme attribute from page.
// If there is a page() function, it means that the locator
// is not a page object but a locator object.
const dataThemeLocator =
typeof locator.page === 'function'
? locator.page().locator('[data-theme]')
: locator.locator('[data-theme]');
matt-fidd marked this conversation as resolved.
Show resolved Hide resolved

// Check lightmode
await locator.evaluate(() => window.Actual.setTheme('auto'));
await baseExpect(dataThemeLocator).toHaveAttribute('data-theme', 'auto');
await baseExpect(locator).toHaveScreenshot(config);

// Switch to darkmode and check
await locator.evaluate(() => window.Actual.setTheme('dark'));
await baseExpect(dataThemeLocator).toHaveAttribute('data-theme', 'dark');
await baseExpect(locator).toHaveScreenshot(config);

// Switch to midnight theme and check
await locator.evaluate(() => window.Actual.setTheme('midnight'));
await baseExpect(dataThemeLocator).toHaveAttribute(
'data-theme',
'midnight',
);
await baseExpect(locator).toHaveScreenshot(config);

// Switch back to lightmode
await locator.evaluate(() => window.Actual.setTheme('auto'));
return {
message: () => 'pass',
pass: true,
};
},
});
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import path from 'path';

import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { AccountPage } from './page-models/account-page';
import { ConfigurationPage } from './page-models/configuration-page';
import { Navigation } from './page-models/navigation';

test.describe('Onboarding', () => {
let page;
let navigation;
let configurationPage;
let page: Page;
let navigation: Navigation;
let configurationPage: ConfigurationPage;

test.beforeEach(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { ConfigurationPage } from './page-models/configuration-page';
import { type CustomReportPage } from './page-models/custom-report-page';
import { Navigation } from './page-models/navigation';
import { type ReportsPage } from './page-models/reports-page';

test.describe.parallel('Reports', () => {
let page;
let navigation;
let reportsPage;
let configurationPage;
let page: Page;
let navigation: Navigation;
let reportsPage: ReportsPage;
let configurationPage: ConfigurationPage;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
Expand Down Expand Up @@ -45,7 +48,7 @@ test.describe.parallel('Reports', () => {
});

test.describe.parallel('custom reports', () => {
let customReportPage;
let customReportPage: CustomReportPage;

test.beforeEach(async () => {
customReportPage = await reportsPage.goToCustomReportPage();
Expand Down
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { ConfigurationPage } from './page-models/configuration-page';
import { Navigation } from './page-models/navigation';
import { type RulesPage } from './page-models/rules-page';

test.describe('Rules', () => {
let page;
let navigation;
let rulesPage;
let configurationPage;
let page: Page;
let navigation: Navigation;
let rulesPage: RulesPage;
let configurationPage: ConfigurationPage;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { ConfigurationPage } from './page-models/configuration-page';
import { Navigation } from './page-models/navigation';
import { type SchedulesPage } from './page-models/schedules-page';

test.describe('Schedules', () => {
let page;
let navigation;
let schedulesPage;
let configurationPage;
let page: Page;
let navigation: Navigation;
let schedulesPage: SchedulesPage;
let configurationPage: ConfigurationPage;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

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

test.describe('Mobile Settings', () => {
let page;
let navigation;
let configurationPage;
let page: Page;
let navigation: MobileNavigation;
let configurationPage: ConfigurationPage;

test.beforeEach(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { test, expect } from '@playwright/test';
import { type Page } from '@playwright/test';

import { expect, test } from './fixtures';
import { ConfigurationPage } from './page-models/configuration-page';
import { Navigation } from './page-models/navigation';
import { type SettingsPage } from './page-models/settings-page';

test.describe('Settings', () => {
let page;
let navigation;
let settingsPage;
let configurationPage;
let page: Page;
let navigation: Navigation;
let settingsPage: SettingsPage;
let configurationPage: ConfigurationPage;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
Expand Down
Diff not rendered.
Loading
Loading