Beispiel #1
0
        public void TestLongPathCheck()
        {
            string[] expectedLongPaths =
            {
                @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\trailing-attribute-no-value.js",
                @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\xmlns-xml-default-prefix-attribute.js",
                @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\xmlns-xml-default-redefine.js",
                @"node_modules\azure\node_modules\request\node_modules\form-data\node_modules\combined-stream\node_modules",
                @"node_modules\azure\node_modules\request\node_modules\http-signature\node_modules\ctype\tst\ctio\uint\tst.roundtrip.js",
            };

            string projectDir = CreateTempPathOfLength(248 - 1 - expectedLongPaths.Min(s => s.Length));

            try {
                foreach (var fileName in new[] { "HelloWorld.njsproj", "HelloWorld.sln", "package.json", "README.md", "server.js" })
                {
                    File.Copy(TestData.GetPath(@"TestData\HelloWorld\" + fileName), projectDir + "\\" + fileName);
                }

                using (var app = new NodejsVisualStudioApp()) {
                    try {
                        NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths = true;

                        var project = app.OpenProject(projectDir + "\\HelloWorld.sln");

                        // Wait for new solution to load.
                        for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++)
                        {
                            System.Threading.Thread.Sleep(250);
                        }

                        const string interpreterDescription = "Node.js Interactive Window";
                        app.Dte.ExecuteCommand("View.Node.jsInteractiveWindow");
                        var interactive = app.GetInteractiveWindow(interpreterDescription);
                        if (interactive == null)
                        {
                            Assert.Inconclusive("Need " + interpreterDescription);
                        }

                        interactive.WaitForIdleState();
                        var npmTask = interactive.ReplWindow.ExecuteCommand(".npm install [email protected]");

                        using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) {
                            // The option to offer "npm dedupe" should be there.
                            var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000");
                            Assert.IsNotNull(firstCommandLink);
                            Assert.IsTrue(firstCommandLink.Current.Name.Contains("npm dedupe"));

                            dialog.ClickButtonByAutomationId("ExpandoButton");
                            var detailsText = dialog.FindByAutomationId("ExpandedFooterTextLink");
                            Assert.IsNotNull(detailsText);

                            var reportedLongPaths =
                                (from line in detailsText.Current.Name.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                                 where line.StartsWith("•")
                                 let nbspIndex = line.IndexOf('\u00A0')
                                                 where nbspIndex >= 0
                                                 select line.Substring(1, nbspIndex - 1).Trim()
                                ).ToArray();
                            Console.WriteLine("Reported paths:");
                            foreach (var path in reportedLongPaths)
                            {
                                Console.WriteLine("\t" + path);
                            }

                            reportedLongPaths = reportedLongPaths.Except(expectedLongPaths).ToArray();
                            if (reportedLongPaths.Length != 0)
                            {
                                Console.WriteLine("Unexpected paths:");
                                foreach (var path in reportedLongPaths)
                                {
                                    Console.WriteLine("\t" + path);
                                }
                                Assert.Fail("Unexpected long paths reported.");
                            }

                            dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => {
                                // Click the first command button (dedupe).
                                firstCommandLink.SetFocus();
                                Keyboard.Press(System.Windows.Input.Key.Enter);
                            });
                        }

                        // Clicking on that button should not change the option.
                        Assert.IsTrue(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths);

                        interactive.WaitForTextContainsAll("dedupe successfully completed");
                        interactive.WaitForIdleState();

                        // npm dedupe won't be able to fix the problem, so we should get the dialog once again.
                        using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) {
                            // The option to offer "npm dedupe" should not be there anymore.
                            var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000");
                            Assert.IsNotNull(firstCommandLink);
                            Assert.IsFalse(firstCommandLink.Current.Name.Contains("npm dedupe"));

                            dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => {
                                Keyboard.Type("\r"); // click the first command button (do nothing, but warn next time)
                            });
                        }

                        npmTask.Wait(1000);
                        Assert.IsTrue(npmTask.IsCompleted);

                        // Clicking on that button should not change the option.
                        Assert.IsTrue(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths);

                        // Try again to see that the dialog still appears. Any npm command triggers the check.
                        // and since we didn't do anything to fix the problem, we should still get the dialog.
                        interactive.WaitForIdleState();
                        npmTask = interactive.ReplWindow.ExecuteCommand(".npm list");

                        using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) {
                            // The option to offer "npm dedupe" should be there again, since this is a new check.
                            var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000");
                            Assert.IsNotNull(firstCommandLink);
                            Assert.IsTrue(firstCommandLink.Current.Name.Contains("npm dedupe"));

                            dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => {
                                // Click the third command button (do nothing, do not warn anymore)
                                firstCommandLink.SetFocus();
                                Keyboard.Press(System.Windows.Input.Key.Tab);
                                Keyboard.Press(System.Windows.Input.Key.Tab);
                                Keyboard.Press(System.Windows.Input.Key.Enter);
                            });
                        }

                        npmTask.Wait(1000);
                        Assert.IsTrue(npmTask.IsCompleted);

                        // Clicking on that button should change the option to false.
                        Assert.IsFalse(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths);

                        // Try again to see that the dialog does not appear anymore.
                        interactive.WaitForIdleState();
                        npmTask = interactive.ReplWindow.ExecuteCommand(".npm list");
                        app.WaitForNoDialog(TimeSpan.FromSeconds(3));
                    } finally {
                        NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths = true;
                    }
                }
            } finally {
                DeleteLongPath(projectDir);
            }
        }
Beispiel #2
0
        public void CustomCommandsRequiredPackages()
        {
            using (var app = new PythonVisualStudioApp())
                using (var dis = app.SelectDefaultInterpreter(PythonVersion, "virtualenv")) {
                    PythonProjectNode node;
                    EnvDTE.Project    proj;
                    OpenProject(app, "CommandRequirePackages.sln", out node, out proj);

                    string envName;
                    var    env = app.CreateVirtualEnvironment(proj, out envName);

                    env.Select();
                    app.Dte.ExecuteCommand("Python.ActivateEnvironment");
                    // Ensure that no error dialog appears
                    app.WaitForNoDialog(TimeSpan.FromSeconds(5.0));

                    // First, execute the command and cancel it.
                    var task = ExecuteAsync(node, "Require Packages");
                    try {
                        var dialogHandle = app.WaitForDialog(task);
                        if (dialogHandle == IntPtr.Zero)
                        {
                            if (task.IsFaulted && task.Exception != null)
                            {
                                Assert.Fail("Unexpected exception in package install confirmation dialog:\n{0}", task.Exception);
                            }
                            else
                            {
                                Assert.AreNotEqual(IntPtr.Zero, dialogHandle);
                            }
                        }

                        using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(dialogHandle))) {
                            var label = dialog.FindByAutomationId("CommandLink_1000");
                            Assert.IsNotNull(label);

                            string expectedLabel =
                                "The following packages will be installed using pip:\r\n" +
                                "\r\n" +
                                "ptvsd\r\n" +
                                "azure==0.1";;
                            Assert.AreEqual(expectedLabel, label.Current.HelpText);

                            dialog.Cancel();
                            try {
                                task.Wait(1000);
                                Assert.Fail("Command was not canceled after dismissing the package install confirmation dialog");
                            } catch (AggregateException ex) {
                                if (!(ex.InnerException is TaskCanceledException))
                                {
                                    throw;
                                }
                            }
                        }
                    } finally {
                        if (!task.IsCanceled && !task.IsCompleted && !task.IsFaulted)
                        {
                            if (task.Wait(10000))
                            {
                                task.Dispose();
                            }
                        }
                        else
                        {
                            task.Dispose();
                        }
                    }

                    // Then, execute command and allow it to proceed.
                    task = ExecuteAsync(node, "Require Packages");
                    try {
                        var dialogHandle = app.WaitForDialog(task);
                        if (dialogHandle == IntPtr.Zero)
                        {
                            if (task.IsFaulted && task.Exception != null)
                            {
                                Assert.Fail("Unexpected exception in package install confirmation dialog:\n{0}", task.Exception);
                            }
                            else
                            {
                                Assert.AreNotEqual(IntPtr.Zero, dialogHandle);
                            }
                        }

                        using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(dialogHandle))) {
                            dialog.ClickButtonAndClose("CommandLink_1000", nameIsAutomationId: true);
                        }
                        task.Wait();

                        var ver = PythonVersion.Version.ToVersion();
                        ExpectOutputWindowText(app, string.Format("pass {0}.{1}", ver.Major, ver.Minor));
                    } finally {
                        if (!task.IsCanceled && !task.IsCompleted && !task.IsFaulted)
                        {
                            if (task.Wait(10000))
                            {
                                task.Dispose();
                            }
                        }
                        else
                        {
                            task.Dispose();
                        }
                    }
                }
        }