private static bool OnNoSccDialog(AutomationDialog dlg) { if (dlg.Text.Contains("source control provider associated with this solution could not be found")) { dlg.ClickButtonByName("No"); return true; } return false; }
/// <summary> /// Checks the text of a dialog and dismisses it. /// /// dlgField is the field to check the text of. /// buttonId is the button to press to dismiss. /// </summary> private void CheckAndDismissDialog(string[] text, int dlgField, string buttonId, bool assertIfNoDialog) { var handle = new IntPtr(Dte.MainWindow.HWnd); IVsUIShell uiShell = ServiceProvider.GetService(typeof(IVsUIShell)) as IVsUIShell; IntPtr hwnd; uiShell.GetDialogOwnerHwnd(out hwnd); for (int i = 0; i < 20 && hwnd == handle; i++) { System.Threading.Thread.Sleep(500); uiShell.GetDialogOwnerHwnd(out hwnd); } if (!assertIfNoDialog && (hwnd == IntPtr.Zero || hwnd == handle)) { return; } Assert.AreNotEqual(IntPtr.Zero, hwnd, "hwnd is null, We failed to get the dialog"); Assert.AreNotEqual(handle, hwnd, "hwnd is Dte.MainWindow, We failed to get the dialog"); Console.WriteLine("Ending dialog: "); var dlg = new AutomationDialog(this, AutomationElement.FromHandle(hwnd)); AutomationWrapper.DumpElement(dlg.Element); Console.WriteLine("--------"); bool closed = false; try { string title = dlg.Text; if (assertIfNoDialog) { AssertUtil.Contains(title, text); } else if (!text.All(title.Contains)) { // We do not want to close the dialog now, as it may be expected // by a later part of the test. closed = true; } } finally { if (!closed) { if (buttonId == MessageBoxButton.Close.ToString()) { dlg.WaitForClosed(TimeSpan.FromSeconds(10.0), dlg.CloseWindow); } else if (!dlg.ClickButtonAndClose(buttonId)) { dlg.CloseWindow(); } } } }
public Project OpenProject( string projName, string startItem = null, int?expectedProjects = null, string projectName = null, bool setStartupItem = true, Func <AutomationDialog, bool> onDialog = null ) { var solution = GetService <IVsSolution>(typeof(SVsSolution)); var solution4 = solution as IVsSolution4; Assert.IsNotNull(solution, "Failed to obtain SVsSolution service"); Assert.IsNotNull(solution4, "Failed to obtain IVsSolution4 interface"); // Close any open solution if (ErrorHandler.Succeeded(solution.GetSolutionInfo(out _, out string slnFile, out _))) { Console.WriteLine("Closing {0}", slnFile); solution.CloseSolutionElement(0, null, 0); } string fullPath = TestData.GetPath(projName); if (!File.Exists(fullPath)) { Assert.Fail("Cannot find " + fullPath); } Console.WriteLine("Opening {0}", fullPath); // If there is a .suo file, delete that so that there is no state carried over from another test. for (int i = 10; i <= 15; ++i) { string suoPath = Path.ChangeExtension(fullPath, ".v" + i + ".suo"); if (File.Exists(suoPath)) { File.Delete(suoPath); } } var dotVsPath = Path.Combine(Path.GetDirectoryName(fullPath), ".vs"); if (Directory.Exists(dotVsPath)) { foreach (var suoPath in FileUtils.EnumerateFiles(dotVsPath, ".vso")) { File.Delete(suoPath); } } Task t; if (fullPath.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)) { t = Task.Run(() => { ErrorHandler.ThrowOnFailure(solution.OpenSolutionFile((uint)0, fullPath)); // Force all projects to load before running any tests. solution4.EnsureSolutionIsLoaded((uint)__VSBSLFLAGS.VSBSLFLAGS_None); }); } else { t = Task.Run(() => { Guid guidNull = Guid.Empty; Guid iidUnknown = Guid.Empty; IntPtr projPtr; ErrorHandler.ThrowOnFailure(solution.CreateProject( ref guidNull, fullPath, "", "", (uint)__VSCREATEPROJFLAGS.CPF_OPENFILE | (uint)__VSCREATEPROJFLAGS2.CPF_OPEN_STANDALONE | (uint)__VSCREATEPROJFLAGS.CPF_SILENT, ref iidUnknown, out projPtr )); // Force all projects to load before running any tests. solution4.EnsureSolutionIsLoaded((uint)__VSBSLFLAGS.VSBSLFLAGS_None); }); } using (var cts = System.Diagnostics.Debugger.IsAttached ? new CancellationTokenSource() : new CancellationTokenSource(30000)) { try { if (!t.Wait(1000, cts.Token)) { // Load has taken a while, start checking whether a dialog has // appeared IVsUIShell uiShell = GetService <IVsUIShell>(typeof(IVsUIShell)); IntPtr hwnd; while (!t.Wait(1000, cts.Token)) { ErrorHandler.ThrowOnFailure(uiShell.GetDialogOwnerHwnd(out hwnd)); if (hwnd != _mainWindowHandle) { using (var dlg = new AutomationDialog(this, AutomationElement.FromHandle(hwnd))) { if (onDialog == null || onDialog(dlg) == false) { Console.WriteLine("Unexpected dialog"); DumpElement(dlg.Element); Assert.Fail("Unexpected dialog while loading project"); } } } } } } catch (OperationCanceledException) { Assert.Fail("Failed to open project quickly enough"); } } var projects = EnumerateLoadedProjects(solution).ToList(); if (expectedProjects != null && expectedProjects.Value != projects.Count) { // if we have other files open we can end up with a bonus project... Assert.AreEqual( expectedProjects, projects.Count(p => { string mk; return(ErrorHandler.Succeeded(solution.GetUniqueNameOfProject((IVsHierarchy)p, out mk)) && mk != "Miscellaneous Files"); }), "Wrong number of loaded projects" ); } var vsProject = string.IsNullOrEmpty(projectName) ? projects.OfType <IVsHierarchy>().FirstOrDefault() : projects.OfType <IVsHierarchy>().FirstOrDefault(p => { string mk; if (ErrorHandler.Failed(solution.GetUniqueNameOfProject(p, out mk))) { return(false); } Console.WriteLine(mk); return(Path.GetFileNameWithoutExtension(mk) == projectName); }); string outputText = "(unable to get Solution output)"; try { outputText = GetOutputWindowText("Solution"); } catch (Exception) { } Assert.IsNotNull(vsProject, "No project loaded: " + outputText); Guid projGuid; ErrorHandler.ThrowOnFailure(solution.GetGuidOfProject(vsProject, out projGuid)); object o; ErrorHandler.ThrowOnFailure(vsProject.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out o)); var project = (Project)o; if (project.Properties == null) { ErrorHandler.ThrowOnFailure(solution4.ReloadProject(ref projGuid)); } // HACK: Testing whether Properties is just slow to initialize for (int retries = 10; retries > 0 && project.Properties == null; --retries) { Trace.TraceWarning("Waiting for project.Properties to become non-null"); System.Threading.Thread.Sleep(250); } Assert.IsNotNull(project.Properties, "No project properties: " + outputText); Assert.IsTrue(project.Properties.GetEnumerator().MoveNext(), "No items in project properties: " + outputText); if (startItem != null && setStartupItem) { project.SetStartupFile(startItem); for (var i = 0; i < 20; i++) { //Wait for the startupItem to be set before returning from the project creation try { if (((string)project.Properties.Item("StartupFile").Value) == startItem) { break; } } catch { } System.Threading.Thread.Sleep(250); } } DeleteAllBreakPoints(); return(project); }
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(); } } } }
public void WebProjectInstallOnNew() { using (var app = new PythonVisualStudioApp()) { app.OptionsService.DefaultInterpreter.PipUninstall("bottle"); var t = Task.Run(() => app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.BottleWebProjectTemplate, TestData.GetTempPath(), "WebProjectInstallOnNew", suppressUI: false )); using (var dlg = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(t)))) { // Install to active environment dlg.ClickButtonAndClose("CommandLink_1001", nameIsAutomationId: true); } var project = t.WaitAndUnwrapExceptions(); Assert.AreSame(app.OptionsService.DefaultInterpreter, project.GetPythonProject().ActiveInterpreter); for (int retries = 60; retries > 0; --retries) { if (project.GetPythonProject().ActiveInterpreter.FindModules("bottle").Any()) { break; } Thread.Sleep(1000); } AssertUtil.ContainsExactly(project.GetPythonProject().ActiveInterpreter.FindModules("bottle"), "bottle"); app.OptionsService.DefaultInterpreter.PipUninstall("bottle"); } }
public void WebProjectCreateVirtualEnvOnNew() { using (var app = new PythonVisualStudioApp()) { var t = Task.Run(() => app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.FlaskWebProjectTemplate, TestData.GetTempPath(), "WebProjectCreateVirtualEnvOnNew", suppressUI: false )); using (var dlg = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(t)))) { // Create a virtual environment dlg.ClickButtonAndClose("CommandLink_1000", nameIsAutomationId: true); } using (var dlg = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(t)))) { dlg.ClickButtonByAutomationId("Create"); dlg.ClickButtonAndClose("Close", nameIsAutomationId: true); } var project = t.WaitAndUnwrapExceptions(); var contextProvider = app.ComponentModel.GetService<VsProjectContextProvider>(); for (int retries = 20; retries > 0; --retries) { if (contextProvider.IsProjectSpecific(project.GetPythonProject().ActiveInterpreter.Configuration)) { break; } Thread.Sleep(1000); } Assert.IsTrue(contextProvider.IsProjectSpecific(project.GetPythonProject().ActiveInterpreter.Configuration), "Did not have virtualenv"); for (int retries = 60; retries > 0; --retries) { if (project.GetPythonProject().ActiveInterpreter.FindModules("flask").Any()) { break; } Thread.Sleep(1000); } AssertUtil.ContainsExactly(project.GetPythonProject().ActiveInterpreter.FindModules("flask"), "flask"); } }
public Project OpenProject( string projName, string startItem = null, int?expectedProjects = null, string projectName = null, bool setStartupItem = true, Func <AutomationDialog, bool> onDialog = null ) { string fullPath = TestData.GetPath(projName); Assert.IsTrue(File.Exists(fullPath), "Cannot find " + fullPath); Console.WriteLine("Opening {0}", fullPath); // If there is a .suo file, delete that so that there is no state carried over from another test. for (int i = 10; i <= 14; ++i) { string suoPath = Path.ChangeExtension(fullPath, ".v" + i + ".suo"); if (File.Exists(suoPath)) { File.Delete(suoPath); } } var t = Task.Run(() => Dte.Solution.Open(fullPath)); using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30))) { try { if (!t.Wait(1000, cts.Token)) { // Load has taken a while, start checking whether a dialog has // appeared IVsUIShell uiShell = GetService <IVsUIShell>(typeof(IVsUIShell)); IntPtr hwnd; while (!t.Wait(1000, cts.Token)) { ErrorHandler.ThrowOnFailure(uiShell.GetDialogOwnerHwnd(out hwnd)); if (hwnd != _mainWindowHandle) { using (var dlg = new AutomationDialog(this, AutomationElement.FromHandle(hwnd))) { if (onDialog == null || onDialog(dlg) == false) { Console.WriteLine("Unexpected dialog"); DumpElement(dlg.Element); Assert.Fail("Unexpected dialog while loading project"); } } } } } } catch (OperationCanceledException) { Assert.Fail("Failed to open project quickly enough"); } } Assert.IsTrue(Dte.Solution.IsOpen, "The solution is not open"); // Force all projects to load before running any tests. var solution = GetService <IVsSolution4>(typeof(SVsSolution)); Assert.IsNotNull(solution, "Failed to obtain SVsSolution service"); solution.EnsureSolutionIsLoaded((uint)__VSBSLFLAGS.VSBSLFLAGS_None); int count = Dte.Solution.Projects.Count; if (expectedProjects != null && expectedProjects.Value != count) { // if we have other files open we can end up with a bonus project... int i = 0; foreach (EnvDTE.Project proj in Dte.Solution.Projects) { if (proj.Name != "Miscellaneous Files") { i++; } } Assert.AreEqual(expectedProjects, i, "Wrong number of loaded projects"); } Project project = GetProject(projectName); string outputText = "(unable to get Solution output)"; try { outputText = GetOutputWindowText("Solution"); } catch (Exception) { } Assert.IsNotNull(project, "No project loaded: " + outputText); // HACK: Testing whether Properties is just slow to initialize for (int retries = 10; retries > 0 && project.Properties == null; --retries) { Trace.TraceWarning("Waiting for project.Properties to become non-null"); System.Threading.Thread.Sleep(250); } Assert.IsNotNull(project.Properties, "No project properties: " + outputText); Assert.IsTrue(project.Properties.GetEnumerator().MoveNext(), "No items in project properties: " + outputText); if (startItem != null && setStartupItem) { project.SetStartupFile(startItem); for (var i = 0; i < 20; i++) { //Wait for the startupItem to be set before returning from the project creation try { if (((string)project.Properties.Item("StartupFile").Value) == startItem) { break; } } catch { } System.Threading.Thread.Sleep(250); } } DeleteAllBreakPoints(); return(project); }