private static void TestCursorVisibilityCommands(CmdApp app, IntPtr hConsole)
        {
            WinCon.COORD cursorExpected;
            Log.Comment("---Cursor Visibility Commands---");
            Log.Comment("Turn cursor display off. (l)");
            app.UIRoot.SendKeys("l");
            Verify.AreEqual(false, app.IsCursorVisible(hConsole), "Check that cursor is invisible.");

            Log.Comment("Turn cursor display on. (h)");
            app.UIRoot.SendKeys("h");
            Verify.AreEqual(true, app.IsCursorVisible(hConsole), "Check that cursor is visible.");

            Log.Comment("---Cursor Save/Restore Commands---");
            Log.Comment("Save current cursor position with DEC save.");
            app.UIRoot.SendKeys("7");
            cursorExpected = app.GetCursorPosition(hConsole);

            Log.Comment("Move the cursor a bit away from the saved position.");
            app.UIRoot.SendKeys("BBBBCCCCC");

            Log.Comment("Restore existing position with DEC restore.");
            app.UIRoot.SendKeys("8");
            Verify.AreEqual(cursorExpected, app.GetCursorPosition(hConsole), "Check that cursor restored back to the saved position.");

            Log.Comment("Move the cursor a bit away from the saved position.");
            app.UIRoot.SendKeys("BBBBCCCCC");

            Log.Comment("Restore existing position with ANSISYS restore.");
            app.UIRoot.SendKeys("u");
            Verify.AreEqual(cursorExpected, app.GetCursorPosition(hConsole), "Check that cursor restored back to the saved position.");

            Log.Comment("Move the cursor a bit away from either position.");
            app.UIRoot.SendKeys("BBB");

            Log.Comment("Save current cursor position with ANSISYS save.");
            app.UIRoot.SendKeys("y");
            cursorExpected = app.GetCursorPosition(hConsole);

            Log.Comment("Move the cursor a bit away from the saved position.");
            app.UIRoot.SendKeys("CCCBB");

            Log.Comment("Restore existing position with DEC restore.");
            app.UIRoot.SendKeys("8");
            Verify.AreEqual(cursorExpected, app.GetCursorPosition(hConsole), "Check that cursor restored back to the saved position.");
        }
        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 static void TestVtToggle(CmdApp app, IntPtr hConsole)
        {
            WinCon.COORD cursorPos;
            Log.Comment("--Test VT Toggle--");

            Verify.IsTrue(app.IsVirtualTerminalEnabled(hConsole), "Verify we're starting with VT on.");

            app.UIRoot.SendKeys("H-"); // move cursor to top left area H location and then turn off VT.

            cursorPos = app.GetCursorPosition(hConsole);

            Verify.IsFalse(app.IsVirtualTerminalEnabled(hConsole), "Verify VT was turned off.");

            app.UIRoot.SendKeys("-");
            Verify.IsTrue(app.IsVirtualTerminalEnabled(hConsole), "Verify VT was turned back on .");
        }
        private static void TestQueryResponses(CmdApp app, IntPtr hConsole)
        {
            WinCon.COORD cursorPos;
            Log.Comment("---Status Request Commands---");
            Globals.WaitForTimeout();
            app.UIRoot.SendKeys("c");
            string expectedTitle = string.Format("Response Received: {0}", "\x1b[?1;0c");

            Globals.WaitForTimeout();
            string title = app.GetWindowTitle();

            Verify.AreEqual(expectedTitle, title, "Verify that we received the proper response to the Device Attributes request.");

            app.UIRoot.SendKeys("R");
            cursorPos     = app.GetCursorPosition(hConsole);
            expectedTitle = string.Format("Response Received: {0}", string.Format("\x1b[{0};{1}R", cursorPos.Y + 1, cursorPos.X + 1));

            Globals.WaitForTimeout();
            title = app.GetWindowTitle();
            Verify.AreEqual(expectedTitle, title, "Verify that we received the proper response to the Cursor Position request.");
        }
        private static void TestAreaEraseCommands(CmdApp app, ViewportArea area, IntPtr hConsole)
        {
            WinCon.COORD cursorPos;
            Log.Comment("---Area Erase Commands---");
            ScreenFillHelper(app, area, hConsole);
            Log.Comment("Clear screen after");
            app.UIRoot.SendKeys("J");

            Globals.WaitForTimeout(); // give buffer time to clear.

            cursorPos = app.GetCursorPosition(hConsole);

            GetExpectedChar expectedCharAlgorithm;

            expectedCharAlgorithm = (int rowId, int colId, int height, int width) =>
            {
                if (rowId == (height - 1) && colId == (width - 1))
                {
                    return(' ');
                }
                else if (rowId < cursorPos.Y)
                {
                    return('Z');
                }
                else if (rowId > cursorPos.Y)
                {
                    return(' ');
                }
                else
                {
                    if (colId < cursorPos.X)
                    {
                        return('Z');
                    }
                    else
                    {
                        return(' ');
                    }
                }
            };

            BufferVerificationHelper(app, area, hConsole, expectedCharAlgorithm);

            ScreenFillHelper(app, area, hConsole);
            Log.Comment("Clear screen before");
            app.UIRoot.SendKeys("j");

            expectedCharAlgorithm = (int rowId, int colId, int height, int width) =>
            {
                if (rowId == (height - 1) && colId == (width - 1))
                {
                    return(' ');
                }
                else if (rowId < cursorPos.Y)
                {
                    return(' ');
                }
                else if (rowId > cursorPos.Y)
                {
                    return('Z');
                }
                else
                {
                    if (colId <= cursorPos.X)
                    {
                        return(' ');
                    }
                    else
                    {
                        return('Z');
                    }
                }
            };

            BufferVerificationHelper(app, area, hConsole, expectedCharAlgorithm);

            ScreenFillHelper(app, area, hConsole);
            Log.Comment("Clear line after");
            app.UIRoot.SendKeys("K");

            expectedCharAlgorithm = (int rowId, int colId, int height, int width) =>
            {
                if (rowId == (height - 1) && colId == (width - 1))
                {
                    return(' ');
                }
                else if (rowId != cursorPos.Y)
                {
                    return('Z');
                }
                else
                {
                    if (colId < cursorPos.X)
                    {
                        return('Z');
                    }
                    else
                    {
                        return(' ');
                    }
                }
            };

            BufferVerificationHelper(app, area, hConsole, expectedCharAlgorithm);

            ScreenFillHelper(app, area, hConsole);
            Log.Comment("Clear line before");
            app.UIRoot.SendKeys("k");

            expectedCharAlgorithm = (int rowId, int colId, int height, int width) =>
            {
                if (rowId == (height - 1) && colId == (width - 1))
                {
                    return(' ');
                }
                else if (rowId != cursorPos.Y)
                {
                    return('Z');
                }
                else
                {
                    if (colId <= cursorPos.X)
                    {
                        return(' ');
                    }
                    else
                    {
                        return('Z');
                    }
                }
            };

            BufferVerificationHelper(app, area, hConsole, expectedCharAlgorithm);
        }
        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.");
        }