summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/helpers.ts114
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/select-location.spec.ts150
2 files changed, 222 insertions, 42 deletions
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/helpers.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/helpers.ts
new file mode 100644
index 0000000000..7490adc6ac
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/helpers.ts
@@ -0,0 +1,114 @@
+import { Page } from 'playwright';
+
+import { getDefaultSettings } from '../../../../src/main/default-settings';
+import {
+ IRelayList,
+ IRelayListCity,
+ IRelayListCountry,
+ IRelayListHostname,
+ Ownership,
+} from '../../../../src/shared/daemon-rpc-types';
+import { RoutePath } from '../../../../src/shared/routes';
+import { RoutesObjectModel } from '../../route-object-models';
+import { MockedTestUtils } from '../mocked-utils';
+
+export type LocatedRelay = {
+ country: IRelayListCountry;
+ city: IRelayListCity;
+ relay: IRelayListHostname;
+};
+
+export const createHelpers = (page: Page, routes: RoutesObjectModel, utils: MockedTestUtils) => {
+ const areAllCheckboxesChecked = async () => {
+ const checkboxes = page.getByRole('checkbox');
+ return checkboxes.evaluateAll((checkboxes) =>
+ checkboxes.every((checkbox) => checkbox.getAttribute('aria-checked') === 'true'),
+ );
+ };
+
+ const expandLocatedRelays = async (locatedRelays: LocatedRelay[]) => {
+ for (const locatedRelay of locatedRelays) {
+ await routes.selectLocation.toggleAccordion(locatedRelay.country.name);
+ await routes.selectLocation.toggleAccordion(locatedRelay.city.name);
+ }
+ };
+
+ const locateRelaysByProvider = (relayList: IRelayList, provider?: string): LocatedRelay[] =>
+ relayList.countries.flatMap((country) =>
+ country.cities.flatMap((city) =>
+ city.relays
+ .filter((relay) => !provider || relay.provider === provider)
+ .map((relay) => ({ country, city, relay })),
+ ),
+ );
+
+ const locateRelaysByOwner = (relayList: IRelayList, owned?: boolean): LocatedRelay[] =>
+ relayList.countries.flatMap((country) =>
+ country.cities.flatMap((city) =>
+ city.relays
+ .filter((relay) => relay.owned === owned)
+ .map((relay) => ({ country, city, relay })),
+ ),
+ );
+
+ const resetOwnership = async () => {
+ await routes.filter.expandOwnership();
+ await routes.filter.selectOwnershipOption('Any');
+ await routes.filter.collapseOwnership();
+ };
+
+ const resetProviders = async () => {
+ await routes.filter.expandProviders();
+ const allCheckboxesChecked = await areAllCheckboxesChecked();
+ if (!allCheckboxesChecked) {
+ await routes.filter.checkAllProvidersCheckbox();
+ }
+ await routes.filter.collapseProviders();
+ };
+
+ const resetView = async () => {
+ const currentRoute = await utils.currentRoute();
+ if (currentRoute === RoutePath.selectLocation) {
+ await routes.selectLocation.gotoFilter();
+ }
+ };
+
+ const updateMockRelayFilter = async ({
+ ownership,
+ providers,
+ }: {
+ ownership?: Ownership;
+ providers?: string[];
+ }) => {
+ const settings = getDefaultSettings();
+ if ('normal' in settings.relaySettings) {
+ if (ownership) {
+ settings.relaySettings.normal.ownership = ownership;
+ }
+ if (providers) {
+ settings.relaySettings.normal.providers = providers;
+ }
+ }
+ await utils.mockIpcHandle({
+ channel: 'settings-setRelaySettings',
+ response: {},
+ });
+ await utils.sendMockIpcResponse({
+ channel: 'settings-',
+ response: settings,
+ });
+ };
+
+ return {
+ areAllCheckboxesChecked,
+ expandLocatedRelays,
+ locateRelaysByProvider,
+ locateRelaysByOwner,
+ resetOwnership,
+ resetProviders,
+ resetView,
+ updateMockRelayFilter,
+ };
+};
+
+export type SelectLocationHelpers = ReturnType<typeof createHelpers>;
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/select-location.spec.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/select-location.spec.ts
index 1984213e2b..b01c5ac054 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/select-location.spec.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/select-location/select-location.spec.ts
@@ -4,54 +4,16 @@ import { Page } from 'playwright';
import { getDefaultSettings } from '../../../../src/main/default-settings';
import { colorTokens } from '../../../../src/renderer/lib/foundations';
import {
- IRelayList,
IRelayListWithEndpointData,
ISettings,
IWireguardEndpointData,
+ Ownership,
} from '../../../../src/shared/daemon-rpc-types';
import { RoutePath } from '../../../../src/shared/routes';
+import { RoutesObjectModel } from '../../route-object-models';
import { MockedTestUtils, startMockedApp } from '../mocked-utils';
-
-const relayList: IRelayList = {
- countries: [
- {
- name: 'Sweden',
- code: 'se',
- cities: [
- {
- name: 'Gothenburg',
- code: 'got',
- latitude: 58,
- longitude: 12,
- relays: [
- {
- hostname: 'se-got-wg-101',
- provider: 'mullvad',
- ipv4AddrIn: '10.0.0.1',
- includeInCountry: true,
- active: true,
- weight: 0,
- owned: true,
- endpointType: 'wireguard',
- daita: true,
- },
- {
- hostname: 'se-got-wg-102',
- provider: 'mullvad',
- ipv4AddrIn: '10.0.0.2',
- includeInCountry: true,
- active: true,
- weight: 0,
- owned: true,
- endpointType: 'wireguard',
- daita: true,
- },
- ],
- },
- ],
- },
- ],
-};
+import { createHelpers, SelectLocationHelpers } from './helpers';
+import { mockData } from './mock-data';
const wireguardEndpointData: IWireguardEndpointData = {
portRanges: [],
@@ -60,10 +22,15 @@ const wireguardEndpointData: IWireguardEndpointData = {
let page: Page;
let util: MockedTestUtils;
+let routes: RoutesObjectModel;
+let helpers: SelectLocationHelpers;
+const { relayList } = mockData;
test.describe('Select location', () => {
test.beforeAll(async () => {
({ page, util } = await startMockedApp());
+ routes = new RoutesObjectModel(page, util);
+ helpers = createHelpers(page, routes, util);
await util.waitForRoute(RoutePath.main);
await page.getByLabel('Select location').click();
await util.waitForRoute(RoutePath.selectLocation);
@@ -151,4 +118,103 @@ test.describe('Select location', () => {
await expect(sweden).toBeVisible();
});
});
+
+ test.describe('Filter', () => {
+ test.beforeEach(async () => {
+ await helpers.resetView();
+ await helpers.resetProviders();
+ await helpers.resetOwnership();
+ });
+
+ test.describe('Filter by provider', () => {
+ test('Should deselect all providers when clicking all providers checkbox', async () => {
+ await routes.filter.expandProviders();
+ await routes.filter.checkAllProvidersCheckbox();
+ expect(await helpers.areAllCheckboxesChecked()).toBe(false);
+
+ await routes.filter.checkAllProvidersCheckbox();
+ expect(await helpers.areAllCheckboxesChecked()).toBe(true);
+ });
+
+ test('Should apply filter when selecting provider', async () => {
+ await routes.filter.expandProviders();
+ await routes.filter.checkAllProvidersCheckbox();
+ expect(await helpers.areAllCheckboxesChecked()).toBe(false);
+
+ // Select one provider
+ const provider = relayList.countries[0].cities[0].relays[0].provider;
+ await routes.filter.checkProviderCheckbox(provider);
+
+ await helpers.updateMockRelayFilter({
+ providers: [provider],
+ });
+
+ await routes.filter.applyFilter();
+ await util.waitForRoute(RoutePath.selectLocation);
+ const providerFilterChip = routes.selectLocation.getFilterChip('Providers: 1');
+ await expect(providerFilterChip).toBeVisible();
+
+ const locatedRelays = helpers.locateRelaysByProvider(relayList, provider);
+ const relays = locatedRelays.map((locatedRelay) => locatedRelay.relay);
+ const relayNames = relays.map((relay) => relay.hostname);
+
+ // Expand all accordions
+ await helpers.expandLocatedRelays(locatedRelays);
+
+ const buttons = routes.selectLocation.getRelaysMatching(relayNames);
+
+ // Expect all filtered relays to have a button
+ await expect(buttons).toHaveCount(relays.length);
+
+ // Clear filter
+ await providerFilterChip.click();
+
+ // Get all relays and expand accordions
+ const allLocatedRelays = helpers.locateRelaysByProvider(relayList);
+ await helpers.expandLocatedRelays(allLocatedRelays);
+
+ // Should not have same length as all relays
+ await expect(buttons).not.toHaveCount(allLocatedRelays.length);
+ });
+ });
+
+ test.describe('Filter by ownership', () => {
+ test('Should apply filter when selecting ownership', async () => {
+ // Select rented only
+ await routes.filter.expandOwnership();
+ await routes.filter.selectOwnershipOption('Rented only');
+ await helpers.updateMockRelayFilter({
+ ownership: Ownership.rented,
+ });
+
+ await routes.filter.applyFilter();
+ await util.waitForRoute(RoutePath.selectLocation);
+
+ const ownerFilterChip = routes.selectLocation.getFilterChip('Rented');
+ await expect(ownerFilterChip).toBeVisible();
+
+ const locatedRelays = helpers.locateRelaysByOwner(relayList, false);
+ const relays = locatedRelays.map((locatedRelay) => locatedRelay.relay);
+ const relayNames = relays.map((relay) => relay.hostname);
+
+ // Expand all accordions
+ await helpers.expandLocatedRelays(locatedRelays);
+
+ const buttons = routes.selectLocation.getRelaysMatching(relayNames);
+
+ // Expect all filtered relays to have a button
+ await expect(buttons).toHaveCount(relays.length);
+
+ // Clear filter
+ await ownerFilterChip.click();
+
+ // Get all relays and expand accordions
+ const allLocatedRelays = helpers.locateRelaysByOwner(relayList);
+ await helpers.expandLocatedRelays(allLocatedRelays);
+
+ // Should not have same length as all relays
+ await expect(buttons).not.toHaveCount(allLocatedRelays.length);
+ });
+ });
+ });
});