using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; namespace AiQ_GUI { internal class Selenium { // Directs to url using chrome drive and waits for the page to fully load public static void GoToUrl(string url, ChromeDriver driver) { try { driver.Navigate().GoToUrl(url); // Wait until the document is fully loaded WebDriverWait wait = new(driver, TimeSpan.FromSeconds(10)); wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete")); } catch (WebDriverTimeoutException) { MainForm.Instance.AddToActionsList("Could not load web page " + url + "1. Check camera has no password set. " + Environment.NewLine + "2. If unable to fix speak to supervisor."); } } // Retrieves lates element ID for Shutter,iris, gain and IR public static ElementID GetElementIds(ChromeDriver driver) { ElementID elementID = new() { modeId = GetLatestElementIdContaining("Mode_", driver), shutterId = GetLatestElementIdContaining("FixShutter_", driver), irisId = GetLatestElementIdContaining("FixIris_", driver), gainId = GetLatestElementIdContaining("FixGain_", driver), irLevelId = GetLatestElementIdContaining("CameraControls_", driver), CamAct = GetLatestElementIdContaining("CameraActivity_", driver) }; return elementID; } public static void SwitchUser(ChromeDriver driver) { try { WebDriverWait wait = new(driver, TimeSpan.FromSeconds(10)); // Click "Switch User" IWebElement switchBtn = wait.Until(d => d.FindElement(By.XPath("//*[contains(text(),'Switch User')]")) ); switchBtn.Click(); // Username IWebElement userBox = wait.Until(d => d.FindElement(By.Id("username"))); userBox.Clear(); userBox.SendKeys("admin"); // Password IWebElement passBox = wait.Until(d => d.FindElement(By.Id("password"))); passBox.Clear(); passBox.SendKeys("admin"); // Login button IWebElement loginBtn = wait.Until(d => d.FindElement(By.XPath("//button[contains(normalize-space(text()), 'Login')]")) ); // Wait until it's clickable manually (no SeleniumExtras) wait.Until(d => loginBtn.Displayed && loginBtn.Enabled); loginBtn.Click(); MainForm.Instance.AddToActionsList("Switched user and logged in."); } catch (Exception ex) { MainForm.Instance.AddToActionsList("SwitchUser failed: " + ex.Message); } } // Attempts to click the web element with the specified ID; refreshes the page and retries once if the initial attempt fails public static void ClickElementByID(string elementID, ChromeDriver driver, bool tryagain = true) { try { WebDriverWait wait = new(driver, TimeSpan.FromSeconds(10)); IWebElement element = wait.Until(driver => driver.FindElement(By.Id(elementID))); element.Click(); } catch { if (tryagain) { driver.Navigate().Refresh(); WebDriverWait wait = new(driver, TimeSpan.FromSeconds(10)); wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete")); ClickElementByID(elementID, driver, false); } MainForm.Instance.AddToActionsList("Could not click " + elementID); } } // Initialises and opens a ChromeDriver with specific options public static ChromeDriver OpenDriver() { string tempProfile = null; try { ChromeOptions options = new(); options.AddArguments("--app=data:,", "--window-size=960,1040", "--window-position=0,0", "--no-sandbox", "--incognito", "--no-first-run", "--no-default-browser-check", "--disable-features=BrowserAddPersonFeature,InterestFeedContentSuggestions"); // Use a unique temporary profile to avoid conflicts tempProfile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); options.AddArguments($"--user-data-dir={tempProfile}"); // manual driver path string driverPath = @"C:\ProgramData\MAV\AiQ_GUI"; ChromeDriverService service = ChromeDriverService.CreateDefaultService(driverPath); service.HideCommandPromptWindow = true; ChromeDriver driver = new(service, options); driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5); return driver; } catch (Exception ex) { MainForm.Instance.AddToActionsList("Failed to create ChromeDriver: " + ex.Message); throw; } } // Changes the value of a dropdown element by ID, logs the action, and verifies the result using flashline feedback public static async Task Dropdown_Change(string fullId, string value, ChromeDriver driver, string SoakLogFile, string CamAct) { WebDriverWait wait = new(driver, TimeSpan.FromSeconds(10)); IWebElement element = wait.Until(driver => driver.FindElement(By.Id(fullId))); await Logging.LogMessage($"Changing dropdown {fullId} to value: {value}", SoakLogFile); await Task.Delay(fullId.Contains("Mode_") ? 4000 : 200); if (value == element.GetAttribute("value")) return; // No change needed setting is already correct SelectElement select = new(element); select.SelectByValue(value); await Task.Delay(500); // Wait for the change to take effect if (!await Checkflashline(driver, CamAct)) { Logging.LogWarningMessage("Bad flashline after changing: " + fullId, SoakLogFile); MainForm.Instance.AddToActionsList("Bad flashline after changing: " + fullId); } } // Monitors the flashline element's color to determine success (green) or failure (red) of a camera public static async Task Checkflashline(ChromeDriver driver, string CamAct) { IWebElement flashline = driver.FindElement(By.Id(CamAct)); string flashlinecolor = flashline.GetCssValue("color"); Task FlashWait = Task.Delay(8000); while (!FlashWait.IsCompleted) { if (flashlinecolor.Contains("0, 255, 127")) return true; else if (flashlinecolor.Contains("255, 69, 0")) return false; await Task.Delay(500); flashlinecolor = flashline.GetCssValue("color"); } return false; } // Retrieves the ID of the last