//do testów public void OpActionDoubleClick(Structs.TestStep testStep1) { IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testStuff.driver); new Actions(testStuff.driver).DoubleClick(element).Build().Perform(); }
//odświeża stronę aż znajdzie wiersz, w którym są teksty określone w texts //w kroku jako xpath należy podać bezpośredniego rodzica wierszy <tr>, zazwyczaj body //w kroku jako text należy podać stałe teksty odzielone podwójnymi przecinkami albo zmienne obramowane podwójnymi nawiasami kwadratowymi public string OpActionRefreshUntil(Structs.TestStep testStep1) { int duration = Settings.ActionsSettings.opActionRefreshUntilSleep; int timeout = Settings.ActionsSettings.opActionRefreshUntilTimeout; DateTime start = DateTime.Now; TimeSpan whileDuration = new TimeSpan(0, 0, 0); while ( (!GetIsMatchForRefreshUntil(testStep1.xpath, GetTextsForRefreshUntil(testStep1))) && (whileDuration.TotalMilliseconds < timeout)) { Sleep(duration); testStuff.driver.Navigate().Refresh(); whileDuration = DateTime.Now - start; } if (whileDuration.TotalMilliseconds >= timeout) { return("timeout"); } else { return("ok"); } }
//testować public string OpActionSetBatchVariable(Structs.TestStep testStep1) { if (testStuff.testManager != null) { IWebElement element = ElementFinder(testStep1); Structs.Variable v; if ((element.Text != null) && (element.Text != "")) { v = new Structs.Variable(testStep1.operationText, element.Text); } else { v = new Structs.Variable(testStep1.operationText, element.GetAttribute("value")); } if (testStuff.testManager.batchVariables.Where(t => t.name == v.name).Count() == 0) { testStuff.testManager.batchVariables.Add(v); } else { testStuff.testManager.batchVariables.Remove(testStuff.variables.Where(t => t.name == v.name).FirstOrDefault()); testStuff.testManager.batchVariables.Add(v); } return("ok"); } else { return("OpActions.OpActionSetBatchVariable(): test manager is null, are you sure you're running a test batch, not a single test? Using batch variables is allowed only in batch tests."); } }
public string OpActionSendBatchVariable(Structs.TestStep testStep1) { //dodać sprawdzenia if (testStuff.testManager != null) { IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testStuff.driver); if (testStuff.testManager.batchVariables.Where(t => t.name == testStep1.operationText).Count() > 0) { string value = testStuff.testManager.batchVariables.Where(t => t.name == testStep1.operationText).SingleOrDefault().value; element.SendKeys(value + "\t"); //ważne - z \t chodzi o zejście z pola; użytkownik też dostałby błąd, gdyby nie zszedł z pola z regułą return("ok"); } else { return("Can't find variable " + testStep1.operationText + ". Possible causes include: " + "\r\nprevious test in batch failed to set variable" + "\r\napplication was restarted mid-batch - as for 2019-08-01 batch variables are stored in RAM."); } } else { return("OpActions.OpActionSendBatchVariable(): test manager is null, are you sure you're running a test batch, not a single test? Using batch variables is allowed only in batch tests."); } }
//tym zastapic szukanie elementow w kazdej op action private IWebElement ElementFinder(Structs.TestStep testStep1) { DateTime start = DateTime.Now; int timeout = Settings.ActionsSettings.elementFinderTimeout; //ms, do settings TimeSpan whileDuration = TimeSpan.FromMilliseconds(0); List <IWebElement> elements = new List <IWebElement>(); while (whileDuration.TotalMilliseconds < timeout) { elements = testStuff.driver.FindElements(By.XPath(testStep1.xpath)).ToList(); if (elements.Count > 0) { if (DisplayedAndEnabled(elements[0])) { //Console.WriteLine("ElementFinder(): proper element found in step" + testStep1.stepDescription); return(elements[0]); } else { testStuff.Log("ElementFinder(): element found is disabled or not displayed in step " + testStep1.stepDescription + ". Next action: sleep, retry."); } } Sleep(100); //do settings whileDuration = DateTime.Now - start; } //po staremu, na chama, rzeby rzuciło wyjątkami return(testStuff.driver.FindElement(By.XPath(testStep1.xpath))); }
public string OpActionClick(Structs.TestStep testStep1) { //IWebElement element = testSetup.driver.FindElement(By.XPath(testStep1.xpath)); IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testSetup.driver); element.Click(); //sprawdzenie wystąpienia błędu zdefiniowanego przez uzytkownika (jako fragment html) if ((Settings.customErrors.Count > 0) && (testStep1.operationText == "Err")) { Sleep(Settings.sleepAfterOperation); string customError = CustomErrorDetected(); if (customError != "no") { return("Custom error detected: " + customError); } else { return("ok"); } } else { return("ok"); } }
private List <string> GetTextsForRefreshUntil(Structs.TestStep testStep1) { List <string> texts0 = new List <string>(); List <string> texts = new List <string>(); texts0 = Regex.Split(testStep1.operationText, @";").ToList(); foreach (string s in texts0) { string s1 = s; s1 = ClearString(s1); if (Regex.IsMatch(s1, @"{(.*?)}")) { s1 = ClearString(s1); s1 = s1.Substring(1); s1 = s1.Substring(0, s1.Length - 1); texts.Add(testStuff.variables.Where(t => t.name == s1).First().value); //opatrzyć wyjątkiem w razie braku setvariable przed uzyciem variable albo rozbudować walidację data table } else { texts.Add(s1); } } return(texts); }
public string OpActionSendEnumKey(Structs.TestStep testStep1) { //IWebElement element = testStuff.driver.FindElement(By.XPath(testStep1.operationText)); IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testStuff.driver); switch (testStep1.operationText) { case "Escape": element.SendKeys(OpenQA.Selenium.Keys.Escape); return("ok"); case "Enter": element.SendKeys(OpenQA.Selenium.Keys.Enter); return("ok"); case "Tab": element.SendKeys(OpenQA.Selenium.Keys.Tab); return("ok"); case "Backspace": element.SendKeys(OpenQA.Selenium.Keys.Backspace); return("ok"); default: return("SendEnumKey(): Can't recognize key code " + testStep1.operationText); } }
public void OpActionSetVariable(Structs.TestStep testStep1) { //IWebElement element = testStuff.driver.FindElement(By.XPath(testStep1.xpath)); IWebElement element = ElementFinder(testStep1); Structs.Variable v; if ((element.Text != null) && (element.Text != "")) { v = new Structs.Variable(testStep1.operationText, element.Text); } else { v = new Structs.Variable(testStep1.operationText, element.GetAttribute("value")); } if (testStuff.variables.Where(t => t.name == v.name).Count() == 0) { testStuff.variables.Add(v); } else { testStuff.variables.Remove(testStuff.variables.Where(t => t.name == v.name).FirstOrDefault()); testStuff.variables.Add(v); } }
public void OpActionSendKeys(Structs.TestStep testStep1) { //IWebElement element = testStuff.driver.FindElement(By.XPath(testStep1.xpath)); IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testStuff.driver); string text = testStep1.operationText; if ((text[0] == '{') && (text[text.Length - 1] == '}')) { switch (text) { case "{DateTimeNow}": text = DateTime.Now.ToString("yyyy-MM-dd") + "T" + DateTime.Now.ToString("hh-mm-ss"); break; case "{DateNow}": text = DateTime.Now.ToString("yyyy-MM-dd"); break; } } element.SendKeys(text + "\t"); //ważne - z \t chodzi o zejście z pola; użytkownik też dostałby błąd, gdyby nie zszedł z pola z regułą }
public void OpActionMoveToElement(Structs.TestStep testStep1) { IWebElement element = ElementFinder(testStep1); HighlightElement(element); //debug, usunąć ScrollAndMoveTo(element, testStuff.driver); }
public void OpActionSendVariable(Structs.TestStep testStep1) { IWebElement element = testSetup.driver.FindElement(By.XPath(testStep1.xpath)); ScrollAndMoveTo(element, testSetup.driver); string value = testSetup.variables.Where(t => t.name == testStep1.operationText).SingleOrDefault().value; element.SendKeys(value + "\t"); //ważne - z \t chodzi o zejście z pola; użytkownik też dostałby błąd, gdyby nie zszedł z pola z regułą }
public void OpActionSelectOption(Structs.TestStep testStep1) { IWebElement element = testSetup.driver.FindElement(By.XPath(testStep1.xpath)); ScrollAndMoveTo(element, testSetup.driver); SelectElement option = new SelectElement(element); int i; Int32.TryParse(testStep1.operationText, out i); option.SelectByIndex(i); element.Click(); }
public void OpActionSendKeys(Structs.TestStep testStep1) { IWebElement element = testSetup.driver.FindElement(By.XPath(testStep1.xpath)); //Actions action = new Actions(testSetup.driver); //dla estetyki tylko //action.MoveToElement(element).Perform(); ScrollAndMoveTo(element, testSetup.driver); string text = testStep1.operationText; element.SendKeys(testStep1.operationText + "\t"); //ważne - z \t chodzi o zejście z pola; użytkownik też dostałby błąd, gdyby nie zszedł z pola z regułą }
public static Structs.TestPlan GetTestPlan(DataTable testPlanTable) { Structs.TestStep step; List <Structs.TestStep> testSteps = new List <Structs.TestStep>(); for (int i = 0; i < testPlanTable.Rows.Count; i++) { DataRow row = testPlanTable.Rows[i]; step = new Structs.TestStep((i + 1).ToString() + ") " + row.ItemArray[0].ToString(), row.ItemArray[1].ToString(), row.ItemArray[2].ToString(), row.ItemArray[3].ToString()); testSteps.Add(step); } Structs.TestPlan testPlan = new Structs.TestPlan(testSteps); return(testPlan); }
public void KeepMaximized(Structs.TestStep testStep1) { if ((testStuff.driver.Manage().Window.Size.Width != testStuff.initialWindowSize.Width) || (testStuff.driver.Manage().Window.Size.Height != testStuff.initialWindowSize.Height)) { testStuff.Log("Operation: window size has changed during test step " + testStep1.stepDescription + ". Next action: try to maximize."); try { testStuff.driver.Manage().Window.Maximize(); } catch (Exception) { testStuff.Log("Failed to maximize window."); } } }
//desperacka próba obsłużenia zapisz i zatwierdź, używać w ostateczności, nie obsługuje err //mam nadziję, że zbędne i do wyeliminowania public string OpActionClickJS(Structs.TestStep testStep1) { Sleep(Settings.ActionsSettings.opActionClickJSInitialSleep); IJavaScriptExecutor js = (IJavaScriptExecutor)testStuff.driver; IWebElement element = testStuff.driver.FindElement(By.XPath(testStep1.xpath)); ScrollAndMoveTo(element, testStuff.driver); //element.Click(); js.ExecuteScript("arguments[0].click();", element); Sleep(Settings.ActionsSettings.opActionClickJSFinalSleep); return("ok"); }
public string OpActionClick(Structs.TestStep testStep1) { if (testStep1.operationText.Contains("Retarded")) { Sleep(Settings.ActionsSettings.opActionClickRetarded); } BrowserFocus(); //dodane ze względu na problemy - czasem nie klika i nie zgłasza błędu testStuff.Log("OpActions.OpActionClick() called in test step " + testStep1.stepDescription); //IWebElement element = testStuff.driver.FindElement(By.XPath(testStep1.xpath)); IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testStuff.driver); element.Click(); //sprawdzenie wystąpienia błędu zdefiniowanego przez uzytkownika (jako fragment html) if ((Settings.customErrors.Count > 0) && (testStep1.operationText.Contains("Err"))) { Sleep(Settings.sleepAfterOperation); string customError = CustomErrorDetected(); if (customError != "no") { return("Custom error detected: " + customError); } else { return("ok"); } } else { return("ok"); } }
public string OpActionPresetVariable(Structs.TestStep testStep1) { string text = testStep1.operationText; string name = ""; string value = ""; try { name = text.Substring(0, text.IndexOf('=')); value = text.Substring(text.IndexOf('=') + 1); name = ClearString(name); value = ClearString(value); //jeżeli wartość ma być pobrana ze zmiennej batcha, np. text: x={y} if (value[0] == '{' && value[value.Length - 1] == '}') { value = testStuff.testManager.batchVariables.Where(t => t.name == value.Substring(1, value.Length - 2)).FirstOrDefault().value; } } catch (Exception e) { return("OpActionPresetVariable(): can't parse \"" + text + "\". Exception:\r\n" + e); } Structs.Variable v = new Structs.Variable(name, value); if (testStuff.variables.Where(t => t.name == v.name).Count() == 0) { testStuff.variables.Add(v); } else { testStuff.variables.Remove(testStuff.variables.Where(t => t.name == v.name).FirstOrDefault()); testStuff.variables.Add(v); } return("ok"); }
public void OpActionSelectOption(Structs.TestStep testStep1) { //IWebElement element = testStuff.driver.FindElement(By.XPath(testStep1.xpath)); IWebElement element = ElementFinder(testStep1); ScrollAndMoveTo(element, testStuff.driver); SelectElement option = new SelectElement(element); //int i = -1; if (Int32.TryParse(testStep1.operationText, out int i)) { option.SelectByIndex(i); } else { option.SelectByText(testStep1.operationText); } element.Click(); }
public static Structs.TestPlan GetTestPlan(DataTable testPlanTable) { Structs.TestStep step; List <Structs.TestStep> testSteps = new List <Structs.TestStep>(); for (int i = 0; i < testPlanTable.Rows.Count; i++) { DataRow row = testPlanTable.Rows[i]; //pominięcie komentarzy if ((row[0].ToString()[0] == '[') && (row[0].ToString()[row[0].ToString().Length - 1] == ']')) { Console.WriteLine("TestPlanFromDataTable.GetTestPlan(): removed comment \"" + row[0].ToString() + "\""); continue; } step = new Structs.TestStep("(" + (i + 1).ToString() + ") " + row.ItemArray[0].ToString(), row.ItemArray[1].ToString(), row.ItemArray[2].ToString(), row.ItemArray[3].ToString()); testSteps.Add(step); } Structs.TestPlan testPlan = new Structs.TestPlan(testSteps); return(testPlan); }
//działania ostatniej szansy, kiedy test się zatnie na NonInteractibleException public void TryHelpNonInteractible(Structs.TestStep testStep, int catchCount) { switch (catchCount) //do zmiany!!! w tym catch mógł się trafić inny błąd //taki switch powinien być w operations? { case 3: //rekurencyjnie szuka interaktywnego (visible, enabled) rodzica i kiedy znajdzie, jedzie do niego MoveToParent(); break; } void MoveToParent() { string log = "TryHelpNonInteractible().MoveToParent(): I will try to find an interactible parent."; string initialXPath = testStep.xpath; string goodXPath = MoveUpAndTry(initialXPath); string MoveUpAndTry(string xpath) { log += "\r\nMoveUpAndTry() called for xpath " + xpath; string parentXPath = xpath.Substring(0, xpath.LastIndexOf('/')); List <IWebElement> parents; if (parentXPath.Count(t => t == '/') > 1) { parents = testStuff.driver.FindElements(By.XPath(parentXPath)).ToList(); } else { return("not xpath"); } if (parents.Count > 0) { if (parents[0].Displayed && parents[0].Enabled) { return(parentXPath); } else { return(MoveUpAndTry(parentXPath)); } } else { return("parents count 0"); } } if (goodXPath.Count(t => t == '/') > 1) { log += "\r\nInteractible parent found, calling ScrollAndMoveTo, xpath found: " + goodXPath; IWebElement parent = testStuff.driver.FindElement(By.XPath(goodXPath)); ScrollAndMoveTo(parent, testStuff.driver); //HighlightElement(parent); } else { log += "\r\nSearch for interactible parent failed."; } testStuff.Log(log); } }
private string PerformOperation(Structs.TestStep testStep1) { string result = "init"; switch (testStep1.operationName) { case "SendKeys": opActions.OpActionSendKeys(testStep1); result = "ok"; break; case "SendEnumKey": result = opActions.OpActionSendEnumKey(testStep1);; break; case "GoToUrl": opActions.OpActionGoToUrl(testStep1); result = "ok"; break; case "Click": result = opActions.OpActionClick(testStep1); break; case "ClickJS": result = opActions.OpActionClickJS(testStep1); break; case "WaitFor": result = opActions.OpActionWaitFor(testStep1); break; case "Refresh": opActions.OpActionRefresh(); result = "ok"; break; case "MoveToElement": opActions.OpActionMoveToElement(testStep1); result = "ok"; break; case "SetVariable": opActions.OpActionSetVariable(testStep1); result = "ok"; break; case "SendVariable": opActions.OpActionSendVariable(testStep1); result = "ok"; break; case "CloseAlert": opActions.OpActionCloseAlert(testStep1.operationText); result = "ok"; break; case "SendEnumKeyToAlert": result = opActions.OpActionSendEnumKeyToAlert(testStep1.operationText); break; case "SelectOption": opActions.OpActionSelectOption(testStep1); result = "ok"; break; case "RefreshUntil": result = opActions.OpActionRefreshUntil(testStep1); break; case "Scroll": result = opActions.OpActionScroll(testStep1); break; default: result = "Error: can't recognize operation \"" + testStep1.operationName + "\"."; break; } return(result); }
private string PerformOperation(Structs.TestStep testStep1) { string result = "init"; //klucz operationName wzorowany na słowniku komend Selenium (jak w plikach .side) switch (testStep1.operationName) { case "type": //dawne "SendKeys": opActions.OpActionSendKeys(testStep1); result = "ok"; break; case "sendKeys": //"SendEnumKey": result = opActions.OpActionSendEnumKey(testStep1);; break; case "goToUrl": opActions.OpActionGoToUrl(testStep1); result = "ok"; break; case "click": result = opActions.OpActionClick(testStep1); break; case "clickJS": result = opActions.OpActionClickJS(testStep1); break; case "clickLast": result = opActions.OpActionClickLast(); break; case "doubleClick": opActions.OpActionDoubleClick(testStep1); result = "ok"; break; case "doubleClickLast": result = opActions.OpActionDoubleClickLast(); break; case "waitFor": result = opActions.OpActionWaitFor(testStep1); break; case "refresh": opActions.OpActionRefresh(); result = "ok"; break; case "mouseOver": //"moveToElement": opActions.OpActionMoveToElement(testStep1); result = "ok"; break; case "setVariable": opActions.OpActionSetVariable(testStep1); result = "ok"; break; case "sendVariable": opActions.OpActionSendVariable(testStep1); result = "ok"; break; case "setBatchVariable": result = opActions.OpActionSetBatchVariable(testStep1); break; case "sendBatchVariable": result = opActions.OpActionSendBatchVariable(testStep1); break; case "closeAlert": opActions.OpActionCloseAlert(testStep1.operationText); result = "ok"; break; case "sendEnumKeyToAlert": result = opActions.OpActionSendEnumKeyToAlert(testStep1.operationText); break; case "select": //"SelectOption": opActions.OpActionSelectOption(testStep1); result = "ok"; break; case "refreshUntil": result = opActions.OpActionRefreshUntil(testStep1); break; case "scroll": result = opActions.OpActionScroll(testStep1); break; case "presetVariable": result = opActions.OpActionPresetVariable(testStep1); break; default: result = "Error: can't recognize operation \"" + testStep1.operationName + "\"."; break; } return(result); }
public void OpActionMoveToElement(Structs.TestStep testStep1) { IWebElement element = testSetup.driver.FindElement(By.XPath(testStep1.xpath)); ScrollAndMoveTo(element, testSetup.driver); }
int catchLimit = Settings.catchLimit; //do settingsów public string Operation(Structs.TestStep testStep1) { string result = "init"; try { opActions.KeepMaximized(testStep1); //wielkość okna chrome, ważne dla niezawodności opetarions result = PerformOperation(testStep1); opActions.Sleep(Settings.sleepAfterOperation); catchCount = 0; } catch (NoAlertPresentException) { catchCount++; testStuff.Log("Exception caught \"NoAlertPresentException\" in step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next: sleep, retry."); opActions.Sleep(200); if (catchCount < catchLimit) { result = Operation(testStep1); } else { //result = "Catch limit exceeded: \"UnhandledAlertException\" in step " + testStep1.stepDescription + "."; result = "ok"; //dziwne, ale chodzi o to, że kiedy leci taki wyjątek, to praktycznie zawsze przy próbie pozbycia się jebanego alertu; więc tu zakładany, że jebańca nie ma } } catch (UnhandledAlertException) { catchCount++; testStuff.Log("Exception caught \"UnhandledAlertException\" in step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next: close alert, retry."); opActions.OpActionCloseAlert("Accept"); if (catchCount < catchLimit) { result = Operation(testStep1); } else { result = "Catch limit exceeded: \"UnhandledAlertException\" in step " + testStep1.stepDescription + "."; } } catch (StaleElementReferenceException) { catchCount++; testStuff.Log("Exception caught \"StaleElementReferenceException\" in step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next: retry."); if (catchCount < catchLimit) { result = Operation(testStep1); } else { result = "Catch limit exceeded: \"StaleElementReferenceException\" in step " + testStep1.stepDescription + "."; } } catch (ElementNotInteractableException) { catchCount++; testStuff.Log("Exception caught \"ElementNotInteractableException\" in step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next: sleep, retry."); opActions.Sleep(Settings.sleepAfterElementNotInteractible); if (catchCount < catchLimit) { if (Settings.allowTryHelps) { opActions.TryHelpNonInteractible(testStep1, catchCount); //znajduje interaktywnego rodzica i najeżdża na niego kursorem } result = Operation(testStep1); } else { result = "Catch limit exceeded. \"ElementNotInteractableException\" in step " + testStep1.stepDescription + "."; } } //niby redundantne z implicit wait, ale w praktyce pomaga catch (NoSuchElementException e) { catchCount += 1; testStuff.Log("Exception caught \"NoSuchElementException\" in test step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next actions: sleep, retry."); opActions.Sleep(Settings.sleepAfterNoSuchElement); //do tego dochodzi implicit wait, więc łącznie 40,3 s x 10... wtf if (catchCount < Settings.noSuchElementCatchLimit) { if (Settings.allowTryHelps) { opActions.TryHelpNoSuchElement(catchCount); //scrolluje } result = Operation(testStep1); } else { result = "Catch limit exceeded. \"NoSuchElementException\" in test step " + testStep1.stepDescription + ". Is test scenario up-to-date? Exception: \r\n" + e; } } catch (Exception e) { result = "Error in step named: \"" + testStep1.stepDescription + "\". Operation: \"" + testStep1.operationName + "\". Exception: \r\n" + e; } return(result); }
int catchLimit = Settings.catchLimit; //do settingsów public string Operation(Structs.TestStep testStep1) { string result = "init"; try { opActions.KeepMaximized(testStep1); //wielkość okna chrome, ważne dla niezawodności opetarions result = PerformOperation(testStep1); opActions.Sleep(Settings.sleepAfterOperation); catchCount = 0; } catch (NoAlertPresentException) { catchCount++; testSetup.Log("Exception caught \"NoAlertPresentException\" in test step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next actions: none."); } catch (UnhandledAlertException) { catchCount++; testSetup.Log("Exception caught \"UnhandledAlertException\" in test step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next actions: close alert, retry."); opActions.OpActionCloseAlert("Accept"); if (catchCount < catchLimit) { result = Operation(testStep1); } else { result = "Catch limit exceeded: \"UnhandledAlertException\" in test step " + testStep1.stepDescription + "."; } } catch (StaleElementReferenceException) { catchCount++; testSetup.Log("Exception caught \"StaleElementReferenceException\" in test step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next action: retry."); if (catchCount < catchLimit) { result = Operation(testStep1); } else { result = "Catch limit exceeded: \"StaleElementReferenceException\" in test step " + testStep1.stepDescription + "."; } } catch (ElementNotInteractableException) { catchCount++; testSetup.Log("Exception caught \"ElementNotInteractableException\" in test step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next actions: sleep, retry."); opActions.Sleep(Settings.sleepAfterElementNotInteractible); if (catchCount < catchLimit) { result = Operation(testStep1); } else { result = "Catch limit exceeded. \"ElementNotInteractableException\" in test step " + testStep1.stepDescription + "."; } } //niby redundantne z implicit wait, ale w praktyce pomaga catch (NoSuchElementException e) { catchCount += 9; //ze względu na implicit wait (jakoś to ogarnąć potem) testSetup.Log("Exception caught \"NoSuchElementException\" in test step " + testStep1.stepDescription + ". Catch number " + catchCount.ToString() + ". Next actions: sleep, retry."); //bez refresh! opActions.Sleep(Settings.sleepAfterNoSuchElement); //do tego dochodzi implicit wait, więc łącznie 40,3 s x 10... wtf if (catchCount < catchLimit) { result = Operation(testStep1); } else { result = "Catch limit exceeded. \"NoSuchElementException\" in test step " + testStep1.stepDescription + ". Exception: \r\n" + e; } } catch (Exception e) { result = "Error in step named: \"" + testStep1.stepDescription + "\". Operation: \"" + testStep1.operationName + "\". Exception: \r\n" + e; } return(result); }
//służy do //1. weryfikacji, że test dotarł do oczekiwanego elementu (ewentualnie z tekstem) //2. oczekiwania sztywno przez x s - np. po zapisz i zatwierdź //3. oczekiwania aż pojawi się element (ew. tekst) public string OpActionWaitFor(Structs.TestStep testStep1) { int timeOut = Settings.ActionsSettings.opActionWaitForTimeout; TimeSpan whileDuration = new TimeSpan(0, 0, 0); DateTime startTime = DateTime.Now; string expectedText = ""; if ((testStep1.operationText != null) && (testStep1.operationText != "")) { expectedText = testStep1.operationText; expectedText = ClearString(expectedText); } List <IWebElement> elements = new List <IWebElement>(); while (whileDuration.TotalMilliseconds < timeOut) { if ((testStep1.xpath != null) && (testStep1.xpath != "")) { elements = testStuff.driver.FindElements(By.XPath(testStep1.xpath)).ToList(); if (elements.Count > 0) { //dodac warunek, ze visible, interactible itp //uładzic te funkcje if (expectedText != "") { if (elements[0].Text.Contains(expectedText)) { if (DisplayedAndEnabled(elements[0])) { return("ok"); } else { return("OpActionWaitFor(): element found is disabled or not displayed."); } } else { elements.Clear(); } } else { if (DisplayedAndEnabled(elements[0])) { return("ok"); } else { return("OpActionWaitFor(): element found is disabled or not displayed."); } } } } Sleep(Settings.ActionsSettings.opActionWaitForSleep); whileDuration = DateTime.Now - startTime; } if ((testStep1.xpath != null) && (testStep1.xpath != "")) { return("Wait for (expected text: \"" + expectedText + "\") timed out"); } else { return("ok"); } }
public void OpActionGoToUrl(Structs.TestStep testStep1) { testStuff.driver.Navigate().GoToUrl(testStep1.operationText); }
public string OpActionScroll(Structs.TestStep testStep1) { Sleep(Settings.ActionsSettings.opActionScrollSleep); IJavaScriptExecutor js = (IJavaScriptExecutor)testStuff.driver; string destination = testStep1.operationText; Tuple <int, int> vector = new Tuple <int, int>(0, 0); bool gotVector = false; if (destination.Contains("{")) { gotVector = TryGetVector2(destination, out vector); } switch (destination) { case "Top": js.ExecuteScript("window.scrollTo(0, 0);"); return("ok"); case "Bottom": js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);"); return("ok"); default: if (gotVector) { js.ExecuteScript("window.scrollTo(" + vector.Item1.ToString() + ", " + vector.Item2.ToString() + ")"); return("ok"); } else { return("Error: can't recognize scroll destination \"" + destination + "\"; use \"Top\" or \"Bottom\" or {dx;dy}"); } } bool TryGetVector2(string input, out Tuple <int, int> tuple) { string input1 = input.Replace("{", "").Replace("}", ""); string[] texts = input1.Split(';'); tuple = new Tuple <int, int>(0, 0); if (texts.Length != 2) { return(false); } int x; int y; for (int i = 0; i < texts.Length; i++) { texts[i] = ClearString(texts[i]); } if (!Int32.TryParse(texts[0], out x) || !Int32.TryParse(texts[1], out y)) { return(false); } tuple = new Tuple <int, int>(x, y); return(true); } }