/* * Copyright (c) 2026 Proton AG * * This file is part of ProtonVPN. * * ProtonVPN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProtonVPN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProtonVPN. If not, see . */ using System; using System.Linq; using System.Threading; using System.Collections.Generic; using NUnit.Framework; using FlaUI.Core.Input; using FlaUI.Core.WindowsAPI; using FlaUI.Core.Definitions; using FlaUI.Core.AutomationElements; using ProtonVPN.UI.Tests.Enums; using ProtonVPN.UI.Tests.UiTools; using ProtonVPN.UI.Tests.TestsHelper; namespace ProtonVPN.UI.Tests.Robots; public class ProfileRobot { protected Element ProfileNameTextBox = Element.ByAutomationId("ProfileNameTextBox"); protected Element ApplyButton = Element.ByAutomationId("ApplyButton"); protected Element CloseButton = Element.ByAutomationId("CloseSettingsButton"); protected Element ToggleSettingsButton = Element.ByAutomationId("ToggleExpanderButton"); protected Element NetShieldDropDown = Element.ByAutomationId("NetShieldDropDown"); protected Element NetShieldOffMenuItem = Element.ByAutomationId("NetShieldOffMenuItem"); protected Element NetShieldLevelOneMenuItem = Element.ByAutomationId("NetShieldLevelOneMenuItem"); protected Element NetShieldLevelTwoMenuItem = Element.ByAutomationId("NetShieldLevelTwoMenuItem"); protected Element NetShieldLevelThreeMenuItem = Element.ByAutomationId("NetShieldLevelThreeMenuItem"); protected Element PortForwardingDropDown = Element.ByAutomationId("PortForwardingDropDown"); protected Element PortForwardingOffMenuItem = Element.ByAutomationId("PortForwardingOffMenuItem"); protected Element PortForwardingOnMenuItem = Element.ByAutomationId("PortForwardingOnMenuItem"); protected Element ProtocolsDropDown = Element.ByAutomationId("ProtocolsDropDown"); protected Element SmartProtocolMenuItem = Element.ByAutomationId("SmartProtocolMenuItem"); protected Element WireGuardUdpProtocolMenuItem = Element.ByAutomationId("WireGuardUdpProtocolMenuItem"); protected Element WireGuardTcpProtocolMenuItem = Element.ByAutomationId("WireGuardTcpProtocolMenuItem"); protected Element WireGuardTlsProtocolMenuItem = Element.ByAutomationId("WireGuardTlsProtocolMenuItem"); protected Element OpenVpnUdpProtocolMenuItem = Element.ByAutomationId("OpenVpnUdpProtocolMenuItem"); protected Element OpenVpnTcpProtocolMenuItem = Element.ByAutomationId("OpenVpnTcpProtocolMenuItem"); protected Element NatTypeDropDown = Element.ByAutomationId("NatTypeDropDown"); protected Element StrictNatMenuItem = Element.ByAutomationId("StrictNatMenuItem"); protected Element ModerateNatMenuItem = Element.ByAutomationId("ModerateNatMenuItem"); protected Element CountryDropdown = Element.ByName("Country").And(Element.ByClassName("ComboBox")); protected Element MiddleCountryDropdown = Element.ByName("Middle country").And(Element.ByClassName("ComboBox")); protected Element CityDropdown = Element.ByName("City").And(Element.ByClassName("ComboBox")); protected Element ConnectionTypes = Element.ByClassName("ListBoxItem"); protected Element ConnectAndGoDropDown = Element.ByAutomationId("ConnectAndGoDropDown"); protected Element ConnectAndGoOffMenuItem = Element.ByAutomationId("ConnectAndGoOffMenuItem"); protected Element ConnectAndGoWebsiteMenuItem = Element.ByAutomationId("ConnectAndGoWebsiteMenuItem"); protected Element ConnectAndGoApplicationMenuItem = Element.ByAutomationId("ConnectAndGoApplicationMenuItem"); protected Element ConnectAndGoParent = Element.ByAutomationId("ConnectAndGoParentSection"); protected Element ConnectAndGoAppSelector = Element.ByAutomationId("ConnectAndGoAppSelector"); protected Element ConnectAndGoPrivateModeCheckbox = Element.ByAutomationId("ConnectAndGoPrivateModeCheckbox"); public ProfileRobot SetProfileName(string profileName) { ProfileNameTextBox.SetText(profileName); return this; } public ProfileRobot CloseProfile() { CloseButton.Invoke(); return this; } public ProfileRobot SaveProfile() { ApplyButton.Invoke(); return this; } public ProfileRobot SelectConnectionType(ConnectionType connectionType) { string? connectionTypeName = null; switch (connectionType) { case ConnectionType.Standard: connectionTypeName = "Standard"; break; case ConnectionType.SecureCore: connectionTypeName = "Secure Core"; break; case ConnectionType.P2P: connectionTypeName = "P2P"; break; default: throw new ArgumentOutOfRangeException(nameof(connectionType), connectionType, "Unhandled connection type"); } AutomationElement connectionTypeElement = ConnectionTypes.FindAllElements() .First(item => item.FindFirstDescendant(cf => cf.ByControlType(ControlType.Text) .And(cf.ByName(connectionTypeName))) != null); connectionTypeElement.Click(); return this; } public ProfileRobot SelectCountry(string countryName) { CountryDropdown .Click() .SelectDropdownItem(countryName); return this; } public ProfileRobot SelectMiddleCountry(string middleCountryName) { MiddleCountryDropdown .Click() .SelectDropdownItem(middleCountryName); return this; } public ProfileRobot SelectCity(string cityName) { CityDropdown .Click() .SelectDropdownItem(cityName); return this; } public ProfileRobot ExpandSettingsSection() { ToggleSettingsButton.Click(); // Remove when VPNWIN-2599 is implemented. Thread.Sleep(TestConstants.AnimationDelay); return this; } public ProfileRobot DisableNetShield() { NetShieldDropDown.Click(); // Remove when VPNWIN-2599 is implemented. Thread.Sleep(TestConstants.AnimationDelay); NetShieldOffMenuItem.DoubleClick(); // Remove when VPNWIN-2599 is implemented. Thread.Sleep(TestConstants.AnimationDelay); return this; } public ProfileRobot SelectProtocol(Protocol protocol) { ProtocolsDropDown.Click(); switch (protocol) { case Protocol.OpenVpnUdp: OpenVpnUdpProtocolMenuItem.Invoke(); break; case Protocol.OpenVpnTcp: OpenVpnTcpProtocolMenuItem.Invoke(); break; case Protocol.WireGuardTcp: WireGuardTcpProtocolMenuItem.Invoke(); break; case Protocol.WireGuardTls: WireGuardTlsProtocolMenuItem.Invoke(); break; case Protocol.WireGuardUdp: WireGuardUdpProtocolMenuItem.Invoke(); break; } return this; } public ProfileRobot SelectNetShieldMode(NetShieldMode netShieldMode) { NetShieldDropDown.Click(); Thread.Sleep(TestConstants.AnimationDelay); switch (netShieldMode) { case NetShieldMode.BlockMalwareOnly: NetShieldLevelOneMenuItem.DoubleClick(); break; case NetShieldMode.BlockAdsMalwareTrackers: NetShieldLevelTwoMenuItem.DoubleClick(); break; case NetShieldMode.BlockAdsMalwareTrackersAdultContent: NetShieldLevelThreeMenuItem.DoubleClick(); break; } return this; } public ProfileRobot SelectPortForwarding(bool state) { PortForwardingDropDown.Click(); Thread.Sleep(TestConstants.AnimationDelay); Element portForwardingMenuItem = state ? PortForwardingOnMenuItem : PortForwardingOffMenuItem; portForwardingMenuItem.DoubleClick(); return this; } public ProfileRobot SelectConnectAndGoOption(ConnectAndGoOption option) { ConnectAndGoDropDown.Click(); Thread.Sleep(TestConstants.AnimationDelay); switch (option) { case ConnectAndGoOption.Off: ConnectAndGoOffMenuItem.DoubleClick(); break; case ConnectAndGoOption.OpenWebsite: ConnectAndGoWebsiteMenuItem.DoubleClick(); break; case ConnectAndGoOption.OpenApp: ConnectAndGoApplicationMenuItem.DoubleClick(); break; } return this; } public ProfileRobot SelectConnectAndGoApp(string appPath) { ConnectAndGoAppSelector.Click(); HandleExplorer(appPath); return this; } public ProfileRobot TypeConnectAndGoWebsite(string websiteUrl, bool usePrivateMode = false) { AutomationElement[] children = ConnectAndGoParent.GetControlType(ControlType.Edit); children[0].AsTextBox().Text = websiteUrl; if (usePrivateMode) { ConnectAndGoPrivateModeCheckbox.Click(); } return this; } public class Verifications : ProfileRobot { public Verifications IsAppSelected(string appName) { List allChildren = ConnectAndGoAppSelector.GetAllChildrenNames(); Assert.That(allChildren, Does.Contain(appName)); return this; } public Verifications ProfileNameEquals(string profileName) { ProfileNameTextBox.TextBoxEquals(profileName); return this; } } private ProfileRobot HandleExplorer(string appPath) { Thread.Sleep(TestConstants.FiveSecondsTimeout); Keyboard.Type(appPath); Thread.Sleep(TestConstants.OneSecondTimeout); Keyboard.Press(VirtualKeyShort.TAB); Keyboard.Press(VirtualKeyShort.TAB); Thread.Sleep(TestConstants.OneSecondTimeout); Keyboard.Press(VirtualKeyShort.ENTER); Thread.Sleep(TestConstants.OneSecondTimeout); return this; } public Verifications Verify => new(); }