private void AcceptButton_Click(object sender, RoutedEventArgs e) { WebElementInfo webElement; if (_isUpdateMode) { webElement = _sourceObject; } else { webElement = new WebElementInfo(); } var info = WebElementControl.GetWebElementInfo(); webElement.Name = info.Name; webElement.Description = info.Description; webElement.IsKeyElement = info.IsKeyElement; webElement.Tags = info.Tags; webElement.WebLocator = info.WebLocator.GetCopy(); WebElement = webElement; DialogResult = true; Close(); }
public static WebContext GetTestInfo() { var emailInput = new WebElementInfo { Name = "Email Input", Description = "Input for Email", IsKey = false, InnerKey = null, Locator = new WebLocatorInfo { LocatorType = WebLocatorType.XPath, LocatorValue = "//input[@id='email']", IsRelative = false } }; var loginForm = new WebContext { Name = "Login Form", Description = "Form to do login", IsKey = false, InnerKey = null, Elements = new List <WebElementInfo>(), Locator = new WebLocatorInfo { LocatorType = WebLocatorType.XPath, LocatorValue = ".", IsRelative = false } }; loginForm.Elements.Add(emailInput); return(loginForm); }
public JsonResult Get_Web_Element_Authorize(string[] access_Functions) { List <WebElementInfo> webElements = new List <WebElementInfo>(); try { foreach (var item in access_Functions) { WebElementInfo webElement = new WebElementInfo(); webElement.Access_Function = item.Split('@')[0]; webElement.Web_Element_Id = item.Split('@')[1]; webElement.User_Id = ((UserInfo)Session["User"]).UserId; webElement.Is_Authorize = _ajaxMgr.Get_Web_Element_Authorize(webElement); webElements.Add(webElement); } } catch (Exception ex) { Logger.Error("Ajax Controller - Delete_Attachment " + ex.ToString()); } return(Json(new { webElements }, JsonRequestBehavior.AllowGet)); }
public IWebElement TryFindElementWithTimeFrame(WebElementInfo elementInfo, int timeoutInMiliSec = 0, bool changeTimeouts = true) { if (timeoutInMiliSec == 0) { timeoutInMiliSec = DefaultTimeoutForTrySearchInMilisec; } try { if (changeTimeouts) { GetDriver().Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(timeoutInMiliSec); } return(FindElement(elementInfo, null)); } catch { return(null); } finally { if (changeTimeouts) { GetDriver().Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(DefaultTimeoutForSearchInSec); } } }
public WebElementState GetElementState(WebElementInfo elementInfo, out IWebElement element, ILogger log, bool changeTimeouts = true) { log = log?.CreateChildLogger($"Get state for {elementInfo}"); log?.INFO($"Description: {elementInfo.Description}"); element = TryFindElementWithTimeFrame(elementInfo, DefaultTimeoutForTrySearchInMilisec, changeTimeouts); if (element == null) { log?.INFO($"State: {WebElementState.NotPresent}"); return(WebElementState.NotPresent); } if (!element.Displayed) { log?.INFO($"State: {WebElementState.NotVisible}"); return(WebElementState.NotVisible); } if (!element.Enabled) { log?.INFO($"State: {WebElementState.Disabled}"); return(WebElementState.Disabled); } log?.INFO($"State: {WebElementState.Enabled}"); return(WebElementState.Enabled); }
public static WebElementViewModel CreateModelFromInfo(WebElementInfo info) { WebElementViewModel model = null; if (info is WebContext webContext) { model = new WebContextViewModel(); model.FillFromInfo(webContext); } else if (info is DropDownElementInfo dropDown) { model = new DropDownElementViewModel(); model.FillFromInfo(dropDown); } else if (info is RadioGroupElementInfo radioGroup) { model = new RadioGroupViewModel(); model.FillFromInfo(radioGroup); } else if (info is CombinedWebElementInfo combined) { model = new CombinedElementViewModel(); model.FillFromInfo(combined); } else { model = new WebElementViewModel(); model.FillFromInfo(info); } return(model); }
public static WebElementInfo CreateInfoFromModel(WebElementViewModel model) { WebElementInfo info = null; if (model is WebContextViewModel webContext) { info = new WebContext(); webContext.FillInfo(info); } else if (model is DropDownElementViewModel dropDown) { info = new DropDownElementInfo(); dropDown.FillInfo(info); } else if (model is RadioGroupViewModel radioGroup) { info = new RadioGroupElementInfo(); radioGroup.FillInfo(info); } else if (model is CombinedElementViewModel combined) { info = new CombinedWebElementInfo(); combined.FillInfo(info); } else { info = new WebElementInfo(); model.FillInfo(info); } return(info); }
public override void FillFromInfo(WebElementInfo info) { if (!(info is CombinedWebElementInfo combined)) { throw new Exception($"Incorrect info type: {info.GetType().Name} for model with type WebContextViewModel"); } base.FillFromInfo(info); }
public IWebElement FindElement(WebElementInfo elementInfo, ILogger log) { log = log?.CreateChildLogger($"Find {elementInfo}"); log?.INFO($"Description: {elementInfo.Description}"); var search = elementInfo.GetWebSearch(); var searchStack = new Stack <WebSearchInfo>(); searchStack.Push(search); while (search.ParentSearch != null) { searchStack.Push(search.ParentSearch); search = search.ParentSearch; } var searchLog = log?.CreateChildLogger("Search element"); searchLog?.INFO($"Search contains: {searchStack.Count} items"); IWebElement foundElement = null; var counter = 0; while (searchStack.Count > 0) { var currentSearch = searchStack.Pop(); searchLog?.INFO($"Search for {++counter} item"); searchLog?.INFO($"Locator type: {currentSearch.LocatorType}"); searchLog?.INFO($"Locator value: {currentSearch.LocatorValue}"); var by = GetBy(currentSearch); try { if (foundElement == null) { foundElement = FindElement(by); } else { foundElement = FindElementRelativeTo(foundElement, by); } } catch (Exception ex) { var err = new SaKiWebElementException(nameof(FindElement), "WebElement could't be found", elementInfo, ex); log?.ERROR(err.Message, err); throw err; } } log?.INFO("Element found successfully"); return(foundElement); }
public IWebElement FindElementRelativeTo(WebElementInfo parentElementInfo, By by, ILogger log) { log = log?.CreateChildLogger($"Find element relativeTo: {parentElementInfo}"); log?.INFO($"using locator: {by}"); var parentElement = FindElement(parentElementInfo, log); var foundElement = FindElementRelativeTo(parentElement, by); return(foundElement); }
public WebInfoGenerationData GetClassForWebElement(WebElementInfo info) { var className = GetClassNameFromElementName(info.Name); var propName = className.Substring(1); var constInfoCD = GetClassForConstInfo(info); var baseClassName = info.GetType().Name; var docComment = GetDocCommentWithText(info.Description); var infoComment = GetDocCommentWithText("Information about element"); var infoProperty = SF.PropertyDeclaration( SF.ParseTypeName($"{InfoStaticClassName}.{InfoClassName}"), SF.Identifier(InfoClassName) ) .WithAccessorList( SF.AccessorList( SF.List( new List <AccessorDeclarationSyntax> { SF.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken)), SF.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken)) } ) ) .WithOpenBraceToken(SF.Token(SyntaxKind.OpenBraceToken)) .WithCloseBraceToken(SF.Token(SyntaxKind.CloseBraceToken)) ) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword).WithLeadingTrivia(SF.Trivia(infoComment))); var getInstMd = GetGetInstanceMethod(className); var cd = SF.ClassDeclaration(className) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword).WithLeadingTrivia(SF.Trivia(docComment))) .AddBaseListTypes(SF.SimpleBaseType(SF.IdentifierName(baseClassName))) .AddMembers(infoProperty, getInstMd, constInfoCD); var genData = new WebInfoGenerationData { ClassName = className, PropertyName = propName, ClassSyntax = cd, Element = info }; FillWithChildrenElementsProperties(genData, out List <WebInfoGenerationData> childrenGens); AddCtor(genData, childrenGens); FillWithChildrenElementsClasses(genData, childrenGens); return(genData); }
public object ExecuteJavaScript(WebElementInfo elementInfo, string javaScript, ILogger log) { var jsExecutor = GetJavaScriptExecutor(); log = log?.CreateChildLogger($"Execute JavaScript on {elementInfo}"); log?.CreateChildLogger("Logged JavaScript")?.INFO(javaScript); LogElementPath(elementInfo, log); var element = FindElement(elementInfo, log); return(jsExecutor.ExecuteScript(javaScript, element)); }
public IWebElement WaitForElementState(WebElementInfo elementInfo, WebElementState elementState, ILogger log, int timeoutInSec = 0, int pollingInMiliSec = 0) { if (timeoutInSec == 0) { timeoutInSec = DefaultTimeoutForSearchInSec; } if (pollingInMiliSec == 0) { pollingInMiliSec = DefaultTimeoutForPollingInSec; } log = log?.CreateChildLogger($"Wait for state: {elementState} for {elementInfo}"); log?.INFO($"With timeout in {timeoutInSec} seconds and with polling interval in {pollingInMiliSec} seconds"); var flags = Enum.GetValues(typeof(WebElementState)).Cast <WebElementState>(); var expectedFlags = flags.Where(f => elementState.HasFlag(f)).ToList(); try { GetDriver().Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(DefaultTimeoutForTrySearchInMilisec); var sw = Stopwatch.StartNew(); long mseconds = 0; while (sw.Elapsed.TotalSeconds <= timeoutInSec) { mseconds = sw.ElapsedMilliseconds; var state = GetElementState(elementInfo, out var element, null, false); if (expectedFlags.All(f => state.HasFlag(f))) { return(element); } var toSleep = pollingInMiliSec * 1000 - (sw.ElapsedMilliseconds - mseconds); if (toSleep > 0) { Thread.Sleep((int)toSleep); } } var err = SaKiWebElementException.TimeoutDuring($"waiting for element state: {elementState}", timeoutInSec, elementInfo); log?.ERROR(err.Message, err); throw err; } finally { GetDriver().Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(DefaultTimeoutForSearchInSec); } }
private ClassDeclarationSyntax GetClassForInfo(WebElementInfo info) { var infoMembers = new List <MemberDeclarationSyntax>(); var infoMembersList = new List <(string type, string fName, string value)> { ("string", nameof(info.ElementType), info.ElementType), ("string", nameof(info.Name), info.Name), ("string", nameof(info.Description), info.Description), ("bool", nameof(info.IsKey), $"{info.IsKey}"), ("string", nameof(info.InnerKey), $"{info.InnerKey ?? "null"}"), (LocatorClassName, LocatorClassName, "Element Locator values") }; var newLineToken = SF.Token(default(SyntaxTriviaList), SyntaxKind.XmlTextLiteralNewLineToken, Environment.NewLine, Environment.NewLine, default(SyntaxTriviaList)); var docCommentToken = SF.Token(SF.TriviaList( SF.SyntaxTrivia(SyntaxKind.DocumentationCommentExteriorTrivia, "///")), SyntaxKind.XmlTextLiteralToken, " ", " ", default(SyntaxTriviaList)); var endNode = SF.XmlText( SF.TokenList(SF.Token(default(SyntaxTriviaList), SyntaxKind.XmlTextLiteralNewLineToken, Environment.NewLine, Environment.NewLine, default(SyntaxTriviaList)))); foreach (var infoMemberItem in infoMembersList) { var docComment = GetDocCommentWithText(infoMemberItem.value); var fd = SF.FieldDeclaration( SF.VariableDeclaration(SF.ParseTypeName(infoMemberItem.type)) .AddVariables(SF.VariableDeclarator(SF.Identifier(infoMemberItem.fName))) ) .AddModifiers( SF.Token(SF.TriviaList(), SyntaxKind.PublicKeyword, SF.TriviaList()) .WithLeadingTrivia(SF.Trivia(docComment)) ); infoMembers.Add(fd); } var infoCD = SF.ClassDeclaration(InfoClassName) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword)) .AddMembers(infoMembers.ToArray()); return(infoCD); }
public WebElementCreateWindow(string title, WebElementInfo webElement = null) { _isUpdateMode = webElement != null; if (_isUpdateMode) { _sourceObject = webElement; _clearedObject = _sourceObject.GetCopy(); } InitializeComponent(); Title = title; Render(); }
public WebElementInfo GetWebElementInfo() { if (WebElement == null) { WebElement = new WebElementInfo(); WebElement.WebLocator = new WebLocatorInfo(); } WebElement.Name = NameTextBox.Text; WebElement.Description = DescriptionTextBox.Text; WebElement.IsKeyElement = IsKeyCheckbox.IsChecked == true; WebElement.WebLocator.IsRelative = IsRelativeCheckBox.IsChecked == true; WebElement.WebLocator.LocatorValue = LocatorValueTextBox.Text; WebElement.WebLocator.LocatorType = (WebLocatorType)Enum.Parse(typeof(WebLocatorType), (LocatorTypeComboBox.SelectedItem as ComboBoxItem).Content.ToString()); return(WebElement); }
public void Type(string text, WebElementInfo elementInfo, ILogger log) { try { log = log?.CreateChildLogger($"Type text '{text}' to {elementInfo}"); LogElementPath(elementInfo, log); var element = WaitForElementState(elementInfo, WebElementState.ReadyForAction, log); element.SendKeys(text); } catch (Exception ex) { if (IsScreenshotOnErrorEnabled) { TryLogScreenShot($"Failed to Type text '{text}' to {elementInfo}", log); } throw SaKiWebElementException.ErrorDuring("Type to element", elementInfo, ex); } }
public void Click(WebElementInfo elementInfo, ILogger log) { try { log = log?.CreateChildLogger($"Click on {elementInfo}"); LogElementPath(elementInfo, log); var element = WaitForElementState(elementInfo, WebElementState.ReadyForAction, log); element.Click(); } catch (Exception ex) { if (IsScreenshotOnErrorEnabled) { TryLogScreenShot($"Failed to Click on {elementInfo}", log); } throw SaKiWebElementException.ErrorDuring("Click on element", elementInfo, ex); } }
public void SetWebElement(WebElementInfo webElement) { WebElement = webElement; NameTextBox.Text = webElement.Name; DescriptionTextBox.Text = webElement.Description; IsRelativeCheckBox.IsChecked = webElement.WebLocator.IsRelative; LocatorValueTextBox.Text = webElement.WebLocator.LocatorValue; IsKeyCheckbox.IsChecked = webElement.IsKeyElement; foreach (var item in LocatorTypeComboBox.Items) { if ((item as ComboBoxItem).Content.ToString() == webElement.WebLocator.LocatorType.ToString()) { LocatorTypeComboBox.SelectedItem = item; } } TagsControl.SetTags(webElement.Tags); }
public bool Get_Web_Element_Authorize(WebElementInfo webElement) { List <SqlParameter> sqlParams = new List <SqlParameter>(); sqlParams.Add(new SqlParameter("@User_Id", webElement.User_Id)); sqlParams.Add(new SqlParameter("@Access_Function_Name", webElement.Access_Function)); DataTable dt = sqlRepo.ExecuteDataTable(sqlParams, StoredProcedures.Authorize_Web_Element_Sp.ToString(), CommandType.StoredProcedure); if (dt != null && dt.Rows.Count > 0) { return(true); } else { return(false); } }
private ClassDeclarationSyntax GetClassForConstInfo(WebElementInfo info) { var infoMembers = new List <MemberDeclarationSyntax>(); var infoMembersList = new List <(string type, string fName, ExpressionSyntax expr)> { ("string", nameof(info.ElementType), GetESForValue(info.ElementType)), ("string", nameof(info.Name), GetESForValue(info.Name)), ("string", nameof(info.Description), GetESForValue(info.Description)), ("bool", nameof(info.IsKey), GetESForValue(info.IsKey)), ("string", nameof(info.InnerKey), GetESForValue(info.InnerKey)), }; foreach (var infoMemberItem in infoMembersList) { var fd = SF.FieldDeclaration( SF.VariableDeclaration(SF.ParseTypeName(infoMemberItem.type)) .AddVariables(SF.VariableDeclarator(SF.Identifier(infoMemberItem.fName)) .WithInitializer(SF.EqualsValueClause(infoMemberItem.expr)) ) ) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.ConstKeyword)); infoMembers.Add(fd); } var locatorStaticCD = GetClassForConstLocatorInInfo(info.Locator); infoMembers.Add(locatorStaticCD); var infoCD = GetClassForInfo(info); infoMembers.Add(infoCD); var locatorCD = GetClassForLocatorInInfo(info.Locator); infoMembers.Add(locatorCD); var infoStaticCD = SF.ClassDeclaration(InfoStaticClassName) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword)) .AddMembers(infoMembers.ToArray()); return(infoStaticCD); }
public static WebElementInfoViewModel CreateModelFromInfo(WebElementInfo elementInfo) { switch (elementInfo) { case WebPageInfo wp: return(new WebPageInfoViewModel(wp)); case WebElementReference re: return(new WebElementWithReferenceViewModel(re)); case FrameWebElementInfo wc: return(new WebElementWithReferenceViewModel(wc)); case CombinedWebElementInfo cw: return(new CombinedWebElementInfoViewModel(cw)); default: return(new WebElementInfoViewModel(elementInfo)); } }
private void LogElementPath(WebElementInfo elementInfo, ILogger log, string elementType = "Element") { log = log?.CreateChildLogger($"{elementType} location"); var search = elementInfo.GetWebSearch(); var stack = new Stack <WebSearchInfo>(); while (search != null) { stack.Push(search); search = search.ParentSearch; } var isFirst = true; while (stack.Count != 0) { search = stack.Pop(); log?.INFO($"{(isFirst ? "Locator" : "Followed by")}: {search.LocatorType} | {search.LocatorValue}"); isFirst = false; } }
public WebElementInfoViewModel(WebElementInfo webElementInfo = null) { _sourceWebElement = webElementInfo ?? new WebElementInfo(); Name = _sourceWebElement.Name; Description = _sourceWebElement.Description; ElementType = _sourceWebElement.ElementType; InnerKey = _sourceWebElement.InnerKey; IsKey = _sourceWebElement.IsKey; if (_sourceWebElement.Tags != null) { Tags = new ObservableCollection <string>(_sourceWebElement.Tags); } if (webElementInfo == null || !(webElementInfo.ElementType == WebElementTypes.Reference && (webElementInfo as WebElementReference).Locator == null)) { Locator = WebElementsViewModelsHelper.CreateLocatorModel(_sourceWebElement.Locator); } }
public void SelectInDropDown(WebElementInfo elementInfo, string value, ILogger log) { log = log?.CreateChildLogger($"Select option with value: {value} in: {elementInfo}"); if (!(elementInfo is DropDownElementInfo dropDown)) { throw new Exception($"Element: {elementInfo}" + $"Is not a DropDownElement"); } LogElementPath(elementInfo, log, "DropDown"); var input = dropDown.GetInputElement() ?? throw new Exception($"{elementInfo} doesn't have specified Input child element"); LogElementPath(elementInfo, log, "DropDown Input"); var option = dropDown.GetOptionElement() ?? throw new Exception($"{elementInfo} doesn't have specified Option child element"); option = option.GetCopyWithResolvedDynamicLocator(value); LogElementPath(elementInfo, log, "DropDown Option to select"); var selectLog = log?.CreateChildLogger("Select option"); var optionState = GetElementState(option, out var optionElement, selectLog); if (!optionState.HasFlag(WebElementState.Visible)) { selectLog?.INFO("As option is not visible. Try to expand DropDown"); Click(input, selectLog); } Click(option, selectLog); log?.INFO($"Option with value: {value} is selected"); }
public void SelectInRadioGroup(WebElementInfo elementInfo, string value, ILogger log) { log = log?.CreateChildLogger($"Select option with value: {value} in: {elementInfo}"); if (!(elementInfo is RadioGroupElementInfo radioGroup)) { throw new Exception($"Element: {elementInfo}" + $"Is not a RadioGroupElement"); } LogElementPath(elementInfo, log, "RadioGroup"); var option = radioGroup.GetOptionElement() ?? throw new Exception($"{elementInfo} doesn't have specified Option child element"); option = option.GetCopyWithResolvedDynamicLocator(value); LogElementPath(elementInfo, log, "RadioGroup Option to select"); Click(option, log); log?.INFO($"Option with value: {value} is selected"); }
public static WebContextInfo GenerateContext(int orderNumber, int elsCount) { var i = orderNumber; var wc = new WebContextInfo { Name = $"Context {i}", Description = $"Description for context {i}", Tags = new List <string> { $"tag{i}", "contextTag" }, Elements = new List <WebElementInfo>(), Locator = new WebLocatorInfo { LocatorValue = "." } }; for (int j = 1; j < elsCount; j++) { if (j != 2) { var c = new CombinedWebElementInfo { Name = $"Control {i}_{j}", Description = $"Description for control {i}_{j}", Tags = new List <string> { $"tag{j}", "controlTag" }, Elements = new List <WebElementInfo>(), Parent = wc, Locator = new WebLocatorInfo { LocatorValue = "./div[@id='control']", IsRelative = true } }; wc.Elements.Add(c); var dd = new DropDownElementInfo { Name = $"DropDown {i}_{j}", Description = $"Description for DropDown {i}_{j}", Tags = new List <string> { $"tag{j}", "controlTag" }, Parent = wc, Locator = new WebLocatorInfo { LocatorValue = "./div[@id='control']", IsRelative = true }, Elements = new List <WebElementInfo>() }; wc.Elements.Add(dd); dd.Elements.Add(new WebElementInfo { Name = $"DropDown {i}_{j} Input", Description = $"Description for DropDown {i}_{j} Input", Tags = new List <string> { $"tag{j}", "controlTag" }, Parent = wc, Locator = new WebLocatorInfo { LocatorValue = "./div[@id='control']", IsRelative = true }, InnerKey = DropDownElementInfo.Keys.Input }); dd.Elements.Add(new WebElementInfo { Name = $"DropDown {i}_{j} Option", Description = $"Description for DropDown {i}_{j} Option", Tags = new List <string> { $"tag{j}", "controlTag" }, Parent = wc, Locator = new WebLocatorInfo { LocatorValue = "./div[@id='control']", IsRelative = true }, InnerKey = DropDownElementInfo.Keys.Option }); var rg = new DropDownElementInfo { Name = $"RadioGroup {i}_{j}", Description = $"Description for RadioGroup {i}_{j}", Tags = new List <string> { $"tag{j}", "controlTag" }, Parent = wc, Locator = new WebLocatorInfo { LocatorValue = "./div[@id='control']", IsRelative = true }, Elements = new List <WebElementInfo>() }; wc.Elements.Add(rg); rg.Elements.Add(new WebElementInfo { Name = $"DropDown {i}_{j} Option", Description = $"Description for RadioGroup {i}_{j} Option", Tags = new List <string> { $"tag{j}", "controlTag" }, Parent = wc, Locator = new WebLocatorInfo { LocatorValue = "./div[@id='control']", IsRelative = true }, InnerKey = RadioGroupElementInfo.Keys.Option }); for (int k = 1; k < 5; k++) { var e = new WebElementInfo { Name = $"Element {i}_{j}_{k}", Description = $"Description for element {i}_{j}_{k}", Tags = new List <string> { $"tag{j}", "elementTag" }, Parent = c, Locator = new WebLocatorInfo { LocatorValue = "./input[@id='input']", IsRelative = true } }; c.Elements.Add(e); } } else { var e = new WebElementInfo { Name = $"Element {i}_{j}", Description = $"Description for element {i}_{j}", Tags = new List <string> { $"tag{j}", "elementTag" }, Parent = wc, IsKey = true, Locator = new WebLocatorInfo { LocatorValue = "./input[@id='input']", IsRelative = true } }; wc.Elements.Add(e); } } return(wc); }
public static SaKiWebElementException TimeoutDuring(string processDesc, int timeoutInSec, WebElementInfo elementInfo) => new SaKiWebElementException(nameof(TimeoutDuring), $"Timeout {timeoutInSec} reached during {processDesc}", elementInfo);
public SaKiWebElementException(string type, string message, WebElementInfo elementInfo, Exception innerException = null) : base($"WebElement.{type}", message, innerException) { ElementInfo = elementInfo; }
public static SaKiWebElementException ErrorDuring(string processDesc, WebElementInfo elementInfo, Exception exception) => new SaKiWebElementException(nameof(ErrorDuring), $"Error occureed during {processDesc}", elementInfo, exception);