summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOliver <oliver@mohlin.dev>2025-09-13 14:40:18 +0200
committerTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-10 13:36:20 +0200
commitc6aedccfe52ab97b3030003639a9bf93a435b7f3 (patch)
tree1dc34879daf89ebed231b6167a2a0246ce0b3254
parent2674ba6138cc45abcff092a7b136be75372702d9 (diff)
downloadmullvadvpn-c6aedccfe52ab97b3030003639a9bf93a435b7f3.tar.xz
mullvadvpn-c6aedccfe52ab97b3030003639a9bf93a435b7f3.zip
Add tests for manage devices view
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/helpers.ts29
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/manage-devices.spec.ts75
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/main-route-object-model.ts5
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/selectors.ts1
4 files changed, 110 insertions, 0 deletions
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/helpers.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/helpers.ts
new file mode 100644
index 0000000000..f806732113
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/helpers.ts
@@ -0,0 +1,29 @@
+import { IDevice } from '../../../../src/shared/daemon-rpc-types';
+import { MockedTestUtils } from '../mocked-utils';
+
+export const createHelpers = (utils: MockedTestUtils) => {
+ const setCurrentDevice = async (currentDevice: IDevice) => {
+ await utils.ipc.account.device.notify({
+ type: 'logged in',
+ deviceState: {
+ type: 'logged in',
+ accountAndDevice: {
+ accountNumber: '0000-0000-0000-0000',
+ device: {
+ id: currentDevice.id,
+ name: currentDevice.name,
+ created: currentDevice.created,
+ },
+ },
+ },
+ });
+ };
+
+ const setDevices = async (devices: IDevice[]) => {
+ await utils.ipc.account.devices.notify(devices);
+ };
+
+ return { setCurrentDevice, setDevices };
+};
+
+export type MAnageDevicesHelpers = ReturnType<typeof createHelpers>;
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/manage-devices.spec.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/manage-devices.spec.ts
new file mode 100644
index 0000000000..04cc376451
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/manage-devices/manage-devices.spec.ts
@@ -0,0 +1,75 @@
+import { expect, test } from '@playwright/test';
+import { Page } from 'playwright';
+
+import { IDevice } from '../../../../src/shared/daemon-rpc-types';
+import { RoutesObjectModel } from '../../route-object-models';
+import { MockedTestUtils, startMockedApp } from '../mocked-utils';
+import { createHelpers, MAnageDevicesHelpers as ManageDevicesHelpers } from './helpers';
+
+let page: Page;
+let util: MockedTestUtils;
+let routes: RoutesObjectModel;
+let helpers: ManageDevicesHelpers;
+
+export const mockDevices: IDevice[] = [
+ { id: '1', name: 'Sneaky dog', created: new Date('2024-12-05') },
+ { id: '2', name: 'Wise cat', created: new Date('2025-01-14') },
+ { id: '3', name: 'Cool panda', created: new Date('2025-03-22') },
+ { id: '4', name: 'Strong fish', created: new Date('2025-06-01') },
+ { id: '5', name: 'Magic elk', created: new Date('2025-09-10') },
+];
+
+let devices = mockDevices;
+
+test.describe('Manage devices view', () => {
+ const currentDevice = mockDevices[0];
+
+ test.beforeAll(async () => {
+ ({ page, util } = await startMockedApp());
+ routes = new RoutesObjectModel(page, util);
+ helpers = createHelpers(util);
+
+ await routes.main.waitForRoute();
+
+ await util.ipc.account.listDevices.handle(devices);
+ await helpers.setCurrentDevice(currentDevice);
+
+ await routes.main.gotoAccount();
+ await routes.account.gotoManageDevices();
+ });
+
+ test.beforeEach(() => {
+ devices = mockDevices;
+ });
+
+ test.afterAll(async () => {
+ await page.close();
+ });
+
+ test('Should display all account devices', async () => {
+ const deviceListItems = routes.manageDevices.selectors.deviceListItems();
+ for (const device of devices) {
+ await expect(deviceListItems.filter({ hasText: device.name })).toBeVisible();
+ }
+ });
+
+ test('Should not be able to delete current device', async () => {
+ const deviceListItems = routes.manageDevices.selectors.removeDeviceButton(currentDevice.name);
+ await expect(deviceListItems).toHaveCount(0);
+ });
+
+ test('Should be able to delete non-current devices', async () => {
+ const nonCurrentDevices = devices.filter((device) => device.id !== currentDevice.id);
+ for (const device of nonCurrentDevices) {
+ const deviceItem = routes.manageDevices.selectors.deviceListItem(device.name);
+ const removeButton = routes.manageDevices.selectors.removeDeviceButton(device.name);
+ await removeButton.click();
+
+ const confirmButton = routes.manageDevices.selectors.confirmRemoveDeviceButton();
+ await Promise.all([util.ipc.account.removeDevice.expect(), confirmButton.click()]);
+ devices = devices.filter((d) => d.name !== device.name);
+ await helpers.setDevices(devices);
+ await expect(deviceItem).toHaveCount(0);
+ }
+ });
+});
diff --git a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/main-route-object-model.ts b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/main-route-object-model.ts
index 2add02f601..e58895cf91 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/main-route-object-model.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/main-route-object-model.ts
@@ -29,6 +29,11 @@ export class MainRouteObjectModel {
await this.utils.expectRoute(RoutePath.selectLocation);
}
+ async gotoAccount() {
+ await this.selectors.accountButton().click();
+ await this.utils.expectRoute(RoutePath.account);
+ }
+
async expandConnectionPanel() {
await this.selectors.connectionPanelChevronButton().click();
}
diff --git a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/selectors.ts b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/selectors.ts
index 95f300c460..dd78ae4ae2 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/selectors.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/main/selectors.ts
@@ -2,6 +2,7 @@ import { Page } from 'playwright';
export const createSelectors = (page: Page) => ({
settingsButton: () => page.locator('button[aria-label="Settings"]'),
+ accountButton: () => page.locator('button[aria-label="Account settings"]'),
selectLocationButton: () => page.getByLabel('Select location'),
connectionPanelChevronButton: () => page.getByTestId('connection-panel-chevron'),
inIpLabel: () => page.getByTestId('in-ip'),