/// <summary>Applies Find Logic to DOM and locates an Element. If find logic does not locate an element or locates more than one returns false and sets /// <see cref="TryException"/> to exception that would be thrown /// </summary> /// <param name="ParentName">Name of parent this Find is from - null for DOM Root level</param> /// <param name="RootElement">Element to search from. If null, search from DOM level</param> /// <param name="FindLogic">Find logic to be applied to DOM</param> /// <param name="FriendlyName">Human readable name of element being located</param> /// <param name="element">Populated with element reference if found. Null if not found (or more than one element found).</param> /// <returns>True if element found or False if not found (or more than one element found)</returns> public bool TryFindElement(Element ParentElement, ObjectMappingDetails Mapping, bool AllowMultipleMatches, TimeSpan?TimeoutOverride, TimeSpan?PollOverride, bool WaitUntilStable, out Element element) { WebDriverWait webDriverWait = GetPollAndTimeout(elementFindTimings, TimeoutOverride, PollOverride); List <Element> clauseResults = new List <Element>(); Stopwatch timer = Stopwatch.StartNew(); Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Timeout - {0} Seconds", webDriverWait.Timeout.TotalSeconds); while (clauseResults.Count == 0) { clauseResults = (ParentElement == null) ? FindElements(Mapping) : FindElements(ParentElement, Mapping); if (clauseResults.Count == 0) { Thread.Sleep(webDriverWait.PollingInterval); } if ((timer.Elapsed >= webDriverWait.Timeout)) { break; } } timer.Stop(); if (clauseResults.Count > 1 && !AllowMultipleMatches) { Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Found {0} matching elements in {1} mS. Do not allow multiple matches.", clauseResults.Count.ToString(), timer.ElapsedMilliseconds.ToString()); TryException = new FindLogicReturnedMultipleElements(((ParentElement == null) ? "DOM Top Level" : (string.IsNullOrEmpty(ParentElement.MappingDetails.FriendlyName) ? ("Unknown Parent (" + ParentElement.MappingDetails.FindLogic + ")") : ParentElement.MappingDetails.FriendlyName)), Mapping, clauseResults.Count); element = null; return(false); } if (clauseResults.Count == 1 || (clauseResults.Count > 1 && AllowMultipleMatches)) { Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Found {0} matching elements in {1} mS.{2}", clauseResults.Count.ToString(), timer.ElapsedMilliseconds.ToString(), AllowMultipleMatches ? " Allow multiple matches so using first match." : string.Empty); if (WaitUntilStable && !clauseResults[0].IsPositionStable) { if (clauseResults[0].WaitForElementPositionStable()) { if (TryFindElement(ParentElement, Mapping, AllowMultipleMatches, TimeoutOverride, PollOverride, false, out element)) { return(true); } else { TryException = new Exception("Could not find element after waiting for position stable!", TryException); element = null; return(false); } } } element = clauseResults[0]; return(true); } else { Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Found no matching elements in {0} mS", timer.ElapsedMilliseconds.ToString()); TryException = new FindLogicReturnedNoElements(ParentElement?.MappingDetails?.FriendlyName ?? "No parent (searched from top level of DOM)", Mapping, webDriverWait.Timeout.TotalSeconds.ToString(), webDriverWait.PollingInterval.TotalMilliseconds.ToString()); element = null; return(false); } }
/// <summary>No elements could be found using given find logic</summary> /// <param name="ParentName">>Parent element</param> /// <param name="RawFindLogic">Find logic applied to parent</param> /// <param name="FriendlyName">Name of element we wanted</param> public FindLogicReturnedNoElements(Element parent, ObjectMappingDetails mappingDetails, string TimeoutInSeconds, string PollIntervalInMinilliseconds) : base(FindLogicReturnedNoElements.FormatMessage(parent?.MappingDetails?.FriendlyName ?? "Parent name cannot be got", mappingDetails?.FindLogicUsed ?? mappingDetails.FindLogic ?? "No Mapping logic!", mappingDetails?.FriendlyName ?? "Logic only. No friendly name set!", TimeoutInSeconds, PollIntervalInMinilliseconds)) { }
/// <summary>No elements could be found using given find logic</summary> /// <param name="ParentName">>Parent element</param> /// <param name="RawFindLogic">Find logic applied to parent</param> /// <param name="FriendlyName">Name of element we wanted</param> public FindLogicReturnedNoElements(string ParentName, string RawFindLogic, string FriendlyName, string TimeoutInSeconds, string PollIntervalInMinilliseconds) : base(FindLogicReturnedNoElements.FormatMessage(ParentName, RawFindLogic, FriendlyName, TimeoutInSeconds, PollIntervalInMinilliseconds)) { }