示例#1
0
            public void Apply(Func <string, string> environmentVariableLookup = null, WindowsAutomationMapping.Map parentMap = null)
            {
                ParentMap = parentMap;

                var mapDesc = WindowsAutomationMappingExtensions.GetMapDescription(this);

                BreezyTrace.Log(TraceEventType.Verbose, String.Format("Searching for element for map {0}...", mapDesc));

                BindElement(environmentVariableLookup);

                if (Element == null)
                {
                    BreezyTrace.Log(TraceEventType.Verbose, String.Format("Element for map {0} could not be found or its conditions were not met. Terminating this search chain.", mapDesc));
                    return;
                }

                BreezyTrace.Log(TraceEventType.Verbose, String.Format("Found element. {0}.", WindowsAutomationMappingExtensions.GetElementDescription(this)));

                var element = Element as AutomationElement;

                ApplyInputs(environmentVariableLookup);

                //recurse through any child maps
                foreach (var childMap in Maps)
                {
                    childMap.Apply(environmentVariableLookup, this);
                }
            }
示例#2
0
            private string EnvironmentVariableSubstitution(string value, Func <string, string> environmentVariableLookup)
            {
                if (environmentVariableLookup == null || !value.StartsWith("$"))
                {
                    return(value);
                }

                //we should look this up but first...
                //strip the $ and any non-alphanums
                var regex = new Regex(@"\${1}(\w*|\d*)");

                if (!regex.IsMatch(value))
                {
                    return(value);
                }

                var property = regex.Match(value).Groups[1].Value;

                var newValue = value;

                try
                {
                    newValue = environmentVariableLookup(property);
                }
                catch (Exception ex)
                {
                    BreezyTrace.Log(TraceEventType.Error, String.Format("Environment variable lookup failed for {0}", value), ex);
                    return(value);
                }

                //just return the value if we don't get anything
                if (String.IsNullOrEmpty(newValue))
                {
                    return(value);
                }

                //replace whatever may have come after something like "\subfolder\stuff"
                value = value.Replace("$" + property, newValue);

                return(value);
            }
示例#3
0
            private static AutomationElement FindFirstInAncestors(Map map, Condition condition)
            {
                if (map.ParentMap == null || map.ParentMap.Element == null)
                {
                    BreezyTrace.Log(TraceEventType.Verbose, String.Format("Terminated automation search in ancestor elements at the root (or the map is missing a parent reference)."));
                    return(null);
                }

                var parentMap     = map.ParentMap;
                var parentElement = parentMap.Element as AutomationElement;

                var e = parentElement.FindFirst(TreeScope.Element, condition);

                //keep going up until we find the element or terminate at the root
                if (e == null)
                {
                    e = FindFirstInAncestors(parentMap, condition);
                }

                return(e);
            }
示例#4
0
            private void ApplyInputs(Func <string, string> environmentVariableLookup = null)
            {
                foreach (var input in Inputs)
                {
                    var    element = Element as AutomationElement;
                    object pattern = null;

                    try
                    {
                        switch (input.Type)
                        {
                        case WindowsAutomationMapping.Map.Input.InputTypes.Direction:
                            var hwnd = NativeWindowsHandle;
                            BreezyTrace.Log(TraceEventType.Verbose, String.Format("Sending direction key: {0} to hwnd: {1}", input.Value, hwnd));
                            var item = new EnumWindowsItem(hwnd, WindowsAutomation.TimeDilation);
                            switch (input.Value)
                            {
                            case "Up":
                                item.SendUp();
                                break;

                            case "Down":
                                item.SendDown();
                                break;

                            case "Left":
                                item.SendLeft();
                                break;

                            case "Right":
                                item.SendRight();
                                break;

                            default:
                                break;
                            }
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Esc:
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Invoke:
                            if (element.TryGetCurrentPattern(InvokePattern.Pattern, out pattern))
                            {
                                (pattern as InvokePattern).Invoke();
                            }
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.ExpandCollapse:
                            if (element.TryGetCurrentPattern(ExpandCollapsePattern.Pattern, out pattern))
                            {
                                element.SetFocus();
                                var expandCollapse = pattern as ExpandCollapsePattern;
                                if (
                                    (expandCollapse.Current.ExpandCollapseState.HasFlag(ExpandCollapseState.Collapsed) || expandCollapse.Current.ExpandCollapseState.HasFlag(ExpandCollapseState.PartiallyExpanded)) &&
                                    input.Value == "Expand"
                                    )
                                {
                                    expandCollapse.Expand();
                                }
                                else if (input.Value == "Collapse")
                                {
                                    expandCollapse.Collapse();
                                }
                            }
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.SendKey:
                            hwnd = NativeWindowsHandle;
                            item = new EnumWindowsItem(hwnd, WindowsAutomation.TimeDilation);
                            var b = Convert.ToByte(input.Value);
                            item.SendKey(b);
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Letter:
                            //hwnd = NativeWindowsHandle;
                            //item = new EnumWindowsItem(hwnd, WindowsAutomation.TimeDilation);
                            //item.SendKey(input.Value);
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Number:
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Return:
                            hwnd = NativeWindowsHandle;
                            BreezyTrace.Log(TraceEventType.Verbose, String.Format("Sending Enter key: {0} to hwnd: {1}", input.Value, hwnd));
                            item = new EnumWindowsItem(hwnd, WindowsAutomation.TimeDilation);
                            item.SendReturn();
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.SelectionItem:
                            if (element.TryGetCurrentPattern(SelectionItemPattern.Pattern, out pattern))
                            {
                                (pattern as SelectionItemPattern).Select();
                            }
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Selection:
                            //doesn't do anything
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Tab:
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Text:
                            //check to see if we're referencing an WF services environment variable (e.g. TempDir) and if so, get that value
                            var val = EnvironmentVariableSubstitution(input.Value, environmentVariableLookup);

                            if (element.TryGetCurrentPattern(ValuePattern.Pattern, out pattern))
                            {
                                (pattern as ValuePattern).SetValue(val);
                            }
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Toggle:
                            if (element.TryGetCurrentPattern(TogglePattern.Pattern, out pattern))
                            {
                                var toggle = pattern as TogglePattern;
                                if (
                                    (toggle.Current.ToggleState == ToggleState.Off && input.Value == "On") ||
                                    (toggle.Current.ToggleState == ToggleState.On && input.Value == "Off")
                                    )
                                {
                                    toggle.Toggle();
                                }
                            }
                            break;

                        case WindowsAutomationMapping.Map.Input.InputTypes.Wait:
                            var delay = Decimal.ToInt32(Convert.ToInt32(input.Value) * WindowsAutomation.TimeDilation);
                            Thread.Sleep(delay);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        BreezyTrace.Log(TraceEventType.Information, "Input failed for this mapping.", ex);
                    }

                    BreezyTrace.Log(TraceEventType.Verbose, String.Format("Successfully applied input type: {0}", input.Type));
                }
            }
示例#5
0
            private void BindElement(Func <string, string> environmentVariableLookup = null)
            {
                //first, build the condition
                Condition condition = null;

                if (!String.IsNullOrEmpty(Tag))
                {
                    _logger.(TraceEventType.Verbose, this.Tag);
                }

                var conditions = new List <PropertyCondition>();

                if (!String.IsNullOrEmpty(ClassName))
                {
                    conditions.Add(new PropertyCondition(AutomationElement.ClassNameProperty, ClassName));
                }
                if (!String.IsNullOrEmpty(Name))
                {
                    conditions.Add(new PropertyCondition(AutomationElement.NameProperty, EnvironmentVariableSubstitution(Name, environmentVariableLookup)));
                }
                if (!String.IsNullOrEmpty(AutomationId))
                {
                    conditions.Add(new PropertyCondition(AutomationElement.AutomationIdProperty, AutomationId));
                }
                if (!String.IsNullOrEmpty(ControlTypeLocalizedControlType))
                {
                    conditions.Add(new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, ControlTypeLocalizedControlType));
                }

                //if we have more than one condition
                if (conditions.Count == 0)
                {
                    throw new ArgumentNullException("ClassName, Name, ControlType and AutomationId cannot all be null.");
                }
                else if (conditions.Count > 1)
                {
                    condition = new AndCondition(conditions.ToArray());
                }
                //otherwise just create the condition direcly
                else
                {
                    condition = conditions[0];
                }

                //.NET doesn't support TreeScope.Ancestors natively, so we'll implement by searching back up the chain
                AutomationElement element = null;

                if (this.Scope == TreeScope.Ancestors)
                {
                    element = FindFirstInAncestors(this, condition);
                }
                else
                {
                    var parentElement = ParentMap == null ? AutomationElement.RootElement : ParentMap.Element as AutomationElement;
                    element = parentElement.FindFirst(this.Scope, condition);
                }

                if (element != null && CustomConditions.Count > 0)
                {
                    //just assume AND operation for all custom conditions for now
                    foreach (var cond in CustomConditions)
                    {
                        if (cond.Type == CustomCondition.ConditionTypes.MapExists)
                        {
                            cond.Map.ParentMap = ParentMap;
                            cond.Map.BindElement(environmentVariableLookup);
                            if (cond.Map.Element == null)
                            {
                                BreezyTrace.Log(TraceEventType.Information, "Custom 'MapExists' condition defined but was not satisfied. No additional action taken.");
                                break;
                            }
                            else
                            {
                                BreezyTrace.Log(TraceEventType.Information, "Custom 'MapExists' condition returned 'true'.");

                                switch (cond.Action)
                                {
                                case CustomCondition.Actions.Skipover:
                                    BreezyTrace.Log(TraceEventType.Information, "Skipping current element.");
                                    element = null;
                                    break;

                                case CustomCondition.Actions.Continue:
                                    BreezyTrace.Log(TraceEventType.Information, "Continuing to process current element.");
                                    break;

                                case CustomCondition.Actions.Abort:
                                    BreezyTrace.Log(TraceEventType.Information, "Aborting current element (aborting the processing chain).");
                                    element = null;
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }
                }

                this.Element = element;
            }