summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-06 10:08:36 +0200
committerTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-06 10:08:36 +0200
commitf82099962e5160b4577038b794170fa2f70ed546 (patch)
tree5ac6819bca247e14e560eae5d43355f32f40e770
parent430e860b6e267f767c06edba0e7a2e4ef793cc4e (diff)
parentfa9f91a4f11dc13c64c6a007ceeb6fb08e956e52 (diff)
downloadmullvadvpn-f82099962e5160b4577038b794170fa2f70ed546.tar.xz
mullvadvpn-f82099962e5160b4577038b794170fa2f70ed546.zip
Merge branch 'add-ui-test-for-linux-split-tunneling-des-2429'
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/LaunchButton.tsx6
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/useHandleClick.ts13
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts12
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/helpers.ts28
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/split-tunneling.spec.ts231
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/selectors.ts34
-rw-r--r--desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/split-tunneling-settings-route-object-model.ts56
8 files changed, 300 insertions, 81 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/LaunchButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/LaunchButton.tsx
index 58c82d4c42..5f9262cd1f 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/LaunchButton.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/LaunchButton.tsx
@@ -1,12 +1,12 @@
import { messages } from '../../../../../../../../../../../../../../shared/gettext';
import { Button } from '../../../../../../../../../../../../../lib/components';
-import { useLaunchApplication } from '../../../../hooks';
+import { useHandleClick } from './hooks';
export function LaunchButton() {
- const launchApplication = useLaunchApplication();
+ const handleClick = useHandleClick();
return (
- <Button onClick={launchApplication}>
+ <Button onClick={handleClick}>
<Button.Text>
{
// TRANSLATORS: Button label for launching an application with split tunneling.
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/index.ts
new file mode 100644
index 0000000000..ea402d648a
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/index.ts
@@ -0,0 +1 @@
+export * from './useHandleClick';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/useHandleClick.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/useHandleClick.ts
new file mode 100644
index 0000000000..cbbd92bdfc
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/split-tunneling/components/linux-settings/components/linux-application-list/components/linux-application-row/components/warning-dialog/components/launch-button/hooks/useHandleClick.ts
@@ -0,0 +1,13 @@
+import { useCallback } from 'react';
+
+import { useLinuxApplicationRowContext } from '../../../../../LinuxApplicationRowContext';
+
+export function useHandleClick() {
+ const { application, onSelect, setShowWarningDialog } = useLinuxApplicationRowContext();
+ const handleClick = useCallback(() => {
+ setShowWarningDialog(false);
+ onSelect?.(application);
+ }, [application, onSelect, setShowWarningDialog]);
+
+ return handleClick;
+}
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts
index 14ee96e925..bada4ae5ff 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts
@@ -94,9 +94,9 @@ export const createMockIpcExpect = (
) => {
const type = 'type' in spec ? spec.type : 'invoke';
- return <T>(): Promise<T> => {
+ return <T>(response: T): Promise<T> => {
return electronApp.evaluate(
- ({ ipcMain }, { event, type }) => {
+ ({ ipcMain }, { event, type, response }) => {
return new Promise<T>((resolve) => {
if (type === 'send') {
ipcMain.once(event, (_event, arg) => resolve(arg));
@@ -105,13 +105,13 @@ export const createMockIpcExpect = (
resolve(arg);
return {
type: 'success',
- value: null,
+ value: response,
};
});
}
});
},
- { event, type },
+ { event, type, response },
);
};
};
@@ -155,14 +155,14 @@ type IpcMockedTestExtraHandlerKey<
type IpcMockedTestFn<I extends AnyIpcCall> = I['direction'] extends 'main-to-renderer'
? Async<NonNullable<ReturnType<I['send']>>>
- : (response: Awaited<ReturnType<Parameters<ReturnType<I['receive']>>[0]>>) => Promise<void>;
+ : (response?: Awaited<ReturnType<Parameters<ReturnType<I['receive']>>[0]>>) => Promise<void>;
export type IpcMockedTest<S extends Schema> = {
[G in keyof S]: {
[K in keyof S[G]]: {
[C in IpcMockedTestKey<S[G][K]>]: IpcMockedTestFn<S[G][K]>;
} & {
- [C in IpcMockedTestExtraHandlerKey<S[G][K], 'expect'>]: () => Promise<void>;
+ [C in IpcMockedTestExtraHandlerKey<S[G][K], 'expect'>]: IpcMockedTestFn<S[G][K]>;
} & {
[C in IpcMockedTestExtraHandlerKey<S[G][K], 'ignore'>]: () => Promise<void>;
} & {
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/helpers.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/helpers.ts
new file mode 100644
index 0000000000..fa5143bd1b
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/helpers.ts
@@ -0,0 +1,28 @@
+import { ILinuxSplitTunnelingApplication } from '../../../../src/shared/application-types';
+
+export const linuxApplicationsList: ILinuxSplitTunnelingApplication[] = [
+ {
+ absolutepath: '/app',
+ exec: 'app',
+ name: 'app',
+ type: 'Application',
+ icon: '',
+ warning: undefined,
+ },
+ {
+ absolutepath: '/launches-elsewhere',
+ exec: 'launches-elsewhere',
+ name: 'launches-elsewhere',
+ type: 'Application',
+ icon: '',
+ warning: 'launches-elsewhere',
+ },
+ {
+ absolutepath: '/launches-in-existing-process',
+ exec: 'launches-in-existing-process',
+ name: 'launches-in-existing-process',
+ type: 'Application',
+ icon: '',
+ warning: 'launches-in-existing-process',
+ },
+];
diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/split-tunneling.spec.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/split-tunneling.spec.ts
index 9dba19e1e1..cb0f0d717e 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/split-tunneling.spec.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/split-tunneling/split-tunneling.spec.ts
@@ -4,89 +4,190 @@ import { Page } from 'playwright';
import { RoutePath } from '../../../../src/shared/routes';
import { RoutesObjectModel } from '../../route-object-models';
import { MockedTestUtils, startMockedApp } from '../mocked-utils';
+import { linuxApplicationsList } from './helpers';
let page: Page;
let util: MockedTestUtils;
let routes: RoutesObjectModel;
-test.describe('Split tunneling', () => {
+const startup = async () => {
+ ({ page, util } = await startMockedApp());
+ routes = new RoutesObjectModel(page, util);
+
+ await util.expectRoute(RoutePath.main);
+ await routes.main.gotoSettings();
+ await routes.settings.gotoSplitTunnelingSettings();
+};
+
+test.describe('Linux Split tunneling unsupported', () => {
+ if (process.platform !== 'linux') {
+ test.skip();
+ }
+
+ test.afterAll(async () => {
+ await page.close();
+ });
+
+ test.beforeAll(async () => {
+ await startup();
+ });
+
test.beforeAll(async () => {
- ({ page, util } = await startMockedApp());
- routes = new RoutesObjectModel(page, util);
+ await util.ipc.linuxSplitTunneling.isSplitTunnelingSupported.handle(false);
+ await util.ipc.linuxSplitTunneling.getApplications.handle(linuxApplicationsList);
+ });
+
+ test('App should show unsupported dialog when link in header is clicked', async () => {
+ // Open the unsupported dialog
+ await routes.splitTunnelingSettings.openUnsupportedDialog();
+ const unsupportedText = routes.splitTunnelingSettings.getSplitTunnelingUnsupportedDialogText();
+ await expect(unsupportedText).toBeVisible();
+
+ // Close the unsupported dialog
+ await routes.splitTunnelingSettings.closeUnsupportedDialog();
+ await expect(unsupportedText).not.toBeVisible();
+ });
+
+ test('App list items should be shown even when split tunneling is unsupported', async () => {
+ // Apps should be shown if split tunneling is unsupported
+ const linuxApplications = routes.splitTunnelingSettings.getLinuxApplications();
+ await expect(linuxApplications).toHaveCount(3);
+ });
+
+ test('App list items should show unsupported dialog when clicked', async () => {
+ // Ensure clicking an application in the list makes the unsupported dialog visible
+ const linuxApplications = routes.splitTunnelingSettings.getLinuxApplications();
+ await linuxApplications.first().click();
+ const unsupportedText = routes.splitTunnelingSettings.getSplitTunnelingUnsupportedDialogText();
+ await expect(unsupportedText).toBeVisible();
- await util.expectRoute(RoutePath.main);
- await routes.main.gotoSettings();
- await routes.settings.gotoSplitTunnelingSettings();
+ // Close the unsupported dialog
+ await routes.splitTunnelingSettings.closeUnsupportedDialog();
+ await expect(unsupportedText).not.toBeVisible();
});
+});
+
+test.describe('Linux Split tunneling supported', () => {
+ if (process.platform !== 'linux') {
+ test.skip();
+ }
test.afterAll(async () => {
await page.close();
});
- test.describe('Linux Split tunneling unsupported', () => {
- if (process.platform !== 'linux') {
- test.skip();
- }
+ test.beforeAll(async () => {
+ await startup();
+ });
+
+ test.beforeAll(async () => {
+ await util.ipc.linuxSplitTunneling.isSplitTunnelingSupported.handle(true);
+ await util.ipc.linuxSplitTunneling.getApplications.handle(linuxApplicationsList);
+ });
+
+ test('App list items should be shown', async () => {
+ const linuxApplications = routes.splitTunnelingSettings.getLinuxApplications();
+ await expect(linuxApplications).toHaveCount(3);
+ });
+
+ test('App list items should be filterered when searching', async () => {
+ // List should be unfiltered at first
+ const linuxApplications = routes.splitTunnelingSettings.getLinuxApplications();
+ await expect(linuxApplications).toHaveCount(3);
+
+ // List should only show 2 matching items
+ await routes.splitTunnelingSettings.fillSearchInput('launches');
+ await expect(linuxApplications).toHaveCount(2);
+ let applicationNames = await linuxApplications.allInnerTexts();
+ expect(applicationNames).toEqual(['launches-elsewhere', 'launches-in-existing-process']);
+
+ // List should only show 1 matching item
+ await routes.splitTunnelingSettings.fillSearchInput('app');
+ await expect(linuxApplications).toHaveCount(1);
+ applicationNames = await linuxApplications.allInnerTexts();
+ expect(applicationNames).toEqual(['app']);
+
+ // Clearing the search value should show all list items
+ await routes.splitTunnelingSettings.clearSearchInput();
+ await expect(linuxApplications).toHaveCount(3);
+ applicationNames = await linuxApplications.allInnerTexts();
+ expect(applicationNames).toEqual(['app', 'launches-elsewhere', 'launches-in-existing-process']);
+ });
+
+ test('App list items should be launched when clicked', async () => {
+ // Launch the "app" application from the list
+ await Promise.all([
+ util.ipc.linuxSplitTunneling.launchApplication.expect({ success: true }),
+ routes.splitTunnelingSettings.openLinuxApplication('app'),
+ ]);
+ });
+
+ test('App list items with "launches-in-existing-process" warnings should show warning dialog when clicked', async () => {
+ // Try to open the application in the list to display the warning dialog
+ await routes.splitTunnelingSettings.openLinuxApplication('launches-in-existing-process');
+
+ // Ensure warning dialog is visible
+ const warningText =
+ routes.splitTunnelingSettings.getLinuxApplicationWarningLaunchesInExistingProcessDialogText(
+ 'launches-in-existing-process',
+ );
+ await expect(warningText).toBeVisible();
- test.beforeAll(async () => {
- await util.ipc.linuxSplitTunneling.isSplitTunnelingSupported.handle(false);
- await util.ipc.linuxSplitTunneling.getApplications.handle([
- {
- absolutepath: '/app',
- exec: 'app',
- name: 'app',
- type: 'app',
- icon: '',
- warning: undefined,
- },
- {
- absolutepath: '/launches-elsewhere',
- exec: 'launches-elsewhere',
- name: 'launches-elsewhere',
- type: 'launches-elsewhere',
- icon: '',
- warning: 'launches-elsewhere',
- },
- {
- absolutepath: '/launches-in-existing-process',
- exec: 'launches-in-existing-process',
- name: 'launches-in-existing-process',
- type: 'launches-in-existing-process',
- icon: '',
- warning: 'launches-in-existing-process',
- },
- ]);
- });
+ // Close the warning dialog
+ await routes.splitTunnelingSettings.closeLinuxApplicationWarningLaunchesInExistingProcessDialog();
+ await expect(warningText).not.toBeVisible();
- test('App should show unsupported dialog when link in header is clicked', async () => {
- // Open the unsupported dialog
- await routes.splitTunnelingSettings.openUnsupportedDialog();
- const unsupportedText =
- routes.splitTunnelingSettings.getSplitTunnelingUnsupportedDialogText();
- await expect(unsupportedText).toBeVisible();
+ // Try to open the application again to display the warning dialog again
+ await routes.splitTunnelingSettings.openLinuxApplication('launches-in-existing-process');
+ await expect(warningText).toBeVisible();
- // Close the unsupported dialog
- await routes.splitTunnelingSettings.closeUnsupportedDialog();
- await expect(unsupportedText).not.toBeVisible();
- });
+ // Launch the application from the warning dialog
+ await Promise.all([
+ util.ipc.linuxSplitTunneling.launchApplication.expect({ success: true }),
+ routes.splitTunnelingSettings.openLinuxApplicationFromWarningLaunchesInExistingProcessDialogText(),
+ ]);
- test('App list items should be shown even when split tunneling is unsupported', async () => {
- // Apps should be shown if split tunneling is unsupported
- const linuxApplications = routes.splitTunnelingSettings.getLinuxApplications();
- await expect(linuxApplications).toHaveCount(3);
- });
+ // Ensure the warning dialog is not visible after application has launched
+ await expect(warningText).not.toBeVisible();
+ });
+
+ test('App list items with "launches-elsewhere" warnings should show warning dialog when clicked', async () => {
+ // Ensure clicking the application in the list makes the warning dialog visible
+ await routes.splitTunnelingSettings.openLinuxApplication('launches-elsewhere');
+
+ const warningText =
+ routes.splitTunnelingSettings.getLinuxApplicationWarningLaunchesElsewhereDialogText(
+ 'launches-elsewhere',
+ );
+ await expect(warningText).toBeVisible();
+
+ // Close the warning dialog
+ await routes.splitTunnelingSettings.closeLinuxApplicationWarningLaunchesElsewhereDialog();
+ await expect(warningText).not.toBeVisible();
+ });
- test('App list items should show unsupported dialog when clicked', async () => {
- // Ensure clicking an application in the list makes the unsupported dialog visible
- const linuxApplications = routes.splitTunnelingSettings.getLinuxApplications();
- await linuxApplications.first().click();
- const unsupportedText =
- routes.splitTunnelingSettings.getSplitTunnelingUnsupportedDialogText();
- await expect(unsupportedText).toBeVisible();
+ test('App should launch file picker when button Find another app button is clicked', async () => {
+ // Ensure clicking the "Find another app" button opens the file picker
+ await Promise.all([
+ util.ipc.app.showOpenDialog.expect({
+ canceled: false,
+ bookmarks: [],
+ filePaths: [],
+ }),
+ routes.splitTunnelingSettings.openFindAnotherApp(),
+ ]);
- // Close the unsupported dialog
- await routes.splitTunnelingSettings.closeUnsupportedDialog();
- await expect(unsupportedText).not.toBeVisible();
- });
+ // Ensure selecting an application with the file picker will launch the application
+ await Promise.all([
+ util.ipc.app.showOpenDialog.expect({
+ canceled: false,
+ bookmarks: [],
+ filePaths: ['/app'],
+ }),
+ routes.splitTunnelingSettings.openFindAnotherApp(),
+ util.ipc.linuxSplitTunneling.launchApplication.expect({
+ success: true,
+ }),
+ ]);
});
});
diff --git a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/selectors.ts b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/selectors.ts
index f7208eab3a..046d29f435 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/selectors.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/selectors.ts
@@ -1,17 +1,45 @@
import { type Page } from 'playwright';
export const createSelectors = (page: Page) => ({
- splitTunnelingUnsupportedDialogOpenLink: () =>
+ applicationWarningLaunchesElsewhereDialogText: (applicationName: string) =>
+ page.getByText(`${applicationName} is problematic and can’t be excluded from the VPN tunnel.`),
+ applicationWarningLaunchesInExistingProcessDialogText: (applicationName: string) =>
+ page.getByText(
+ `If it’s already running, close ${applicationName} before launching it from here. Otherwise it might not be excluded from the VPN tunnel.`,
+ ),
+ findAnotherAppButton: () =>
page.getByRole('button', {
- name: 'Click here to learn more',
+ name: 'Find another app',
+ }),
+ linuxApplication: (applicationName: string) =>
+ page.getByRole('button', {
+ name: applicationName,
+ exact: true,
+ }),
+ linuxApplications: () => page.getByTestId('linux-applications').getByRole('button'),
+ linuxApplicationWarningDialogBackButton: () =>
+ page.getByRole('dialog').getByRole('button', {
+ name: 'Back',
}),
+ linuxApplicationWarningDialogCancelButton: () =>
+ page.getByRole('dialog').getByRole('button', {
+ name: 'Cancel',
+ }),
+ linuxApplicationWarningDialogLaunchButton: () =>
+ page.getByRole('dialog').getByRole('button', {
+ name: 'Launch',
+ }),
+ searchInput: () => page.getByPlaceholder('Search for...'),
splitTunnelingUnsupportedDialogCloseButton: () =>
page.getByRole('button', {
name: 'Got it!',
}),
+ splitTunnelingUnsupportedDialogOpenLink: () =>
+ page.getByRole('button', {
+ name: 'Click here to learn more',
+ }),
splitTunnelingUnsupportedDialogText: () =>
page.getByText(
'To use Split tunneling, please change to a Linux kernel version that supports cgroup v1.',
),
- linuxApplications: () => page.getByTestId('linux-applications').locator('button'),
});
diff --git a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/split-tunneling-settings-route-object-model.ts b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/split-tunneling-settings-route-object-model.ts
index d0de2cc413..5623cf160e 100644
--- a/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/split-tunneling-settings-route-object-model.ts
+++ b/desktop/packages/mullvad-vpn/test/e2e/route-object-models/split-tunneling-settings/split-tunneling-settings-route-object-model.ts
@@ -15,22 +15,70 @@ export class SplitTunnelingSettingsRouteObjectModel {
this.selectors = createSelectors(page);
}
- async waitForRoute() {
- await this.utils.expectRoute(RoutePath.splitTunneling);
+ getLinuxApplication(applicationName: string) {
+ return this.selectors.linuxApplication(applicationName);
}
getLinuxApplications() {
return this.selectors.linuxApplications();
}
- getSplitTunnelingUnsupportedDialogText() {
- return this.selectors.splitTunnelingUnsupportedDialogText();
+ openFindAnotherApp() {
+ return this.selectors.findAnotherAppButton().click();
+ }
+
+ openLinuxApplication(applicationName: string) {
+ return this.getLinuxApplication(applicationName).click();
+ }
+
+ async waitForRoute() {
+ await this.utils.expectRoute(RoutePath.splitTunneling);
+ }
+
+ // Search input
+
+ async clearSearchInput() {
+ await this.selectors.searchInput().clear();
+ }
+
+ async fillSearchInput(value: string) {
+ await this.selectors.searchInput().fill(value);
+ }
+
+ // Launches elsewhere
+
+ closeLinuxApplicationWarningLaunchesElsewhereDialog() {
+ return this.selectors.linuxApplicationWarningDialogBackButton().click();
+ }
+
+ getLinuxApplicationWarningLaunchesElsewhereDialogText(applicationName: string) {
+ return this.selectors.applicationWarningLaunchesElsewhereDialogText(applicationName);
+ }
+
+ // Launches in existing process
+
+ closeLinuxApplicationWarningLaunchesInExistingProcessDialog() {
+ return this.selectors.linuxApplicationWarningDialogCancelButton().click();
+ }
+
+ getLinuxApplicationWarningLaunchesInExistingProcessDialogText(applicationName: string) {
+ return this.selectors.applicationWarningLaunchesInExistingProcessDialogText(applicationName);
+ }
+
+ openLinuxApplicationFromWarningLaunchesInExistingProcessDialogText() {
+ return this.selectors.linuxApplicationWarningDialogLaunchButton().click();
}
+ // Unsupported dialog
+
closeUnsupportedDialog() {
return this.selectors.splitTunnelingUnsupportedDialogCloseButton().click();
}
+ getSplitTunnelingUnsupportedDialogText() {
+ return this.selectors.splitTunnelingUnsupportedDialogText();
+ }
+
openUnsupportedDialog() {
return this.selectors.splitTunnelingUnsupportedDialogOpenLink().click();
}