diff options
| author | Oskar <oskar@mullvad.net> | 2024-08-21 17:08:37 +0200 |
|---|---|---|
| committer | Oskar <oskar@mullvad.net> | 2024-08-21 17:08:37 +0200 |
| commit | 0cc9684200426eef11b65cf8373d29eddf8aa90e (patch) | |
| tree | 68dc1c457f693035ea26b723414b7cd2a28958e3 /gui/test | |
| parent | b26659e05b50c3a1b0499620f683748287707769 (diff) | |
| parent | 6ceed1dffca2fc0c4b867fe60638db5bf29f1065 (diff) | |
| download | mullvadvpn-0cc9684200426eef11b65cf8373d29eddf8aa90e.tar.xz mullvadvpn-0cc9684200426eef11b65cf8373d29eddf8aa90e.zip | |
Merge branch 'implement-feature-indicators-in-main-view-des-910'
Diffstat (limited to 'gui/test')
| -rw-r--r-- | gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts | 33 | ||||
| -rw-r--r-- | gui/test/e2e/mocked/feature-indicators.spec.ts | 133 | ||||
| -rw-r--r-- | gui/test/e2e/mocked/tunnel-state.spec.ts | 4 | ||||
| -rw-r--r-- | gui/test/e2e/shared/tunnel-state.ts | 63 | ||||
| -rw-r--r-- | gui/test/unit/notification-evaluation.spec.ts | 2 |
5 files changed, 175 insertions, 60 deletions
diff --git a/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts b/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts index 6c079629fb..af32668efb 100644 --- a/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts +++ b/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts @@ -4,7 +4,6 @@ import { expect, test } from '@playwright/test'; import { Page } from 'playwright'; import { expectConnected, - expectConnectedPq, expectDisconnected, expectError, } from '../../shared/tunnel-state'; @@ -35,7 +34,7 @@ test('App should show disconnected tunnel state', async () => { }); test('App should connect', async () => { - await page.getByText('Secure my connection').click(); + await page.getByText('Connect', { exact: true }).click(); await expectConnected(page); const relay = page.getByTestId('hostname-line'); @@ -65,10 +64,12 @@ test('App should show correct WireGuard port', async () => { await exec('mullvad obfuscation set mode off'); await exec('mullvad relay set tunnel wireguard --port=53'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':53')); await exec('mullvad relay set tunnel wireguard --port=51820'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':51820')); await exec('mullvad relay set tunnel wireguard --port=any'); @@ -80,10 +81,12 @@ test('App should show correct WireGuard transport protocol', async () => { await exec('mullvad obfuscation set mode udp2tcp'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp('TCP')); await exec('mullvad obfuscation set mode off'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp('UDP$')); }); @@ -94,6 +97,7 @@ test('App should show correct tunnel protocol', async () => { await exec('mullvad relay set tunnel-protocol openvpn'); await exec('mullvad relay set location se'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(tunnelProtocol).toHaveText('OpenVPN'); }); @@ -104,23 +108,28 @@ test('App should show correct OpenVPN transport protocol and port', async () => await expect(inData).toContainText(new RegExp('(TCP|UDP)$')); await exec('mullvad relay set tunnel openvpn --transport-protocol udp --port 1195'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':1195')); await exec('mullvad relay set tunnel openvpn --transport-protocol udp --port 1300'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':1300')); await exec('mullvad relay set tunnel openvpn --transport-protocol tcp --port any'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':[0-9]+')); await expect(inData).toContainText(new RegExp('TCP$')); await exec('mullvad relay set tunnel openvpn --transport-protocol tcp --port 80'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':80')); await exec('mullvad relay set tunnel openvpn --transport-protocol tcp --port 443'); await expectConnected(page); + await page.getByTestId('connection-panel-chevron').click(); await expect(inData).toContainText(new RegExp(':443')); await exec('mullvad relay set tunnel openvpn --transport-protocol any'); @@ -144,29 +153,19 @@ test('App should enter blocked state', async () => { await expectConnected(page); }); -test('App should disconnect', async () => { - await page.getByText('Disconnect').click(); - await expectDisconnected(page); -}); - -test('App should create quantum secure connection', async () => { - await exec('mullvad tunnel set wireguard --quantum-resistant on'); - await page.getByText('Secure my connection').click(); - - await expectConnectedPq(page); -}); - test('App should show multihop', async () => { await exec('mullvad relay set tunnel wireguard --use-multihop=on'); - await expectConnectedPq(page); + await expectConnected(page); const relay = page.getByTestId('hostname-line'); await expect(relay).toHaveText(new RegExp('^' + escapeRegExp(`${process.env.HOSTNAME} via`), 'i')); await exec('mullvad relay set tunnel wireguard --use-multihop=off'); - - await exec('mullvad tunnel set wireguard --quantum-resistant off'); await page.getByText('Disconnect').click(); }); +test('App should disconnect', async () => { + await page.getByText('Disconnect').click(); + await expectDisconnected(page); +}); test('App should become connected when other frontend connects', async () => { await expectDisconnected(page); diff --git a/gui/test/e2e/mocked/feature-indicators.spec.ts b/gui/test/e2e/mocked/feature-indicators.spec.ts new file mode 100644 index 0000000000..0cb0b1b1ec --- /dev/null +++ b/gui/test/e2e/mocked/feature-indicators.spec.ts @@ -0,0 +1,133 @@ +import { expect, test } from '@playwright/test'; +import { Page } from 'playwright'; + +import { MockedTestUtils, startMockedApp } from './mocked-utils'; +import { FeatureIndicator, ILocation, ITunnelEndpoint, TunnelState } from '../../../src/shared/daemon-rpc-types'; +import { expectConnected } from '../shared/tunnel-state'; + +const endpoint: ITunnelEndpoint = { + address: 'wg10:80', + protocol: 'tcp', + quantumResistant: false, + tunnelType: 'wireguard', + daita: false, +}; + +const mockDisconnectedLocation: ILocation = { + country: 'Sweden', + city: 'Gothenburg', + latitude: 58, + longitude: 12, + mullvadExitIp: false, +}; + +const mockConnectedLocation: ILocation = { ...mockDisconnectedLocation, mullvadExitIp: true }; + +let page: Page; +let util: MockedTestUtils; + +test.beforeAll(async () => { + ({ page, util } = await startMockedApp()); +}); + +test.afterAll(async () => { + await page.close(); +}); + +test('App should show no feature indicators', async () => { + await util.mockIpcHandle<ILocation>({ + channel: 'location-get', + response: mockDisconnectedLocation, + }); + await util.sendMockIpcResponse<TunnelState>({ + channel: 'tunnel-', + response: { + state: 'connected', + details: { endpoint, location: mockConnectedLocation }, + featureIndicators: undefined, + }, + }); + + await expectConnected(page); + await expectFeatureIndicators(page, []); + + const ellipsis = page.getByText(/^\d more.../); + await expect(ellipsis).not.toBeVisible(); + + await page.getByTestId('connection-panel-chevron').click(); + await expect(ellipsis).not.toBeVisible(); + + await expectFeatureIndicators(page, []); +}); + +test('App should show feature indicators', async () => { + await util.mockIpcHandle<ILocation>({ + channel: 'location-get', + response: mockDisconnectedLocation, + }); + await util.sendMockIpcResponse<TunnelState>({ + channel: 'tunnel-', + response: { + state: 'connected', + details: { endpoint, location: mockConnectedLocation }, + featureIndicators: [ + FeatureIndicator.daita, + FeatureIndicator.udp2tcp, + FeatureIndicator.customMssFix, + FeatureIndicator.customMtu, + FeatureIndicator.lanSharing, + FeatureIndicator.serverIpOverride, + FeatureIndicator.customDns, + FeatureIndicator.lockdownMode, + FeatureIndicator.quantumResistance, + FeatureIndicator.multihop, + ], + }, + }); + + await expectConnected(page); + await expectFeatureIndicators(page, ["DAITA", "Quantum resistance"], false); + await expectHiddenFeatureIndicator(page, "Mssfix"); + + const ellipsis = page.getByText(/^\d more.../); + await expect(ellipsis).toBeVisible(); + + await page.getByTestId('connection-panel-chevron').click(); + await expect(ellipsis).not.toBeVisible(); + + await expectFeatureIndicators(page, [ + "DAITA", + "Quantum resistance", + "Mssfix", + "MTU", + "Obfuscation", + "Local network sharing", + "Lockdown mode", + "Multihop", + "Custom DNS", + "Server IP override", + ]); +}); + +async function expectHiddenFeatureIndicator(page: Page, hiddenIndicator: string) { + const indicators = page.getByTestId('feature-indicator'); + const indicator = indicators.getByText(hiddenIndicator, { exact: true }); + + await expect(indicator).toHaveCount(1); + await expect(indicator).not.toBeVisible(); +} + +async function expectFeatureIndicators( + page: Page, + expectedIndicators: Array<string>, + only = true, +) { + const indicators = page.getByTestId('feature-indicator'); + if (only) { + await expect(indicators).toHaveCount(expectedIndicators.length); + } + + for (const indicator of expectedIndicators) { + await expect(indicators.getByText(indicator, { exact: true })).toBeVisible(); + } +} diff --git a/gui/test/e2e/mocked/tunnel-state.spec.ts b/gui/test/e2e/mocked/tunnel-state.spec.ts index b4de405841..3e20dab6ec 100644 --- a/gui/test/e2e/mocked/tunnel-state.spec.ts +++ b/gui/test/e2e/mocked/tunnel-state.spec.ts @@ -49,7 +49,7 @@ test('App should show connecting tunnel state', async () => { }); await util.sendMockIpcResponse<TunnelState>({ channel: 'tunnel-', - response: { state: 'connecting' }, + response: { state: 'connecting', featureIndicators: undefined }, }); await expectConnecting(page); }); @@ -73,7 +73,7 @@ test('App should show connected tunnel state', async () => { }; await util.sendMockIpcResponse<TunnelState>({ channel: 'tunnel-', - response: { state: 'connected', details: { endpoint, location } }, + response: { state: 'connected', details: { endpoint, location }, featureIndicators: undefined }, }); await expectConnected(page); diff --git a/gui/test/e2e/shared/tunnel-state.ts b/gui/test/e2e/shared/tunnel-state.ts index db7b7e3658..4d75f79d01 100644 --- a/gui/test/e2e/shared/tunnel-state.ts +++ b/gui/test/e2e/shared/tunnel-state.ts @@ -3,51 +3,54 @@ import { Page } from 'playwright'; import { colors } from '../../../src/config.json'; import { anyOf } from '../utils'; -const UNSECURED_COLOR = colors.red; -const SECURE_COLOR = colors.green; +const DISCONNECTED_COLOR = colors.red; +const CONNECTED_COLOR = colors.green; const WHITE_COLOR = colors.white; -const UNSECURE_BUTTON_COLOR = anyOf(colors.red60, colors.red80); -const SECURE_BUTTON_COLOR = anyOf(colors.green, colors.green90); +const DISCONNECTED_BUTTON_COLOR = anyOf(colors.red, colors.red80); +const DISCONNECTING_BUTTON_COLOR = anyOf(colors.green40); +const CONNECTED_BUTTON_COLOR = anyOf(colors.green, colors.green90); const getLabel = (page: Page) => page.locator('span[role="status"]'); const getHeader = (page: Page) => page.locator('header'); export async function expectDisconnected(page: Page) { await expectTunnelState(page, { - labelText: 'unsecured connection', - labelColor: UNSECURED_COLOR, - headerColor: UNSECURED_COLOR, - buttonText: 'secure my connection', - buttonColor: SECURE_BUTTON_COLOR, + labelText: 'disconnected', + labelColor: DISCONNECTED_COLOR, + headerColor: DISCONNECTED_COLOR, + buttonText: 'connect', + buttonColor: CONNECTED_BUTTON_COLOR, }); } export async function expectConnecting(page: Page) { await expectTunnelState(page, { - labelText: 'creating secure connection', + labelText: 'connecting', labelColor: WHITE_COLOR, - headerColor: SECURE_COLOR, + headerColor: CONNECTED_COLOR, buttonText: 'cancel', - buttonColor: UNSECURE_BUTTON_COLOR, + buttonColor: DISCONNECTED_BUTTON_COLOR, }); } export async function expectConnected(page: Page) { await expectTunnelState(page, { - labelText: 'secure connection', - labelColor: SECURE_COLOR, - headerColor: SECURE_COLOR, + labelText: 'connected', + labelColor: CONNECTED_COLOR, + headerColor: CONNECTED_COLOR, buttonText: 'disconnect', - buttonColor: UNSECURE_BUTTON_COLOR, + buttonColor: DISCONNECTED_BUTTON_COLOR, }); } export async function expectDisconnecting(page: Page) { await expectTunnelState(page, { - headerColor: UNSECURED_COLOR, - buttonText: 'secure my connection', - buttonColor: SECURE_BUTTON_COLOR, + labelText: 'disconnecting', + labelColor: WHITE_COLOR, + headerColor: DISCONNECTED_COLOR, + buttonText: 'connect', + buttonColor: DISCONNECTING_BUTTON_COLOR, }); } @@ -55,27 +58,7 @@ export async function expectError(page: Page) { await expectTunnelState(page, { labelText: 'blocked connection', labelColor: WHITE_COLOR, - headerColor: SECURE_COLOR, - }); -} - -export async function expectConnectingPq(page: Page) { - await expectTunnelState(page, { - labelText: 'creating quantum secure connection', - labelColor: WHITE_COLOR, - headerColor: SECURE_COLOR, - buttonText: 'cancel', - buttonColor: UNSECURE_BUTTON_COLOR, - }); -} - -export async function expectConnectedPq(page: Page) { - await expectTunnelState(page, { - labelText: 'quantum secure connection', - labelColor: SECURE_COLOR, - headerColor: SECURE_COLOR, - buttonText: 'disconnect', - buttonColor: UNSECURE_BUTTON_COLOR, + headerColor: CONNECTED_COLOR, }); } diff --git a/gui/test/unit/notification-evaluation.spec.ts b/gui/test/unit/notification-evaluation.spec.ts index d7d5e1fea6..27de83cf29 100644 --- a/gui/test/unit/notification-evaluation.spec.ts +++ b/gui/test/unit/notification-evaluation.spec.ts @@ -107,7 +107,7 @@ describe('System notifications', () => { const controller = createController(); const disconnectedState: TunnelState = { state: 'disconnected' }; - const connectingState: TunnelState = { state: 'connecting' }; + const connectingState: TunnelState = { state: 'connecting', featureIndicators: undefined }; const result1 = controller.notifyTunnelState(disconnectedState, false, false, false, true); const result2 = controller.notifyTunnelState(disconnectedState, false, false, false, false); const result3 = controller.notifyTunnelState(connectingState, false, false, false, true); |
