private void btnRecord_Click(object sender, RoutedEventArgs e)
        {
            SelectChangedSource = UiSelectChangedSource.SelectChangeFinished;

            if (IsRecording == false)
            {
                MouseKeyboardEventHandler.Init();

                btnRecord.Content            = "Pause";
                textBoxRecording.Text        = "Recording";
                gridTextRecording.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0, 0));

                IsRecording = true;
                AppInsights.LogEvent("Record");
            }
            else
            {
                IsRecording = false;

                MouseKeyboardEventHandler.UnInit();

                btnRecord.Content            = "Record";
                textBoxRecording.Text        = "";
                gridTextRecording.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));

                AddInspectUi(null); // remove last Inspect node
                AppInsights.LogEvent("Pause");
            }
        }
 protected override void OnStartup(StartupEventArgs e)
 {
     base.OnStartup(e);
     NativeMethods.SetProcessDPIAware();
     AppInsights.InitAppSights();
     NativeMethods.InitUiTreeWalk();
 }
        private void SetSessionRoot_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = treeUiPath.SelectedItem as UiTreeNode;

            if (selectedItem == null)
            {
                return;
            }

            int nNodeCount = 1;
            var pParent    = selectedItem.Parent;

            while (pParent != null)
            {
                nNodeCount++;
                pParent = pParent.Parent;
            }

            string sessionRootPath = HighlightPath(nNodeCount, false);
            var    textPath        = new TextRange(rtbXPath.Document.ContentStart, rtbXPath.Document.ContentEnd).Text;
            var    pos1            = rtbXPath.Document.ContentStart.GetPositionAtOffset(1, LogicalDirection.Forward);
            int    nPos2           = textPath.IndexOf(sessionRootPath) + sessionRootPath.Length;

            RootSessionPath = textPath.Substring(0, nPos2);
            var pos2      = rtbXPath.Document.ContentStart.GetPositionAtOffset(nPos2 + 2, LogicalDirection.Forward);
            var textRange = new TextRange(pos1, pos2);

            textRange.ClearAllProperties();
            textRange.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.LightGray);

            AppInsights.LogEvent("SetSessionRoot_Click");
        }
 protected override void OnExit(ExitEventArgs e)
 {
     NativeMethods.UnInitUiTreeWalk();
     AppInsights.Flush();
     base.OnExit(e);
     Environment.Exit(0);
 }
        private void Window_Closed(object sender, EventArgs e)
        {
            MouseKeyboardEventHandler.UnInit();
            MouseKeyboardHook.StopHook();
            s_mainWin = null;

            System.Windows.Interop.HwndSource.FromHwnd(s_windowHandle).RemoveHook(RunOnUiThread);

            AppInsights.LogEvent("Window_Closed");
        }
        private void MenuCopyFullPath(object sender, RoutedEventArgs e)
        {
            var tr = new TextRange(rtbXPath.Document.ContentStart, rtbXPath.Document.ContentEnd);

            if (tr != null)
            {
                Clipboard.SetText(tr.Text);
            }

            AppInsights.LogEvent("Copy full xpath");
        }
        private void btnWinAppDriverCode_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            lock (RecordedUiTask.s_lockRecordedUi)
            {
                if (RecordedUiTask.s_listRecordedUi.Count == 0)
                {
                    return;
                }

                // Stop recording
                if (btnRecord.IsChecked == true)
                {
                    btnRecord_Click(null, null);
                }

                string focusedLeftElementName = "";
                foreach (var uiTask in RecordedUiTask.s_listRecordedUi)
                {
                    if (uiTask.UiTaskName != EnumUiTaskName.Inspect)
                    {
                        if (uiTask.UiTaskName == EnumUiTaskName.LeftClick)
                        {
                            focusedLeftElementName = uiTask.VariableName;
                        }

                        sb.AppendLine(uiTask.GetPyCode(focusedLeftElementName));
                    }
                }
            }

            if (sb.Length > 0)
            {
                Clipboard.SetText(sb.ToString());

                this.Dispatcher.Invoke(new Action(() =>
                {
                    this.toolTipText.Text = "WinAppDriver client code copied to clipboard";
                    ((ToolTip)btnWinAppDriverCode.ToolTip).IsOpen = true;

                    timer = new System.Timers.Timer(2000)
                    {
                        Enabled = true, AutoReset = false
                    };
                    timer.Elapsed += ResetToolTip;
                    timer.Start();
                }), System.Windows.Threading.DispatcherPriority.ContextIdle);
            }

            AppInsights.LogEvent("Recorded UI Count", $"{RecordedUiTask.s_listRecordedUi.Count}");
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            s_windowHandle = new System.Windows.Interop.WindowInteropHelper(Application.Current.MainWindow).Handle;
            System.Windows.Interop.HwndSource.FromHwnd(s_windowHandle).AddHook(RunOnUiThread);

            s_mainWin = this;
            this.comboBoxRecordedUi.ItemsSource = RecordedUiTask.s_listRecordedUi;
            this.treeUiPath.ItemsSource         = UiTreeNode.s_uiTreeNodes;

            ConstVariables.InitVk2StringMap();

            AppInsights.LogEvent("Window_Loaded");
        }
        private void EditAttribute_Click(object sender, RoutedEventArgs e)
        {
            AppInsights.LogEvent("EditAttribute_Click");

            var uiTreeNode = treeUiPath.SelectedItem as UiTreeNode;

            if (uiTreeNode == null)
            {
                return;
            }

            RecordedUiTask leafUiTask = uiTreeNode.UiTask;

            if (leafUiTask == null)
            {
                if (treeUiPath.Items != null && treeUiPath.Items.Count > 0)
                {
                    var x = (TreeViewItem)treeUiPath.ItemContainerGenerator.ContainerFromItem(treeUiPath.Items[0]);
                    if (x != null)
                    {
                        TreeViewItem tvi = UiTreeNode2TreeViewItem(x, UiTreeNode.s_uiTreeNodes.First(), uiTreeNode);
                        if (tvi != null)
                        {
                            leafUiTask = GetExpandedLeafNode(tvi, uiTreeNode, selectedTreeViewItem);
                            if (leafUiTask == null)
                            {
                                leafUiTask           = GetExpandedLeafNode(tvi, uiTreeNode, null);
                                selectedTreeViewItem = leafUiTask;
                            }
                        }
                    }
                }
            }

            if (leafUiTask == null)
            {
                return;
            }

            string oldNodePath = uiTreeNode.NodePath;

            var winEditAttr = new WindowEditNodeAttribute(uiTreeNode);

            if (true == winEditAttr.ShowDialog())
            {
                var xpath = leafUiTask.GetXPath(false).Replace(oldNodePath, uiTreeNode.NodePath);
                var tr    = new TextRange(rtbXPath.Document.ContentStart, rtbXPath.Document.ContentEnd);
                tr.Text = leafUiTask.UpdateXPath(xpath);
            }
        }
        private void Highlight_Click(object sender, RoutedEventArgs e)
        {
            AppInsights.LogEvent("Highlight_Click");

            var selectedItem = treeUiPath.SelectedItem as UiTreeNode;

            if (selectedItem == null)
            {
                return;
            }

            RECT rect = new RECT();

            NativeMethods.HighlightCachedUI(selectedItem.RuntimeId, ref rect);
        }
        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            lock (RecordedUiTask.s_lockRecordedUi)
            {
                RecordedUiTask.s_listRecordedUi.Clear();
                UiTreeNode.s_uiTreeNodes.Clear();
            }

            this.comboBoxRecordedUi.Items.Refresh();
            treeUiPath.Items.Refresh();

            TextRange tr = new TextRange(rtbXPath.Document.ContentStart, rtbXPath.Document.ContentEnd);

            tr.Text            = "";
            textBoxPyCode.Text = "";
            RootSessionPath    = null;

            AppInsights.LogEvent("btnClear_Click");
        }
        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (comboBoxRecordedUi.Items == null ||
                comboBoxRecordedUi.Items.Count == 0 ||
                comboBoxRecordedUi.SelectedItem == null)
            {
                return;
            }

            var uiTask = (RecordedUiTask)comboBoxRecordedUi.SelectedItem;

            if (uiTask == null)
            {
                return;
            }

            DeleteRecordedUiTask(uiTask);

            AppInsights.LogEvent("btnDelete_Click");
        }
        private void MenuCopyPathWithoutSessionPath(object sender, RoutedEventArgs e)
        {
            var tr = new TextRange(rtbXPath.Document.ContentStart, rtbXPath.Document.ContentEnd);

            if (tr != null && RootSessionPath != null)
            {
                int nPos = tr.Text.IndexOf(RootSessionPath);
                if (nPos > -1)
                {
                    string xpath = "\"" + tr.Text.Substring(nPos + RootSessionPath.Length);
                    Clipboard.SetText(xpath);
                }
                else
                {
                    Clipboard.SetText(tr.Text);
                }
            }

            AppInsights.LogEvent("Copy relative xpath");
        }
        public static void AddKeyboardInputTask(ref string strBase64, bool bCapsLock, bool bNumLock, bool bScrollLock)
        {
            if (string.IsNullOrEmpty(strBase64))
            {
                AppInsights.LogException("AddKeyboardInputTask", "strBase64 is null");
                return;
            }

            var keyboardTaskDescription = GenerateCSCode.GetDecodedKeyboardInput(strBase64, bCapsLock, bNumLock, bScrollLock);

            StringBuilder sb = new StringBuilder();

            foreach (var strLine in keyboardTaskDescription)
            {
                sb.Append(GenerateXPath.XmlEncode(strLine));
            }

            RecordedUiTask lastRecordedUi = null;

            lock (RecordedUiTask.s_lockRecordedUi)
            {
                if (RecordedUiTask.s_listRecordedUi.Count > 0)
                {
                    lastRecordedUi = RecordedUiTask.s_listRecordedUi.Last();
                }
            }

            if (lastRecordedUi != null && lastRecordedUi.UiTaskName == EnumUiTaskName.KeyboardInput)
            {
                lastRecordedUi.AppendKeyboardInput(strBase64);
            }
            else
            {
                var keyboarTask = new RecordedUiTask(EnumUiTaskName.KeyboardInput, strBase64, bCapsLock, bScrollLock, bNumLock);
                MainWindow.AddRecordedUi(keyboarTask);
            }

            strBase64 = null;
        }
        static List <string> GetRootToLeafNodes(string strLeafToRoot)
        {
            if (string.IsNullOrEmpty(strLeafToRoot))
            {
                AppInsights.LogException("GetRootToLeafNodes", "strLeafToRoot is null");
                return(null);
            }

            List <string> listRet = new List <string>();
            string        patNode = "/[^\n]+\n";

            System.Text.RegularExpressions.Regex regNode = new System.Text.RegularExpressions.Regex(patNode, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            if (regNode != null && string.IsNullOrEmpty(strLeafToRoot) == false)
            {
                System.Text.RegularExpressions.Match matchNode = regNode.Match(strLeafToRoot);
                while (matchNode.Success)
                {
                    listRet.Insert(0, matchNode.Value.Substring(0, matchNode.Value.Length - 1));
                    matchNode = matchNode.NextMatch();
                }
            }

            return(listRet);
        }
Exemple #16
0
        private static void RecorderThread()
        {
            StringBuilder sb = new StringBuilder(NativeMethods.BUFFERSIZE);

            System.Drawing.Point pt = new System.Drawing.Point(0, 0);

            while (true)
            {
                bool bStartWalk = s_eventRecordNow.WaitOne(nDelayRecord);

                PublishKeyboardInput();

                if (s_eventQuitRecording.WaitOne(0))
                {
                    break;
                }

                NativeMethods.GetPhysicalCursorPos(out pt);
                int dist = Math.Abs(pt.X - ptUiWalking.X) + Math.Abs(pt.Y - ptUiWalking.Y);

                if (bStartWalk && MouseKeyboardHook.s_bPauseMouseKeyboard == false)
                {
                    // check if cursor has moved
                    if (dist > nMinDist)
                    {
                        NativeMethods.PostMessage(MainWindow.s_windowHandle, (int)MainWindow.UiThreadTask.Active, 0, 0);

                        ptUiWalking.X = pt.X;
                        ptUiWalking.Y = pt.Y;

                        var tick = Environment.TickCount;

                        NativeMethods.GetUiXPath(ptUiWalking.X, ptUiWalking.Y, sb, sb.Capacity);
                        AppInsights.LogMetric("GetUiXPathPerf", Environment.TickCount - tick);

                        if (MouseKeyboardHook.s_bPauseMouseKeyboard == true)
                        {
                            continue;
                        }

                        if (s_eventQuitRecording.WaitOne(0))
                        {
                            break;
                        }

                        string strXmlNode = sb.ToString();
                        if (!string.IsNullOrEmpty(strXmlNode))
                        {
                            int nHash = strXmlNode.GetHashCode();
                            if (nHash != s_nPathHash)
                            {
                                lock (s_lockUiPath)
                                {
                                    MouseKeyboardEventHandler.s_strXmlNodes = strXmlNode;

                                    s_nPathHash = nHash;
                                }

                                XmlNodePathRecorder.HandleUiEvent(ref s_strXmlNodes, EnumUiTaskName.Inspect, 0, 0);
                            }
                        }
                    }

                    s_eventRecordNow.Reset();
                }
            }
        }
 private void ComboBoxRecordedUi_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
 {
     AppInsights.LogEvent("ComboBoxRecordedUi_PreviewMouseLeftButtonDown");
 }
        public static void HandleUiEvent(ref string strXml, EnumUiTaskName uiTaskName, int deltaX, int deltaY)
        {
            List <string> nodesRootToLeaf = null;

            if (uiTaskName == EnumUiTaskName.Inspect)
            {
                nodesRootToLeaf = GetRootToLeafNodes(strXml);
                if (nodesRootToLeaf != null && nodesRootToLeaf.Count > 0)
                {
                    MainWindow.AddInspectUi(new RecordedUiTask(nodesRootToLeaf, uiTaskName));
                }
                return;
            }

            if (uiTaskName != EnumUiTaskName.KeyboardInput)
            {
                nodesRootToLeaf = GetRootToLeafNodes(strXml);
                strXml          = null;
            }

            RecordedUiTask lastRecordedUi = null;

            lock (RecordedUiTask.s_lockRecordedUi)
            {
                if (RecordedUiTask.s_listRecordedUi.Count > 0)
                {
                    lastRecordedUi = RecordedUiTask.s_listRecordedUi.Last();
                }
            }

            bool bAddNewTask = true;

            // Completing last UI
            if (uiTaskName == EnumUiTaskName.LeftDblClick && lastRecordedUi != null)
            {
                lastRecordedUi.ChangeClickToDoubleClick();
                bAddNewTask = false;
            }
            else if (uiTaskName == EnumUiTaskName.MouseWheel)
            {
                if (lastRecordedUi == null || lastRecordedUi.UiTaskName != EnumUiTaskName.MouseWheel)
                {
                    if (nodesRootToLeaf != null && nodesRootToLeaf.Count > 0)
                    {
                        lastRecordedUi = new RecordedUiTask(nodesRootToLeaf, uiTaskName);
                        MainWindow.AddRecordedUi(lastRecordedUi);
                    }
                }

                if (lastRecordedUi != null && lastRecordedUi.UiTaskName == EnumUiTaskName.MouseWheel)
                {
                    lastRecordedUi.UpdateWheelData(deltaX);
                }

                bAddNewTask = false;
            }

            if (bAddNewTask)
            {
                if (nodesRootToLeaf != null && nodesRootToLeaf.Count > 0)
                {
                    MainWindow.AddRecordedUi(new RecordedUiTask(nodesRootToLeaf, uiTaskName));
                }
            }
            else if (lastRecordedUi != null)
            {
                //MouseWheel, DoubleClick
                MainWindow.UpdateLastUi(lastRecordedUi);
            }

            NativeMethods.PostMessage(MainWindow.s_windowHandle, (int)MainWindow.UiThreadTask.ActionAdded, 0, 0);

            AppInsights.LogEvent("HandleUiEvent", uiTaskName.ToString());
        }
        private void treeUiPath_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            if (SelectChangedSource == UiSelectChangedSource.TreeViewItemSelected)
            {
                return;
            }

            var selectedItem = treeUiPath.SelectedItem as UiTreeNode;

            if (selectedItem == null)
            {
                return;
            }

            if (SelectChangedSource != UiSelectChangedSource.ComboBoxSelected)
            {
                SelectChangedSource = UiSelectChangedSource.TreeViewItemSelected;
            }

            RecordedUiTask leafUiTask = selectedItem.UiTask;

            if (leafUiTask == null)
            {
                if (treeUiPath.Items != null && treeUiPath.Items.Count > 0)
                {
                    var x = (TreeViewItem)treeUiPath.ItemContainerGenerator.ContainerFromItem(treeUiPath.Items[0]);
                    if (x != null)
                    {
                        TreeViewItem tvi = UiTreeNode2TreeViewItem(x, UiTreeNode.s_uiTreeNodes.First(), selectedItem);
                        if (tvi != null)
                        {
                            // sync xpath with last selected tree view leaf if a parent node is selected
                            // and the selected parent has more than 1 expanded leaf children
                            leafUiTask = GetExpandedLeafNode(tvi, selectedItem, selectedTreeViewItem);
                            {
                                leafUiTask           = GetExpandedLeafNode(tvi, selectedItem, null);
                                selectedTreeViewItem = leafUiTask;
                            }
                        }
                    }
                }
            }

            if (leafUiTask == null)
            {
                if (SelectChangedSource != UiSelectChangedSource.ComboBoxSelected)
                {
                    SelectChangedSource = UiSelectChangedSource.SelectChangeFinished;
                }

                return;
            }
            else
            {
                selectedTreeViewItem = leafUiTask;
            }

            if (leafUiTask != comboBoxRecordedUi.SelectedItem)
            {
                comboBoxRecordedUi.SelectedItem = leafUiTask;
            }

            int childCount = selectedItem.Items.Count;

            if (childCount > 0)
            {
                treeUiPath.ContextMenu = treeUiPath.Resources["UiNode"] as System.Windows.Controls.ContextMenu;
            }
            else
            {
                treeUiPath.ContextMenu = treeUiPath.Resources["LeafNode"] as System.Windows.Controls.ContextMenu;
            }

            int nNodeCount = 1;
            var pParent    = selectedItem.Parent;

            while (pParent != null)
            {
                nNodeCount++;
                pParent = pParent.Parent;
            }

            HighlightPath(nNodeCount, true);

            if (SelectChangedSource != UiSelectChangedSource.ComboBoxSelected)
            {
                SelectChangedSource = UiSelectChangedSource.SelectChangeFinished;
            }

            AppInsights.LogEvent("treeUiPath_SelectedItemChanged");
        }