protected AppiumWebElement SearchWindowsElement(WindowsDriver <AppiumWindowsElement> desktopSession, AppiumWebElement parentElement, WindowsElementSearchSpec windowsElementSearchSpec, IList <string> log) { log.Clear(); var elements = new List <AppiumWebElement>(); if (desktopSession != null && !string.IsNullOrWhiteSpace(windowsElementSearchSpec.Name)) { elements = desktopSession.FindElementsByName(windowsElementSearchSpec.Name).Cast <AppiumWebElement>().ToList(); } else if (desktopSession != null && windowsElementSearchSpec.ClassNames.Any()) { windowsElementSearchSpec.ClassNames.ForEach(n => elements.AddRange(desktopSession.FindElementsByClassName(n))); } else if (!string.IsNullOrWhiteSpace(windowsElementSearchSpec.Name)) { elements = parentElement.FindElementsByName(windowsElementSearchSpec.Name).ToList(); } else if (windowsElementSearchSpec.ClassNames.Any()) { windowsElementSearchSpec.ClassNames.ForEach(n => elements.AddRange(parentElement.FindElementsByClassName(n))); } else { throw new ArgumentException($"Invalid {nameof(WindowsElementSearchSpec)}, name or class name is required"); } var reverseSearchSpecs = elements.Select(e => new WindowsElementSearchSpec(e)); log.Add(elements.Any() ? $"[{windowsElementSearchSpec}] applied to root element resulted in {elements.Count} elements: {string.Join(", ", reverseSearchSpecs)}" : $"[{windowsElementSearchSpec}] applied to root element did not yield any results"); foreach (var element in elements) { if (!DoesElementMatchSearchSpec(element, windowsElementSearchSpec, 0, log, "", out var elementOrMatchingChildElement)) { continue; } if (elementOrMatchingChildElement == null) { throw new Exception("Element matches search specification, but no element is returned"); } return(elementOrMatchingChildElement); } return(null); }
private static bool DoesElementMatchSearchSpec(AppiumWebElement element, WindowsElementSearchSpec windowsElementSearchSpec, int depth, ICollection <string> log, string parentElementIds, out AppiumWebElement elementOrMatchingChildElement) { if (parentElementIds.Contains(element.Id + ';')) { throw new Exception($"Element {element.Id} already is a parent element"); } parentElementIds += element.Id + ';'; elementOrMatchingChildElement = element; if (depth > 20) { throw new Exception($"Search depth exceeds {depth}"); } var reverseSearchSpec = new WindowsElementSearchSpec(element); log.Add($"Checking {windowsElementSearchSpec} against {reverseSearchSpec} at depth {depth}"); if (windowsElementSearchSpec.ClassNames.Any() && !windowsElementSearchSpec.ClassNames.Contains(element.GetClassName())) { log.Add($"Mismatch, class name is {element.GetClassName() ?? "empty"}"); return(false); } if (windowsElementSearchSpec.NameMustNotBeEmpty) { if (string.IsNullOrWhiteSpace(element.GetName())) { log.Add("Mismatch, name must not be empty"); return(false); } } if (!string.IsNullOrWhiteSpace(windowsElementSearchSpec.Name) && element.GetName() != windowsElementSearchSpec.Name) { log.Add($"Mismatch, name is {element.GetName() ?? "empty"}"); return(false); } if (!string.IsNullOrWhiteSpace(windowsElementSearchSpec.NameContains)) { var elementName = element.GetName(); if (elementName?.Contains(windowsElementSearchSpec.NameContains) != true) { log.Add($"Mismatch, name {element.GetName() ?? "empty"} does not contain {windowsElementSearchSpec.NameContains}"); return(false); } } foreach (var nameDoesNotContain in windowsElementSearchSpec.NameDoesNotContain.Where(n => element.GetName()?.Contains(n) == true)) { log.Add($"Mismatch, name {element.GetName()} contains {nameDoesNotContain}"); return(false); } log.Add($"Element is indeed {windowsElementSearchSpec}, checking child search specifications"); if (!windowsElementSearchSpec.WindowsChildElementSearchSpecs.All( spec => { var elements = new List <AppiumWebElement>(); if (!string.IsNullOrWhiteSpace(spec.Name)) { elements = element.FindElementsByName(spec.Name).ToList(); } else if (spec.ClassNames.Any()) { spec.ClassNames.ForEach(n => elements.AddRange(element.FindElementsByClassName(n))); } else { throw new ArgumentException($"Invalid {nameof(WindowsElementSearchSpec)}, name or class name is required"); } var reverseSearchSpecs = elements.Select(e => new WindowsElementSearchSpec(e)).ToList(); log.Add(elements.Any() ? $"[{spec}] applied to parent element {new WindowsElementSearchSpec(element)} resulted in {elements.Count} elements: {string.Join(", ", reverseSearchSpecs)}" : $"[{spec}] applied to parent element {new WindowsElementSearchSpec(element)} did not yield any results"); return(elements.Any(e => DoesElementMatchSearchSpec(e, spec, depth + 1, log, parentElementIds, out _))); })) { log.Add($"Child specifications not met for '{elementOrMatchingChildElement.GetName()}' of class '{elementOrMatchingChildElement.GetClassName()}' at depth {depth}"); return(false); } if (elementOrMatchingChildElement == null) { throw new Exception("Child element matches search specification, but no element is returned"); } log.Add($"Found '{elementOrMatchingChildElement.GetName()}' of class '{elementOrMatchingChildElement.GetClassName()}' at depth {depth}"); return(true); }
public static IEnumerable <AppiumWebElement> FindAllByClassName(string id, AppiumWebElement ele) => FindByAny(() => ele.FindElementsByClassName(id));
private AndroidElement GetNextPersonElement(AndroidAppAccess appAccess, Dictionary <string, string> personSimpleInfos, int noneNewCount) { AndroidElement listContainerElement = appAccess.GetElementByClassNameAndIndex("android.support.v7.widget.RecyclerView", 0, true); if (!appAccess.CheckElementContainText(listContainerElement, new string[] { "没有找到结果" }, true)) { ReadOnlyCollection <AndroidElement> listElements = appAccess.GetElementsByClassName(listContainerElement, "android.widget.FrameLayout", false); if (listElements != null) { for (int i = 0; i < listElements.Count; i++) { AppiumWebElement listRElement = listElements[i].FindElementByClassName("android.widget.RelativeLayout"); if (listRElement != null) { ReadOnlyCollection <AppiumWebElement> listLElements = listRElement.FindElementsByClassName("android.widget.LinearLayout"); if (listLElements != null && listLElements.Count > 0) { string elementText = this.GetListPersonElementText(appAccess, (AndroidElement)listLElements[0]); if (elementText == null) { //获取个人信息出错,可能是个人信息展示不完全造成的,那么翻页吧 break; } else if (elementText.Contains("领英会员")) { continue; } else if (!personSimpleInfos.ContainsKey(elementText)) { personSimpleInfos.Add(elementText, null); return((AndroidElement)listLElements[0]); } } } } if (noneNewCount < 3) { noneNewCount++; //滑动翻页 appAccess.Swipe(new Point(100, 700), new Point(100, 200), 500); Thread.Sleep(500); return(this.GetNextPersonElement(appAccess, personSimpleInfos, noneNewCount)); } else { //滑动翻页了3次,仍然没有新的,那么就认为真的没有新的了 return(null); } } else { //没有匹配的结果 return(null); } } else { //没有匹配的结果 return(null); } }