public override ToolWindowPane ActivateInteractiveWindow(VisualStudioApp app, string executionMode) { string description = null; if (Version.IsCPython) { description = string.Format("{0} {1}", Version.Isx64 ? "Python 64-bit" : "Python 32-bit", Version.Version.ToVersion() ); } else if (Version.IsIronPython) { description = string.Format("{0} {1}", Version.Isx64 ? "IronPython 64-bit" : "IronPython", Version.Version.ToVersion() ); } Assert.IsNotNull(description, "Unknown interpreter"); var automation = (IVsPython)app.Dte.GetObject("VsPython"); var options = (IPythonOptions)automation; var replOptions = options.Interactive; Assert.IsNotNull(replOptions, "Could not find options for " + description); var oldAddNewLineAtEndOfFullyTypedWord = options.Intellisense.AddNewLineAtEndOfFullyTypedWord; app.OnDispose(() => options.Intellisense.AddNewLineAtEndOfFullyTypedWord = oldAddNewLineAtEndOfFullyTypedWord); options.Intellisense.AddNewLineAtEndOfFullyTypedWord = AddNewLineAtEndOfFullyTypedWord; var interpreters = app.ComponentModel.GetService<IInterpreterRegistryService>(); var replId = PythonReplEvaluatorProvider.GetEvaluatorId( interpreters.FindConfiguration(Version.Id) ); return app.ServiceProvider.GetUIThread().Invoke(() => { var provider = app.ComponentModel.GetService<InteractiveWindowProvider>(); return (ToolWindowPane)provider.OpenOrCreate(replId); }); }
public static VisualStudioApp FromProcessId(int processId) { VisualStudioApp inst; lock (_knownInstances) { if (!_knownInstances.TryGetValue(processId, out inst)) { _knownInstances[processId] = inst = new VisualStudioApp(processId); } } return inst; }
internal void OpenProject(VisualStudioApp app, string slnName, out PythonProjectNode projectNode, out EnvDTE.Project dteProject) { PythonVersion.AssertInstalled(); dteProject = app.OpenProject("TestData\\Targets\\" + slnName); projectNode = dteProject.GetPythonProject(); var fact = projectNode.InterpreterFactories.Where(x => x.Configuration.Id == PythonVersion.Id).FirstOrDefault(); Assert.IsNotNull(fact, "Project does not contain expected interpreter"); projectNode.ActiveInterpreter = fact; dteProject.Save(); }
private EnvDTE.Project CreateTemporaryProject(VisualStudioApp app) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.PythonApplicationTemplate, TestData.GetTempPath(), TestContext.TestName ); Assert.IsNotNull(project, "Project was not created"); return project; }
public void TestNpmUIInitialization() { using (var app = new VisualStudioApp()) { // Initialize call is required because NTVS does not autoload its package // We may not be on UI thread, but Dev11 and Dev12 know how to sort that out. app.ServiceProvider.GetUIThread().Invoke(() => { NpmPackageInstallWindow npmWindow = OpenNpmWindowAndWaitForReady(); Assert.IsTrue(npmWindow.FilterTextBox.IsKeyboardFocused, "FilterTextBox should be keyboard focused"); Assert.AreEqual(0, npmWindow._packageList.SelectedIndex, "First item in package list should be selected"); }); } }
public void NpmUIArrowKeyBehavior() { using (var app = new VisualStudioApp()) { app.ServiceProvider.GetUIThread().Invoke(() => { NpmPackageInstallWindow npmWindow = OpenNpmWindowAndWaitForReady(); System.Windows.Input.Keyboard.Focus(npmWindow.FilterTextBox); TestUtilities.UI.Keyboard.PressAndRelease(Key.Down); WaitForUIInputIdle(); var selectedItem = GetSelectedPackageListItemContainer(npmWindow); Assert.IsTrue(selectedItem.IsKeyboardFocused, "Focus should be on newly selected item"); Assert.AreEqual(0, npmWindow._packageList.SelectedIndex); TestUtilities.UI.Keyboard.PressAndRelease(Key.Down); WaitForUIInputIdle(); Assert.AreEqual(1, npmWindow._packageList.SelectedIndex); npmWindow.FilterTextBox.Focus(); TestUtilities.UI.Keyboard.PressAndRelease(Key.Up); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.FilterTextBox.IsKeyboardFocused, "Focus should remain on filter box"); Assert.AreEqual(1, npmWindow._packageList.SelectedIndex, "Pressing up while in filter box should maintain current selection"); selectedItem = GetSelectedPackageListItemContainer(npmWindow); selectedItem.Focus(); TestUtilities.UI.Keyboard.PressAndRelease(Key.Up); TestUtilities.UI.Keyboard.PressAndRelease(Key.Up); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.FilterTextBox.IsKeyboardFocused, "Focus should move to filter textbox after pressing up key while on topmost package is selected"); TestUtilities.UI.Keyboard.PressAndRelease(Key.Up); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.FilterTextBox.IsKeyboardFocused, "Focus should remain on textbox while pressing up when topmost package is selected"); Assert.IsFalse(npmWindow.InstallButton.IsEnabled, "Install button should not be enabled when filter box has focus"); TestUtilities.UI.Keyboard.PressAndRelease(Key.Enter); WaitForUIInputIdle(); selectedItem = GetSelectedPackageListItemContainer(npmWindow); Assert.IsTrue(selectedItem.IsKeyboardFocused, "Focus should be on newly selected item"); Assert.AreEqual(0, npmWindow._packageList.SelectedIndex); }); } }
public static VisualStudioApp FromCommandLineArgs(string[] commandLineArgs) { for (int i = 0; i < commandLineArgs.Length - 1; ++i) { int processId; if (commandLineArgs[i].Equals("/parentProcessId", StringComparison.InvariantCultureIgnoreCase) && int.TryParse(commandLineArgs[i + 1], out processId)) { VisualStudioApp inst; lock (_knownInstances) { if (!_knownInstances.TryGetValue(processId, out inst)) { _knownInstances[processId] = inst = new VisualStudioApp(processId); } } return inst; } } return null; }
public void NewDjangoProject() { using (var app = new VisualStudioApp()) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.DjangoWebProjectTemplate, TestData.GetTempPath(), "NewDjangoProject" ); var folder = project.ProjectItems.Item(project.Name); Assert.IsNotNull(project.ProjectItems.Item("manage.py")); Assert.IsNotNull(folder.ProjectItems.Item("settings.py")); Assert.IsNotNull(folder.ProjectItems.Item("urls.py")); Assert.IsNotNull(folder.ProjectItems.Item("__init__.py")); Assert.IsNotNull(folder.ProjectItems.Item("wsgi.py")); } }
public void NewDjangoProjectSafeProjectName() { using (var app = new VisualStudioApp()) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.DjangoWebProjectTemplate, TestData.GetTempPath(), "Django Project $100" ); var folder = project.ProjectItems.Item("Django_Project__100"); Assert.IsNotNull(project.ProjectItems.Item("manage.py")); Assert.IsNotNull(folder.ProjectItems.Item("settings.py")); Assert.IsNotNull(folder.ProjectItems.Item("urls.py")); Assert.IsNotNull(folder.ProjectItems.Item("__init__.py")); Assert.IsNotNull(folder.ProjectItems.Item("wsgi.py")); var settings = app.ServiceProvider.GetUIThread().Invoke(() => project.GetPythonProject().GetProperty("DjangoSettingsModule")); Assert.AreEqual("Django_Project__100.settings", settings); } }
public void TestAttachBasic() { string debugSolution = TestData.GetPath(@"TestData\DebugAttach\DebugAttach.sln"); string startFile = "Simple.py"; using (var app = new VisualStudioApp()) { var dbg2 = (Debugger2)app.Dte.Debugger; SD.Process processToAttach = OpenSolutionAndLaunchFile(app, debugSolution, startFile, "", ""); try { AttachAndWaitForMode(app, processToAttach, AD7Engine.DebugEngineName, dbgDebugMode.dbgRunMode); } finally { dbg2.DetachAll(); DebugProject.WaitForMode(app, dbgDebugMode.dbgDesignMode); if (!processToAttach.HasExited) processToAttach.Kill(); } } }
public void CustomCommandsAdded() { using (var app = new VisualStudioApp()) { PythonProjectNode node; EnvDTE.Project proj; OpenProject(app, "Commands1.sln", out node, out proj); AssertUtil.ContainsExactly( node._customCommands.Select(cc => cc.DisplayLabel), "Test Command 1", "Test Command 2" ); app.OpenSolutionExplorer().FindItem("Solution 'Commands1' (1 project)", "Commands1").Select(); var menuBar = app.FindByAutomationId("MenuBar").AsWrapper(); Assert.IsNotNull(menuBar, "Unable to find menu bar"); var projectMenu = menuBar.FindByName("Project").AsWrapper(); Assert.IsNotNull(projectMenu, "Unable to find Project menu"); projectMenu.Element.EnsureExpanded(); try { foreach (var name in node._customCommands.Select(cc => cc.DisplayLabelWithoutAccessKeys)) { Assert.IsNotNull(projectMenu.FindByName(name), name + " not found"); } } finally { try { // Try really really hard to collapse and deselect the // Project menu, since VS will keep it selected and it // may not come back for some reason... projectMenu.Element.Collapse(); Keyboard.PressAndRelease(System.Windows.Input.Key.Escape); Keyboard.PressAndRelease(System.Windows.Input.Key.Escape); } catch { // ...but don't try so hard that we fail if we can't // simulate keypresses. } } } }
private static void AutoBraceCompetionTest(VisualStudioApp app, Project project, string typedText, string expectedText) { var item = project.ProjectItems.Item("Program.py"); var window = item.Open(); window.Activate(); Keyboard.Type(typedText); var doc = app.GetDocument(item.Document.FullName); string actual = null; for (int i = 0; i < 100; i++) { actual = doc.TextView.TextBuffer.CurrentSnapshot.GetText(); if (expectedText == actual) { break; } System.Threading.Thread.Sleep(100); } Assert.AreEqual(expectedText, actual); window.Document.Close(vsSaveChanges.vsSaveChangesNo); }
public void AddReferenceAndBuild() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\ProjectReference.sln"); TargetInfo ti = TargetInfo.GetTargetInfo(); // Wait for solution to load... for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { System.Threading.Thread.Sleep(250); } Assert.IsFalse(0 == app.Dte.Solution.Projects.Count); // Set platform foreach (SolutionConfiguration2 solConfiguration2 in app.Dte.Solution.SolutionBuild.SolutionConfigurations) { if (String.Equals(solConfiguration2.PlatformName, ti.Plat, StringComparison.Ordinal)) { solConfiguration2.Activate(); break; } } // Build project app.Dte.Solution.SolutionBuild.Build(true); // Check for C# reference in the appxrecipe file string appxRecipePath = string.Format("{0}\\TestData\\ProjectReference\\bin\\{1}\\Debug\\ProjectReference.build.appxrecipe", Directory.GetCurrentDirectory(), ti.Plat); Assert.AreEqual(true, File.Exists(appxRecipePath), string.Format("ProjectReference.build.appxrecipe is missing from bin output folder")); string appxRecipeStr = File.ReadAllText(appxRecipePath); Assert.IsTrue(appxRecipeStr.Contains("CSComponent")); } }
private static void CloudProjectTest(string roleType, bool openServiceDefinition) { Assert.IsTrue(roleType == "Web" || roleType == "Worker", "Invalid roleType: " + roleType); using (var app = new VisualStudioApp()) using (FileUtils.Backup(TestData.GetPath(@"TestData\CloudProject\CloudProject\ServiceDefinition.csdef"))) { app.OpenProject("TestData\\CloudProject.sln", expectedProjects: 3); var ccproj = app.Dte.Solution.Projects.Cast<EnvDTE.Project>().FirstOrDefault(p => p.Name == "CloudProject"); Assert.IsNotNull(ccproj); if (openServiceDefinition) { var wnd = ccproj.ProjectItems.Item("ServiceDefinition.csdef").Open(); wnd.Activate(); app.OnDispose(() => wnd.Close()); } IVsHierarchy hier; var sln = app.GetService<IVsSolution>(typeof(SVsSolution)); ErrorHandler.ThrowOnFailure(sln.GetProjectOfUniqueName(ccproj.FullName, out hier)); app.ServiceProvider.GetUIThread().Invoke(() => NodejsProject.UpdateServiceDefinition( hier, roleType, roleType + "Role1", new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)app.Dte) ) ); var doc = new XmlDocument(); for (int retries = 5; retries > 0; --retries) { try { doc.Load(TestData.GetPath(@"TestData\CloudProject\CloudProject\ServiceDefinition.csdef")); break; } catch (IOException ex) { Console.WriteLine("Exception while reading ServiceDefinition.csdef.{0}{1}", Environment.NewLine, ex); } catch (XmlException) { var copyTo = TestData.GetPath(@"TestData\CloudProject\CloudProject\" + Path.GetRandomFileName()); File.Copy(TestData.GetPath(@"TestData\CloudProject\CloudProject\ServiceDefinition.csdef"), copyTo); Console.WriteLine("Copied file to " + copyTo); throw; } Thread.Sleep(100); } var ns = new XmlNamespaceManager(doc.NameTable); ns.AddNamespace("sd", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"); doc.Save(Console.Out); var nav = doc.CreateNavigator(); if (roleType == "Web") { Assert.IsNotNull(nav.SelectSingleNode( "/sd:ServiceDefinition/sd:WebRole[@name='WebRole1']/sd:Startup/sd:Task[@commandLine='setup_web.cmd > log.txt']", ns )); } else if (roleType == "Worker") { Assert.IsNotNull(nav.SelectSingleNode( "/sd:ServiceDefinition/sd:WorkerRole[@name='WorkerRole1']/sd:Startup/sd:Task[@commandLine='setup_worker.cmd > log.txt']", ns )); Assert.IsNotNull(nav.SelectSingleNode( "/sd:ServiceDefinition/sd:WorkerRole[@name='WorkerRole1']/sd:Runtime/sd:EntryPoint/sd:ProgramEntryPoint[@commandLine='node.cmd .\\server.js']", ns )); } } }
public void ErrorListAndTaskListAreClearedWhenProjectWithMultipleFilesIsUnloaded() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\ErrorProjectMultipleFiles.sln"); app.WaitForTaskListItems(typeof(SVsErrorList), 14); app.WaitForTaskListItems(typeof(SVsTaskList), 4); var solutionService = app.GetService<IVsSolution>(typeof(SVsSolution)); Assert.IsNotNull(solutionService); IVsHierarchy selectedHierarchy; ErrorHandler.ThrowOnFailure(solutionService.GetProjectOfUniqueName(project.UniqueName, out selectedHierarchy)); Assert.IsNotNull(selectedHierarchy); Console.WriteLine("Unloading project"); ErrorHandler.ThrowOnFailure(solutionService.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_UnloadProject, selectedHierarchy, 0)); app.WaitForTaskListItems(typeof(SVsErrorList), 0); app.WaitForTaskListItems(typeof(SVsTaskList), 0); } }
internal void TaskListTest(VisualStudioApp app, Type taskListService, IList<TaskItemInfo> expectedItems, int[] navigateTo = null) { var items = app.WaitForTaskListItems(taskListService, expectedItems.Count); var actualItems = items.Select(item => new TaskItemInfo(item)).ToList(); Assert.AreEqual(expectedItems.Count, actualItems.Count); AssertUtil.ContainsExactly(actualItems, expectedItems.ToSet()); if (navigateTo != null) { foreach (var i in navigateTo) { Console.WriteLine("Trying to navigate to " + expectedItems[i]); var j = actualItems.IndexOf(expectedItems[i]); Assert.IsTrue(j >= 0); app.ServiceProvider.GetUIThread().Invoke((Action)delegate { items[j].NavigateTo(); }); var doc = app.Dte.ActiveDocument; Assert.IsNotNull(doc); Assert.AreEqual(expectedItems[i].Document, doc.FullName); var textDoc = (EnvDTE.TextDocument)doc.Object("TextDocument"); Assert.AreEqual(expectedItems[i].Line + 1, textDoc.Selection.ActivePoint.Line); Assert.AreEqual(expectedItems[i].Column + 1, textDoc.Selection.ActivePoint.DisplayColumn); } } }
public void TestNpmUITabKeyBehavior() { using (var app = new VisualStudioApp()) { app.ServiceProvider.GetUIThread().Invoke(() => { NpmPackageInstallWindow npmWindow = OpenNpmWindowAndWaitForReady(); npmWindow.FilterTextBox.Focus(); WaitForUIInputIdle(); TestUtilities.UI.Keyboard.PressAndRelease(Key.Tab); WaitForUIInputIdle(); var selectedItem = GetSelectedPackageListItemContainer(npmWindow); Assert.IsTrue(selectedItem.IsKeyboardFocused); // Install button disabled, must key down to select "installable" package TestUtilities.UI.Keyboard.PressAndRelease(Key.Down); TestUtilities.UI.Keyboard.PressAndRelease(Key.Tab); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.DependencyComboBox.IsKeyboardFocused); TestUtilities.UI.Keyboard.PressAndRelease(Key.Tab); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.SaveToPackageJsonCheckbox.IsKeyboardFocused); TestUtilities.UI.Keyboard.PressAndRelease(Key.Tab); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.SelectedVersionComboBox.IsKeyboardFocused); TestUtilities.UI.Keyboard.PressAndRelease(Key.Tab); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.ArgumentsTextBox.IsKeyboardFocused); TestUtilities.UI.Keyboard.PressAndRelease(Key.Tab); WaitForUIInputIdle(); Assert.IsTrue(npmWindow.InstallButton.IsKeyboardFocused); }); } }
public void DjangoProjectWithSubdirectory() { using (var app = new VisualStudioApp()) { var project = app.OpenProject("TestData\\DjangoProjectWithSubDirectory.sln"); var pyProj = (IPythonProject2)project.GetPythonProject(); var dsm = pyProj.Site.GetUIThread().Invoke(() => pyProj.GetProperty("DjangoSettingsModule")); Assert.AreEqual("config.settings", dsm); var workDir = pyProj.Site.GetUIThread().Invoke(() => pyProj.GetWorkingDirectory()).TrimEnd('\\'); Assert.AreEqual(TestData.GetPath("TestData\\DjangoProjectWithSubDirectory\\project"), workDir, true); var cmd = pyProj.FindCommand("DjangoCollectStaticCommand"); pyProj.Site.GetUIThread().Invoke(() => { Assert.IsTrue(cmd.CanExecute(pyProj), "Cannot execute DjangoCollectStaticCommand"); cmd.Execute(pyProj); }); // The static dir is 'test_static', check that the admin files // are copied into there. Assert.IsTrue(Directory.Exists(Path.Combine(workDir, "test_static", "admin")), "admin static directory was not created"); Assert.IsTrue(File.Exists(Path.Combine(workDir, "test_static", "admin", "css", "base.css")), "admin static files were not copied"); } }
private void RunTestCase(VisualStudioApp app, IFrameworkHandle frameworkHandle, IRunContext runContext, TestCase test, Dictionary<string, NodejsProjectSettings> sourceToSettings) { var testResult = new TestResult(test); frameworkHandle.RecordStart(test); testResult.StartTime = DateTimeOffset.Now; NodejsProjectSettings settings; if (!sourceToSettings.TryGetValue(test.Source, out settings)) { sourceToSettings[test.Source] = settings = LoadProjectSettings(test.Source); } if (settings == null) { frameworkHandle.SendMessage( TestMessageLevel.Error, "Unable to determine interpreter to use for " + test.Source); RecordEnd( frameworkHandle, test, testResult, null, "Unable to determine interpreter to use for " + test.Source, TestOutcome.Failed); return; } NodejsTestInfo testInfo = new NodejsTestInfo(test.FullyQualifiedName); List<string> args = new List<string>(); int port = 0; if (runContext.IsBeingDebugged && app != null) { app.GetDTE().Debugger.DetachAll(); args.AddRange(GetDebugArgs(settings, out port)); } var workingDir = Path.GetDirectoryName(CommonUtils.GetAbsoluteFilePath(settings.WorkingDir, testInfo.ModulePath)); args.AddRange(GetInterpreterArgs(test, workingDir, settings.ProjectRootDir)); //Debug.Fail("attach debugger"); if (!File.Exists(settings.NodeExePath)) { frameworkHandle.SendMessage(TestMessageLevel.Error, "Interpreter path does not exist: " + settings.NodeExePath); return; } lock (_syncObject) { _nodeProcess = ProcessOutput.Run( settings.NodeExePath, args, workingDir, null, false, null, false); #if DEBUG frameworkHandle.SendMessage(TestMessageLevel.Informational, "cd " + workingDir); frameworkHandle.SendMessage(TestMessageLevel.Informational, _nodeProcess.Arguments); #endif _nodeProcess.Wait(TimeSpan.FromMilliseconds(500)); if (runContext.IsBeingDebugged && app != null) { try { //the '#ping=0' is a special flag to tell VS node debugger not to connect to the port, //because a connection carries the consequence of setting off --debug-brk, and breakpoints will be missed. string qualifierUri = string.Format("tcp://localhost:{0}#ping=0", port); while (!app.AttachToProcess(_nodeProcess, NodejsRemoteDebugPortSupplierUnsecuredId, qualifierUri)) { if (_nodeProcess.Wait(TimeSpan.FromMilliseconds(500))) { break; } } #if DEBUG } catch (COMException ex) { frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee."); frameworkHandle.SendMessage(TestMessageLevel.Error, ex.ToString()); KillNodeProcess(); } #else } catch (COMException) { frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee."); KillNodeProcess(); } #endif } }
public TestExecutor() { _app = VisualStudioApp.FromEnvironmentVariable(PythonConstants.PythonToolsProcessIdEnvironmentVariable); _interpreterService = InterpreterOptionsServiceProvider.GetService(_app); }
public void ClientServerIntelliSenseModes() { string solutionLabel = "Solution 'ClientServerCode' (1 project)", projectLabel = "ClientServerCode", nodeDirectoryLabel = NodejsFolderNode.AppendLabel("NodeDirectory", FolderContentType.Node), nodeSubDirectoryLabel = NodejsFolderNode.AppendLabel("NodeSubDirectory", FolderContentType.Node), browserDirectoryLabel = NodejsFolderNode.AppendLabel("BrowserDirectory", FolderContentType.Browser), emptyBrowserSubDirectoryLabel = "BrowserSubDirectory", browserSubDirectoryLabel = NodejsFolderNode.AppendLabel("BrowserSubDirectory", FolderContentType.Browser), mixedDirectoryLabel = NodejsFolderNode.AppendLabel("MixedDirectory", FolderContentType.Mixed), mixedDirectoryBrowserDirectoryLabel = NodejsFolderNode.AppendLabel("BrowserDirectory", FolderContentType.Browser), mixedDirectoryNodeDirectoryLabel = NodejsFolderNode.AppendLabel("NodeDirectory", FolderContentType.Node), browserCodeLabel = "browserCode.js", mixedDirectoryRenamedLabel = NodejsFolderNode.AppendLabel("MixedDirectoryRenamed", FolderContentType.Mixed); using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\ClientServerCode\ClientServerCode.sln"); using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", true)) { // Wait until project is loaded var solutionExplorer = app.OpenSolutionExplorer(); solutionExplorer.WaitForItem( solutionLabel, projectLabel, "app.js"); var nodejsProject = app.GetProject("ClientServerCode").GetNodejsProject(); var projectNode = solutionExplorer.WaitForItem( solutionLabel, projectLabel); var browserDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, browserDirectoryLabel ); Assert.IsNotNull( browserDirectory, "Browser directories should be labeled as such. Could not find " + browserDirectoryLabel); var browserSubDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, browserDirectoryLabel, emptyBrowserSubDirectoryLabel ); Assert.IsNotNull( browserSubDirectory, "Project initialization: could not find " + emptyBrowserSubDirectoryLabel); var nodeDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, nodeDirectoryLabel ); Assert.IsNotNull( nodeDirectory, "Node directories should be labeled as such. Could not find " + nodeDirectoryLabel); var nodeSubDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, nodeDirectoryLabel, nodeSubDirectoryLabel ); Assert.IsNotNull( nodeSubDirectory, "Project initialization: could not find " + nodeSubDirectoryLabel); projectNode.Select(); using (var newItem = NewItemDialog.FromDte(app)) { newItem.FileName = "newItem.js"; newItem.OK(); } Assert.AreEqual( "Compile", nodejsProject.GetItemType("newItem.js"), "Top level files should be set to item type 'Compile'"); Keyboard.Type("process."); Keyboard.Type(Keyboard.CtrlSpace.ToString()); using (var session = app.GetDocument(Path.Combine(nodejsProject.ProjectHome, @"newItem.js")).WaitForSession<ICompletionSession>()) { var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); Assert.IsTrue( completions.Contains("env"), "New documents of the node type should open with default VS editor" ); } browserSubDirectory.Select(); using (var newBrowserItem = NewItemDialog.FromDte(app)) { newBrowserItem.FileName = "newBrowserItem.js"; newBrowserItem.OK(); } Keyboard.Type("document."); System.Threading.Thread.Sleep(2000); Keyboard.Type(Keyboard.CtrlSpace.ToString()); using (var session = app.GetDocument(Path.Combine(nodejsProject.ProjectHome, @"BrowserDirectory\browserSubDirectory\newBrowserItem.js")).WaitForSession<ICompletionSession>()) { var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); Assert.IsTrue( completions.Contains("body"), "New documents of the browser type should open with default VS editor" ); } browserSubDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, browserDirectoryLabel, browserSubDirectoryLabel ); Assert.IsNotNull( browserSubDirectory, "Folder label was not updated to " + browserSubDirectoryLabel); var newBrowserItemFile = solutionExplorer.WaitForItem( solutionLabel, projectLabel, browserDirectoryLabel, browserSubDirectoryLabel, "newBrowserItem.js" ); Assert.AreEqual( "Content", nodejsProject.GetItemType(@"BrowserDirectory\BrowserSubDirectory\newBrowserItem.js"), "Adding a javascript file to a 'browser' directory should set the item type as Content."); var mixedDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, mixedDirectoryLabel ); Assert.IsNotNull( mixedDirectory, "Folder with mixed browser/node content should be specified as such. Could not find: " + mixedDirectoryLabel); nodeDirectory.Select(); using (var newTypeScriptItem = NewItemDialog.FromDte(app)) { newTypeScriptItem.FileName = "newTypeScriptItem.ts"; newTypeScriptItem.OK(); } Assert.AreEqual( "TypeScriptCompile", nodejsProject.GetItemType(@"NodeDirectory\newTypeScriptItem.ts"), "Non-javascript files should retain their content type."); var newBrowserItemNode = nodejsProject.FindNodeByFullPath( Path.Combine(nodejsProject.ProjectHome, @"BrowserDirectory\BrowserSubDirectory\newBrowserItem.js") ); newBrowserItemNode.ExcludeFromProject(); var excludedBrowserItem = solutionExplorer.WaitForItem( solutionLabel, projectLabel, browserDirectoryLabel, emptyBrowserSubDirectoryLabel ); Assert.IsNotNull( emptyBrowserSubDirectoryLabel, "Label should be removed when there are no included javascript files the directory. Could not find " + emptyBrowserSubDirectoryLabel); (newBrowserItemNode as NodejsFileNode).IncludeInProject(false); var includedBrowserItem = solutionExplorer.WaitForItem( solutionLabel, projectLabel, browserDirectoryLabel, browserSubDirectoryLabel ); Assert.IsNotNull( includedBrowserItem, "Label should be added when a javascript file is included in the directory. Could not find " + browserSubDirectoryLabel); var mixedDirectoryNode = app.GetProject("ClientServerCode").GetNodejsProject().FindNodeByFullPath( Path.Combine(nodejsProject.ProjectHome, @"MixedDirectory\")); System.Threading.Thread.Sleep(2000); mixedDirectory.Select(); Keyboard.PressAndRelease(Key.F2); Keyboard.Type("MixedDirectoryRenamed"); Keyboard.PressAndRelease(Key.Enter); mixedDirectoryNode.ExpandItem(EXPANDFLAGS.EXPF_ExpandFolderRecursively); var renamedMixedDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, mixedDirectoryRenamedLabel, mixedDirectoryBrowserDirectoryLabel, browserCodeLabel ); Assert.IsNotNull( renamedMixedDirectory, "Renaming mixed directory failed: could not find " + browserCodeLabel); newBrowserItemNode.ItemNode.ItemTypeName = "Compile"; var nodeBrowserSubDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, NodejsFolderNode.AppendLabel("BrowserDirectory", FolderContentType.Mixed), NodejsFolderNode.AppendLabel("BrowserSubDirectory", FolderContentType.Node) ); Assert.IsNotNull( nodeBrowserSubDirectory, "Changing the item type should change the directory label. Could not find " + NodejsFolderNode.AppendLabel("BrowserSubDirectory", FolderContentType.Node) ); var nodeDirectoryNode = app.GetProject("ClientServerCode").GetNodejsProject().FindNodeByFullPath( Path.Combine(app.GetProject("ClientServerCode").GetNodejsProject().ProjectHome, @"NodeDirectory\")); (nodeDirectoryNode as NodejsFolderNode).SetItemTypeRecursively(VSLangProj.prjBuildAction.prjBuildActionContent); Assert.AreEqual( "Content", nodejsProject.GetItemType(@"NodeDirectory\NodeSubDirectory\nodeCode.js"), "nodeCode.js file should be marked as content after recursively setting directory contents as Content." ); Assert.AreEqual( "TypeScriptCompile", nodejsProject.GetItemType(@"NodeDirectory\newTypeScriptItem.ts"), "Only javascript file item types should change when marking item types recursively." ); var fromPoint = solutionExplorer.WaitForItem( solutionLabel, projectLabel, mixedDirectoryRenamedLabel, mixedDirectoryNodeDirectoryLabel ).GetClickablePoint(); var toPoint = solutionExplorer.WaitForItem( solutionLabel, projectLabel, mixedDirectoryRenamedLabel, mixedDirectoryBrowserDirectoryLabel ).GetClickablePoint(); Mouse.MoveTo(fromPoint); Mouse.Down(MouseButton.Left); Mouse.MoveTo(toPoint); Mouse.Up(MouseButton.Left); var draggedDirectory = solutionExplorer.WaitForItem( solutionLabel, projectLabel, mixedDirectoryRenamedLabel, NodejsFolderNode.AppendLabel("BrowserDirectory", FolderContentType.Mixed), NodejsFolderNode.AppendLabel("NodeDirectory", FolderContentType.Node) ); Assert.IsNotNull( draggedDirectory, "Labels not properly updated after dragging and dropping directory." ); } } }
internal static void InstallWebFramework(VisualStudioApp app, string moduleName, string packageName, IPythonInterpreterFactory factory) { var task = app.ServiceProvider.GetUIThread().InvokeTask(() => factory.PipInstallAsync(packageName)); try { Assert.IsTrue(task.Wait(TimeSpan.FromMinutes(3.0)), "Timed out waiting for install " + packageName); } catch (AggregateException ex) { throw ex.InnerException; } Assert.AreEqual(1, factory.FindModules(moduleName).Count); }
private static void LaunchAndVerifyNoDebug( VisualStudioApp app, int port, string textInResponse ) { bool prevNormal = true, prevAbnormal = true; string text; int retries; try { using (var processes = new ProcessScope("python")) { EndToEndLog("Transitioning to UI thread to build"); app.ServiceProvider.GetUIThread().Invoke(() => { EndToEndLog("Building"); app.Dte.Solution.SolutionBuild.Build(true); EndToEndLog("Build output: {0}", app.GetOutputWindowText("Build")); EndToEndLog("Updating settings"); prevNormal = app.GetService<PythonToolsService>().DebuggerOptions.WaitOnNormalExit; prevAbnormal = app.GetService<PythonToolsService>().DebuggerOptions.WaitOnAbnormalExit; app.GetService<PythonToolsService>().DebuggerOptions.WaitOnNormalExit = false; app.GetService<PythonToolsService>().DebuggerOptions.WaitOnAbnormalExit = false; EndToEndLog("Starting running"); app.Dte.Solution.SolutionBuild.Run(); EndToEndLog("Running"); }); var newProcesses = processes.WaitForNewProcess(TimeSpan.FromSeconds(30)).ToList(); Assert.IsTrue(newProcesses.Any(), "Did not find new Python process"); EndToEndLog("Found new processes with IDs {0}", string.Join(", ", newProcesses.Select(p => p.Id.ToString()))); for (retries = 100; retries > 0 && !IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().Any(p => p.Port == port); --retries) { Thread.Sleep(300); } EndToEndLog("Active at http://localhost:{0}/", port); text = WebDownloadUtility.GetString(new Uri(string.Format("http://localhost:{0}/", port))); } } finally { app.ServiceProvider.GetUIThread().Invoke(() => { app.GetService<PythonToolsService>().DebuggerOptions.WaitOnNormalExit = prevNormal; app.GetService<PythonToolsService>().DebuggerOptions.WaitOnAbnormalExit = prevAbnormal; }); } EndToEndLog("Response from http://localhost:{0}/", port); EndToEndLog(text); Assert.IsTrue(text.Contains(textInResponse), text); for (retries = 20; retries > 0 && !IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().All(p => p.Port != port); --retries) { Thread.Sleep(500); } if (retries > 0) { EndToEndLog("Process ended"); } else { EndToEndLog("Timed out waiting for process to exit"); } }
private static void LaunchAndVerifyDebug(VisualStudioApp app, int port, string textInResponse) { EndToEndLog("Building"); app.Dte.Solution.SolutionBuild.Build(true); EndToEndLog("Starting debugging"); if (!System.Threading.Tasks.Task.Run(() => app.Dte.Debugger.Go(false)).Wait(TimeSpan.FromSeconds(10))) { Assert.Fail("Run was interrupted by dialog"); } EndToEndLog("Debugging started"); string text = string.Empty; int retries; try { for (retries = 100; retries > 0 && (app.Dte.Debugger.CurrentMode != EnvDTE.dbgDebugMode.dbgRunMode || !IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().Any(p => p.Port == port)); --retries) { Thread.Sleep(300); } if (retries > 0) { EndToEndLog("Active at http://localhost:{0}/", port); } else { EndToEndLog("Timed out waiting for http://localhost:{0}/", port); } text = WebDownloadUtility.GetString(new Uri(string.Format("http://localhost:{0}/", port))); } finally { app.Dte.Debugger.Stop(); } EndToEndLog("Response from http://localhost:{0}/", port); EndToEndLog(text); Assert.IsTrue(text.Contains(textInResponse), text); for (retries = 20; retries > 0 && (app.Dte.Debugger.CurrentMode != EnvDTE.dbgDebugMode.dbgRunMode || !IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().All(p => p.Port != port)); --retries) { Thread.Sleep(500); } if (retries > 0) { EndToEndLog("Debugging stopped"); } else { EndToEndLog("Timed out waiting for debugging to stop"); } }
public void CustomCommandsWithResourceLabel() { using (var app = new VisualStudioApp()) { PythonProjectNode node; EnvDTE.Project proj; OpenProject(app, "Commands2.sln", out node, out proj); AssertUtil.ContainsExactly( node._customCommands.Select(cc => cc.Label), "resource:PythonToolsUITests;PythonToolsUITests.Resources;CommandName" ); AssertUtil.ContainsExactly( node._customCommands.Select(cc => cc.DisplayLabel), "Command from Resource" ); } }
public void StartNewAppDuplicateName() { using (var app = new VisualStudioApp()) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.DjangoWebProjectTemplate, TestData.GetTempPath(), "StartNewAppDuplicateName" ); app.SolutionExplorerTreeView.SelectProject(project); using (var newAppDialog = NewAppDialog.FromDte(app)) { newAppDialog.AppName = "Fob"; newAppDialog.OK(); } app.SolutionExplorerTreeView.WaitForItem( app.Dte.Solution.FullName, app.Dte.Solution.Projects.Item(1).Name, "Fob", "models.py" ); app.Dte.Documents.CloseAll(EnvDTE.vsSaveChanges.vsSaveChangesNo); app.SolutionExplorerTreeView.SelectProject(project); using (var newAppDialog = NewAppDialog.FromDte(app)) { newAppDialog.AppName = "Fob"; newAppDialog.OK(); } using (var dlg = AutomationDialog.WaitForDialog(app)) { } } }
private static void ExpectOutputWindowText(VisualStudioApp app, string expected) { var outputWindow = app.Element.FindFirst(TreeScope.Descendants, new AndCondition( new PropertyCondition(AutomationElement.ClassNameProperty, "GenericPane"), new PropertyCondition(AutomationElement.NameProperty, "Output") ) ); Assert.IsNotNull(outputWindow, "Output Window was not opened"); var outputText = ""; for (int retries = 100; !outputText.Contains(expected) && retries > 0; --retries) { Thread.Sleep(100); outputText = outputWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ClassNameProperty, "WpfTextView") ).AsWrapper().GetValue(); } Console.WriteLine("Output Window: " + outputText); Assert.IsTrue(outputText.Contains(expected), string.Format("Expected to see:\r\n\r\n{0}\r\n\r\nActual content:\r\n\r\n{1}", expected, outputText)); }
public void StartNewAppSameAsProjectName() { using (var app = new VisualStudioApp()) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.DjangoWebProjectTemplate, TestData.GetTempPath(), "StartNewAppSameAsProjectName" ); app.SolutionExplorerTreeView.SelectProject(project); using (var newAppDialog = NewAppDialog.FromDte(app)) { newAppDialog.AppName = app.Dte.Solution.Projects.Item(1).Name; newAppDialog.OK(); } using (var dlg = AutomationDialog.WaitForDialog(app)) { } } }
internal static IPythonInterpreterFactory CreateVirtualEnvironment(string pythonVersion, VisualStudioApp app, PythonProjectNode pyProj) { var uiThread = app.ServiceProvider.GetUIThread(); var task = uiThread.InvokeTask(() => { var model = app.GetService<IComponentModel>(typeof(SComponentModel)); var service = model.GetService<IInterpreterRegistryService>(); return pyProj.CreateOrAddVirtualEnvironment( service, true, Path.Combine(pyProj.ProjectHome, "env"), service.FindInterpreter("Global|PythonCore|" + pythonVersion + "-32"), Version.Parse(pythonVersion) >= new Version(3, 3) ); }); try { Assert.IsTrue(task.Wait(TimeSpan.FromMinutes(2.0)), "Timed out waiting for venv"); } catch (AggregateException ex) { throw ex.InnerException; } var factory = task.Result; Assert.IsTrue(uiThread.Invoke(() => factory.Configuration.Id == pyProj.GetInterpreterFactory().Configuration.Id)); return factory; }
internal TestDiscoverer(VisualStudioApp app, IInterpreterOptionsService interpreterService) { _app = app; _interpreterService = interpreterService; }