public void RunVtAppTester()
        {
            using (RegistryHelper reg = new RegistryHelper())
            {
                reg.BackupRegistry(); // we're going to modify the virtual terminal state for this, so back it up first.
                VersionSelector.SetConsoleVersion(reg, ConsoleVersion.V2);
                reg.SetDefaultValue(VIRTUAL_TERMINAL_KEY_NAME, VIRTUAL_TERMINAL_ON_VALUE);

                bool haveVtAppPath = !string.IsNullOrEmpty(vtAppLocation);

                Verify.IsTrue(haveVtAppPath, "Ensure that we passed in the location to VtApp.exe");

                if (haveVtAppPath)
                {
                    using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext, vtAppLocation))
                    {
                        using (ViewportArea area = new ViewportArea(app))
                        {
                            // Get console handle.
                            IntPtr hConsole = app.GetStdOutHandle();
                            Verify.IsNotNull(hConsole, "Ensure the STDOUT handle is valid.");

                            Log.Comment("Check that the VT test app loaded up properly with its output line and the cursor down one line.");
                            Rectangle            selectRect  = new Rectangle(0, 0, 9, 1);
                            IEnumerable <string> scrapedText = area.GetLinesInRectangle(hConsole, selectRect);

                            Verify.AreEqual(scrapedText.Count(), 1, "We should have retrieved one line.");
                            string testerWelcome = scrapedText.Single();

                            Verify.AreEqual(testerWelcome, "VT Tester");

                            WinCon.COORD cursorPos      = app.GetCursorPosition(hConsole);
                            WinCon.COORD cursorExpected = new WinCon.COORD();
                            cursorExpected.X = 0;
                            cursorExpected.Y = 1;
                            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to expected starting position.");

                            TestCursorPositioningCommands(app, hConsole, cursorExpected);

                            TestCursorVisibilityCommands(app, hConsole);

                            TestAreaEraseCommands(app, area, hConsole);

                            TestGraphicsCommands(app, area, hConsole);

                            TestQueryResponses(app, hConsole);

                            TestVtToggle(app, hConsole);

                            TestInsertDelete(app, area, hConsole);
                        }
                    }
                }
            }
        }
        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 WinCon.CHAR_INFO[,] GetCharInfoInRectangle(IntPtr handle, Rectangle rect)
        {
            WinCon.SMALL_RECT readRectangle = new WinCon.SMALL_RECT();
            readRectangle.Top    = (short)rect.Top;
            readRectangle.Bottom = (short)(rect.Bottom - 1);
            readRectangle.Left   = (short)rect.Left;
            readRectangle.Right  = (short)(rect.Right - 1);

            WinCon.COORD dataBufferSize = new WinCon.COORD();
            dataBufferSize.X = (short)rect.Width;
            dataBufferSize.Y = (short)rect.Height;

            WinCon.COORD dataBufferPos = new WinCon.COORD();
            dataBufferPos.X = 0;
            dataBufferPos.Y = 0;

            WinCon.CHAR_INFO[,] data = new WinCon.CHAR_INFO[dataBufferSize.Y, dataBufferSize.X];

            NativeMethods.Win32BoolHelper(WinCon.ReadConsoleOutput(handle, data, dataBufferSize, dataBufferPos, ref readRectangle), string.Format("Attempting to read rectangle (L: {0}, T: {1}, R: {2}, B: {3}) from output buffer.", readRectangle.Left, readRectangle.Top, readRectangle.Right, readRectangle.Bottom));

            return(data);
        }
        private void _WriteCharTestText(CmdApp app)
        {
            IntPtr outHandle = app.GetStdOutHandle();

            WinCon.COORD coord = new WinCon.COORD();
            coord.X = 0;
            coord.Y = 0;
            string row1         = "1234567890";
            string row2         = "   abcdefghijk";
            UInt32 charsWritten = 0;

            WinCon.WriteConsoleOutputCharacter(outHandle,
                                               row1,
                                               (uint)row1.Length,
                                               coord,
                                               ref charsWritten);

            coord.Y = 1;
            WinCon.WriteConsoleOutputCharacter(outHandle,
                                               row2,
                                               (uint)row2.Length,
                                               coord,
                                               ref charsWritten);
        }
        private static void TestCursorPositioningCommands(CmdApp app, IntPtr hConsole, WinCon.COORD cursorExpected)
        {
            WinCon.COORD cursorPos;
            Log.Comment("---Cursor Positioning Commands---");
            // Try cursor commands
            Log.Comment("Press B key (cursor down)");
            app.UIRoot.SendKeys("B");
            cursorExpected.Y++;
            cursorPos = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved down by 1.");

            Log.Comment("Press A key (cursor up)");
            app.UIRoot.SendKeys("A");
            cursorExpected.Y--;
            cursorPos = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved up by 1.");

            Log.Comment("Press C key (cursor right)");
            app.UIRoot.SendKeys("C");
            cursorExpected.X++;
            cursorPos = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved right by 1.");

            Log.Comment("Press D key (cursor left)");
            app.UIRoot.SendKeys("D");
            cursorExpected.X--;
            cursorPos = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved left by 1.");

            Log.Comment("Move to the right (C) then move down a line (E)");
            app.UIRoot.SendKeys("CCC");
            cursorExpected.X += 3;
            cursorPos         = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has right by 3.");

            app.UIRoot.SendKeys("E");
            cursorExpected.Y++;
            cursorExpected.X = 0;
            cursorPos        = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved down by 1 line and reset X position to 0.");

            Log.Comment("Move to the right (C) then move up a line (F)");
            app.UIRoot.SendKeys("CCC");
            cursorExpected.X += 3;
            cursorPos         = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check curs has right by 3.");

            app.UIRoot.SendKeys("F");
            cursorExpected.Y--;
            cursorExpected.X = 0;
            cursorPos        = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved up by 1 line.");

            Log.Comment("Check move directly to position 14 horizontally (G)");
            app.UIRoot.SendKeys("G");
            cursorExpected.X = 14 - 1; // 14 is the VT position which starts at array offset 1. 13 is the buffer position starting at array offset 0.
            cursorPos        = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to horizontal position 14.");

            Log.Comment("Check move directly to position 14 vertically (v key mapped to d)");
            app.UIRoot.SendKeys("v");
            cursorExpected.Y = 14 - 1; // 14 is the VT position which starts at array offset 1. 13 is the buffer position starting at array offset 0.
            cursorPos        = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to vertical position 14.");

            Log.Comment("Check move directly to row 5, column 1 (H)");
            app.UIRoot.SendKeys("H");
            // Again -1s are to convert index base 1 VT to console base 0 arrays
            cursorExpected.Y = 5 - 1;
            cursorExpected.X = 1 - 1;
            cursorPos        = app.GetCursorPosition(hConsole);
            Verify.AreEqual(cursorExpected, cursorPos, "Check cursor has moved to row 5, column 1.");
        }
Example #6
0
        public void TestMouseSelection()
        {
            using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext))
            {
                using (ViewportArea area = new ViewportArea(app))
                {
                    // Set up the area we're going to attempt to select
                    Point startPoint = new Point();
                    Point endPoint   = new Point();

                    startPoint.X = 1;
                    startPoint.Y = 2;

                    endPoint.X = 10;
                    endPoint.Y = 10;

                    // Save expected anchor
                    WinCon.COORD expectedAnchor = new WinCon.COORD();
                    expectedAnchor.X = (short)startPoint.X;
                    expectedAnchor.Y = (short)startPoint.Y;

                    // Also save bottom right corner for the end of the selection
                    WinCon.COORD expectedBottomRight = new WinCon.COORD();
                    expectedBottomRight.X = (short)endPoint.X;
                    expectedBottomRight.Y = (short)endPoint.Y;

                    // Prepare the mouse by moving it into the start position. Prepare the structure
                    WinCon.CONSOLE_SELECTION_INFO csi;
                    WinCon.SMALL_RECT             expectedRect = new WinCon.SMALL_RECT();

                    WinCon.CONSOLE_SELECTION_INFO_FLAGS flagsExpected = WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION;

                    // 1. Place mouse button down to start selection and check state
                    area.MouseMove(startPoint);
                    area.MouseDown();

                    Globals.WaitForTimeout();                                                           // must wait after mouse operation. No good waiters since we have no UI objects

                    flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_IN_PROGRESS; // a selection is occurring
                    flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_MOUSE_SELECTION;       // it's a "Select" mode not "Mark" mode selection
                    flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_MOUSE_DOWN;            // the mouse is still down
                    flagsExpected |= WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_SELECTION_NOT_EMPTY;   // mouse selections are never empty. minimum 1x1

                    expectedRect.Top    = expectedAnchor.Y;                                             // rectangle is just at the point itself 1x1 size
                    expectedRect.Left   = expectedAnchor.X;
                    expectedRect.Bottom = expectedRect.Top;
                    expectedRect.Right  = expectedRect.Left;

                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Check state on mouse button down to start selection.");
                    Log.Comment("Selection Info: {0}", csi);

                    Verify.AreEqual(csi.Flags, flagsExpected, "Check initial mouse selection with button still down.");
                    Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Check that the anchor is equal to the start point.");
                    Verify.AreEqual(csi.Selection, expectedRect, "Check that entire rectangle is the size of 1x1 and is just at the anchor point.");

                    // 2. Move to end point and release cursor
                    area.MouseMove(endPoint);
                    area.MouseUp();

                    Globals.WaitForTimeout(); // must wait after mouse operation. No good waiters since we have no UI objects

                    // on button up, remove mouse down flag
                    flagsExpected &= ~WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_MOUSE_DOWN;

                    // anchor remains the same
                    // bottom right of rectangle now changes to the end point
                    expectedRect.Bottom = expectedBottomRight.Y;
                    expectedRect.Right  = expectedBottomRight.X;

                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Check state after drag and release mouse.");
                    Log.Comment("Selection Info: {0}", csi);

                    Verify.AreEqual(csi.Flags, flagsExpected, "Check selection is still on and valid, but button is up.");
                    Verify.AreEqual(csi.SelectionAnchor, expectedAnchor, "Check that the anchor is still equal to the start point.");
                    Verify.AreEqual(csi.Selection, expectedRect, "Check that entire rectangle reaches from start to end point.");

                    // 3. Leave mouse selection
                    area.ExitModes();

                    flagsExpected = WinCon.CONSOLE_SELECTION_INFO_FLAGS.CONSOLE_NO_SELECTION;

                    NativeMethods.Win32BoolHelper(WinCon.GetConsoleSelectionInfo(out csi), "Check state after exiting mouse selection.");
                    Log.Comment("Selection Info: {0}", csi);

                    Verify.AreEqual(csi.Flags, flagsExpected, "Check that selection state is reset.");
                }
            }
        }
Example #7
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 #8
0
 public void FillCursorPosition(IntPtr hConsole, ref Point pt)
 {
     WinCon.COORD coord = GetCursorPosition(hConsole);
     pt.X = coord.X;
     pt.Y = coord.Y;
 }