zoukankan      html  css  js  c++  java
  • UI Testing via windows API

    Using C# language to call windows API, in following codes we mainly used methods located in user32.dll , so we firstly should create a method in C# that will mapping the corresponding method in user32.dll. in these codes, you will see:

    1.  to get a window handler

    2. to get a control in the window

    3.  to get the control text

    4. to click a mouse left button in the current position

    5.  to invoke a button just same as user click on it

        public class UITest
        {
            /// <summary>
            
    /// To Get a window handler by window caption(Text)
            
    /// </summary>
            
    /// <param name="caption">window's catpoin</param>
            
    /// <param name="delay">set delay time ; which may not find window because of window not completely loaded</param>
            
    /// <param name="maxTries">maximum tries times</param>
            
    /// <returns>a window handler</returns>
            public static IntPtr FindTopLevelWindow(string caption, int delay, int maxTries)
            {
                IntPtr mwh = IntPtr.Zero;
                bool formFound = false;
                int attempts = 0;

                do
                {
                    mwh = FindWindow(null, caption);
                    if (mwh == IntPtr.Zero)
                    {
                        Thread.Sleep(delay);
                        attempts++;
                    }
                    else
                    {
                        formFound = true;
                    }
                } while (attempts < maxTries && !formFound);

                return mwh;
            }

            /// <summary>
            
    /// To get control handler by control caption(Text)
            
    /// </summary>
            
    /// <param name="hwndParent"></param>
            
    /// <param name="caption"></param>
            
    /// <returns>a control handler</returns>
            public static IntPtr FindControlByCaption(IntPtr hwndParent, string caption)
            {
                if (hwndParent == IntPtr.Zero)
                    return IntPtr.Zero;
                IntPtr result = IntPtr.Zero;
                result = FindWindowEx(hwndParent, IntPtr.Zero, null, caption);
                return result;
            }

            /// <summary>
            
    /// To Get a control by Index, you can calculate it's index using Spy++
            
    /// </summary>
            
    /// <param name="hwndParent">parent handler</param>
            
    /// <param name="index">index in parent handler</param>
            
    /// <returns>a control hander</returns>
            public static IntPtr FindControlByIndex(IntPtr hwndParent, int index)
            {
                if (hwndParent == IntPtr.Zero)
                    return IntPtr.Zero;
                if (index == 0)
                    return hwndParent;
                else
                {
                    int ct = 0;
                    IntPtr result = IntPtr.Zero;
                    do
                    {
                        result = FindWindowEx(hwndParent, result, nullnull);
                        if (result != IntPtr.Zero)
                            ct++;
                    }
                    while (ct < index && result != IntPtr.Zero);

                    return result;
                }
            }

            /// <summary>
            
    /// To click on a button or something like that
            
    /// </summary>
            
    /// <param name="hControl">control to click on</param>
            public static void ClickOn(IntPtr hControl)
            {
                if (hControl == IntPtr.Zero)
                    return;
                uint WM_LBUTTONDOWN = 0x0201;
                uint WM_LBUTTONUP = 0x0202;
                PostMessage1(hControl, WM_LBUTTONDOWN, 00);
                PostMessage1(hControl, WM_LBUTTONUP, 00);
            }

            /// <summary>
            
    /// Close the window
            
    /// </summary>
            
    /// <param name="hControl"></param>
            public static void CloseWindow(IntPtr hControl)
            {
                if (hControl == IntPtr.Zero)
                    return;
                uint WM_CLOSE = 0x0010;
                PostMessage1(hControl, WM_CLOSE, 00);
            }
            /// <summary>
            
    /// send one char to an editable control
            
    /// </summary>
            
    /// <param name="hControl">an editable control</param>
            
    /// <param name="c">one char</param>
            public static void SendChar(IntPtr hControl, char c)
            {
                if (hControl == IntPtr.Zero)
                    return;
                uint WM_CHAE = 0x0102;
                SendMessage1(hControl, WM_CHAE, c, 0);
            }

            /// <summary>
            
    /// Fill in a string in an Editable control like textbox
            
    /// </summary>
            
    /// <param name="hControl">an editable control</param>
            
    /// <param name="s">a string</param>
            public static void SendString(IntPtr hControl, string s)
            {
                foreach (char c in s)
                {
                    SendChar(hControl, c);
                }
            }

            /// <summary>
            
    /// To get the display text of control
            
    /// </summary>
            
    /// <param name="hControl">a control handler</param>
            
    /// <returns>text string</returns>
            public static string GetControlText(IntPtr hControl)
            {
                if (hControl == IntPtr.Zero)
                    return "Control Not Find!";
                uint WM_GETTEXT = 0x000D;
                uint WM_GETTEXTLENGTH = 0x000E;
                int textLength = 0;
                string result = null;
                textLength = SendMessage5(hControl, WM_GETTEXTLENGTH, 00);
                if (textLength == 0)
                    return "Control Text is empty";
                //if we use textLength as wParam, we will get the length of the older text for this control
                byte[] buffer = new byte[256];
                int numFetched = SendMessage3(hControl, WM_GETTEXT, 256, buffer);
                result = System.Text.Encoding.Unicode.GetString(buffer);
                if (result != null)
                    return result;
                else
                    return "Failed to Get Text";
            }

            /// <summary>
            
    /// To check if the specified text was contained in this list box
            
    /// </summary>
            
    /// <param name="hControl">list box handler</param>
            
    /// <param name="itemText"></param>
            
    /// <returns>return true if text was contained</returns>
            public static bool IsListBoxContainItem(IntPtr hControl, string itemText)
            {
                if (hControl == IntPtr.Zero)
                    return false;
                uint LB_FINDSTRING = 0x018F;
                bool isFound = false;
                int result = -1;
                result = SendMessage4(hControl, LB_FINDSTRING, -1, itemText);
                if (result >= 0)
                    isFound = true;
                else
                    isFound = false;
                return isFound;

            }

            //Menu
            public static void SelectMenu(IntPtr hwForm, int menuID)
            {
                uint WM_COMMAND = 0x0111;
                SendMessage2(hwForm, WM_COMMAND, menuID, IntPtr.Zero);
            }

            //P/Invoke
            [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

            //hwndChildAfter default is IntPtr.Zero(Find from all controls)
            [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAter, string lpszClass, string lpszWindow);

            //used for sending command "WM_CHAR"
            [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
            static extern void SendMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);

            //Used for sending command "WM_COMMAND"
            [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
            static extern void SendMessage2(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);

            //Used for sending command "WM_LBUTTONDOWN" and "WM_LBUTTONUP"
            [DllImport("user32.dll", EntryPoint = "PostMessage", CharSet = CharSet.Auto)]
            static extern void PostMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);

            //Used for sending command "WM_GETTEXT"
            [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
            static extern int SendMessage3(IntPtr hWndControl, uint Msg, int wParam, byte[] lParam);

            //Used for sending command "LB_FINDSTRING"
            [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
            static extern int SendMessage4(IntPtr hWnd, uint Msg, int wParam, string lParam);

            //Used for sending command "WM_GETTEXTLENGTH"
            [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
            static extern int SendMessage5(IntPtr hWnd, uint Msg, int wParam, int lParam);

            [DllImport("user32.dll", EntryPoint = "GetMenu", CharSet = CharSet.Auto)]
            public static extern IntPtr GetMenu(IntPtr hWnd);

            [DllImport("user32.dll", EntryPoint = "GetSubMenu", CharSet = CharSet.Auto)]
            public static extern IntPtr GetSubMenu(IntPtr hWnd, int nPos);

            [DllImport("user32.dll", EntryPoint = "GetMenuItemID", CharSet = CharSet.Auto)]
            public static extern int GetMenuItemID(IntPtr hMenu, int nPos);



            //Test used in mouse_event
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            internal static extern IntPtr GetMessageExtraInfo();

            [DllImport("user32.dll")]
            internal static extern bool GetCursorPos(ref Point lpPoint);

            [DllImport("user32.dll")]
            internal static extern bool SetCursorPos(int X, int Y);

            [DllImport("user32.dll", EntryPoint = "mouse_event", CharSet = CharSet.Auto)]
            static extern void mouse_event(uint command, int x, int y, int dwdata, IntPtr dwExtraInfo);

            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern uint RegisterWindowMessage(string lpString);

            [DllImport("oleacc.dll", PreserveSig = false)]
            [return: MarshalAs(UnmanagedType.Interface)]
            public static extern object ObjectFromLresult(UIntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam);


            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);

            public enum SendMessageTimeoutFlags :
            uint
            {
                SMTO_NORMAL = 0x0000,
                SMTO_BLOCK = 0x0001,
                SMTO_ABORTIFHUNG = 0x0002,
                SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
            }


            /// <summary>
            
    /// Click left button on the Point(X, Y)
            
    /// </summary>
            
    /// <param name="x"></param>
            
    /// <param name="y"></param>
            public static void ClickOnPosition(int x, int y)
            {
                uint MOUSEEVENTF_LEFTDOWN = 0x0002;
                uint MOUSEEVENTF_LEFTUP = 0x0004;
                mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, GetMessageExtraInfo());
                mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, GetMessageExtraInfo());
            }

            /// <summary>
            
    /// Move Cursor
            
    /// </summary>
            
    /// <param name="x">X direction Increment</param>
            
    /// <param name="y">Y direction Increment</param>
            public static void MoveCursor(int x, int y)
            {
                uint MOUSEEVENTF_MOVE = 0x0001;
                mouse_event(MOUSEEVENTF_MOVE, x, y, 0, GetMessageExtraInfo());

            }

            /// <summary>
            
    /// Click on Current cursor position
            
    /// </summary>
            public static void ClickOnCurrentPosition()
            {
                try
                {
                    System.Drawing.Point defPnt = new System.Drawing.Point();
                    GetCursorPos(ref defPnt);

                    ClickOnPosition(defPnt.X, defPnt.Y);
                    Thread.Sleep(1000);
                }
                catch { }
            }
        }
  • 相关阅读:
    解决:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure(真实有效)
    数据库连接池Druid的介绍,配置分析对比总结
    浅谈mybatis如何半自动化解耦和ORM实现
    IntelliJ Idea14 创建Maven多模块项目,多继承,热部署配置总结(三)
    IntelliJ Idea14 创建Maven多模块项目,多继承,热部署配置总结(二)
    IntelliJ Idea14 创建Maven多模块项目,多继承,热部署配置总结(一)
    IntelliJ IDEA 创建Spring+SpringMVC+mybatis+maven项目
    跨站点请求伪造(CSRF)总结和防御
    移动端网站开发要点-meta设置
    数组去重
  • 原文地址:https://www.cnblogs.com/qixue/p/2143944.html
Copyright © 2011-2022 走看看