Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 public static IEnumerable <AppiumWebElement> FindAllByClassName(string id, AppiumWebElement ele) => FindByAny(() => ele.FindElementsByClassName(id));
Пример #4
0
        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);
            }
        }