summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar <oskar@mullvad.net>2024-08-16 15:25:04 +0200
committerOskar <oskar@mullvad.net>2024-08-21 17:05:50 +0200
commit6ceed1dffca2fc0c4b867fe60638db5bf29f1065 (patch)
tree68dc1c457f693035ea26b723414b7cd2a28958e3
parent897fa5eaa1cc5bcd140047ac454ab846fec5e62f (diff)
downloadmullvadvpn-6ceed1dffca2fc0c4b867fe60638db5bf29f1065.tar.xz
mullvadvpn-6ceed1dffca2fc0c4b867fe60638db5bf29f1065.zip
Add feature-indicator test
-rw-r--r--gui/src/renderer/components/main-view/ConnectionPanelChevron.tsx5
-rw-r--r--gui/src/renderer/components/main-view/FeatureIndicators.tsx5
-rw-r--r--gui/test/e2e/mocked/feature-indicators.spec.ts133
3 files changed, 141 insertions, 2 deletions
diff --git a/gui/src/renderer/components/main-view/ConnectionPanelChevron.tsx b/gui/src/renderer/components/main-view/ConnectionPanelChevron.tsx
index d62ec6402d..a50fada589 100644
--- a/gui/src/renderer/components/main-view/ConnectionPanelChevron.tsx
+++ b/gui/src/renderer/components/main-view/ConnectionPanelChevron.tsx
@@ -25,7 +25,10 @@ interface IProps {
export default function ConnectionPanelChevron(props: IProps) {
return (
- <Container className={props.className} onClick={props.onToggle}>
+ <Container
+ data-testid="connection-panel-chevron"
+ className={props.className}
+ onClick={props.onToggle}>
<Chevron
source={props.pointsUp ? 'icon-chevron-up' : 'icon-chevron-down'}
width={24}
diff --git a/gui/src/renderer/components/main-view/FeatureIndicators.tsx b/gui/src/renderer/components/main-view/FeatureIndicators.tsx
index b3152c2f45..81495e46eb 100644
--- a/gui/src/renderer/components/main-view/FeatureIndicators.tsx
+++ b/gui/src/renderer/components/main-view/FeatureIndicators.tsx
@@ -164,7 +164,10 @@ export default function FeatureIndicators(props: FeatureIndicatorsProps) {
ref={featureIndicatorsContainerRef}
$expanded={props.expanded}>
{featureIndicators.current.sort().map((indicator) => (
- <StyledFeatureIndicatorLabel key={indicator.toString()} $expanded={props.expanded}>
+ <StyledFeatureIndicatorLabel
+ key={indicator.toString()}
+ data-testid="feature-indicator"
+ $expanded={props.expanded}>
{getFeatureIndicatorLabel(indicator)}
</StyledFeatureIndicatorLabel>
))}
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();
+ }
+}