void RunTest(AccessibilityTest test)
        {
            using (RegistryHelper reg = new RegistryHelper())
            {
                reg.BackupRegistry();
                using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
                {
                    using (WinEventSystem sys = app.AttachWinEventSystem(this))
                    {
                        using (ViewportArea area = new ViewportArea(app))
                        {
                            Globals.WaitForTimeout(); // wait for everything to settle with winevents
                            IntPtr hConsole = app.GetStdOutHandle();

                            // Prep structures to hold cursor and size of buffer.
                            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                            sbiex.cbSize = (uint)Marshal.SizeOf(sbiex);

                            // this is where we will hold our expected messages
                            Queue <EventData> expected = new Queue <EventData>();

                            NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Get initial console data.");
                            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal = sbiex; // keep a copy of the original data for later.

                            // Run the test
                            test(app, area, hConsole, sbiex, expected, sbiexOriginal);
                        }
                    }
                }
            }
        }
Example #2
0
 public void VerifyCtrlHCmd()
 {
     using (RegistryHelper reg = new RegistryHelper())
     {
         reg.BackupRegistry();
         using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
         {
             using (ViewportArea area = new ViewportArea(app))
             {
                 string testText = "1234blah5678";
                 IntPtr hConsole = app.GetStdOutHandle();
                 Verify.IsNotNull(hConsole, "Ensure the handle is valid.");
                 // get cursor location
                 WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenBufferInfo = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                 WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref screenBufferInfo);
                 // send some text and a ^H to remove the last character
                 app.UIRoot.SendKeys(testText + Keys.Control + "h" + Keys.Control);
                 Globals.WaitForTimeout();
                 // test that we're missing the last character of testText on the line
                 Rectangle            rect = new Rectangle(0, 0, 200, 20);
                 IEnumerable <string> text = area.GetLinesInRectangle(hConsole, rect);
                 bool foundCtrlH           = false;
                 foreach (string line in text)
                 {
                     if (line.Contains(testText.Substring(0, testText.Length - 1)) && !line.Contains(testText))
                     {
                         foundCtrlH = true;
                         break;
                     }
                 }
                 Verify.IsTrue(foundCtrlH);
             }
         }
     }
 }
        public void CanGetDocumentRangeText()
        {
            using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
            {
                // get the text from uia api
                AutomationElement textAreaUiaElement = GetTextAreaUiaElement(app);
                TextPattern       textPattern        = textAreaUiaElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
                TextPatternRange  documentRange      = textPattern.DocumentRange;
                string            allText            = documentRange.GetText(-1);
                // get text from console api
                IntPtr hConsole = app.GetStdOutHandle();
                using (ViewportArea area = new ViewportArea(app))
                {
                    WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenInfo = app.GetScreenBufferInfo();
                    Rectangle            rect         = new Rectangle(0, 0, screenInfo.dwSize.X, screenInfo.dwSize.Y);
                    IEnumerable <string> viewportText = area.GetLinesInRectangle(hConsole, rect);

                    // the uia api does not return spaces beyond the last
                    // non -whitespace character so we need to trim those from
                    // the viewportText. The uia api also inserts \r\n to indicate
                    // a new linen so we need to add those back in after trimming.
                    string consoleText = "";
                    for (int i = 0; i < viewportText.Count(); ++i)
                    {
                        consoleText += viewportText.ElementAt(i).Trim() + "\r\n";
                    }
                    consoleText = consoleText.Trim();
                    allText     = allText.Trim();
                    // compare
                    Verify.IsTrue(consoleText.Equals(allText));
                }
            }
        }
        public void CanGetVisibleRange()
        {
            using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
            {
                // get the ranges from uia api
                AutomationElement  textAreaUiaElement = GetTextAreaUiaElement(app);
                TextPattern        textPattern        = textAreaUiaElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
                TextPatternRange[] ranges             = textPattern.GetVisibleRanges();

                // get the ranges from the console api
                WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenInfo = app.GetScreenBufferInfo();
                int viewportHeight = screenInfo.srWindow.Bottom - screenInfo.srWindow.Top + 1;

                // we should have one range per line in the viewport
                Verify.AreEqual(ranges.GetLength(0), viewportHeight);

                // each line should have the same text
                ViewportArea viewport = new ViewportArea(app);
                IntPtr       hConsole = app.GetStdOutHandle();
                for (int i = 0; i < viewportHeight; ++i)
                {
                    Rectangle            rect = new Rectangle(0, i, screenInfo.dwSize.X, 1);
                    IEnumerable <string> text = viewport.GetLinesInRectangle(hConsole, rect);
                    Verify.AreEqual(text.ElementAt(0).Trim(), ranges[i].GetText(-1).Trim());
                }
            }
        }
Example #5
0
 public void VerifyCtrlZCmd()
 {
     using (RegistryHelper reg = new RegistryHelper())
     {
         reg.BackupRegistry();
         using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
         {
             using (ViewportArea area = new ViewportArea(app))
             {
                 IntPtr hConsole = app.GetStdOutHandle();
                 Verify.IsNotNull(hConsole, "Ensure the handle is valid.");
                 // get cursor location
                 WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenBufferInfo = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                 WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref screenBufferInfo);
                 // send ^Z
                 app.UIRoot.SendKeys(Keys.Control + "z" + Keys.Control);
                 Globals.WaitForTimeout();
                 // test that "^Z" exists on the screen
                 Rectangle            rect = new Rectangle(0, 0, 200, 20);
                 IEnumerable <string> text = area.GetLinesInRectangle(hConsole, rect);
                 bool foundCtrlZ           = false;
                 foreach (string line in text)
                 {
                     if (line.Contains("^Z"))
                     {
                         foundCtrlZ = true;
                         break;
                     }
                 }
                 Verify.IsTrue(foundCtrlZ);
             }
         }
     }
 }
Example #6
0
 public WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX GetScreenBufferInfo(IntPtr hConsole)
 {
     WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
     sbiex.cbSize = (uint)Marshal.SizeOf(sbiex);
     NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Get screen buffer info for cursor position.");
     return(sbiex);
 }
        public void TestMouseWheel()
        {
            // Use a registry helper to backup and restore registry state before/after test
            using (RegistryHelper reg = new RegistryHelper())
            {
                reg.BackupRegistry();

                // Start our application to test
                using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
                {
                    Log.Comment("First ensure that word wrap is off so we can get scroll bars in both directions.");
                    // Make sure wrap is off
                    app.SetWrapState(false);

                    IntPtr handle = app.GetStdOutHandle();
                    Verify.IsNotNull(handle, "Ensure we have the output handle.");

                    Log.Comment("Set up the window so the buffer is larger than the window. Retrieve existing properties then set the viewport to smaller than the buffer.");

                    WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX info = app.GetScreenBufferInfo(handle);

                    info.srWindow.Left   = 0;
                    info.srWindow.Right  = 30;
                    info.srWindow.Top    = 0;
                    info.srWindow.Bottom = 30;

                    info.dwSize.X = 100;
                    info.dwSize.Y = 100;
                    app.SetScreenBufferInfo(handle, info);

                    Log.Comment("Now retrieve the starting position of the window viewport.");

                    Log.Comment("Scroll down one.");
                    VerifyScroll(app, ScrollDir.Vertical, -1);

                    Log.Comment("Scroll right one.");
                    VerifyScroll(app, ScrollDir.Horizontal, 1);

                    Log.Comment("Scroll left one.");
                    VerifyScroll(app, ScrollDir.Horizontal, -1);

                    Log.Comment("Scroll up one.");
                    VerifyScroll(app, ScrollDir.Vertical, 1);
                }
            }
        }
        private void _ClearScreenBuffer(CmdApp app)
        {
            IntPtr outHandle = app.GetStdOutHandle();

            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenInfo = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
            screenInfo.cbSize = (uint)Marshal.SizeOf(screenInfo);
            WinCon.GetConsoleScreenBufferInfoEx(outHandle, ref screenInfo);
            int    charCount   = screenInfo.dwSize.X * screenInfo.dwSize.Y;
            string writeString = new string(' ', charCount);

            WinCon.COORD coord = new WinCon.COORD();
            coord.X = 0;
            coord.Y = 0;
            UInt32 charsWritten = 0;

            WinCon.WriteConsoleOutputCharacter(outHandle,
                                               writeString,
                                               (uint)charCount,
                                               coord,
                                               ref charsWritten);
            Verify.AreEqual((UInt32)charCount, charsWritten);
        }
        public void TestTypeStringHelper(string str, CmdApp app, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex)
        {
            Queue <EventData> expected = new Queue <EventData>();

            foreach (char c in str)
            {
                // For each character, we expect a pair of messages.
                // 1. A Update Simple where the cursor was to represent the letter inserted where the cursor was.
                expected.Enqueue(new EventData(EventType.UpdateSimple, sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y, c, (int)sbiex.wAttributes));
                // Move cursor right by 1.
                sbiex.dwCursorPosition.X++;
                // 2. A caret visible to represent where the cursor moved after the letter was inserted.
                expected.Enqueue(new EventData(EventType.CaretVisible, sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y));

                // Type in the letter
                app.UIRoot.SendKeys($"{c}");

                Globals.WaitForTimeout();
            }

            // Verify that we saw the right messages
            this.VerifyQueue(expected);
        }
        private void TestScrollByOverflowImpl(CmdApp app, ViewportArea area, IntPtr hConsole, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex, Queue <EventData> expected, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal)
        {
            // Get original screen information
            sbiexOriginal = app.GetScreenBufferInfo();
            short promptLineEnd = sbiexOriginal.dwCursorPosition.X;

            promptLineEnd--; // prompt line ended one position left of cursor

            // Resize the window to only have two lines left at the bottom to test overflow when we echo some text
            sbiex = sbiexOriginal;
            sbiex.srWindow.Bottom  = sbiex.dwCursorPosition.Y;
            sbiex.srWindow.Bottom += 3;
            app.SetScreenBufferInfo(sbiex);

            string echoText    = "foo";
            string echoCommand = "echo";

            int echoLine = sbiexOriginal.dwCursorPosition.Y + 1;

            expected.Enqueue(new EventData(EventType.UpdateRegion, 0, echoLine, echoText.Length - 1, echoLine));
            expected.Enqueue(new EventData(EventType.UpdateScroll, 0, -1));
            int newPromptLine = echoLine + 2;

            expected.Enqueue(new EventData(EventType.UpdateRegion, 0, newPromptLine, promptLineEnd, newPromptLine));
            expected.Enqueue(new EventData(EventType.Layout));
            expected.Enqueue(new EventData(EventType.CaretVisible, promptLineEnd + 1, newPromptLine));

            // type command to echo foo and press enter
            app.UIRoot.SendKeys($"{echoCommand} {echoText}");
            Globals.WaitForTimeout();
            received.Clear();
            app.UIRoot.SendKeys(Keys.Enter);
            Globals.WaitForTimeout();

            VerifyQueue(expected);
        }
Example #11
0
        public WinCon.COORD GetCursorPosition(IntPtr hConsole)
        {
            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex = GetScreenBufferInfo(hConsole);

            return(sbiex.dwCursorPosition);
        }
 private int _GetTotalRows(CmdApp app)
 {
     WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX screenBufferInfo = app.GetScreenBufferInfo();
     return(screenBufferInfo.dwSize.Y);
 }
Example #13
0
 public void SetScreenBufferInfo(WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex)
 {
     SetScreenBufferInfo(GetStdOutHandle(), sbiex);
 }
Example #14
0
 public void SetScreenBufferInfo(IntPtr hConsole, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex)
 {
     NativeMethods.Win32BoolHelper(WinCon.SetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Set screen buffer info with given data.");
 }
        private void TestScrollByWheelImpl(CmdApp app, ViewportArea area, IntPtr hConsole, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex, Queue <EventData> expected, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal)
        {
            int rowsPerScroll = app.GetRowsPerScroll();
            int scrollDelta;

            // A. Scroll down.
            {
                scrollDelta = -1;
                expected.Enqueue(new EventData(EventType.UpdateScroll, 0, scrollDelta * rowsPerScroll));
                expected.Enqueue(new EventData(EventType.Layout));

                app.ScrollWindow(scrollDelta);

                Globals.WaitForTimeout();
                VerifyQueue(expected);
            }

            // B. Scroll up.
            {
                scrollDelta = 1;
                expected.Enqueue(new EventData(EventType.UpdateScroll, 0, scrollDelta * rowsPerScroll));
                expected.Enqueue(new EventData(EventType.Layout));

                app.ScrollWindow(scrollDelta);

                Globals.WaitForTimeout();
                VerifyQueue(expected);
            }
        }
        private void TestLaunchAndExitChildImpl(CmdApp app, ViewportArea area, IntPtr hConsole, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex, Queue <EventData> expected, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal)
        {
            // A. We're going to type "cmd" into the prompt to start a command prompt.
            {
                Log.Comment("Type 'cmd' to get ready to start nested prompt.");
                NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Update console data.");
                TestTypeStringHelper("cmd", app, sbiex);
            }

            // B. Now we're going to press enter to launch the CMD application
            {
                Log.Comment("Press enter to launch and observe launch events.");
                NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Update console data.");
                expected.Enqueue(new EventData(EventType.StartApplication));
                expected.Enqueue(new EventData(EventType.UpdateRegion, 0, 0, sbiex.dwSize.X - 1, sbiex.dwSize.Y - 1));
                sbiex.dwCursorPosition.Y++;
                expected.Enqueue(new EventData(EventType.UpdateRegion, 0, sbiex.dwCursorPosition.Y, "Microsoft Windows [Version 10.0.14974.1001]".Length - 1, sbiex.dwCursorPosition.Y));
                sbiex.dwCursorPosition.Y++;
                expected.Enqueue(new EventData(EventType.UpdateRegion, 0, sbiex.dwCursorPosition.Y, "(c) 2016 Microsoft Corporation. All rights reserved.".Length - 1, sbiex.dwCursorPosition.Y));
                sbiex.dwCursorPosition.Y++;
                sbiex.dwCursorPosition.Y++;
                expected.Enqueue(new EventData(EventType.UpdateRegion, 0, sbiex.dwCursorPosition.Y, sbiexOriginal.dwCursorPosition.X - 1, sbiex.dwCursorPosition.Y));
                expected.Enqueue(new EventData(EventType.CaretVisible, sbiexOriginal.dwCursorPosition.X, sbiex.dwCursorPosition.Y));

                app.UIRoot.SendKeys(Keys.Enter);
                Globals.WaitForTimeout();
                Globals.WaitForTimeout();
                VerifyQueue(expected);
            }

            // C. Now we're going to type exit to leave the nested CMD application
            {
                Log.Comment("Type 'exit' to get ready to exit nested prompt.");
                NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Update console data.");
                TestTypeStringHelper("exit", app, sbiex);
            }

            // D. Now we're going to press enter to exit the CMD application
            {
                Log.Comment("Press enter to launch and observe exit events.");
                NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Update console data.");
                expected.Enqueue(new EventData(EventType.EndApplication));
                sbiex.dwCursorPosition.Y++;
                sbiex.dwCursorPosition.Y++;
                expected.Enqueue(new EventData(EventType.UpdateRegion, 0, sbiex.dwCursorPosition.Y, sbiexOriginal.dwCursorPosition.X - 1, sbiex.dwCursorPosition.Y));
                expected.Enqueue(new EventData(EventType.CaretVisible, sbiexOriginal.dwCursorPosition.X, sbiex.dwCursorPosition.Y));

                app.UIRoot.SendKeys(Keys.Enter);
                Globals.WaitForTimeout();
                Globals.WaitForTimeout();
                VerifyQueue(expected);
            }
        }
Example #17
0
        public WinCon.SMALL_RECT GetViewport(IntPtr hConsole)
        {
            WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex = GetScreenBufferInfo(hConsole);

            return(sbiex.srWindow);
        }
Example #18
0
        public void TestKeyboardSelection()
        {
            using (RegistryHelper reg = new RegistryHelper())
            {
                reg.BackupRegistry();

                VersionSelector.SetConsoleVersion(reg, ConsoleVersion.V2);

                using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
                {
                    using (ViewportArea area = new ViewportArea(app))
                    {
                        WinCon.CONSOLE_SELECTION_INFO csi;
                        NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Get initial selection state.");
                        Log.Comment("Selection Info: {0}", csi);

                        Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION, "Confirm no selection in progress.");
                        // ignore rectangle and coords. They're undefined when there is no selection.

                        // Get cursor position at the beginning of this operation. The anchor will start at the cursor position for v2 console.
                        // NOTE: It moved to 0,0 for the v1 console.
                        IntPtr hConsole = WinCon.GetStdHandle(WinCon.CONSOLE_STD_HANDLE.STD_OUTPUT_HANDLE);
                        Verify.IsNotNull(hConsole, "Ensure the STDOUT handle is valid.");

                        WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX cbiex = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                        cbiex.cbSize = (uint)Marshal.SizeOf(cbiex);
                        NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref cbiex), "Get initial cursor position (from screen buffer info)");

                        // The expected anchor when we're done is this initial cursor position
                        WinCon.COORD expectedAnchor = new WinCon.COORD();
                        expectedAnchor.X = cbiex.dwCursorPosition.X;
                        expectedAnchor.Y = cbiex.dwCursorPosition.Y;

                        // The expected rect is going to start from this cursor position. We'll modify it after we perform some operations.
                        WinCon.SMALL_RECT expectedRect = new WinCon.SMALL_RECT();
                        expectedRect.Top    = expectedAnchor.Y;
                        expectedRect.Left   = expectedAnchor.X;
                        expectedRect.Right  = expectedAnchor.X;
                        expectedRect.Bottom = expectedAnchor.Y;

                        // Now set up the keyboard and enter mark mode.
                        // NOTE: We must wait after every keyboard sequence to give the console time to process before asking it for changes.
                        area.EnterMode(ViewportArea.ViewportStates.Mark);

                        NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Get state on entering mark mode.");
                        Log.Comment("Selection Info: {0}", csi);

                        Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS, "Selection should now be in progress since mark mode is started.");

                        // Select a small region
                        Log.Comment("1. Select a small region");

                        app.UIRoot.SendKeys(Keys.Shift + Keys.Right + Keys.Right + Keys.Right + Keys.Down + Keys.Shift);

                        Globals.WaitForTimeout();

                        // Adjust the expected rectangle for the commands we just entered.
                        expectedRect.Right  += 3; // same as the number of Rights we put in
                        expectedRect.Bottom += 1; // same as the number of Downs we put in

                        NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Get state of selected region.");
                        Log.Comment("Selection Info: {0}", csi);

                        Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS | WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_NOT_EMPTY, "Selection in progress and is no longer empty now that we've selected a region.");
                        Verify.AreEqual(csi.Selection, expectedRect, "Verify that the selected rectangle matches the keystrokes we entered.");
                        Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Verify anchor didn't go anywhere since we started in the top left.");

                        // End selection by moving
                        Log.Comment("2. End the selection by moving.");

                        app.UIRoot.SendKeys(Keys.Down);

                        Globals.WaitForTimeout();

                        NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Move cursor to attempt to clear selection.");
                        Log.Comment("Selection Info: {0}", csi);

                        Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS, "Selection should be still running, but empty.");

                        // Select another region to ensure anchor moved.
                        Log.Comment("3. Select one more region from new position to verify anchor");

                        app.UIRoot.SendKeys(Keys.Shift + Keys.Right + Keys.Shift);

                        Globals.WaitForTimeout();

                        expectedAnchor.X = expectedRect.Right;
                        expectedAnchor.Y = expectedRect.Bottom;
                        expectedAnchor.Y++; // +1 for the Down in step 2. Not incremented in the line above because C# is unhappy with adding +1 to a short while assigning.

                        Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Verify anchor moved to the new start position.");

                        // Exit mark mode
                        area.EnterMode(ViewportArea.ViewportStates.Normal);

                        NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Move cursor to attempt to clear selection.");
                        Log.Comment("Selection Info: {0}", csi);

                        Verify.AreEqual(csi.Flags, WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION, "Selection should be empty when mode is exited.");
                    }
                }
            }
        }
Example #19
0
        public void TestCtrlHomeEnd()
        {
            using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
            {
                using (ViewportArea area = new ViewportArea(app))
                {
                    // Get console handle.
                    IntPtr hConsole = app.GetStdOutHandle();
                    Verify.IsNotNull(hConsole, "Ensure the STDOUT handle is valid.");

                    // Get us to an expected initial state.
                    app.UIRoot.SendKeys("C:" + Keys.Enter);
                    app.UIRoot.SendKeys(@"cd C:\" + Keys.Enter);
                    app.UIRoot.SendKeys("cls" + Keys.Enter);

                    // Get initial screen buffer position
                    WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                    sbiexOriginal.cbSize = (uint)Marshal.SizeOf(sbiexOriginal);
                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexOriginal), "Get initial viewport position.");

                    // Prep comparison structure
                    WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexCompare = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                    sbiexCompare.cbSize = (uint)Marshal.SizeOf(sbiexCompare);

                    // Ctrl-End shouldn't move anything yet.
                    Log.Comment("Attempt Ctrl-End. Nothing should move yet.");
                    app.UIRoot.SendKeys(Keys.Control + Keys.End + Keys.Control);

                    Globals.WaitForTimeout();

                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexCompare), "Get comparison position.");
                    Verify.AreEqual <WinCon.SMALL_RECT>(sbiexOriginal.srWindow, sbiexCompare.srWindow, "Compare viewport positions before and after.");

                    // Ctrl-Home shouldn't move anything yet.
                    Log.Comment("Attempt Ctrl-Home. Nothing should move yet.");
                    app.UIRoot.SendKeys(Keys.Control + Keys.Home + Keys.Control);

                    Globals.WaitForTimeout();

                    Log.Comment("Now test the line with some text in it.");
                    // Retrieve original position (including cursor)
                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexOriginal), "Get position of viewport with nothing on edit line.");

                    // Put some text onto the edit line now
                    Log.Comment("Place some text onto the edit line to ensure behavior will change with edit line full.");
                    const string testText = "SomeTestText";
                    app.UIRoot.SendKeys(testText);

                    Globals.WaitForTimeout();

                    // Get the position of the cursor after the text is entered
                    WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexWithText = new WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX();
                    sbiexWithText.cbSize = (uint)Marshal.SizeOf(sbiexWithText);
                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexWithText), "Get position of viewport with edit line text.");

                    // The cursor can't have moved down a line. We're going to verify the text by reading its "rectangle" out of the screen buffer.
                    // If it moved down a line, the calculation of what to select is more complicated than the simple rectangle assignment below.
                    Verify.AreEqual(sbiexOriginal.dwCursorPosition.Y, sbiexWithText.dwCursorPosition.Y, "There's an assumption here that the cursor stayed on the same line when we added our bit of text.");

                    // Prepare the read rectangle for what we want to get out of the buffer.
                    Rectangle readRectangle = new Rectangle(sbiexOriginal.dwCursorPosition.X,
                                                            sbiexOriginal.dwCursorPosition.Y,
                                                            (sbiexWithText.dwCursorPosition.X - sbiexOriginal.dwCursorPosition.X),
                                                            1);

                    Log.Comment("Verify that the text we keyed matches what's in the buffer.");
                    IEnumerable <string> text = area.GetLinesInRectangle(hConsole, readRectangle);
                    Verify.AreEqual(text.Count(), 1, "We should only have retrieved one line.");
                    Verify.AreEqual(text.First(), testText, "Verify text matches keyed input.");

                    // Move cursor into the middle of the text.
                    Log.Comment("Move cursor into the middle of the string.");

                    const int lefts = 4;
                    for (int i = 0; i < lefts; i++)
                    {
                        app.UIRoot.SendKeys(Keys.Left);
                    }

                    Globals.WaitForTimeout();

                    // Get cursor position now that it's moved.
                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexWithText), "Get position of viewport with cursor moved into the middle of the edit line text.");

                    Log.Comment("Ctrl-End should trim the end of the input line from the cursor (and not move the cursor.)");
                    app.UIRoot.SendKeys(Keys.Control + Keys.End + Keys.Control);

                    Globals.WaitForTimeout();

                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexCompare), "Get comparison position.");
                    Verify.AreEqual <WinCon.SMALL_RECT>(sbiexWithText.srWindow, sbiexCompare.srWindow, "Compare viewport positions before and after.");
                    Verify.AreEqual <WinCon.COORD>(sbiexWithText.dwCursorPosition, sbiexCompare.dwCursorPosition, "Compare cursor positions before and after.");

                    Log.Comment("Compare actual text visible on screen.");
                    text = area.GetLinesInRectangle(hConsole, readRectangle);
                    Verify.AreEqual(text.Count(), 1, "We should only have retrieved one line.");

                    // the substring length is the original length of the string minus the number of lefts
                    int substringCtrlEnd = testText.Length - lefts;
                    Verify.AreEqual(text.First().Trim(), testText.Substring(0, substringCtrlEnd), "Verify text matches keyed input without the last characters removed by Ctrl+End.");

                    Log.Comment("Ctrl-Home should trim the remainder of the edit line from the cursor to the beginning (restoring cursor to position before we entered anything.)");
                    app.UIRoot.SendKeys(Keys.Control + Keys.Home + Keys.Control);

                    Globals.WaitForTimeout();

                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiexCompare), "Get comparison position.");
                    Verify.AreEqual <WinCon.SMALL_RECT>(sbiexOriginal.srWindow, sbiexCompare.srWindow, "Compare viewport positions before and after.");
                    Verify.AreEqual <WinCon.COORD>(sbiexOriginal.dwCursorPosition, sbiexCompare.dwCursorPosition, "Compare cursor positions before and after.");

                    Log.Comment("Compare actual text visible on screen.");
                    text = area.GetLinesInRectangle(hConsole, readRectangle);
                    Verify.AreEqual(text.Count(), 1, "We should only have retrieved one line.");

                    Verify.AreEqual(text.First().Trim(), string.Empty, "Verify text is now empty after Ctrl+Home from the end of it.");
                }
            }
        }
        private void TestSelectionImpl(CmdApp app, ViewportArea area, IntPtr hConsole, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex, Queue <EventData> expected, WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiexOriginal)
        {
            // A. Test single area click
            {
                // Move mouse pointer to where the cursor is
                NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Update console data.");
                Point pt = new Point(sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y);
                area.MouseMove(pt);

                // Click on this area.
                expected.Enqueue(new EventData(EventType.CaretSelection, sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y));
                area.MouseDown();
                area.MouseUp();

                Globals.WaitForTimeout();

                VerifyQueue(expected);

                // We may receive more than one caret and that's OK. Clear it out.
                this.received.Clear();

                // End selection with escape
                app.UIRoot.SendKeys(Keys.Escape);
                Globals.WaitForTimeout();

                // Expect to see the caret again after leaving selection mode
                expected.Enqueue(new EventData(EventType.CaretVisible, sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y));
                VerifyQueue(expected);
            }

            // B. Drag area click
            {
                // Move mouse pointer to where the cursor is
                NativeMethods.Win32BoolHelper(WinCon.GetConsoleScreenBufferInfoEx(hConsole, ref sbiex), "Update console data.");
                Point pt = new Point(sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y);
                area.MouseMove(pt);

                // Click on this area.
                expected.Enqueue(new EventData(EventType.CaretSelection, sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y));
                area.MouseDown();

                Globals.WaitForTimeout();

                Point ptDrag = pt;
                // Drag down and right for "some" distance. 10 isn't for a specific reason, it's just "some".
                ptDrag.X += 10;
                ptDrag.Y += 10;

                area.MouseMove(ptDrag);

                Globals.WaitForTimeout();

                area.MouseUp();

                Globals.WaitForTimeout();

                // Verify that the first one in the queue starts with where we put the mouse down.
                VerifyQueue(expected);

                // Now we have to take the final message in the queue and make sure it is where we released the mouse
                EventData expectedLast = new EventData(EventType.CaretSelection, ptDrag.X, ptDrag.Y);
                EventData actualLast   = received.Last();
                Verify.AreEqual(expectedLast, actualLast);

                // Empty the received queue.
                received.Clear();

                // End selection with escape
                app.UIRoot.SendKeys(Keys.Escape);
                Globals.WaitForTimeout();

                // Expect to see the caret again after leaving selection mode
                expected.Enqueue(new EventData(EventType.CaretVisible, sbiex.dwCursorPosition.X, sbiex.dwCursorPosition.Y));
                VerifyQueue(expected);
            }
        }
Example #21
0
 public WinCon.CONSOLE_ATTRIBUTES GetCurrentAttributes(IntPtr hConsole)
 {
     WinCon.CONSOLE_SCREEN_BUFFER_INFO_EX sbiex = GetScreenBufferInfo(hConsole);
     return(sbiex.wAttributes);
 }