public Window(Process p, string className, string rootElementName) { this.p = p; IntPtr h = p.Handle; while (h == IntPtr.Zero || !p.Responding) { Sleep(1000); p.WaitForInputIdle(); h = p.Handle; if (p.HasExited) { throw new InvalidOperationException(string.Format("Process '{0}' has exited!", p.StartInfo.FileName)); } } p.WaitForInputIdle(); p.Exited += new EventHandler(OnExited); int id = p.Id; if (this.acc == null) { // p.MainWindowHandle always returns 0 for some unknown reason... int retries = 20; while (retries-- > 0 && this.acc == null) { this.acc = FindWindowForProcessId(id, className, rootElementName); Sleep(1000); } if (this.acc == null) { throw new Exception("Process as no window handle"); } this.handle = this.acc.Hwnd; } }
public void LoadSearchPath(PythonVisualStudioApp app) { var project = app.OpenProject(@"TestData\LoadSearchPaths.sln"); // Ensure we complete analysis. VS may crash if the invalid // path is not handled correctly. project.GetPythonProject().GetAnalyzer().WaitForCompleteAnalysis(_ => true); var tree = app.OpenSolutionExplorer(); const string sln = "Solution 'LoadSearchPaths' (1 project)"; const string proj = "LoadSearchPaths"; var sp = Strings.SearchPaths; // Entered in file as ..\AddSearchPaths\ var path1 = tree.WaitForItem(sln, proj, sp, "..\\AddSearchPaths"); Assert.IsNotNull(path1, "Could not find ..\\AddSearchPaths"); // Entered in file as ..\HelloWorld var path2 = tree.WaitForItem(sln, proj, sp, "..\\HelloWorld"); Assert.IsNotNull(path2, "Could not find ..\\HelloWorld"); // Entered in file as ..\LoadSearchPaths\NotHere\..\ - resolves to .\ var path3 = tree.WaitForItem(sln, proj, sp, "."); Assert.IsNotNull(path3, "Could not find ."); // Entered in file as .\NotHere\ var path4 = tree.WaitForItem(sln, proj, sp, "NotHere"); Assert.IsNotNull(path4, "Could not find NotHere"); Assert.AreEqual("NotHere", path4.Current.Name); AutomationWrapper.Select(path4); app.ExecuteCommand("Edit.Delete"); // should not prompt, https://pytools.codeplex.com/workitem/1233 Assert.IsNull(tree.WaitForItemRemoved(sln, proj, sp, "NotHere")); // Entered in file as Invalid*Search?Path var path5 = tree.WaitForItem(sln, proj, sp, "Invalid*Search?Path"); Assert.IsNotNull(path5, "Could not find Invalid*Search?Path"); Assert.AreEqual(path5.Current.Name, "Invalid*Search?Path"); AutomationWrapper.Select(path5); app.ExecuteCommand("Edit.Delete"); Assert.IsNull(tree.WaitForItemRemoved(sln, proj, sp, "Invalid*Search?Path")); // Ensure NotHere hasn't come back path4 = tree.WaitForItem(sln, proj, sp, "NotHere"); Assert.IsNull(path4, "NotHere came back"); }
public void SelectProject(EnvDTE.Project project) { var slnName = string.Format("Solution '{0}' ({1} of {1} project{2})", Path.GetFileNameWithoutExtension(project.DTE.Solution.FullName), project.DTE.Solution.Projects.Count, project.DTE.Solution.Projects.Count == 1 ? "" : "s" ); AutomationWrapper item = WaitForItem(slnName, project.Name).AsWrapper(); Assert.IsNotNull(item); item.Select(); }
public void StartNewApp() { using (var app = new PythonVisualStudioApp()) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.DjangoWebProjectTemplate, TestData.GetTempPath(), "StartNewApp" ); 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" ); var appFolder = project.ProjectItems.Item("Fob"); Assert.IsNotNull(appFolder.ProjectItems.Item("models.py")); Assert.IsNotNull(appFolder.ProjectItems.Item("tests.py")); Assert.IsNotNull(appFolder.ProjectItems.Item("views.py")); Assert.IsNotNull(appFolder.ProjectItems.Item("__init__.py")); app.SolutionExplorerTreeView.SelectProject(project); app.Dte.ExecuteCommand("Project.DjangoCheckDjango17"); using (var console = app.GetInteractiveWindow("Django Management Console - " + project.Name)) { Assert.IsNotNull(console); console.WaitForTextEnd("The interactive Python process has exited.", ">"); Assert.IsTrue(console.TextView.TextSnapshot.GetText().Contains("Executing manage.py check")); Assert.IsTrue(console.TextView.TextSnapshot.GetText().Contains("System check identified no issues (0 silenced).")); } app.SolutionExplorerTreeView.SelectProject(project); using (var newItem = NewItemDialog.FromDte(app)) { AutomationWrapper.Select(newItem.ProjectTypes.FindItem("HTML Page")); newItem.FileName = "NewPage.html"; newItem.OK(); } System.Threading.Thread.Sleep(1000); Assert.IsNotNull(project.ProjectItems.Item("NewPage.html")); } }
public void MoveLinkedNode() { foreach (var projectType in ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs()) { var projectNode = solution.FindItem("LinkedFiles", "MovedLinkedFile" + projectType.CodeExtension); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); solution.ExecuteCommand("Edit.Cut"); var folderNode = solution.FindItem("LinkedFiles", "MoveToFolder"); AutomationWrapper.Select(folderNode); solution.ExecuteCommand("Edit.Paste"); // item should have moved var movedLinkedFile = solution.WaitForItem("LinkedFiles", "MoveToFolder", "MovedLinkedFile" + projectType.CodeExtension); Assert.IsNotNull(movedLinkedFile, "movedLinkedFile"); // file should be at the same location Assert.IsTrue(File.Exists(Path.Combine(solution.SolutionDirectory, "MovedLinkedFile" + projectType.CodeExtension))); Assert.IsFalse(File.Exists(Path.Combine(solution.SolutionDirectory, "MoveToFolder\\MovedLinkedFile" + projectType.CodeExtension))); // now move it back AutomationWrapper.Select(movedLinkedFile); solution.ExecuteCommand("Edit.Cut"); var originalFolder = solution.FindItem("LinkedFiles"); AutomationWrapper.Select(originalFolder); solution.ExecuteCommand("Edit.Paste"); var movedLinkedFilePaste = solution.WaitForItem("LinkedFiles", "MovedLinkedFile" + projectType.CodeExtension); Assert.IsNotNull(movedLinkedFilePaste, "movedLinkedFilePaste"); // and make sure we didn't mess up the path in the project file MSBuild.Project buildProject = new MSBuild.Project(solution.GetProject("LinkedFiles").FullName); bool found = false; foreach (var item in buildProject.GetItems("Compile")) { if (item.UnevaluatedInclude == "..\\MovedLinkedFile" + projectType.CodeExtension) { found = true; break; } } Assert.IsTrue(found); } } }
/// <summary> /// Moves one or more items in solution explorer using the keyboard to cut and paste. /// </summary> /// <param name="destination"></param> /// <param name="source"></param> private static void MoveByKeyboard(AutomationElement destination, params AutomationElement[] source) { AutomationWrapper.Select(source.First()); for (int i = 1; i < source.Length; i++) { AutomationWrapper.AddToSelection(source[i]); } Keyboard.ControlX(); AutomationWrapper.Select(destination); Keyboard.ControlV(); }
/// <summary> /// Moves one or more items in solution explorer using the keyboard to cut and paste. /// </summary> /// <param name="destination"></param> /// <param name="source"></param> private static void MoveByKeyboard(IVisualStudioInstance vs, ITreeNode destination, params ITreeNode[] source) { AutomationWrapper.Select(source.First()); for (int i = 1; i < source.Length; i++) { AutomationWrapper.AddToSelection(source[i]); } vs.ControlX(); AutomationWrapper.Select(destination); vs.ControlV(); }
public void DirtyProperties() { using (var solution = Project("DirtyProperties").Generate().ToVs()) { var proj = solution.FindItem("DirtyProperties"); AutomationWrapper.Select(proj); solution.App.Dte.ExecuteCommand("ClassViewContextMenus.ClassViewMultiselectProjectreferencesItems.Properties"); var window = solution.App.Dte.Windows.Item("DirtyProperties"); Assert.AreEqual(window.Caption, "DirtyProperties"); solution.Project.Properties.Item("NodejsPort").Value = 3000; Assert.AreEqual(false, solution.Project.Saved); } }
private static T Pattern <T>(this AutomationElement node, AutomationPattern pattern) where T : BasePattern { try { return((T)node.GetCurrentPattern(pattern)); } catch (InvalidOperationException) { Console.WriteLine("{0} pattern is not supported by {1}.", pattern.ProgrammaticName, node.Current.Name); AutomationWrapper.DumpElement(node); throw; } }
public void CopyPasteRenameFile() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\CopyPasteRenameProject\CopyPasteRenameProject.sln"); using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { var window = app.OpenSolutionExplorer(); var jsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameJavaScript", "app.js"); AutomationWrapper.Select(jsFile); Keyboard.ControlC(); Keyboard.ControlV(); var copiedJsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameJavaScript", "app - Copy.js"); Assert.AreNotEqual(null, copiedJsFile); AutomationWrapper.Select(copiedJsFile); Keyboard.PressAndRelease(Key.F2); System.Threading.Thread.Sleep(100); Keyboard.Type("renamed"); Keyboard.PressAndRelease(Key.Enter); Assert.AreNotEqual(null, window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameJavaScript", "renamed.js")); var tsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameProjectTypeScript", "app.ts"); AutomationWrapper.Select(tsFile); Keyboard.ControlC(); Keyboard.ControlV(); var copiedTsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameProjectTypeScript", "app - Copy.ts"); Assert.AreNotEqual(null, copiedTsFile); AutomationWrapper.Select(copiedTsFile); Keyboard.PressAndRelease(Key.F2); System.Threading.Thread.Sleep(100); Keyboard.Type("renamed"); Keyboard.PressAndRelease(Key.Enter); Assert.AreNotEqual(null, window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameProjectTypeScript", "renamed.ts")); } } }
public void TestProjectProperties() { var filename = Path.Combine(TestData.GetTempPath(), Path.GetRandomFileName()); var project = Project("ProjectProperties", Compile("server"), Property("StartupFile", "server.js") ); using (var solution = project.Generate().ToVs()) { var projectNode = solution.WaitForItem("ProjectProperties"); AutomationWrapper.Select(projectNode); solution.App.Dte.ExecuteCommand("ClassViewContextMenus.ClassViewMultiselectProjectReferencesItems.Properties"); AutomationElement doc = null; for (int i = 0; i < 10; i++) { doc = solution.App.GetDocumentTab("ProjectProperties"); if (doc != null) { break; } System.Threading.Thread.Sleep(1000); } Assert.IsNotNull(doc, "Failed to find project properties tab"); var nodeExeArguments = new TextBox( new AutomationWrapper(doc).FindByAutomationId("_nodeArguments") ); var debuggerMachineName = new TextBox( new AutomationWrapper(doc).FindByAutomationId("_debuggerMachineName") ); debuggerMachineName.SetFocus(); Keyboard.ControlA(); Keyboard.Backspace(); Keyboard.Type("10.11.22.33"); nodeExeArguments.SetFocus(); Keyboard.ControlA(); Keyboard.Backspace(); Keyboard.Type("--no-console --debug"); solution.App.Dte.ExecuteCommand("File.SaveAll"); var projFile = File.ReadAllText(solution.Project.FullName); Assert.AreNotEqual(-1, projFile.IndexOf("<DebuggerMachineName>10.11.22.33</DebuggerMachineName>")); Assert.AreNotEqual(-1, projFile.IndexOf("<NodeExeArguments>--no-console --debug</NodeExeArguments>")); } }
/// <summary> /// Moves one or more items in solution explorer using the keyboard to cut and paste. /// </summary> /// <param name="destination"></param> /// <param name="source"></param> private static void MoveByKeyboard(IVisualStudioInstance vs, ITreeNode destination, params ITreeNode[] source) { AutomationWrapper.Select(source.First()); for (int i = 1; i < source.Length; i++) { AutomationWrapper.AddToSelection(source[i]); } vs.ControlX(); AutomationWrapper.Select(destination); vs.ControlV(); vs.MaybeCheckMessageBox(TestUtilities.MessageBoxButton.Ok, "One or more files will be"); }
public void AddItemPreviousSiblingNotVisible(PythonVisualStudioApp app) { var project = app.OpenProject(@"TestData\AddItemPreviousSiblingNotVisible.sln"); app.OpenSolutionExplorer(); var window = app.SolutionExplorerTreeView; var projectNode = window.WaitForItem("Solution 'AddItemPreviousSiblingNotVisible' (1 of 1 project)", "HelloWorld"); Assert.IsNotNull(projectNode); AutomationWrapper.Select(projectNode); var solutionService = app.GetService <IVsSolution>(typeof(SVsSolution)); Assert.IsNotNull(solutionService); IVsHierarchy selectedHierarchy; ErrorHandler.ThrowOnFailure(solutionService.GetProjectOfUniqueName(project.UniqueName, out selectedHierarchy)); Assert.IsNotNull(selectedHierarchy); HierarchyEvents events = new HierarchyEvents(); uint cookie; selectedHierarchy.AdviseHierarchyEvents(events, out cookie); using (var newItem = NewItemDialog.FromDte(app)) { var pythonFile = newItem.ProjectTypes.FindItem("Empty Python File"); pythonFile.Select(); newItem.FileName = "zmodule1.py"; newItem.OK(); } var test2 = window.WaitForItem("Solution 'AddItemPreviousSiblingNotVisible' (1 of 1 project)", "HelloWorld", "zmodule1.py"); Assert.IsNotNull(test2); selectedHierarchy.UnadviseHierarchyEvents(cookie); object caption; ErrorHandler.ThrowOnFailure( selectedHierarchy.GetProperty( events.SiblingPrev, (int)__VSHPROPID.VSHPROPID_Caption, out caption ) ); Assert.AreEqual("Program.py", caption); }
public void StartNewApp() { using (var app = new PythonVisualStudioApp()) { var project = app.CreateProject( PythonVisualStudioApp.TemplateLanguageName, PythonVisualStudioApp.DjangoWebProjectTemplate, TestData.GetTempPath(), "StartNewApp" ); 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" ); var appFolder = project.ProjectItems.Item("Fob"); Assert.IsNotNull(appFolder.Collection.Item("models.py")); Assert.IsNotNull(appFolder.Collection.Item("tests.py")); Assert.IsNotNull(appFolder.Collection.Item("views.py")); Assert.IsNotNull(appFolder.Collection.Item("__init__.py")); app.SolutionExplorerTreeView.SelectProject(project); app.Dte.ExecuteCommand("Project.ValidateDjangoApp"); var console = app.GetInteractiveWindow("Django Management Console - " + project.Name); Assert.IsNotNull(console); console.WaitForTextEnd("Executing manage.py validate", "0 errors found", "The Python REPL process has exited", ">>> "); app.SolutionExplorerTreeView.SelectProject(project); using (var newItem = NewItemDialog.FromDte(app)) { AutomationWrapper.Select(newItem.ProjectTypes.FindItem("HTML Page")); newItem.FileName = "NewPage.html"; newItem.OK(); } System.Threading.Thread.Sleep(1000); Assert.IsNotNull(project.ProjectItems.Item("NewPage.html")); } }
public void DeleteLinkedNode(VisualStudioApp app, ProjectGenerator pg) { foreach (var projectType in pg.ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs(app)) { var projectNode = solution.FindItem("LinkedFiles", "DeletedLinkedFile" + projectType.CodeExtension); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); solution.ExecuteCommand("Edit.Delete"); projectNode = solution.FindItem("LinkedFiles", "DeletedLinkedFile" + projectType.CodeExtension); Assert.AreEqual(null, projectNode); Assert.IsTrue(File.Exists(Path.Combine(solution.SolutionDirectory, "DeletedLinkedFile" + projectType.CodeExtension))); } } }
public void CopyPasteRenameFile() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\CopyPasteRenameProject\CopyPasteRenameProject.sln"); app.OpenSolutionExplorer(); var window = app.SolutionExplorerTreeView; var jsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameJavaScript", "app.js"); AutomationWrapper.Select(jsFile); Keyboard.ControlC(); Keyboard.ControlV(); var copiedJsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameJavaScript", "app - Copy.js"); Assert.AreNotEqual(null, copiedJsFile); AutomationWrapper.Select(copiedJsFile); Keyboard.PressAndRelease(Key.F2); System.Threading.Thread.Sleep(100); Keyboard.Type("renamed"); Keyboard.PressAndRelease(Key.Enter); Assert.AreNotEqual(null, window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameJavaScript", "renamed.js")); var tsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameProjectTypeScript", "app.ts"); AutomationWrapper.Select(tsFile); Keyboard.ControlC(); Keyboard.ControlV(); var copiedTsFile = window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameProjectTypeScript", "app - Copy.ts"); Assert.AreNotEqual(null, copiedTsFile); AutomationWrapper.Select(copiedTsFile); Keyboard.PressAndRelease(Key.F2); System.Threading.Thread.Sleep(100); Keyboard.Type("renamed"); Keyboard.PressAndRelease(Key.Enter); Assert.AreNotEqual(null, window.WaitForItem("Solution 'CopyPasteRenameProject' (2 projects)", "CopyPasteRenameProjectTypeScript", "renamed.ts")); } }
public void AddNewFolderNested() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\NodejsProjectData\HelloWorld.sln"); using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { var window = app.OpenSolutionExplorer(); // find server.js, send copy & paste, verify copy of file is there var projectNode = window.WaitForItem("Solution 'HelloWorld' (1 project)", "HelloWorld"); AutomationWrapper.Select(projectNode); Keyboard.PressAndRelease(Key.F10, Key.LeftCtrl, Key.LeftShift); Keyboard.PressAndRelease(Key.D); Keyboard.PressAndRelease(Key.Right); Keyboard.PressAndRelease(Key.D); Keyboard.Type("FolderX"); Keyboard.PressAndRelease(Key.Enter); var folderNode = window.WaitForItem("Solution 'HelloWorld' (1 project)", "HelloWorld", "FolderX"); Assert.AreNotEqual(null, folderNode, "failed to find folder X"); AutomationWrapper.Select(folderNode); Keyboard.PressAndRelease(Key.F10, Key.LeftCtrl, Key.LeftShift); Keyboard.PressAndRelease(Key.D); Keyboard.PressAndRelease(Key.Right); Keyboard.PressAndRelease(Key.D); Keyboard.Type("FolderY"); Keyboard.PressAndRelease(Key.Enter); var innerFolderNode = window.WaitForItem("Solution 'HelloWorld' (1 project)", "HelloWorld", "FolderX", "FolderY"); Assert.AreNotEqual(null, innerFolderNode, "failed to find folder Y"); AutomationWrapper.Select(innerFolderNode); var newItem = project.ProjectItems.Item("FolderX").Collection.Item("FolderY").Collection.AddFromFile( TestData.GetPath(@"TestData\DebuggerProject\BreakpointBreakOn.js") ); Assert.AreNotEqual(null, window.WaitForItem("Solution 'HelloWorld' (1 project)", "HelloWorld", "FolderX", "FolderY", "BreakpointBreakOn.js"), "failed to find added file"); } } }
/// <summary> /// Adding a duplicate link to the same item. /// /// Also because the linked file dir is "LinkedFilesDir" which is a substring of "LinkedFiles" (our project name) /// this verifies we deal with the project name string comparison correctly (including a \ at the end of the /// path). /// </summary> public void AddExistingItemAndLinkAlreadyExists(VisualStudioApp app, ProjectGenerator pg) { foreach (var projectType in pg.ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs(app)) { var projectNode = solution.FindItem("LinkedFiles", "Oar"); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); using (var addExistingDlg = solution.AddExistingItem()) { addExistingDlg.FileName = Path.Combine(solution.SolutionDirectory, "LinkedFilesDir\\SomeLinkedFile" + projectType.CodeExtension); addExistingDlg.AddLink(); } solution.WaitForDialog(); solution.CheckMessageBox(MessageBoxButton.Ok, "There is already a link to", "SomeLinkedFile" + projectType.CodeExtension); } } }
/// <summary> /// Adding new linked item when the file lives in the project dir but not in the directory we selected /// Add Existing Item from. We should add the file to the directory where it lives. /// </summary> public void AddExistingItemAsLinkButFileExistsInProjectDirectory(VisualStudioApp app, ProjectGenerator pg) { foreach (var projectType in pg.ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs(app)) { var projectNode = solution.FindItem("LinkedFiles", "Fob"); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); using (var addExistingDlg = solution.AddExistingItem()) { addExistingDlg.FileName = Path.Combine(solution.SolutionDirectory, "LinkedFiles\\Fob\\AddExistingInProjectDirButNotInProject" + projectType.CodeExtension); addExistingDlg.AddLink(); } var addExistingInProjectDirButNotInProject = solution.WaitForItem("LinkedFiles", "Fob", "AddExistingInProjectDirButNotInProject" + projectType.CodeExtension); Assert.IsNotNull(addExistingInProjectDirButNotInProject, "addExistingInProjectDirButNotInProject"); } } }
public void RenameLinkedNode() { foreach (var projectType in ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs()) { // implicitly linked node var projectNode = solution.FindItem("LinkedFiles", "ImplicitLinkedFile" + projectType.CodeExtension); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); try { solution.ExecuteCommand("File.Rename"); Assert.Fail("Should have failed to rename"); } catch (Exception e) { Debug.WriteLine(e.ToString()); } // explicitly linked node var explicitLinkedFile = solution.FindItem("LinkedFiles", "ExplicitDir", "ExplicitLinkedFile" + projectType.CodeExtension); Assert.IsNotNull(explicitLinkedFile, "explicitLinkedFile"); AutomationWrapper.Select(explicitLinkedFile); try { solution.ExecuteCommand("File.Rename"); Assert.Fail("Should have failed to rename"); } catch (Exception e) { Debug.WriteLine(e.ToString()); } var autoItem = solution.GetProject("LinkedFiles").ProjectItems.Item("ImplicitLinkedFile" + projectType.CodeExtension); try { autoItem.Properties.Item("FileName").Value = "Fob"; Assert.Fail("Should have failed to rename"); } catch (InvalidOperationException) { } autoItem = solution.GetProject("LinkedFiles").ProjectItems.Item("ExplicitDir").ProjectItems.Item("ExplicitLinkedFile" + projectType.CodeExtension); try { autoItem.Properties.Item("FileName").Value = "Fob"; Assert.Fail("Should have failed to rename"); } catch (InvalidOperationException) { } } } }
/// <summary> /// Adding new linked item when file of same name exists (in the project, but not on disk) /// </summary> public void AddExistingItemAndFileByNameExistsInProjectButNotOnDisk(VisualStudioApp app, ProjectGenerator pg) { foreach (var projectType in pg.ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs(app)) { var projectNode = solution.FindItem("LinkedFiles", "FolderWithAFile"); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); using (var addExistingDlg = solution.AddExistingItem()) { addExistingDlg.FileName = Path.Combine(solution.SolutionDirectory, "ExistsInProjectButNotOnDisk" + projectType.CodeExtension); addExistingDlg.AddLink(); } solution.WaitForDialog(); solution.CheckMessageBox(MessageBoxButton.Ok, "There is already a file of the same name in this folder."); } } }
/// <summary> /// Adding a duplicate link to the same item /// </summary> public void AddExistingItem(VisualStudioApp app, ProjectGenerator pg) { foreach (var projectType in pg.ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs(app)) { var projectNode = solution.FindItem("LinkedFiles", "FolderWithAFile"); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); using (var addExistingDlg = solution.AddExistingItem()) { addExistingDlg.FileName = Path.Combine(solution.SolutionDirectory, "ExistingItem" + projectType.CodeExtension); addExistingDlg.AddLink(); } var existingItem = solution.WaitForItem("LinkedFiles", "FolderWithAFile", "ExistingItem" + projectType.CodeExtension); Assert.IsNotNull(existingItem, "existingItem"); } } }
public void CopyFolderOnToSelf() { using (var app = new VisualStudioApp()) { app.OpenProject(@"TestData\NodejsProjectData\HelloWorld2.sln", expectedProjects: 2); app.OpenSolutionExplorer(); var window = app.SolutionExplorerTreeView; var folder = window.WaitForItem("Solution 'HelloWorld2' (2 projects)", "HelloWorld2", "TestFolder"); AutomationWrapper.Select(folder); Keyboard.ControlC(); AutomationWrapper.Select(folder); Keyboard.ControlV(); Assert.AreNotEqual(null, window.WaitForItem("Solution 'HelloWorld2' (2 projects)", "HelloWorld2", "TestFolder - Copy")); } }
public void CopyFolderOnToSelf() { using (var app = new VisualStudioApp()) { app.OpenProject(@"TestData\NodejsProjectData\HelloWorld2.sln", expectedProjects: 2); using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { var window = app.OpenSolutionExplorer(); var folder = window.WaitForItem("Solution 'HelloWorld2' (2 projects)", "HelloWorld2", "TestFolder"); AutomationWrapper.Select(folder); Keyboard.ControlC(); AutomationWrapper.Select(folder); Keyboard.ControlV(); Assert.AreNotEqual(null, window.WaitForItem("Solution 'HelloWorld2' (2 projects)", "HelloWorld2", "TestFolder - Copy")); } } }
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(); AutomationWrapper projectMenu = null; for (int retries = 10; retries > 0 && projectMenu == null; --retries) { Thread.Sleep(100); projectMenu = app.FindByAutomationId("MenuBar").AsWrapper().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. } } } }
public void AddNewItemLongPathTooLong() { using (var app = new VisualStudioApp()) { var project = OpenLongFileNameProject(app, 12); var window = app.OpenSolutionExplorer(); // find server.js, send copy & paste, verify copy of file is there var projectNode = window.WaitForItem("Solution 'LongFileNames' (1 project)", "LFN"); AutomationWrapper.Select(projectNode); using (var newItem = NewItemDialog.FromDte(app)) { newItem.FileName = "NewJSFile.js"; newItem.OK(); } VisualStudioApp.CheckMessageBox("The filename or extension is too long."); } }
public void CreateNewScript() { using (var app = new VisualStudioApp()) { var project = app.CreateProject( RConstants.TemplateLanguageName, RConstants.ProjectTemplate_EmptyProject, System.IO.Path.GetTempPath(), "RTestProject"); app.OpenSolutionExplorer().SelectProject(project); using (var newItem = NewItemDialog.FromDte(app)) { AutomationWrapper.Select(newItem.ProjectTypes.FindItem("R Script")); newItem.FileName = "my-script.r"; newItem.OK(); } var document = app.GetDocument("my-script.r"); document.SetFocus(); document.Type("2 -> a"); document.Text.Should().Be("2 -> a# R Script"); } }
public void AddExistingItemAndItemIsAlreadyLinked() { foreach (var projectType in ProjectTypes) { using (var solution = LinkedFiles(projectType).Generate().ToVs()) { var projectNode = solution.FindItem("LinkedFiles", "AlreadyLinkedFolder"); Assert.IsNotNull(projectNode, "projectNode"); AutomationWrapper.Select(projectNode); using (var addExistingDlg = solution.AddExistingItem()) { addExistingDlg.FileName = Path.Combine(solution.SolutionDirectory, "FileNotInProject" + projectType.CodeExtension); addExistingDlg.AddLink(); } solution.WaitForDialog(); solution.CheckMessageBox(MessageBoxButton.Ok, "There is already a link to", "A project cannot have more than one link to the same file.", "FileNotInProject" + projectType.CodeExtension); } } }
public void AddNewItemLongPathBoundary() { using (var app = new VisualStudioApp()) { var project = OpenLongFileNameProject(app, 12); var window = app.OpenSolutionExplorer(); // find server.js, send copy & paste, verify copy of file is there var projectNode = window.WaitForItem("Solution 'LongFileNames' (1 project)", "LFN"); AutomationWrapper.Select(projectNode); using (var newItem = NewItemDialog.FromDte(app)) { newItem.FileName = "NewJSFil.js"; newItem.OK(); } Assert.IsNotNull(window.WaitForItem("Solution 'LongFileNames' (1 project)", "LFN", "NewJSFil.js")); Assert.IsTrue(File.Exists(Path.Combine(Path.GetDirectoryName(project.FullName), "LongFileNames", "NewJSFil.js"))); } }
public void DeleteLockedFolder() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\NodejsProjectData\DeleteLockedFolder.sln"); using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { var window = app.OpenSolutionExplorer(); var folderNode = window.WaitForItem("Solution 'DeleteLockedFolder' (1 project)", "DeleteLockedFolder", "Folder"); AutomationWrapper.Select(folderNode); var psi = new ProcessStartInfo( Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "system32", "cmd.exe")); psi.WorkingDirectory = Path.Combine(Environment.CurrentDirectory, @"TestData\NodejsProjectData\DeleteLockedFolder\Folder"); psi.CreateNoWindow = true; psi.UseShellExecute = false; using (var process = System.Diagnostics.Process.Start(psi)) { try { //Ensure the other process started and has time to lock the file System.Threading.Thread.Sleep(1000); Keyboard.Type(Key.Delete); app.WaitForDialog(); Keyboard.Type(Key.Enter); System.Threading.Thread.Sleep(500); VisualStudioApp.CheckMessageBox("The process cannot access the file 'Folder' because it is being used by another process."); } finally { process.Kill(); } } Assert.IsNotNull(window.FindItem("Solution 'DeleteLockedFolder' (1 project)", "DeleteLockedFolder", "Folder")); } } }
public void RenameProjectToExisting() { using (var app = new VisualStudioApp()) { var project = app.OpenProject(@"TestData\NodejsProjectData\RenameProjectTestUI.sln"); using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { var window = app.OpenSolutionExplorer(); // find server.js, send copy & paste, verify copy of file is there var projectNode = window.WaitForItem("Solution 'RenameProjectTestUI' (1 project)", "HelloWorld"); // rename once, cancel renaming to existing file.... AutomationWrapper.Select(projectNode); Keyboard.PressAndRelease(Key.F2); System.Threading.Thread.Sleep(100); Keyboard.Type("HelloWorldExisting"); Keyboard.PressAndRelease(Key.Enter); IntPtr dialog = app.WaitForDialog(); VisualStudioApp.CheckMessageBox("HelloWorldExisting.njsproj", "overwrite"); // rename again, don't cancel... AutomationWrapper.Select(projectNode); Keyboard.PressAndRelease(Key.F2); System.Threading.Thread.Sleep(100); Keyboard.Type("HelloWorldExisting"); Keyboard.PressAndRelease(Key.Enter); dialog = app.WaitForDialog(); VisualStudioApp.CheckMessageBox(MessageBoxButton.Yes, "HelloWorldExisting.njsproj", "overwrite"); Assert.AreNotEqual(null, window.WaitForItem("Solution 'RenameProjectTestUI' (1 project)", "HelloWorldExisting")); } } }
void CheckNodeName(AutomationWrapper acc, string expected) { string name = acc.Name; if (name != expected) { throw new ApplicationException(string.Format("Expecting node name '{0}', but found '{1}'", expected, name)); } Trace.WriteLine("Name=" + name); #if DEBUG Sleep(200); // so we can watch it! #endif }
void CheckNodeValue(AutomationWrapper acc, string expected) { string value = acc.Value; if (value != expected) { throw new ApplicationException(string.Format("Expecting node value '{0}'", expected)); } Trace.WriteLine("Value=" + value); #if DEBUG Sleep(200); // so we can watch it! #endif }
void TestHitTest(Point pt, AutomationWrapper parent, AutomationWrapper expected) { AutomationWrapper obj = parent.HitTest(pt.X, pt.Y); if (obj.Name != expected.Name) { throw new ApplicationException( string.Format("Found node '{0}' at {1},{2} instead of node '{3}'", obj.Name, pt.X.ToString(), pt.Y.ToString(), expected.Name) ); } }
void CheckProperties(AutomationWrapper node) { // Get code coverage on the boring stuff. Trace.WriteLine("Name=" + node.Name); // not all nodes support a ValuePattern (comment, pi, cdata). //Trace.WriteLine("\tValue=" + node.Value); Trace.WriteLine("\tParent=" + node.Parent.Name); Trace.WriteLine("\tChildCount=" + node.GetChildCount()); Trace.WriteLine("\tBounds=" + node.Bounds.ToString()); //Trace.WriteLine("\tDefaultAction=" + node.DefaultAction); //Trace.WriteLine("\tDescription=" + node.Description); Trace.WriteLine("\tHelp=" + node.Help); Trace.WriteLine("\tKeyboardShortcut=" + node.KeyboardShortcut); Trace.WriteLine("\tRole=" + node.Role); //Trace.WriteLine("\tState=" + node.State); //string filename = null; //Trace.WriteLine("\tHelpTopic=" + node.GetHelpTopic(out filename)); }
private void SetNodeName(AutomationWrapper node, string text) { // must not be a leaf node then, unfortunately the mapping from IAccessible to AutomationElement // don't add ValuePattern on ListItems that have children, so we have to get the value the hard way. Sleep(100); this.window.SendKeystrokes("{ENTER}"); Sleep(300); // wait for editor to pop up this.window.SendKeystrokes(text); Sleep(300); this.window.SendKeystrokes("{ENTER}"); Sleep(300); }
public void ClickSignOut() { WaitForInputIdle(); var sign = new AutomationWrapper(FindByAutomationId("AzureSigninControl")); sign.ClickButtonByName("Sign Out"); }
public Window(Window parent, IntPtr handle) { this.parent = parent; this.handle = handle; this.acc = AutomationWrapper.AccessibleObjectForWindow(handle); }