Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'main/tests/UserInterfaceTests')
-rw-r--r--main/tests/UserInterfaceTests/Controllers/NewFileController.cs27
-rw-r--r--main/tests/UserInterfaceTests/Controllers/NewProjectController.cs73
-rw-r--r--main/tests/UserInterfaceTests/Controllers/NuGetController.cs87
-rw-r--r--main/tests/UserInterfaceTests/Controllers/NuGetOptions.cs179
-rw-r--r--main/tests/UserInterfaceTests/Controllers/OptionsController.cs148
-rw-r--r--main/tests/UserInterfaceTests/Controllers/SolutionExplorerController.cs62
-rw-r--r--main/tests/UserInterfaceTests/CreateBuildTemplatesTestBase.cs119
-rw-r--r--main/tests/UserInterfaceTests/DialogTests/NewProjectDialogTests.cs3
-rw-r--r--main/tests/UserInterfaceTests/DialogTests/NuGetDialogTests.cs229
-rw-r--r--main/tests/UserInterfaceTests/Exceptions/CreateProjectException.cs37
-rw-r--r--main/tests/UserInterfaceTests/Exceptions/NuGetException.cs41
-rw-r--r--main/tests/UserInterfaceTests/Exceptions/TemplateSelectionException.cs37
-rw-r--r--main/tests/UserInterfaceTests/Ide.cs171
-rw-r--r--main/tests/UserInterfaceTests/IdeQuery.cs20
-rw-r--r--main/tests/UserInterfaceTests/LogMessageValidator.cs56
-rw-r--r--main/tests/UserInterfaceTests/TemplateTestOptions.cs39
-rw-r--r--main/tests/UserInterfaceTests/TemplateTests/ASPNETTemplateTests.cs28
-rw-r--r--main/tests/UserInterfaceTests/TemplateTests/DotNetTemplatesTest.cs15
-rw-r--r--main/tests/UserInterfaceTests/TemplateTests/MiscTemplatesTest.cs24
-rw-r--r--main/tests/UserInterfaceTests/TestService.cs2
-rw-r--r--main/tests/UserInterfaceTests/UITestBase.cs158
-rw-r--r--main/tests/UserInterfaceTests/UserInterfaceTests.csproj36
-rw-r--r--main/tests/UserInterfaceTests/Util.cs28
-rw-r--r--main/tests/UserInterfaceTests/VersionControlTests/Git/GitBase.cs478
-rw-r--r--main/tests/UserInterfaceTests/VersionControlTests/Git/GitRepositoryConfigurationTests.cs356
-rw-r--r--main/tests/UserInterfaceTests/VersionControlTests/Git/GitStashManagerTests.cs119
-rw-r--r--main/tests/UserInterfaceTests/VersionControlTests/Git/GitTests.cs (renamed from main/tests/UserInterfaceTests/VersionControlTests/GitTests.cs)45
-rw-r--r--main/tests/UserInterfaceTests/VersionControlTests/GitRepositoryConfigurationTests.cs310
-rw-r--r--main/tests/UserInterfaceTests/VersionControlTests/VCSBase.cs106
-rw-r--r--main/tests/UserInterfaceTests/Workbench.cs147
30 files changed, 2655 insertions, 525 deletions
diff --git a/main/tests/UserInterfaceTests/Controllers/NewFileController.cs b/main/tests/UserInterfaceTests/Controllers/NewFileController.cs
index b87fbdb0ca..b4e8879936 100644
--- a/main/tests/UserInterfaceTests/Controllers/NewFileController.cs
+++ b/main/tests/UserInterfaceTests/Controllers/NewFileController.cs
@@ -37,14 +37,25 @@ namespace UserInterfaceTests
Action<string> takeScreenshot;
+ Func<AppQuery, AppQuery> categoryViewQuery = c => c.TreeView ().Marked ("catView").Model ();
+ Func<AppQuery, AppQuery> fileTypeQuery = c => c.TreeView ().Marked ("newFileTemplateTreeView").Model ("templateStore__Name");
+
public NewFileController (Action<string> takeScreenshot = null)
{
- this.takeScreenshot = takeScreenshot ?? delegate { };
+ this.takeScreenshot = Util.GetNonNullAction (takeScreenshot);
}
- public static void Create (NewFileOptions options, Action<string> takeScreenshot = null)
+ public static void Create (NewFileOptions options, UITestBase testContext = null)
{
- var ctrl = new NewFileController (takeScreenshot);
+ options.PrintData ();
+ Action<string> screenshotAction = (s) => {};
+ if (testContext != null) {
+ testContext.ReproStep (string.Format ("Add a new file of type '{0}' named '{1}'",
+ options.FileType, options.FileName), options);
+ screenshotAction = testContext.TakeScreenShot;
+ }
+
+ var ctrl = new NewFileController (screenshotAction);
ctrl.Open ();
ctrl.ConfigureAddToProject (!string.IsNullOrEmpty (options.AddToProjectName), options.AddToProjectName);
ctrl.SelectFileTypeCategory (options.FileTypeCategory, options.FileTypeCategoryRoot);
@@ -63,16 +74,18 @@ namespace UserInterfaceTests
public bool SelectFileTypeCategory (string fileTypeCategory, string fileTypeCategoryRoot = "C#")
{
- var openChild = Session.ClickElement (c => c.TreeView ().Marked ("catView").Model ().Text (fileTypeCategoryRoot));
- var resultParent = Session.SelectElement (c => c.TreeView ().Marked ("catView").Model ().Text (fileTypeCategoryRoot).Children ().Text (fileTypeCategory));
- var result = Session.SelectElement (c => c.TreeView ().Marked ("catView").Model ().Text (fileTypeCategory));
+ var openChild = Session.ClickElement (c => categoryViewQuery (c).Text (fileTypeCategoryRoot));
+ var resultParent = Session.SelectElement (c => categoryViewQuery (c).Text (fileTypeCategoryRoot).Children ().Text (fileTypeCategory));
+ var result = Session.SelectElement (c => categoryViewQuery (c).Text (fileTypeCategory)) &&
+ Session.WaitForElement (c => categoryViewQuery (c).Text (fileTypeCategory).Selected ()).Length > 0;
takeScreenshot ("FileTypeCategory-Selected");
return resultParent || result;
}
public bool SelectFileType (string fileType)
{
- var result = Session.SelectElement (c => c.TreeView ().Marked ("newFileTemplateTreeView").Model ("templateStore__Name").Contains (fileType));
+ var result = Session.SelectElement (c => fileTypeQuery (c).Contains (fileType)) &&
+ Session.WaitForElement (c => fileTypeQuery (c).Contains (fileType).Selected ()).Length > 0;
takeScreenshot ("FileType-Selected");
return result;
}
diff --git a/main/tests/UserInterfaceTests/Controllers/NewProjectController.cs b/main/tests/UserInterfaceTests/Controllers/NewProjectController.cs
index 1b9c517323..05719054c0 100644
--- a/main/tests/UserInterfaceTests/Controllers/NewProjectController.cs
+++ b/main/tests/UserInterfaceTests/Controllers/NewProjectController.cs
@@ -28,6 +28,7 @@ using MonoDevelop.Components.AutoTest;
using MonoDevelop.Ide.Commands;
using NUnit.Framework;
using System.Threading;
+using System.Linq;
namespace UserInterfaceTests
{
@@ -37,27 +38,74 @@ namespace UserInterfaceTests
get { return TestService.Session; }
}
- Func<AppQuery, AppQuery> previewTree = (c) => c.TreeView ().Marked ("folderTreeView").Model ("folderTreeStore__NodeName");
+ Func<AppQuery, AppQuery> templateCategoriesTreeViewQuery = c => c.TreeView ().Marked ("templateCategoriesTreeView");
+ Func<AppQuery, AppQuery> templatesTreeViewQuery = c => c.TreeView ().Marked ("templatesTreeView");
+
+ Func<AppQuery, AppQuery> previewTree = c => c.TreeView ().Marked ("folderTreeView").Model ("folderTreeStore__NodeName");
+ Func<AppQuery, AppQuery> templateCategoriesQuery = c => c.TreeView ().Marked ("templateCategoriesTreeView").Model ("templateCategoriesListStore__Name");
+ Func<AppQuery, AppQuery> templatesQuery = c => c.TreeView ().Marked ("templatesTreeView").Model ("templateListStore__Name");
public void Open ()
{
Session.ExecuteCommand (FileCommands.NewProject);
+ WaitForOpen ();
+ }
+
+ public void Open (string addToSolutionName)
+ {
+ SolutionExplorerController.SelectSolution (addToSolutionName);
+ Session.ExecuteCommand (ProjectCommands.AddNewProject);
+ WaitForOpen ();
+ }
+
+ public void WaitForOpen ()
+ {
Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.Ide.Projects.GtkNewProjectDialogBackend"));
}
+ public void Select (TemplateSelectionOptions templateOptions)
+ {
+ SelectTemplateType (templateOptions.CategoryRoot, templateOptions.Category);
+ SelectTemplate (templateOptions.TemplateKindRoot, templateOptions.TemplateKind);
+ }
+
+ public bool IsSelected (TemplateSelectionOptions templateOptions)
+ {
+ return true;
+// return Session.SelectElement (templateCategoriesTreeViewQuery) && IsTemplateTypeSelected (templateOptions.CategoryRoot, templateOptions.Category)
+// && Session.SelectElement (templatesTreeViewQuery) && IsTemplateSelected (templateOptions.TemplateKindRoot, templateOptions.TemplateKind);
+ }
+
public bool SelectTemplateType (string categoryRoot, string category)
{
- return Session.SelectElement (c => c.TreeView ().Marked ("templateCategoriesTreeView").Model ("templateCategoriesListStore__Name").Contains (categoryRoot).NextSiblings ().Text (category));
+ return Session.SelectElement (c => templateCategoriesQuery (c).Contains (categoryRoot).NextSiblings ().Text (category))
+ && IsTemplateTypeSelected (categoryRoot, category);
}
public bool SelectTemplate (string kindRoot, string kind)
{
- return Session.SelectElement (c => c.TreeView ().Marked ("templatesTreeView").Model ("templateListStore__Name").Contains (kindRoot).NextSiblings ().Text (kind));
+ return Session.SelectElement (c => templatesQuery (c).Contains (kindRoot).NextSiblings ().Text (kind))
+ && IsTemplateSelected (kindRoot, kind);
+ }
+
+ public bool IsTemplateTypeSelected (string categoryRoot, string category)
+ {
+ return Session.WaitForElement (c => templateCategoriesQuery (c).Contains (categoryRoot).NextSiblings ().Text (category).Selected ()).Any ();
+ }
+
+ public bool IsTemplateSelected (string kindRoot, string kind)
+ {
+ return Session.WaitForElement (c => templatesQuery (c).Contains (kindRoot).NextSiblings ().Text (kind).Selected ()).Any ();
}
public bool Next ()
{
- return Session.ClickElement (c => c.Button ().Marked ("nextButton"));
+ return Session.ClickElement (c => c.Button ().Text ("Next"));
+ }
+
+ public bool Create ()
+ {
+ return Session.ClickElement (c => c.Button ().Text ("Create"));
}
public bool Previous ()
@@ -70,14 +118,23 @@ namespace UserInterfaceTests
return Session.ClickElement (c => c.Button ().Marked ("cancelButton"));
}
- public bool SetProjectName (string projectName)
+ public bool SetProjectName (string projectName, bool addToExistingSolution)
{
- return Session.EnterText (c => c.Textfield ().Marked ("projectNameTextBox"), projectName);
+ Func<AppQuery, AppQuery> projectNameTextBox = c => c.Textfield ().Marked ("projectNameTextBox");
+ if (addToExistingSolution && Session.Query (c => projectNameTextBox (c).Sensitivity (false)).Length > 0) {
+ return Session.Query (c => projectNameTextBox (c).Text (projectName)).Length > 0;
+ }
+ return Session.EnterText (projectNameTextBox, projectName);
}
- public bool SetSolutionName (string solutionName)
+ public bool SetSolutionName (string solutionName, bool addToExistingSolution)
{
- return Session.EnterText (c => c.Textfield ().Marked ("solutionNameTextBox"), solutionName);
+ Func<AppQuery, AppQuery> solutionNameTextBox = c => c.Textfield ().Marked ("solutionNameTextBox");
+ if (addToExistingSolution) {
+ return Session.Query (c => solutionNameTextBox (c).Sensitivity (false)).Length > 0 &&
+ Session.Query (c => solutionNameTextBox (c).Text (solutionName)).Length > 0;
+ }
+ return Session.EnterText (solutionNameTextBox, solutionName);
}
public bool SetSolutionLocation (string solutionLocation)
diff --git a/main/tests/UserInterfaceTests/Controllers/NuGetController.cs b/main/tests/UserInterfaceTests/Controllers/NuGetController.cs
index 92cf57a4ad..3425a7b31c 100644
--- a/main/tests/UserInterfaceTests/Controllers/NuGetController.cs
+++ b/main/tests/UserInterfaceTests/Controllers/NuGetController.cs
@@ -25,21 +25,11 @@
// THE SOFTWARE.
using System;
using MonoDevelop.Components.AutoTest;
-using UserInterfaceTests;
using MonoDevelop.Components.Commands;
using NUnit.Framework;
namespace UserInterfaceTests
{
- public class NuGetPackageOptions
- {
- public string PackageName { get; set;}
-
- public string Version { get; set;}
-
- public bool IsPreRelease { get; set;}
- }
-
public class NuGetController
{
static AutoTestClientSession Session {
@@ -48,31 +38,76 @@ namespace UserInterfaceTests
Action<string> takeScreenshot;
- readonly Func<AppQuery,AppQuery> nugetWindow;
+ bool isUpdate;
+
+ static readonly Func<AppQuery,AppQuery> nugetWindow = c => c.Window ().Marked ("Add Packages");
readonly Func<AppQuery,AppQuery> addPackageButton;
+ readonly Func<AppQuery,AppQuery> updatePackageButton;
readonly Func<AppQuery,AppQuery> resultList;
readonly Func<AppQuery,AppQuery> includePreRelease;
- public static void AddPackage (NuGetPackageOptions packageOptions, Action<string> takeScreenshot = null)
+ public static void AddPackage (NuGetPackageOptions packageOptions, UITestBase testContext = null)
+ {
+ Action<string> screenshotAction = delegate { };
+ if (testContext != null) {
+ testContext.ReproStep (string.Format ("Add NuGet package '{0}'", packageOptions.PackageName), packageOptions);
+ screenshotAction = testContext.TakeScreenShot;
+ }
+ AddUpdatePackage (packageOptions, screenshotAction, false);
+ }
+
+ public static void UpdatePackage (NuGetPackageOptions packageOptions, UITestBase testContext = null)
{
- var nuget = new NuGetController (takeScreenshot);
+ Action<string> screenshotAction = delegate { };
+ if (testContext != null) {
+ testContext.ReproStep (string.Format ("Update NuGet package '{0}'", packageOptions.PackageName), packageOptions);
+ screenshotAction = testContext.TakeScreenShot;
+ }
+ AddUpdatePackage (packageOptions, screenshotAction, true);
+ }
+
+ public static void UpdateAllNuGetPackages (UITestBase testContext = null)
+ {
+ Session.ExecuteCommand ("MonoDevelop.PackageManagement.Commands.UpdateAllPackagesInSolution");
+ WaitForNuGet.UpdateSuccess (string.Empty);
+ if (testContext != null)
+ testContext.TakeScreenShot ("All-NuGet-Packages-Updated");
+ }
+
+ static void AddUpdatePackage (NuGetPackageOptions packageOptions, Action<string> takeScreenshot, bool isUpdate = false)
+ {
+ packageOptions.PrintData ();
+ var nuget = new NuGetController (takeScreenshot, isUpdate);
nuget.Open ();
nuget.EnterSearchText (packageOptions.PackageName, packageOptions.Version, packageOptions.IsPreRelease);
- nuget.SelectResultByPackageName (packageOptions.PackageName, packageOptions.Version);
+ for (int i = 0; i < packageOptions.RetryCount; i++) {
+ try {
+ nuget.SelectResultByPackageName (packageOptions.PackageName, packageOptions.Version);
+ break;
+ } catch (NuGetException e) {
+ if (i == packageOptions.RetryCount - 1)
+ Assert.Inconclusive ("Unable to find NuGet package, could be network related.", e);
+ }
+ }
nuget.ClickAdd ();
- Ide.WaitForStatusMessage (new [] {
- string.Format ("{0} successfully added.", packageOptions.PackageName)
- });
- if (takeScreenshot != null)
- takeScreenshot ("Package-Added");
+ Session.WaitForNoElement (nugetWindow);
+ takeScreenshot ("NuGet-Update-Is-"+isUpdate);
+ try {
+ WaitForNuGet.Success (packageOptions.PackageName, isUpdate ? NuGetOperations.Update : NuGetOperations.Add);
+ } catch (TimeoutException e) {
+ takeScreenshot ("Wait-For-NuGet-Operation-Failed");
+ throw;
+ }
+ takeScreenshot ("NuGet-Operation-Finished");
}
- public NuGetController (Action<string> takeScreenshot = null)
+ public NuGetController (Action<string> takeScreenshot = null, bool isUpdate = false)
{
this.takeScreenshot = takeScreenshot ?? delegate { };
+ this.isUpdate = isUpdate;
- nugetWindow = c => c.Window ().Marked ("Add Packages");
addPackageButton = c => nugetWindow (c).Children ().Button ().Text ("Add Package");
+ updatePackageButton = c => nugetWindow (c).Children ().Button ().Text ("Update Package");
resultList = c => nugetWindow (c).Children ().TreeView ().Model ();
includePreRelease = c => nugetWindow (c).Children ().CheckButton ().Text ("Show pre-release packages");
}
@@ -112,18 +147,18 @@ namespace UserInterfaceTests
var found = Session.Query (c => nugetWindow (c).Children ().CheckType (typeof(Gtk.Label)).Text (packageName)).Length > 0;
if (version != null) {
found = found && (Session.Query (c => nugetWindow (c).Children ().CheckType (typeof(Gtk.Label)).Text (version)).Length > 0);
- if (found)
- return;
}
+ if (found)
+ return;
}
takeScreenshot ("Package-Failed-To-Be-Found");
- Assert.Fail ("No package '{0}' with version: '{1}' found", packageName, version);
+ throw new NuGetException (string.Format ("No package '{0}' with version: '{1}' found", packageName, version));
}
public void ClickAdd ()
{
WaitForAddButton (true);
- Assert.IsTrue (Session.ClickElement (addPackageButton));
+ Assert.IsTrue (Session.ClickElement (isUpdate ? updatePackageButton : addPackageButton));
Session.WaitForElement (IdeQuery.TextArea);
}
@@ -138,7 +173,7 @@ namespace UserInterfaceTests
if (enabled == null)
Session.WaitForElement (addPackageButton);
else
- Session.WaitForElement (c => addPackageButton (c).Sensitivity (enabled.Value), 10000);
+ Session.WaitForElement (c => (isUpdate? updatePackageButton(c) : addPackageButton (c)).Sensitivity (enabled.Value), 30000);
}
}
}
diff --git a/main/tests/UserInterfaceTests/Controllers/NuGetOptions.cs b/main/tests/UserInterfaceTests/Controllers/NuGetOptions.cs
new file mode 100644
index 0000000000..9fb53d57cb
--- /dev/null
+++ b/main/tests/UserInterfaceTests/Controllers/NuGetOptions.cs
@@ -0,0 +1,179 @@
+//
+// NuGetOptions.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+
+namespace UserInterfaceTests
+{
+ public class NuGetPackageOptions
+ {
+ public NuGetPackageOptions ()
+ {
+ RetryCount = 3;
+ }
+
+ public string PackageName { get; set;}
+
+ public string Version { get; set;}
+
+ public bool IsPreRelease { get; set;}
+
+ public int RetryCount { get; set;}
+
+ public override string ToString ()
+ {
+ return string.Format ("PackageName={0}, Version={1}, IsPreRelease={2}, RetryCount={3}",
+ PackageName, Version, IsPreRelease, RetryCount);
+ }
+ }
+
+ public enum NuGetOperations
+ {
+ Add,
+ Remove,
+ Update
+ }
+
+ public class WaitForNuGet
+ {
+ public WaitForNuGet ()
+ {
+ TimeOutSeconds = 180;
+ PollStepSeconds = 1;
+ }
+
+ public NuGetOperations Operation { get; set;}
+
+ public string PackageName { get; set;}
+
+ public bool WaitForSuccess { get; set;}
+
+ public bool WaitForWarning { get; set;}
+
+ public bool WaitForError { get; set;}
+
+ public int TimeOutSeconds { get; set;}
+
+ public int PollStepSeconds { get; set;}
+
+ public override string ToString ()
+ {
+ return string.Format ("Operation={0}, PackageName={1}, WaitForSuccess={2}, WaitForWarning={3}, WaitForError={4}, TimeOutSeconds={5}, PollStepSeconds={6}",
+ Operation, PackageName, WaitForSuccess, WaitForWarning, WaitForError, TimeOutSeconds, PollStepSeconds);
+ }
+
+ public static void UpdateSuccess (string packageName, bool waitForWarning = true, UITestBase testContext = null)
+ {
+ Success (packageName, NuGetOperations.Update, waitForWarning, testContext);
+ }
+
+ public static void AddSuccess (string packageName, bool waitForWarning = true, UITestBase testContext = null)
+ {
+ Success (packageName, NuGetOperations.Add, waitForWarning, testContext);
+ }
+
+ public static void Success (string packageName, NuGetOperations operation, bool waitForWarning = true, UITestBase testContext = null)
+ {
+ var waitPackage = new WaitForNuGet {
+ Operation = operation,
+ PackageName = packageName,
+ WaitForSuccess = true,
+ WaitForWarning = waitForWarning
+ };
+ if (testContext != null) {
+ testContext.ReproStep (string.Format ("Wait for one of these messages:\n\t{0}",
+ string.Join ("\t\n", waitPackage.ToMessages ())));
+ }
+ waitPackage.Wait ();
+ }
+
+ public void Wait ()
+ {
+ Ide.WaitForStatusMessage (ToMessages (), TimeOutSeconds, PollStepSeconds);
+ }
+
+ public string [] ToMessages ()
+ {
+ if ((WaitForSuccess | WaitForWarning | WaitForError) == false)
+ throw new ArgumentException ("Atleast one of the 'WaitForSuccess', 'WaitForWarning', 'WaitForError' needs to be true");
+
+ List<string> waitForMessages = new List<string> ();
+
+ if (WaitForSuccess) {
+ if (Operation == NuGetOperations.Add) {
+ waitForMessages.Add (string.Format ("{0} successfully added.", PackageName));
+ waitForMessages.Add ("Packages successfully added.");
+ waitForMessages.Add ("packages successfully added.");
+ }
+ if (Operation == NuGetOperations.Update) {
+ waitForMessages.Add (string.Format ("{0} is up to date.", PackageName));
+ waitForMessages.Add (string.Format ("{0} successfully updated.", PackageName));
+ waitForMessages.Add ("Packages successfully updated.");
+ waitForMessages.Add ("packages successfully updated.");
+ waitForMessages.Add ("successfully updated.");
+ waitForMessages.Add ("Packages are up to date.");
+ }
+ if (Operation == NuGetOperations.Remove) {
+ waitForMessages.Add (string.Format ("{0} successfully removed.", PackageName));
+ }
+ }
+
+ if (WaitForWarning) {
+ if (Operation == NuGetOperations.Add) {
+ waitForMessages.Add (string.Format ("{0} added with warnings.", PackageName));
+ waitForMessages.Add ("Packages added with warnings.");
+ waitForMessages.Add ("packages added with warnings.");
+ }
+ if (Operation == NuGetOperations.Update) {
+ waitForMessages.Add (string.Format ("{0} updated with warnings.", PackageName));
+ waitForMessages.Add ("Packages updated with warnings.");
+ waitForMessages.Add ("packages updated with warnings.");
+ waitForMessages.Add ("No update found but warnings were reported.");
+ waitForMessages.Add ("No updates found but warnings were reported.");
+ }
+ if (Operation == NuGetOperations.Remove) {
+ waitForMessages.Add (string.Format ("{0} removed with warnings.", PackageName));
+ }
+ }
+
+ if (WaitForError) {
+ if (Operation == NuGetOperations.Add) {
+ waitForMessages.Add (string.Format ("Could not add {0}.", PackageName));
+ waitForMessages.Add ("Could not add packages.");
+ }
+ if (Operation == NuGetOperations.Update) {
+ waitForMessages.Add (string.Format ("Could not update {0}.", PackageName));
+ waitForMessages.Add ("Could not update packages.");
+ }
+ if (Operation == NuGetOperations.Remove) {
+ waitForMessages.Add (string.Format ("Could not remove {0}.", PackageName));
+ }
+ }
+ return waitForMessages.ToArray ();
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/Controllers/OptionsController.cs b/main/tests/UserInterfaceTests/Controllers/OptionsController.cs
new file mode 100644
index 0000000000..7a3c9cc0eb
--- /dev/null
+++ b/main/tests/UserInterfaceTests/Controllers/OptionsController.cs
@@ -0,0 +1,148 @@
+//
+// ProjectOptionsController.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Components.AutoTest;
+using MonoDevelop.Ide.Commands;
+
+namespace UserInterfaceTests
+{
+ public class ProjectOptionsController : OptionsController
+ {
+ readonly static Func<AppQuery, AppQuery> windowQuery = c => c.Window ().Marked ("MonoDevelop.Ide.Projects.ProjectOptionsDialog");
+
+ readonly string solutionName;
+ readonly string projectName;
+
+ public ProjectOptionsController (string solutionName, string projectName, UITestBase testContext = null) : base (windowQuery,testContext)
+ {
+ this.solutionName = solutionName;
+ this.projectName = projectName;
+ }
+
+ public ProjectOptionsController (UITestBase testContext = null) : base (windowQuery, testContext) { }
+
+ public void OpenProjectOptions ()
+ {
+ ReproStep (string.Format ("In Solution Explorer, right click '{0}' and select 'Options'", projectName));
+ SolutionExplorerController.SelectProject (solutionName, projectName);
+
+ Session.Query (IdeQuery.TextArea);
+ Session.ExecuteCommand (ProjectCommands.ProjectOptions);
+ Session.WaitForElement (windowQuery);
+ TakeScreenshot ("Opened-ProjectOptionsDialog");
+ }
+ }
+
+ public class PreferencesController : OptionsController
+ {
+ readonly static Func<AppQuery, AppQuery> windowQuery = c => c.Window ().Marked ("Preferences");
+
+ public PreferencesController (Action<string> takeScreenshot = null) : base (windowQuery, takeScreenshot) {}
+
+ public void Open ()
+ {
+ Session.ExecuteCommand (EditCommands.MonodevelopPreferences);
+ Session.WaitForElement (windowQuery);
+ TakeScreenshot ("Opened-Preferences-Window");
+ }
+
+ public static void SetAuthorInformation (string name = null, string email = null , string copyright = null,
+ string company = null, string trademark = null, Action<string> takeScreenshot = null)
+ {
+ takeScreenshot = takeScreenshot ?? new Action<string> (delegate {});
+
+ if (name == null && email == null && copyright == null && company == null && trademark == null)
+ throw new ArgumentNullException ("Atleast one of these arguments need to be not null: name, email, copyright, company, trademark");
+
+ var prefs = new PreferencesController ();
+ prefs.Open ();
+ prefs.SelectPane ("Author Information");
+ prefs.SetEntry ("nameEntry", name, "Name", takeScreenshot);
+ prefs.SetEntry ("emailEntry", email, "Email", takeScreenshot);
+ prefs.SetEntry ("copyrightEntry", copyright, "Copyright", takeScreenshot);
+ prefs.SetEntry ("companyEntry", company, "Company", takeScreenshot);
+ prefs.SetEntry ("trademarkEntry", trademark, "Trademark", takeScreenshot);
+ prefs.ClickOK ();
+ }
+ }
+
+ public abstract class OptionsController
+ {
+ protected static AutoTestClientSession Session {
+ get { return TestService.Session; }
+ }
+
+ protected Action<string> TakeScreenshot;
+ readonly UITestBase testContext;
+ readonly Func<AppQuery, AppQuery> windowQuery;
+
+ protected OptionsController (Func<AppQuery, AppQuery> windowQuery, UITestBase testContext) : this (windowQuery, testContext.TakeScreenShot)
+ {
+ this.testContext = testContext;
+ }
+
+ protected OptionsController (Func<AppQuery, AppQuery> windowQuery, Action<string> takeScreenshot = null)
+ {
+ this.windowQuery = windowQuery;
+ TakeScreenshot = Util.GetNonNullAction (takeScreenshot);
+ }
+
+ protected void ReproStep (string stepDescription, params object[] info)
+ {
+ testContext.ReproStep (stepDescription, info);
+ }
+
+ public void SelectPane (string name)
+ {
+ ReproStep (string.Format ("Select pane: '{0}'", name));
+ string.Format ("Selected Pane :{0}", name).PrintData ();
+ Session.SelectElement (c => windowQuery (c).Children ().Marked (
+ "MonoDevelop.Components.HeaderBox").Children ().TreeView ().Model ().Children ().Property ("Label", name));
+ }
+
+ protected void SetEntry (string entryName, string entryValue, string stepName, Action<string> takeScreenshot)
+ {
+ if (entryValue != null) {
+ Session.EnterText (c => c.Marked (entryName), entryValue);
+ Session.WaitForElement (c => c.Marked (entryName).Text (entryValue));
+ takeScreenshot (string.Format("{0}-Entry-Set", stepName));
+ }
+ }
+
+ public void ClickOK ()
+ {
+ ReproStep ("Click OK");
+ Session.ClickElement (c => windowQuery (c).Children ().Button ().Text ("OK"));
+ }
+
+ public void ClickCancel ()
+ {
+ ReproStep ("Click Cancel");
+ Session.ClickElement (c => windowQuery (c).Children ().Button ().Text ("Cancel"));
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/Controllers/SolutionExplorerController.cs b/main/tests/UserInterfaceTests/Controllers/SolutionExplorerController.cs
index 0afd044380..abd0a1f69b 100644
--- a/main/tests/UserInterfaceTests/Controllers/SolutionExplorerController.cs
+++ b/main/tests/UserInterfaceTests/Controllers/SolutionExplorerController.cs
@@ -24,7 +24,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
+using System.Linq;
using MonoDevelop.Components.AutoTest;
+using System.Collections.Generic;
namespace UserInterfaceTests
{
@@ -39,12 +41,68 @@ namespace UserInterfaceTests
public static Func<AppQuery, AppQuery> GetSolutionQuery (string solutionLabel)
{
- return c => topLevel (c).Children().Property ("Label", solutionLabel).Index (0);
+ return c => topLevel (c).Children (false).Index (0).Property ("Label", solutionLabel);
}
public static Func<AppQuery, AppQuery> GetProjectQuery (string solutionLabel, string projectLabel)
{
- return c => topLevel (c).Children().Property ("Label", solutionLabel).Children ().Property ("Label", projectLabel).Index (0);
+ return c => topLevel (c).Children (false).Index (0).Property ("Label", solutionLabel).Children (false).Property ("Label", projectLabel).Index (0);
+ }
+
+ public static bool Select (params string[] selectionTree)
+ {
+ string.Join (" > ", selectionTree).PrintData ();
+ Func<AppQuery, AppQuery> query = GetNodeQuery (selectionTree);
+ return Session.SelectElement (GetNodeQuery (selectionTree)) && Session.WaitForElement (c => query (c).Selected ()).Any ();
+ }
+
+ public static Func<AppQuery, AppQuery> GetNodeQuery (params string[] selectionTree)
+ {
+ var funcs = new List<Func<AppQuery, AppQuery>> ();
+ funcs.Add (topLevel);
+ foreach (var nodeName in selectionTree) {
+ var lastFunc = funcs.Last ();
+ funcs.Add (c => lastFunc (c).Children (false).Property ("Label", nodeName).Index (0));
+ }
+ return funcs.Last ();
+ }
+
+ public static bool SelectSolution (string solutionName, UITestBase testContext = null)
+ {
+ LogReproSteps (testContext, string.Format ("Under Solution Explorer, select Solution '{0}'", solutionName.StripBold ()));
+ return Select (solutionName);
+ }
+
+ public static bool SelectProject (string solutionName, string projectName, UITestBase testContext = null)
+ {
+ LogReproSteps (testContext, string.Format ("Under Solution Explorer, select Project '{0}' under '{1}'", projectName.StripBold (), solutionName.StripBold ()));
+ return Select (solutionName, projectName);
+ }
+
+ public static bool SelectReferenceFolder (string solutionName, string projectName, UITestBase testContext = null)
+ {
+ LogReproSteps (testContext, string.Format ("Under Solution Explorer, expand References node under '{0}'> '{1}'", projectName.StripBold (), solutionName.StripBold ()));
+ return Select (solutionName, projectName, "References");
+ }
+
+ public static bool SelectSingleReference (string solutionName, string projectName, string referenceName, bool fromPackage = false, UITestBase testContext = null)
+ {
+ LogReproSteps (testContext, string.Format ("Under Solution Explorer, select NuGet package '{0}' under '{1}' > '{2}' > From Packages",
+ referenceName, projectName.StripBold (), solutionName.StripBold ()));
+ return fromPackage ? Select (solutionName, projectName, "From Packages", referenceName) : Select (solutionName, projectName, referenceName);
+ }
+
+ public static bool SelectPackage (string solutionName, string projectName, string package, UITestBase testContext = null)
+ {
+ LogReproSteps (testContext, string.Format ("Under Solution Explorer, select package '{0}' under '{1}' > '{2}' > 'Packages'", package, projectName.StripBold (), solutionName.StripBold ()));
+ return Select (solutionName, projectName, "Packages", package);
+ }
+
+ static void LogReproSteps (UITestBase testContext, string message, params object[] info)
+ {
+ if (testContext != null) {
+ testContext.ReproStep (message, info);
+ }
}
}
}
diff --git a/main/tests/UserInterfaceTests/CreateBuildTemplatesTestBase.cs b/main/tests/UserInterfaceTests/CreateBuildTemplatesTestBase.cs
index 806cad1800..914d78b0da 100644
--- a/main/tests/UserInterfaceTests/CreateBuildTemplatesTestBase.cs
+++ b/main/tests/UserInterfaceTests/CreateBuildTemplatesTestBase.cs
@@ -1,8 +1,9 @@
-//
-// SimpleTest.cs
+//
+// CreateBuildTemplatesTestBase.cs
//
// Author:
// Lluis Sanchez Gual <lluis@novell.com>
+// Manish Sinha <manish.sinha@xamarin.com>
//
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
//
@@ -29,8 +30,7 @@ using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
-
-using MonoDevelop.Core;
+using MonoDevelop.Components.AutoTest;
using NUnit.Framework;
namespace UserInterfaceTests
@@ -92,8 +92,7 @@ namespace UserInterfaceTests
TakeScreenShot ("BeforeBuildActionFailed");
Assert.Fail (e.ToString ());
}
-
- OnBuildTemplate ();
+ OnBuildTemplate ((int)projectDetails.BuildTimeout.TotalSeconds);
} catch (Exception e) {
TakeScreenShot ("TestFailedWithGenericException");
Assert.Fail (e.ToString ());
@@ -105,26 +104,44 @@ namespace UserInterfaceTests
public void CreateProject (TemplateSelectionOptions templateOptions,
ProjectDetails projectDetails, GitOptions gitOptions = null, object miscOptions = null)
{
+ PrintToTestRunner (templateOptions, projectDetails, gitOptions, miscOptions);
+ ReproStep ("Create a new project", templateOptions, projectDetails, gitOptions, miscOptions);
var newProject = new NewProjectController ();
- newProject.Open ();
+
+ if (projectDetails.AddProjectToExistingSolution)
+ newProject.Open (projectDetails.SolutionName);
+ else
+ newProject.Open ();
TakeScreenShot ("Open");
OnSelectTemplate (newProject, templateOptions);
OnEnterTemplateSpecificOptions (newProject, projectDetails.ProjectName, miscOptions);
-
+
OnEnterProjectDetails (newProject, projectDetails, gitOptions, miscOptions);
- OnClickCreate (newProject);
+ OnClickCreate (newProject, projectDetails);
+
+ FoldersToClean.Add (projectDetails.SolutionLocation);
}
protected virtual void OnSelectTemplate (NewProjectController newProject, TemplateSelectionOptions templateOptions)
{
- Assert.IsTrue (newProject.SelectTemplateType (templateOptions.CategoryRoot, templateOptions.Category));
+ if (!newProject.SelectTemplateType (templateOptions.CategoryRoot, templateOptions.Category)) {
+ throw new TemplateSelectionException (string.Format ("Failed to select Category '{0}' under '{1}'",
+ templateOptions.Category, templateOptions.CategoryRoot));
+ }
TakeScreenShot ("TemplateCategorySelected");
- Assert.IsTrue (newProject.SelectTemplate (templateOptions.TemplateKindRoot, templateOptions.TemplateKind));
+
+ if (!newProject.SelectTemplate (templateOptions.TemplateKindRoot, templateOptions.TemplateKind)) {
+ throw new TemplateSelectionException (string.Format ("Failed to select Template '{0}' under '{1}'",
+ templateOptions.TemplateKind, templateOptions.TemplateKindRoot));
+ }
TakeScreenShot ("TemplateSelected");
- Assert.IsTrue (newProject.Next ());
+
+ if (!newProject.Next ()) {
+ throw new TemplateSelectionException ("Clicking Next failed after selecting template");
+ }
TakeScreenShot ("NextAfterTemplateSelected");
}
@@ -133,38 +150,98 @@ namespace UserInterfaceTests
protected virtual void OnEnterProjectDetails (NewProjectController newProject, ProjectDetails projectDetails,
GitOptions gitOptions = null, object miscOptions = null)
{
- Assert.IsTrue (newProject.SetProjectName (projectDetails.ProjectName));
+ if (!newProject.SetProjectName (projectDetails.ProjectName, projectDetails.AddProjectToExistingSolution)) {
+ throw new CreateProjectException (string.Format ("Failed at entering ProjectName as '{0}'", projectDetails.ProjectName));
+ }
if (!string.IsNullOrEmpty (projectDetails.SolutionName)) {
- Assert.IsTrue (newProject.SetSolutionName (projectDetails.SolutionName));
+ if (!newProject.SetSolutionName (projectDetails.SolutionName, projectDetails.AddProjectToExistingSolution)) {
+ throw new CreateProjectException (string.Format ("Failed at entering SolutionName as '{0}'", projectDetails.SolutionName));
+ }
}
if (!string.IsNullOrEmpty (projectDetails.SolutionLocation)) {
- Assert.IsTrue (newProject.SetSolutionLocation (projectDetails.SolutionLocation));
+ if (!newProject.SetSolutionLocation (projectDetails.SolutionLocation)) {
+ throw new CreateProjectException (string.Format ("Failed at entering SolutionLocation as '{0}'", projectDetails.SolutionLocation));
+ }
}
- Assert.IsTrue (newProject.CreateProjectInSolutionDirectory (projectDetails.ProjectInSolution));
+ if (!newProject.CreateProjectInSolutionDirectory (projectDetails.ProjectInSolution)) {
+ throw new CreateProjectException (string.Format ("Failed at entering ProjectInSolution as '{0}'", projectDetails.ProjectInSolution));
+ }
- if (gitOptions != null)
- Assert.IsTrue (newProject.UseGit (gitOptions));
+ if (gitOptions != null && !projectDetails.AddProjectToExistingSolution) {
+ if (!newProject.UseGit (gitOptions)) {
+ throw new CreateProjectException (string.Format ("Failed at setting Git as - '{0}'", gitOptions));
+ }
+ }
TakeScreenShot ("AfterProjectDetailsFilled");
}
- protected virtual void OnClickCreate (NewProjectController newProject)
+ protected virtual void OnClickCreate (NewProjectController newProject, ProjectDetails projectDetails)
{
- Session.RunAndWaitForTimer (() => newProject.Next(), "Ide.Shell.SolutionOpened");
+ if (projectDetails.AddProjectToExistingSolution)
+ newProject.Create ();
+ else
+ Session.RunAndWaitForTimer (() => newProject.Create (), "Ide.Shell.SolutionOpened");
}
protected virtual void OnBuildTemplate (int buildTimeoutInSecs = 180)
{
+ ReproStep ("Build solution");
try {
- Assert.IsTrue (Ide.BuildSolution (timeoutInSecs : buildTimeoutInSecs));
+ Assert.IsTrue (Ide.BuildSolution (timeoutInSecs : buildTimeoutInSecs), "Build Failed");
TakeScreenShot ("AfterBuildFinishedSuccessfully");
} catch (TimeoutException e) {
+ Session.DebugObject.Debug ("Build Failed");
+ ReproStep (string.Format ("Expected: Build should finish within '{0}' seconds\nActual: Build timed out", buildTimeoutInSecs));
TakeScreenShot ("AfterBuildFailed");
Assert.Fail (e.ToString ());
}
}
+
+ protected void IsTemplateSelected (TemplateSelectionOptions templateOptions, string addToExistingSolution = null)
+ {
+// var newProject = new NewProjectController ();
+// try {
+// newProject.WaitForOpen ();
+// } catch (TimeoutException) {
+// if (!string.IsNullOrEmpty (addToExistingSolution))
+// newProject.Open (addToExistingSolution);
+// else
+// newProject.Open ();
+// }
+// newProject.IsSelected (templateOptions);
+ }
+
+ protected void WaitForElement (Func<AppQuery, AppQuery> query, string expected, string actual, int timeoutInSecs = 5)
+ {
+ try {
+ Session.WaitForElement (query, timeoutInSecs * 1000);
+ } catch (TimeoutException) {
+ ReproStep (expected, actual);
+ throw;
+ }
+ }
+
+ protected void WaitForElement (Action action, string expected, string actual)
+ {
+ try {
+ action ();
+ } catch (TimeoutException) {
+ ReproStep (string.Format ("Expected: {0}\nActual:{1}", expected, actual));
+ throw;
+ }
+ }
+
+ void PrintToTestRunner (TemplateSelectionOptions templateOptions,
+ ProjectDetails projectDetails, GitOptions gitOptions, object miscOptions)
+ {
+ templateOptions.PrintData ();
+ projectDetails.PrintData ();
+ gitOptions.PrintData ();
+ miscOptions.PrintData ();
+ }
}
}
diff --git a/main/tests/UserInterfaceTests/DialogTests/NewProjectDialogTests.cs b/main/tests/UserInterfaceTests/DialogTests/NewProjectDialogTests.cs
index 96f7edf3f0..26253e1ea8 100644
--- a/main/tests/UserInterfaceTests/DialogTests/NewProjectDialogTests.cs
+++ b/main/tests/UserInterfaceTests/DialogTests/NewProjectDialogTests.cs
@@ -28,7 +28,7 @@ using NUnit.Framework;
namespace UserInterfaceTests
{
- [TestFixture]
+ [TestFixture, Timeout(60000)]
[Category ("Dialog")]
[Category ("ProjectDialog")]
public class NewProjectDialogTests : CreateBuildTemplatesTestBase
@@ -48,6 +48,7 @@ namespace UserInterfaceTests
readonly string solutionLocation = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
[Test]
+ [Category ("Cycle6")]
[TestCase (true, true, true, TestName = "WithGit--WithGitIgnore--WithProjectWithinSolution")]
[TestCase (true, true, false, TestName = "WithGit--WithGitIgnore--WithoutProjectWithinSolution")]
[TestCase (true, true, true, TestName = "WithGit--WithGitIgnore--WithProjectWithinSolution")]
diff --git a/main/tests/UserInterfaceTests/DialogTests/NuGetDialogTests.cs b/main/tests/UserInterfaceTests/DialogTests/NuGetDialogTests.cs
index bd97ab3c39..f27c95b8c0 100644
--- a/main/tests/UserInterfaceTests/DialogTests/NuGetDialogTests.cs
+++ b/main/tests/UserInterfaceTests/DialogTests/NuGetDialogTests.cs
@@ -25,26 +25,36 @@
// THE SOFTWARE.
using NUnit.Framework;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Core;
+using System.IO;
+using System.Xml;
+using System;
+using System.Collections.Generic;
namespace UserInterfaceTests
{
- [TestFixture]
+ [TestFixture, Timeout(60000)]
[Category ("Dialog")]
+ [Category ("NuGet")]
[Category ("PackagesDialog")]
public class NuGetDialogTests : CreateBuildTemplatesTestBase
{
- [Test]
+ [Test, Category("Smoke")]
+ [Description ("Add a single NuGet Package")]
public void AddPackagesTest ()
{
CreateProject ();
NuGetController.AddPackage (new NuGetPackageOptions {
PackageName = "CommandLineParser",
- Version = "2.0.1-pre",
+ Version = "2.0.257-beta",
IsPreRelease = true
- });
+ }, this);
}
- ProjectDetails CreateProject ()
+ [Test, Timeout(300000), Category ("Cycle6")]
+ [Description ("When a solution is opened and package updates are available, don't show in status bar")]
+ public void DontShowPackageUpdatesAvailable ()
{
var templateOptions = new TemplateSelectionOptions {
CategoryRoot = OtherCategoryRoot,
@@ -53,6 +63,201 @@ namespace UserInterfaceTests
TemplateKind = "Console Project"
};
var projectDetails = new ProjectDetails (templateOptions);
+ CreateProject (templateOptions, projectDetails);
+ NuGetController.AddPackage (new NuGetPackageOptions {
+ PackageName = "CommandLineParser",
+ Version = "1.9.3.34",
+ IsPreRelease = false
+ }, this);
+
+ string solutionFolder = GetSolutionDirectory ();
+ string solutionPath = Path.Combine (solutionFolder, projectDetails.SolutionName+".sln");
+ var projectPath = Path.Combine (solutionFolder, projectDetails.ProjectName, projectDetails.ProjectName + ".csproj");
+ Assert.IsTrue (File.Exists (projectPath));
+
+ Workbench.CloseWorkspace (this);
+
+ Workbench.OpenWorkspace (solutionPath, this);
+ try {
+ const string expected = "When a solution is opened and package updates are available, it don't show in status bar";
+ ReproStep (expected);
+ Ide.WaitForPackageUpdate ();
+ var failureMessage = string.Format ("Expected: {0}\nActual: {1}",
+ expected, "When a solution is opened and package updates are available, it shows in status bar");
+ ReproStep (failureMessage);
+ Assert.Fail (failureMessage);
+ } catch (TimeoutException) {
+ Session.DebugObject.Debug ("WaitForPackageUpdate throws TimeoutException as expected");
+ }
+ Ide.WaitForSolutionLoaded ();
+ TakeScreenShot ("Solution-Ready");
+ }
+
+ [Test, Category("Smoke")]
+ [Description ("Add a single NuGet Package and check if it's readme.txt opens")]
+ public void TestReadmeTxtOpens ()
+ {
+ CreateProject ();
+ NuGetController.AddPackage (new NuGetPackageOptions {
+ PackageName = "RestSharp",
+ Version = "105.2.3",
+ IsPreRelease = true
+ }, this);
+ WaitForNuGetReadmeOpened ();
+ }
+
+ [Test, Category ("Cycle6")]
+ [Description ("Add a single NuGet Package. Check if readme.txt opens even when updating")]
+ public void TestReadmeTxtUpgradeOpens ()
+ {
+ CreateProject ();
+ NuGetController.AddPackage (new NuGetPackageOptions {
+ PackageName = "RestSharp",
+ Version = "105.2.2",
+ IsPreRelease = true
+ }, this);
+ WaitForNuGetReadmeOpened ();
+
+ Session.ExecuteCommand (FileCommands.CloseFile);
+ Session.WaitForElement (IdeQuery.TextArea);
+ TakeScreenShot ("About-To-Update-Package");
+ NuGetController.UpdatePackage (new NuGetPackageOptions {
+ PackageName = "RestSharp",
+ Version = "105.2.3",
+ IsPreRelease = true
+ }, this);
+ WaitForNuGetReadmeOpened ();
+ }
+
+ [Test, Category("Smoke"), Category ("Cycle6")]
+ [Timeout (90000)]
+ [Description ("When readme.txt from a package has already been opened, adding same package to another project should not open readme.txt")]
+ public void TestDontOpenReadmeOpenedInOther ()
+ {
+ var packageInfo = new NuGetPackageOptions {
+ PackageName = "RestSharp",
+ Version = "105.2.3",
+ IsPreRelease = true
+ };
+
+ var projectDetails = CreateProject ();
+ NuGetController.AddPackage (packageInfo, this);
+ WaitForNuGetReadmeOpened ();
+ Session.ExecuteCommand (FileCommands.CloseFile);
+
+ var pclTemplateOptions = new TemplateSelectionOptions {
+ CategoryRoot = "Other",
+ Category = ".NET",
+ TemplateKindRoot = "General",
+ TemplateKind = "Library"
+ };
+ var pclProjectDetails = ProjectDetails.ToExistingSolution (projectDetails.SolutionName,
+ GenerateProjectName (pclTemplateOptions.TemplateKind));
+ CreateProject (pclTemplateOptions, pclProjectDetails);
+ Ide.WaitForIdeIdle (30);
+
+ SolutionExplorerController.SelectProject (projectDetails.SolutionName, pclProjectDetails.ProjectName);
+ NuGetController.AddPackage (packageInfo, this);
+ try {
+ WaitForNuGetReadmeOpened (false);
+ var failureMessage = string.Format ("Expected: {0}\nActual:{1}",
+ "readme.txt tab should not open", "readme.txt tab opens");
+ ReproStep (failureMessage);
+ Assert.Fail (failureMessage);
+ } catch (TimeoutException) {
+ Session.DebugObject.Debug ("readme.txt tab failed to open as expected");
+ }
+ }
+
+ [Test, Category ("Cycle6")]
+ [Description ("Add a package with powershell scripts and assert that Xamarin Studio doesn't report warnings "+
+ "when trying to add powershell scripts to Xamarin Studio")]
+ public void TestDontShowWarningWithPowerShellScripts ()
+ {
+ CreateProject ();
+ NuGetController.AddPackage (new NuGetPackageOptions {
+ PackageName = "Newtonsoft.Json",
+ }, this);
+ WaitForNuGet.Success ("Newtonsoft.Json", NuGetOperations.Add, false, this);
+ TakeScreenShot ("NewtonSoftJson-Package-Added-Without-Warning");
+ }
+
+ [Test, Timeout (300000), Category ("Cycle6")]
+ [Description ("When a NuGet package is updated, the 'Local Copy' value should be preserved")]
+ public void TestLocalCopyPreservedUpdate ()
+ {
+ var templateOptions = new TemplateSelectionOptions {
+ CategoryRoot = OtherCategoryRoot,
+ Category = ".NET",
+ TemplateKindRoot = GeneralKindRoot,
+ TemplateKind = "Console Project"
+ };
+ var projectDetails = new ProjectDetails (templateOptions);
+ CreateProject (templateOptions, projectDetails);
+ NuGetController.AddPackage (new NuGetPackageOptions {
+ PackageName = "CommandLineParser",
+ Version = "1.9.71",
+ IsPreRelease = false
+ }, this);
+
+ string solutionFolder = GetSolutionDirectory ();
+ string solutionPath = Path.Combine (solutionFolder, projectDetails.SolutionName+".sln");
+ var projectPath = Path.Combine (solutionFolder, projectDetails.ProjectName, projectDetails.ProjectName + ".csproj");
+ Assert.IsTrue (File.Exists (projectPath));
+
+ ReproStep ("Check 'Local Copy' on CommandLine package under References");
+
+ Workbench.CloseWorkspace (this);
+
+ AddOrCheckLocalCopy (projectPath, true);
+
+ Workbench.OpenWorkspace (solutionPath, this);
+
+ NuGetController.UpdateAllNuGetPackages (this);
+
+ ReproStep ("Check if CommandLine package under References has 'Local Copy' checked");
+ AddOrCheckLocalCopy (projectPath, false);
+ }
+
+ void AddOrCheckLocalCopy (string projectPath, bool addLocalCopy)
+ {
+ using (var stream = new FileStream (projectPath, FileMode.Open, FileAccess.ReadWrite)) {
+ var xmlDoc = new XmlDocument();
+ xmlDoc.Load(stream);
+ var ns = "http://schemas.microsoft.com/developer/msbuild/2003";
+ XmlNamespaceManager xnManager = new XmlNamespaceManager(xmlDoc.NameTable);
+ xnManager.AddNamespace("ui", ns);
+ XmlNode root = xmlDoc.DocumentElement;
+ var uitest = root.SelectSingleNode ("//ui:Reference[@Include=\"CommandLine\"]", xnManager);
+ Assert.IsNotNull (uitest, "Cannot find CommandLine package reference in file: "+projectPath);
+ var privateUITestNode = uitest.SelectSingleNode ("./ui:Private", xnManager);
+
+ if (addLocalCopy) {
+ Assert.IsNull (privateUITestNode, uitest.InnerXml, "CommandLine package is already set to 'No Local Copy'");
+ var privateNode = xmlDoc.CreateElement ("Private", ns);
+ privateNode.InnerText = "False";
+ uitest.AppendChild (privateNode);
+ stream.SetLength (0);
+ xmlDoc.Save (stream);
+ stream.Flush ();
+ } else {
+ Assert.IsNotNull (privateUITestNode, "Cannot find CommandLine package with 'No Local Copy' set");
+ Assert.AreEqual (privateUITestNode.InnerText, "False");
+ }
+ stream.Close ();
+ }
+ }
+
+
+ ProjectDetails CreateProject (TemplateSelectionOptions templateOptions = null, ProjectDetails projectDetails = null)
+ {
+ templateOptions = templateOptions ?? new TemplateSelectionOptions {
+ CategoryRoot = OtherCategoryRoot,
+ Category = ".NET",
+ TemplateKindRoot = GeneralKindRoot,
+ TemplateKind = "Console Project"
+ };
+ projectDetails = projectDetails ?? new ProjectDetails (templateOptions);
CreateProject (templateOptions,
projectDetails,
new GitOptions { UseGit = true, UseGitIgnore = true});
@@ -60,6 +265,20 @@ namespace UserInterfaceTests
FoldersToClean.Add (projectDetails.SolutionLocation);
return projectDetails;
}
+
+ void WaitForNuGetReadmeOpened (bool expectSuccess = true)
+ {
+ ReproStep ("Wait for tab with readme.txt to be opened");
+ try {
+ Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.DefaultWorkbench").Property ("TabControl.CurrentTab.Text", "readme.txt"));
+ } catch (TimeoutException) {
+ if (expectSuccess) {
+ ReproStep (string.Format ("Expected: {0}\nActual: {1}",
+ "readme.txt tab should open", "readm.txt tab did not open"));
+ }
+ throw;
+ }
+ }
}
}
diff --git a/main/tests/UserInterfaceTests/Exceptions/CreateProjectException.cs b/main/tests/UserInterfaceTests/Exceptions/CreateProjectException.cs
new file mode 100644
index 0000000000..0e91464f13
--- /dev/null
+++ b/main/tests/UserInterfaceTests/Exceptions/CreateProjectException.cs
@@ -0,0 +1,37 @@
+//
+// CreateProjectException.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+
+namespace UserInterfaceTests
+{
+ public class CreateProjectException : Exception
+ {
+ public CreateProjectException (string message): base (message)
+ {
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/Exceptions/NuGetException.cs b/main/tests/UserInterfaceTests/Exceptions/NuGetException.cs
new file mode 100644
index 0000000000..935dc6d3b4
--- /dev/null
+++ b/main/tests/UserInterfaceTests/Exceptions/NuGetException.cs
@@ -0,0 +1,41 @@
+//
+// NuGetException.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+
+namespace UserInterfaceTests
+{
+ public class NuGetException : Exception
+ {
+ public NuGetException (string message) : base (message)
+ {
+ }
+
+ public NuGetException (string message, Exception innerExceotion) : base (message, innerExceotion)
+ {
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/Exceptions/TemplateSelectionException.cs b/main/tests/UserInterfaceTests/Exceptions/TemplateSelectionException.cs
new file mode 100644
index 0000000000..041f4bb5e5
--- /dev/null
+++ b/main/tests/UserInterfaceTests/Exceptions/TemplateSelectionException.cs
@@ -0,0 +1,37 @@
+//
+// TemplateSelectionException.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+
+namespace UserInterfaceTests
+{
+ public class TemplateSelectionException : Exception
+ {
+ public TemplateSelectionException (string message) : base (message)
+ {
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/Ide.cs b/main/tests/UserInterfaceTests/Ide.cs
index 14a4b86857..37af208fa8 100644
--- a/main/tests/UserInterfaceTests/Ide.cs
+++ b/main/tests/UserInterfaceTests/Ide.cs
@@ -1,5 +1,5 @@
//
-// IdeApi.cs
+// Ide.cs
//
// Author:
// Lluis Sanchez Gual <lluis@novell.com>
@@ -26,6 +26,7 @@
using System;
using System.Threading;
+using System.Linq;
using MonoDevelop.Core;
using MonoDevelop.Core.Instrumentation;
@@ -33,11 +34,8 @@ using MonoDevelop.Ide.Commands;
using MonoDevelop.Components.AutoTest;
using NUnit.Framework;
-
-using Gdk;
-using System.Linq;
-
-
+using System.Collections.Generic;
+
namespace UserInterfaceTests
{
public static class Ide
@@ -48,12 +46,13 @@ namespace UserInterfaceTests
public static void OpenFile (FilePath file)
{
- Session.GlobalInvoke ("MonoDevelop.Ide.IdeApp.Workbench.OpenDocument", (string) file, true);
+ Session.RunAndWaitForTimer (() => Session.GlobalInvoke ("MonoDevelop.Ide.IdeApp.Workbench.OpenDocument", (string)file, true), "Ide.Shell.DocumentOpened");
Assert.AreEqual (file, GetActiveDocumentFilename ());
}
public static void CloseAll ()
{
+ Session.ExecuteCommand (FileCommands.SaveAll);
Session.ExecuteCommand (FileCommands.CloseWorkspace);
Session.ExitApp ();
}
@@ -63,15 +62,13 @@ namespace UserInterfaceTests
return Session.GetGlobalValue<FilePath> ("MonoDevelop.Ide.IdeApp.Workbench.ActiveDocument.FileName");
}
- public static bool BuildSolution (bool isPass = true, int timeoutInSecs = 180)
+ public static bool BuildSolution (bool isPass = true, int timeoutInSecs = 360)
{
- Session.RunAndWaitForTimer (() => Session.ExecuteCommand (ProjectCommands.BuildSolution),
- "Ide.Shell.ProjectBuilt", timeout: timeoutInSecs * 1000);
- var status = IsBuildSuccessful ();
- return isPass == status;
+ Session.RunAndWaitForTimer (() => Session.ExecuteCommand (ProjectCommands.BuildSolution), "Ide.Shell.ProjectBuilt", timeoutInSecs * 1000);
+ return isPass == Workbench.IsBuildSuccessful (timeoutInSecs);
}
- public static void WaitUntil (Func<bool> done, int timeout = 20000, int pollStep = 200)
+ public static void WaitUntil (Func<bool> done, int timeout = 20000, int pollStep = 200, Func<string> timeoutMessage = null)
{
do {
if (done ())
@@ -80,30 +77,22 @@ namespace UserInterfaceTests
Thread.Sleep (pollStep);
} while (timeout > 0);
- throw new TimeoutException ("Timed out waiting for Function: "+done.Method.Name);
+ if (timeoutMessage != null) {
+ throw new TimeoutException ("Timed out waiting for Function: " + done.Method.Name + " Message: " + timeoutMessage ());
+ } else {
+ throw new TimeoutException ("Timed out waiting for Function: " + done.Method.Name);
+ }
}
- //no saner way to do this
- public static string GetStatusMessage (int timeout = 20000)
+ public static bool ClickButtonAlertDialog (string buttonText)
{
if (Platform.IsMac) {
- WaitUntil (
- () => Session.GetGlobalValue<string> ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.text") != string.Empty,
- timeout
- );
- return (string)Session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.text");
+ Ide.WaitUntil (() => Session.Query (c => c.Marked ("Xamarin Studio").Marked ("AppKit.NSPanel")).Any ());
+ return Session.ClickElement (c => c.Marked ("AppKit.NSButton").Text (buttonText));
+ } else {
+ Ide.WaitUntil (() => Session.Query (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.Dialogs.GtkAlertDialog")).Any ());
+ return Session.ClickElement (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.Dialogs.GtkAlertDialog").Children ().Button ().Text (buttonText));
}
-
- WaitUntil (
- () => Session.GetGlobalValue<int> ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.messageQueue.Count") == 0,
- timeout
- );
- return (string) Session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.renderArg.CurrentText");
- }
-
- public static bool IsBuildSuccessful ()
- {
- return Session.ErrorCount (MonoDevelop.Ide.Tasks.TaskSeverity.Error) == 0;
}
public static void RunAndWaitForTimer (Action action, string counter, int timeout = 20000)
@@ -113,32 +102,51 @@ namespace UserInterfaceTests
action ();
- WaitUntil (() => c.TotalTime > tt, timeout);
+ WaitUntil (() => c.TotalTime > tt, timeout,
+ timeoutMessage: () => "Counter:" + counter + " T1:" + c.TotalTime + " T2:" + tt + " Timeout:" + timeout);
}
+
+ public readonly static Action WaitForPackageUpdateOrSaved = delegate {
+ try {
+ WaitForPackageUpdate ();
+ } catch (TimeoutException e1) {
+ try {
+ WaitForSolutionLoaded ();
+ } catch (TimeoutException e2) {
+ throw new TimeoutException (string.Format ("{0}\n{1}", e1.Message, e2.Message), e1);
+ }
+ }
+ };
+
public readonly static Action EmptyAction = delegate { };
+ static string[] waitForNuGetMessages = {
+ "Package updates are available.",
+ "Packages are up to date.",
+ "No updates found but warnings were reported.",
+ "Packages successfully added.",
+ "Packages successfully updated.",
+ "Packages added with warnings.",
+ "Packages updated with warnings."};
+
public readonly static Action WaitForPackageUpdate = delegate {
- WaitForStatusMessage (new [] {
- "Package updates are available.",
- "Packages are up to date.",
- "No updates found but warnings were reported.",
- "Packages successfully updated.",
- "Packages updated with warnings."},
- timeoutInSecs: 360, pollStepInSecs: 5);
+ WaitForStatusMessage (waitForNuGetMessages, timeoutInSecs: 180, pollStepInSecs: 5);
};
+ public static void WaitForPackageUpdateExtra (List<string> otherMessages)
+ {
+ otherMessages.AddRange (waitForNuGetMessages);
+ WaitForStatusMessage (otherMessages.ToArray (), timeoutInSecs: 180, pollStepInSecs: 5);
+ }
+
public readonly static Action WaitForSolutionCheckedOut = delegate {
WaitForStatusMessage (new [] {"Solution checked out", "Solution Loaded."}, timeoutInSecs: 360, pollStepInSecs: 5);
};
- public static void WaitForSolutionLoaded (Action<string> afterEachStep)
- {
- WaitForStatusMessage (new [] {"Loading..."});
- afterEachStep ("Loading-Solution");
- WaitForNoStatusMessage (new [] {"Loading..."});
- afterEachStep ("Solution-Loaded");
- }
+ public readonly static Action WaitForSolutionLoaded = delegate {
+ WaitForStatusMessage (new [] {"Project saved.", "Solution loaded."}, timeoutInSecs: 120, pollStepInSecs: 5);
+ };
public static void WaitForStatusMessage (string[] statusMessage, int timeoutInSecs = 240, int pollStepInSecs = 1)
{
@@ -153,10 +161,71 @@ namespace UserInterfaceTests
static void PollStatusMessage (string[] statusMessage, int timeoutInSecs, int pollStepInSecs, bool waitForMessage = true)
{
Ide.WaitUntil (() => {
- var actualStatusMessage = Ide.GetStatusMessage ();
- return waitForMessage == (statusMessage.Contains (actualStatusMessage, StringComparer.OrdinalIgnoreCase));
- }, pollStep: pollStepInSecs * 1000, timeout: timeoutInSecs * 1000);
+ string actualStatusMessage = string.Empty;
+ try {
+ actualStatusMessage = Workbench.GetStatusMessage ();
+ return waitForMessage == (statusMessage.Contains (actualStatusMessage, StringComparer.OrdinalIgnoreCase));
+ } catch (TimeoutException e) {
+ throw new TimeoutException (
+ string.Format ("Timed out. Found status message '{0}'\nand expected one of these:\n\t {1}",
+ actualStatusMessage, string.Join ("\n\t", statusMessage)), e);
+ }
+ },
+ pollStep: pollStepInSecs * 1000,
+ timeout: timeoutInSecs * 1000,
+ timeoutMessage: () => "GetStatusMessage=" + Workbench.GetStatusMessage ());
+ }
+
+ static readonly List<string> ignoreStatusMessgaes = new List<string> {
+ "Saving...",
+ "Restoring packages for solution...",
+ "Restoring packages before update...",
+ "Restoring packages for project...",
+ "Updating packages in solution...",
+ "Updating packages in project..."
+ };
+
+ public static void WaitForIdeIdle (uint totalTimeoutInSecs = 100, uint idlePeriodInSecs = 10, string[] ignoreMessages = null)
+ {
+ uint retriesLeft = (uint)Math.Ceiling ((double)totalTimeoutInSecs/(double)idlePeriodInSecs);
+ ManualResetEvent resetEvent = new ManualResetEvent (false);
+ if (ignoreMessages != null)
+ ignoreStatusMessgaes.AddRange (ignoreMessages);
+
+ var timer = new System.Timers.Timer {
+ Interval = idlePeriodInSecs * 1000,
+ AutoReset = true
+ };
+ bool didTimeout = false;
+
+ var initialStatusMessage = Workbench.GetStatusMessage (waitForNonEmpty: false);
+ timer.Elapsed += (sender, e) => {
+ if (retriesLeft == 0) {
+ didTimeout = true;
+ resetEvent.Set ();
+ }
+
+ var finalStatusMessage = Workbench.GetStatusMessage (waitForNonEmpty: false);
+ var isIdle = string.Equals (initialStatusMessage, finalStatusMessage) && !ignoreStatusMessgaes.Contains (finalStatusMessage);
+
+ if (!isIdle) {
+ retriesLeft--;
+ initialStatusMessage = finalStatusMessage;
+ }
+ if (isIdle) {
+ resetEvent.Set ();
+ }
+ };
+
+ timer.Start ();
+ resetEvent.WaitOne ();
+ timer.Stop ();
+ timer.AutoReset = false;
+ timer.Dispose ();
+
+ if (didTimeout)
+ throw new TimeoutException ("Timeout waiting for IDE to be ready and idle");
}
}
-} \ No newline at end of file
+}
diff --git a/main/tests/UserInterfaceTests/IdeQuery.cs b/main/tests/UserInterfaceTests/IdeQuery.cs
index c47068d6ed..69fda74e57 100644
--- a/main/tests/UserInterfaceTests/IdeQuery.cs
+++ b/main/tests/UserInterfaceTests/IdeQuery.cs
@@ -25,6 +25,7 @@
// THE SOFTWARE.
using System;
using MonoDevelop.Components.AutoTest;
+using MonoDevelop.Core;
namespace UserInterfaceTests
{
@@ -36,6 +37,18 @@ namespace UserInterfaceTests
readonly static Func<AppQuery, AppQuery> _editRemoteDialog = c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.EditRemoteDialog");
readonly static Func<AppQuery, AppQuery> _editBranchDialog = c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.EditBranchDialog");
readonly static Func<AppQuery, AppQuery> _textArea = c => c.Window ().Children ().Marked ("Mono.TextEditor.TextArea");
+ readonly static Func<AppQuery, AppQuery> _xamarinUpdate = c => c.Marked ("Xamarin Update");
+
+ readonly static Func<AppQuery, AppQuery> _macRunButton = c => c.Marked ("MonoDevelop.MacIntegration.MainToolbar.RunButton");
+
+ public static Func<AppQuery, AppQuery> RunButton
+ {
+ get {
+ if (Platform.IsMac)
+ return _macRunButton;
+ throw new NotImplementedException ("Run Button is not implemented for Windows");
+ }
+ }
public static Func<AppQuery, AppQuery> DefaultWorkbench
{
@@ -78,6 +91,13 @@ namespace UserInterfaceTests
return _textArea;
}
}
+
+ public static Func<AppQuery, AppQuery> XamarinUpdate
+ {
+ get {
+ return _xamarinUpdate;
+ }
+ }
}
}
diff --git a/main/tests/UserInterfaceTests/LogMessageValidator.cs b/main/tests/UserInterfaceTests/LogMessageValidator.cs
new file mode 100644
index 0000000000..fc2f875f14
--- /dev/null
+++ b/main/tests/UserInterfaceTests/LogMessageValidator.cs
@@ -0,0 +1,56 @@
+//
+// LogMessageValidator.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.IO;
+using NUnit.Framework;
+using System.Collections.Generic;
+
+namespace UserInterfaceTests
+{
+ public class LogMessageValidator
+ {
+ static List<string> invalidLogStrings = new List<string> {
+ "Gtk-Critical: void gtk_container_remove(GtkContainer , GtkWidget )"
+ };
+
+ public static void Validate (string fileName)
+ {
+ string readIdeLog = string.Empty;
+ using (FileStream fileStream = new FileStream (fileName, FileMode.Open,
+ FileAccess.Read, FileShare.ReadWrite)) {
+ using (StreamReader streamReader = new StreamReader (fileStream)) {
+ readIdeLog = streamReader.ReadToEnd ();
+ }
+ }
+
+ foreach (var error in invalidLogStrings) {
+ Assert.IsFalse (readIdeLog.Contains (error),
+ string.Format ("GTK Error detected in Ide.log file:\n\t{0}",error));
+ }
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/TemplateTestOptions.cs b/main/tests/UserInterfaceTests/TemplateTestOptions.cs
index 6385b9928b..370f4237ce 100644
--- a/main/tests/UserInterfaceTests/TemplateTestOptions.cs
+++ b/main/tests/UserInterfaceTests/TemplateTestOptions.cs
@@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+
using System;
namespace UserInterfaceTests
@@ -57,6 +58,12 @@ namespace UserInterfaceTests
public string TemplateKindRoot { get; set; }
public string TemplateKind { get; set; }
+
+ public override string ToString ()
+ {
+ return string.Format ("CategoryRoot={0}, Category={1}, TemplateKindRoot={2}, TemplateKind={3}",
+ CategoryRoot, Category, TemplateKindRoot, TemplateKind);
+ }
}
public class GitOptions
@@ -70,6 +77,11 @@ namespace UserInterfaceTests
public bool UseGit { get; set; }
public bool UseGitIgnore { get; set; }
+
+ public override string ToString ()
+ {
+ return string.Format ("UseGit={0}, UseGitIgnore={1}", UseGit, UseGitIgnore);
+ }
}
public class ProjectDetails
@@ -78,6 +90,7 @@ namespace UserInterfaceTests
{
SolutionLocation = Util.CreateTmpDir ();
ProjectInSolution = true;
+ BuildTimeout = TimeSpan.FromSeconds (180);
}
public ProjectDetails (TemplateSelectionOptions templateData) : this ()
@@ -86,6 +99,16 @@ namespace UserInterfaceTests
SolutionName = ProjectName;
}
+ public static ProjectDetails ToExistingSolution (string solutionName, string projectName)
+ {
+ return new ProjectDetails {
+ ProjectName = projectName,
+ SolutionName = solutionName,
+ AddProjectToExistingSolution = true,
+ SolutionLocation = null
+ };
+ }
+
public string ProjectName { get; set; }
public string SolutionName { get; set; }
@@ -93,6 +116,16 @@ namespace UserInterfaceTests
public string SolutionLocation { get; set; }
public bool ProjectInSolution { get; set; }
+
+ public bool AddProjectToExistingSolution { get; set; }
+
+ public TimeSpan BuildTimeout { get; set; }
+
+ public override string ToString ()
+ {
+ return string.Format ("ProjectName={0}, SolutionName={1}, SolutionLocation={2}, ProjectInSolution={3}, AddProjectToExistingSolution={4}",
+ ProjectName, SolutionName, SolutionLocation, ProjectInSolution, AddProjectToExistingSolution);
+ }
}
public class NewFileOptions
@@ -106,6 +139,12 @@ namespace UserInterfaceTests
public string FileTypeCategoryRoot { get; set; }
public string AddToProjectName { get; set; }
+
+ public override string ToString ()
+ {
+ return string.Format ("FileName={0}, FileType={1}, FileTypeCategory={2}, FileTypeCategoryRoot={3}, AddToProjectName={4}",
+ FileName, FileType, FileTypeCategory, FileTypeCategoryRoot, AddToProjectName);
+ }
}
}
diff --git a/main/tests/UserInterfaceTests/TemplateTests/ASPNETTemplateTests.cs b/main/tests/UserInterfaceTests/TemplateTests/ASPNETTemplateTests.cs
index 0ab34f71b6..904726c71d 100644
--- a/main/tests/UserInterfaceTests/TemplateTests/ASPNETTemplateTests.cs
+++ b/main/tests/UserInterfaceTests/TemplateTests/ASPNETTemplateTests.cs
@@ -35,15 +35,22 @@ namespace UserInterfaceTests
{
readonly string aspCategory = "ASP.NET";
- [Test]
- [TestCase ("Empty ASP.NET MVC Project", BeforeBuildAction.WaitForPackageUpdate, TestName = "TestEmptyASPMVCProject")]
- [TestCase ("Empty ASP.NET Project", BeforeBuildAction.None, TestName = "TestEmptyASPProject")]
- [TestCase ("ASP.NET MVC Project", BeforeBuildAction.WaitForPackageUpdate, TestName = "TestASPMVCProject")]
- [TestCase ("ASP.NET MVC Project with Unit Tests", BeforeBuildAction.WaitForPackageUpdate, TestName = "TestASPMVCProjectWithUnitTests")]
- [TestCase ("ASP.NET MVC Razor Project", BeforeBuildAction.WaitForPackageUpdate, TestName = "TestASPMVCMazorProject")]
- [TestCase ("ASP.NET MVC Razor Project with Unit Tests", BeforeBuildAction.WaitForPackageUpdate, TestName = "TestASPMVCMazorProjectWithUnitTests")]
- [TestCase ("ASP.NET Project", BeforeBuildAction.None, TestName = "TestASPProject")]
- public void RunASPTest (string templateName, BeforeBuildAction beforeBuild)
+ [Test, Timeout (90000)]
+ [TestCase ("Empty ASP.NET MVC Project", TestName = "TestEmptyASPMVCProject",
+ Description = "Create and build Empty ASP.NET MVC Project")]
+ [TestCase ("Empty ASP.NET Project", TestName = "TestEmptyASPProject",
+ Description = "Create and build Empty ASP.NET MVC Project")]
+ [TestCase ("ASP.NET MVC Project", TestName = "TestASPMVCProject",
+ Description = "Create and build ASP.NET MVC Project")]
+ [TestCase ("ASP.NET MVC Project with Unit Tests", TestName = "TestASPMVCProjectWithUnitTests",
+ Description = "Create and build ASP.NET MVC Project with Unit Tests")]
+ [TestCase ("ASP.NET MVC Razor Project", TestName = "TestASPMVCMazorProject",
+ Description = "Create and build ASP.NET MVC Razor Project")]
+ [TestCase ("ASP.NET MVC Razor Project with Unit Tests", TestName = "TestASPMVCMazorProjectWithUnitTests",
+ Description = "Create and build ASP.NET MVC Razor Project with Unit Tests", Category="Smoke")]
+ [TestCase ("ASP.NET Project", TestName = "TestASPProject",
+ Description = "Create and build ASP.NET Project")]
+ public void RunASPTest (string templateName)
{
var templateOptions = new TemplateSelectionOptions {
CategoryRoot = OtherCategoryRoot,
@@ -51,7 +58,8 @@ namespace UserInterfaceTests
TemplateKindRoot = GeneralKindRoot,
TemplateKind = templateName
};
- CreateBuildProject (templateOptions, beforeBuild.GetAction ());
+
+ CreateBuildProject (templateOptions, () => Ide.WaitForIdeIdle (totalTimeoutInSecs: 50));
}
}
}
diff --git a/main/tests/UserInterfaceTests/TemplateTests/DotNetTemplatesTest.cs b/main/tests/UserInterfaceTests/TemplateTests/DotNetTemplatesTest.cs
index 53abdb7d70..48eb89b26b 100644
--- a/main/tests/UserInterfaceTests/TemplateTests/DotNetTemplatesTest.cs
+++ b/main/tests/UserInterfaceTests/TemplateTests/DotNetTemplatesTest.cs
@@ -34,12 +34,13 @@ namespace UserInterfaceTests
{
readonly string dotNetCategory = ".NET";
- [Test]
- [TestCase ("Console Project", BeforeBuildAction.None, TestName = "TestCreateBuildConsoleProject")]
- [TestCase ("Gtk# 2.0 Project", BeforeBuildAction.None, TestName = "TestCreateBuildGtkSharp20Project")]
- [TestCase ("Library", BeforeBuildAction.None, TestName = "TestCreateBuildLibrary")]
- [TestCase ("NUnit Library Project", BeforeBuildAction.WaitForPackageUpdate, TestName = "TestCreateBuildNUnitLibraryProject")]
- public void RunDotNetTests (string templateName, BeforeBuildAction beforeBuild)
+ [Test, Timeout (90000)]
+ [TestCase ("Console Project", 30, TestName = "TestCreateBuildConsoleProject", Description = "Create and build C# Console Project", Category="Smoke")]
+ [TestCase ("Gtk# 2.0 Project", 30, TestName = "TestCreateBuildGtkSharp20Project", Description = "Create and build a GTK#2 Project")]
+ [TestCase ("Library", 30, TestName = "TestCreateBuildLibrary", Description = "Create and build a Library Project")]
+ [TestCase ("NUnit Library Project", 50, TestName = "TestCreateBuildNUnitLibraryProject",
+ Description = "Create and build NUnit Library Project", Category="Smoke")]
+ public void RunDotNetTests (string templateName, int totalTimeoutInSecs)
{
var templateOptions = new TemplateSelectionOptions {
CategoryRoot = OtherCategoryRoot,
@@ -47,7 +48,7 @@ namespace UserInterfaceTests
TemplateKindRoot = GeneralKindRoot,
TemplateKind = templateName
};
- CreateBuildProject (templateOptions, beforeBuild.GetAction ());
+ CreateBuildProject (templateOptions, () => Ide.WaitForIdeIdle ((uint)totalTimeoutInSecs));
}
}
}
diff --git a/main/tests/UserInterfaceTests/TemplateTests/MiscTemplatesTest.cs b/main/tests/UserInterfaceTests/TemplateTests/MiscTemplatesTest.cs
index 196e3392db..8a041ac129 100644
--- a/main/tests/UserInterfaceTests/TemplateTests/MiscTemplatesTest.cs
+++ b/main/tests/UserInterfaceTests/TemplateTests/MiscTemplatesTest.cs
@@ -28,18 +28,25 @@ using NUnit.Framework;
namespace UserInterfaceTests
{
- [TestFixture]
- [Category("Misc")]
+ [TestFixture, Timeout (60000), Category ("Misc")]
public class MiscTemplatesTest : CreateBuildTemplatesTestBase
{
readonly string miscCategory = "Miscellaneous";
[Test]
- [TestCase ("Generic Project", "Generic", TestName = "TestMiscGenericProject")]
- [TestCase ("Packaging project", "Generic", TestName = "TestMiscPackagingProject")]
- [TestCase ("Shared Library", "C/C++", TestName = "TestMiscCCPlusSharedLibrary")]
- [TestCase ("Static Library", "C/C++", TestName = "TestMiscCCPlusStaticLibrary")]
- [TestCase ("Console Project", "C/C++", TestName = "TestMiscCCPlusConsoleProject")]
+ [Platform (Exclude="Win")]
+ [TestCase ("Shared Library", "C/C++", TestName = "TestMiscCCPlusSharedLibrary", Description = "Create and build Shared C/C++ Library")]
+ [TestCase ("Static Library", "C/C++", TestName = "TestMiscCCPlusStaticLibrary", Description = "Create and build Static C/C++ Library")]
+ [TestCase ("Console Project", "C/C++", TestName = "TestMiscCCPlusConsoleProject", Description = "Create and build Console C/C++ Project")]
+ public void RunMiscCPlusPlusTemplatesTest (string templateName, string templateKind)
+ {
+ RunMiscTemplatesTest (templateName, templateKind);
+ }
+
+ [Test]
+ [TestCase ("Generic Project", "Generic", TestName = "TestMiscGenericProject", Description = "Create and build Generic Project")]
+ [TestCase ("Packaging project", "Generic", TestName = "TestMiscPackagingProject", Description = "Create and build Packaging Project")]
+
public void RunMiscTemplatesTest (string templateName, string templateKind)
{
var templateOptions = new TemplateSelectionOptions {
@@ -48,7 +55,8 @@ namespace UserInterfaceTests
TemplateKindRoot = templateKind,
TemplateKind = templateName
};
- CreateBuildProject (templateOptions, EmptyAction);
+ CreateBuildProject (templateOptions, () => Ide.WaitForIdeIdle ());
+ IsTemplateSelected (templateOptions);
}
}
}
diff --git a/main/tests/UserInterfaceTests/TestService.cs b/main/tests/UserInterfaceTests/TestService.cs
index ba24222dee..a66d0c374c 100644
--- a/main/tests/UserInterfaceTests/TestService.cs
+++ b/main/tests/UserInterfaceTests/TestService.cs
@@ -38,8 +38,6 @@ namespace UserInterfaceTests
{
Session = new AutoTestClientSession ();
- //TODO: support for testing the installed app
-
Session.StartApplication (file: monoDevelopBinPath, environment: new Dictionary<string,string> {
{ "MONODEVELOP_TEST_PROFILE", profilePath ?? Util.CreateTmpDir ("profile") }
});
diff --git a/main/tests/UserInterfaceTests/UITestBase.cs b/main/tests/UserInterfaceTests/UITestBase.cs
index f446223ff0..5ca0da478d 100644
--- a/main/tests/UserInterfaceTests/UITestBase.cs
+++ b/main/tests/UserInterfaceTests/UITestBase.cs
@@ -30,6 +30,9 @@ using MonoDevelop.Components.AutoTest;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
+using System.Linq;
+using MonoDevelop.Core.Logging;
+using MonoDevelop.Core;
namespace UserInterfaceTests
{
@@ -38,12 +41,13 @@ namespace UserInterfaceTests
{
string currentWorkingDirectory;
string testResultFolder;
- string memoryUsageFolder;
string currentTestResultFolder;
+ string currentTestResultScreenshotFolder;
- int testScreenshotIndex;
+ int testScreenshotIndex, reproStepIndex;
protected readonly List<string> FoldersToClean = new List<string> ();
+ protected FileLogger Logger;
public AutoTestClientSession Session {
get { return TestService.Session; }
@@ -55,7 +59,23 @@ namespace UserInterfaceTests
protected UITestBase (string mdBinPath)
{
- MonoDevelopBinPath = mdBinPath;
+ var installedXS = Environment.GetEnvironmentVariable ("USE_INSTALLED_XS");
+ if (!string.IsNullOrWhiteSpace(installedXS)) {
+ if (Platform.IsMac)
+ installedXS = Path.Combine(installedXS, "Contents/MacOS/XamarinStudio");
+ else if (Platform.IsWindows)
+ installedXS = Path.Combine(installedXS, @"bin\XamarinStudio.exe");
+ }
+
+ if (File.Exists (installedXS)) {
+ MonoDevelopBinPath = installedXS;
+ Console.WriteLine ("[UITEST] Using installed Xamarin Studio from this location: " + installedXS);
+ }
+ else {
+ Console.WriteLine ("[UITEST] Installed Xamarin Studio not found. Falling back to default behavior.");
+ MonoDevelopBinPath = mdBinPath;
+ }
+
currentWorkingDirectory = Directory.GetCurrentDirectory ();
}
@@ -63,58 +83,143 @@ namespace UserInterfaceTests
public virtual void FixtureSetup ()
{
testResultFolder = Path.Combine (currentWorkingDirectory, "TestResults");
- memoryUsageFolder = Path.Combine (testResultFolder, "MemoryUsage");
- if (!Directory.Exists (memoryUsageFolder))
- Directory.CreateDirectory (memoryUsageFolder);
}
[SetUp]
public virtual void SetUp ()
{
- SetupTestResultFolder (TestContext.CurrentContext.Test.FullName);
- var currentXSIdeLog = Path.Combine (currentTestResultFolder,string.Format ("{0}.Ide.log", TestContext.CurrentContext.Test.FullName) );
- Environment.SetEnvironmentVariable ("MONODEVELOP_LOG_FILE", currentXSIdeLog);
- Environment.SetEnvironmentVariable ("MONODEVELOP_FILE_LOG_LEVEL", "UpToInfo");
+ SetupTestResultFolder ();
+ SetupTestLogger ();
+ SetupScreenshotsFolder ();
+ SetupIdeLogFolder ();
var mdProfile = Util.CreateTmpDir ();
TestService.StartSession (MonoDevelopBinPath, mdProfile);
TestService.Session.DebugObject = new UITestDebug ();
FoldersToClean.Add (mdProfile);
+
+ Session.WaitForElement (IdeQuery.DefaultWorkbench);
+ TakeScreenShot ("Application-Started");
+ CloseIfXamarinUpdateOpen ();
+ TakeScreenShot ("Application-Ready");
}
[TearDown]
public virtual void Teardown ()
{
- File.WriteAllText (Path.Combine (memoryUsageFolder, TestContext.CurrentContext.Test.FullName),
- JsonConvert.SerializeObject (Session.MemoryStats, Formatting.Indented));
+ try {
+ bool isInconclusive = false;
+ var testStatus = TestContext.CurrentContext.Result.Status;
+ if (testStatus != TestStatus.Passed) {
+ try {
+ var updateOpened = Session.Query (IdeQuery.XamarinUpdate);
+ if (updateOpened != null && updateOpened.Any ())
+ isInconclusive = true;
+ TakeScreenShot (string.Format ("{0}-Test-Failed", TestContext.CurrentContext.Test.Name));
+ } catch (Exception e) {
+ Session.DebugObject.Debug ("Final Screenshot failed");
+ Session.DebugObject.Debug (e.ToString ());
+ }
+ }
+
+ File.WriteAllText (Path.Combine (currentTestResultFolder, "MemoryUsage.json"),
+ JsonConvert.SerializeObject (Session.MemoryStats, Formatting.Indented));
- Ide.CloseAll ();
- TestService.EndSession ();
+ Ide.CloseAll ();
+ TestService.EndSession ();
- OnCleanUp ();
- if (TestContext.CurrentContext.Result.Status == TestStatus.Passed) {
- if (Directory.Exists (currentTestResultFolder))
- Directory.Delete (currentTestResultFolder, true);
+ ValidateIdeLogMessages ();
+
+ OnCleanUp ();
+ if (testStatus == TestStatus.Passed) {
+ if (Directory.Exists (currentTestResultScreenshotFolder))
+ Directory.Delete (currentTestResultScreenshotFolder, true);
+ }
+
+ if (isInconclusive)
+ Assert.Inconclusive ("Xamarin Update is blocking the application focus");
+ } finally {
+ LoggingService.RemoveLogger (Logger.Name);
+ Logger.Dispose ();
}
}
- void SetupTestResultFolder (string testName)
+ static void ValidateIdeLogMessages ()
{
- testScreenshotIndex = 1;
- currentTestResultFolder = Path.Combine (testResultFolder, testName);
+ LogMessageValidator.Validate (Environment.GetEnvironmentVariable ("MONODEVELOP_LOG_FILE"));
+ }
+
+ protected void CloseIfXamarinUpdateOpen ()
+ {
+ try {
+ Session.WaitForElement (IdeQuery.XamarinUpdate, 10 * 1000);
+ TakeScreenShot ("Xamarin-Update-Opened");
+ Session.ClickElement (c => IdeQuery.XamarinUpdate (c).Children ().Button ().Text ("Close"));
+ }
+ catch (TimeoutException) {
+ TestService.Session.DebugObject.Debug ("Xamarin Update did not open");
+ }
+ }
+
+ void SetupTestResultFolder ()
+ {
+ currentTestResultFolder = Path.Combine (testResultFolder, TestContext.CurrentContext.Test.Name);
if (Directory.Exists (currentTestResultFolder))
Directory.Delete (currentTestResultFolder, true);
Directory.CreateDirectory (currentTestResultFolder);
}
- protected void TakeScreenShot (string stepName)
+ void SetupTestLogger ()
+ {
+ reproStepIndex = 0;
+ var currentTestLog = Path.Combine (currentTestResultFolder, string.Format ("{0}.Test.log.txt", TestContext.CurrentContext.Test.Name.ToPathSafeString ()));
+ Logger = new FileLogger (currentTestLog) {
+ Name = TestContext.CurrentContext.Test.Name,
+ EnabledLevel = EnabledLoggingLevel.All,
+ };
+ LoggingService.AddLogger (Logger);
+ }
+
+ void SetupScreenshotsFolder ()
{
- stepName = string.Format ("{0:D3}-{1}", testScreenshotIndex++, stepName);
- var screenshotPath = Path.Combine (currentTestResultFolder, stepName) + ".png";
+ testScreenshotIndex = 1;
+ currentTestResultScreenshotFolder = Path.Combine (currentTestResultFolder, "Screenshots");
+ if (Directory.Exists (currentTestResultScreenshotFolder))
+ Directory.Delete (currentTestResultScreenshotFolder, true);
+ Directory.CreateDirectory (currentTestResultScreenshotFolder);
+ }
+
+ void SetupIdeLogFolder ()
+ {
+ var currentXSIdeLog = Path.Combine (currentTestResultFolder, string.Format ("{0}.Ide.log", TestContext.CurrentContext.Test.Name.ToPathSafeString ()));
+ Environment.SetEnvironmentVariable ("MONODEVELOP_LOG_FILE", currentXSIdeLog);
+ Environment.SetEnvironmentVariable ("MONODEVELOP_FILE_LOG_LEVEL", "UpToInfo");
+ }
+
+ public void TakeScreenShot (string stepName)
+ {
+ stepName = string.Format ("{0:D3}-{1}", testScreenshotIndex++, stepName).ToPathSafeString ();
+ var screenshotPath = Path.Combine (currentTestResultScreenshotFolder, stepName) + ".png";
Session.TakeScreenshot (screenshotPath);
}
+ public void ReproStep (string stepDescription, params object[] info)
+ {
+ reproStepIndex++;
+ stepDescription = string.Format ("@Repro-Step-{0:D2}: {1}", reproStepIndex, stepDescription);
+ LoggingService.LogInfo (stepDescription);
+ foreach (var obj in info) {
+ if (obj != null)
+ LoggingService.LogInfo (string.Format("@Repro-Info-{0:D2}: {1}", reproStepIndex, obj.ToString ()));
+ }
+ }
+
+ public void ReproFailedStep (string expected, string actual, params object [] info)
+ {
+ ReproStep (string.Format ("Expected: {0}\nActual: {1}", expected, actual), info);
+ }
+
protected virtual void OnCleanUp ()
{
foreach (var folder in FoldersToClean) {
@@ -122,7 +227,9 @@ namespace UserInterfaceTests
if (folder != null && Directory.Exists (folder))
Directory.Delete (folder, true);
} catch (IOException e) {
- Console.WriteLine ("Cleanup failed\n" +e.ToString ());
+ TestService.Session.DebugObject.Debug ("Cleanup failed\n" +e);
+ } catch (UnauthorizedAccessException e) {
+ TestService.Session.DebugObject.Debug (string.Format ("Unable to clean directory: {0}\n", folder) + e);
}
}
}
@@ -133,6 +240,7 @@ namespace UserInterfaceTests
var dirObj = Session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.ProjectOperations.CurrentSelectedSolution.RootFolder.BaseDirectory");
return dirObj != null ? dirObj.ToString () : null;
} catch (Exception) {
+ TestService.Session.DebugObject.Debug ("GetSolutionDirectory () returns null");
return null;
}
}
diff --git a/main/tests/UserInterfaceTests/UserInterfaceTests.csproj b/main/tests/UserInterfaceTests/UserInterfaceTests.csproj
index 42facba4c7..63d7d1963f 100644
--- a/main/tests/UserInterfaceTests/UserInterfaceTests.csproj
+++ b/main/tests/UserInterfaceTests/UserInterfaceTests.csproj
@@ -8,7 +8,7 @@
<ProjectGuid>{07F55155-51A8-4072-9F80-FA473666F086}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>UserInterfaceTests</RootNamespace>
- <AssemblyName>UserInterfaceTests</AssemblyName>
+ <AssemblyName>MonoDevelop.UITests</AssemblyName>
<TestRunnerCommand>..\..\build\bin\mdtool.exe</TestRunnerCommand>
<TestRunnerArgs>run-md-tests</TestRunnerArgs>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
@@ -30,6 +30,20 @@
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMac|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\build\tests</OutputPath>
+ <DefineConstants>DEBUG,MAC</DefineConstants>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMac|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\build\tests</OutputPath>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -53,6 +67,7 @@
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+ <Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="UITestBase.cs" />
@@ -66,10 +81,8 @@
<Compile Include="TemplateTests\ASPNETTemplateTests.cs" />
<Compile Include="TemplateTests\DotNetTemplatesTest.cs" />
<Compile Include="TemplateTests\MiscTemplatesTest.cs" />
- <Compile Include="VersionControlTests\GitTests.cs" />
<Compile Include="VersionControlTests\VCSBase.cs" />
<Compile Include="VersionControlTests\SvnTests.cs" />
- <Compile Include="VersionControlTests\GitRepositoryConfigurationTests.cs" />
<Compile Include="DialogTests\NewProjectDialogTests.cs" />
<Compile Include="IdeQuery.cs" />
<Compile Include="Controllers\NewFileController.cs" />
@@ -77,6 +90,17 @@
<Compile Include="Controllers\SolutionExplorerController.cs" />
<Compile Include="Controllers\NuGetController.cs" />
<Compile Include="DialogTests\NuGetDialogTests.cs" />
+ <Compile Include="Exceptions\TemplateSelectionException.cs" />
+ <Compile Include="Exceptions\CreateProjectException.cs" />
+ <Compile Include="Workbench.cs" />
+ <Compile Include="VersionControlTests\Git\GitBase.cs" />
+ <Compile Include="VersionControlTests\Git\GitRepositoryConfigurationTests.cs" />
+ <Compile Include="VersionControlTests\Git\GitStashManagerTests.cs" />
+ <Compile Include="VersionControlTests\Git\GitTests.cs" />
+ <Compile Include="Controllers\NuGetOptions.cs" />
+ <Compile Include="Controllers\OptionsController.cs" />
+ <Compile Include="Exceptions\NuGetException.cs" />
+ <Compile Include="LogMessageValidator.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -107,10 +131,12 @@
<NuGet>$(SolutionDir)\external\nuget-binary\NuGet.exe</NuGet>
<NuGet Condition="$(OS)=='Unix'">mono $(NuGet)</NuGet>
</PropertyGroup>
- <Exec Command="$(NuGet) restore -SolutionDirectory $(SolutionDir)" />
+ <Exec Condition="Exists('$(SolutionDir)\..\.git')" Command="$(NuGet) restore -SolutionDirectory $(SolutionDir)" />
</Target>
<ItemGroup>
<Folder Include="DialogTests\" />
<Folder Include="Controllers\" />
+ <Folder Include="Exceptions\" />
+ <Folder Include="VersionControlTests\Git\" />
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/main/tests/UserInterfaceTests/Util.cs b/main/tests/UserInterfaceTests/Util.cs
index a983c16adb..8658e5f179 100644
--- a/main/tests/UserInterfaceTests/Util.cs
+++ b/main/tests/UserInterfaceTests/Util.cs
@@ -28,11 +28,29 @@ using System;
using System.IO;
using MonoDevelop.Core;
using System.Reflection;
+using System.Linq;
namespace UserInterfaceTests
{
public static class Util
{
+ public static void PrintData (this object data)
+ {
+ if (data != null)
+ TestService.Session.DebugObject.Debug (data.ToString ());
+ }
+
+ public static string ToPathSafeString (this string str, char replaceWith = '-')
+ {
+ var invalids = Path.GetInvalidFileNameChars ().Concat (Path.GetInvalidPathChars ()).Distinct ().ToArray ();
+ return new string (str.Select (c => invalids.Contains (c) ? replaceWith : c).ToArray ());
+ }
+
+ public static string ToBoldText (this string str)
+ {
+ return str != null ? string.Format ("<b>{0}</b>", str) : null;
+ }
+
public static FilePath CreateTmpDir (string hint = null)
{
var cwd = new FileInfo (Assembly.GetExecutingAssembly ().Location).DirectoryName;
@@ -57,5 +75,15 @@ namespace UserInterfaceTests
return Ide.EmptyAction;
}
}
+
+ public static Action<string> GetNonNullAction (Action<string> action)
+ {
+ return action ?? delegate { };
+ }
+
+ public static string StripBold (this string value)
+ {
+ return value != null ? value.Replace ("<b>", string.Empty).Replace ("</b>", string.Empty) : null;
+ }
}
}
diff --git a/main/tests/UserInterfaceTests/VersionControlTests/Git/GitBase.cs b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitBase.cs
new file mode 100644
index 0000000000..293015c5f9
--- /dev/null
+++ b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitBase.cs
@@ -0,0 +1,478 @@
+//
+// GitBase.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Components.AutoTest;
+using NUnit.Framework;
+
+namespace UserInterfaceTests
+{
+ public abstract class GitBase : VCSBase
+ {
+ static string notString = "not";
+
+ #region Git Repository Configuration
+
+ #region Remotes
+
+ Func<AppQuery, AppQuery> remoteTreeName = c => c.TreeView ().Marked ("treeRemotes").Model ("storeRemotes__Name");
+ Func<AppQuery, AppQuery> remoteTreeUrl = c => c.TreeView ().Marked ("treeRemotes").Model ("storeRemotes__Url");
+ Func<AppQuery, AppQuery> remoteTreeFullName = c => c.TreeView ().Marked ("treeRemotes").Model ("storeRemotes__FullName");
+
+ protected void AssertRemotesButtonSensitivity (bool editSensitivity, bool removeSensitivity, bool trackSensitivity, bool fetchSensitivity)
+ {
+ AssertButtonSensitivity ("Add", true);
+ AssertButtonSensitivity ("Edit", editSensitivity);
+ AssertButtonSensitivity ("Remove", removeSensitivity);
+ AssertButtonSensitivity ("Track in Local Branch", trackSensitivity);
+ AssertButtonSensitivity ("Fetch", fetchSensitivity);
+ }
+
+ protected void SelectRemote (string remoteName, string remoteUrl = null)
+ {
+ ReproStep (string.Format ("Select a remote named '{0}' {1}", remoteName,
+ remoteUrl != null ? string.Format (" and Remote URL '{0}'", remoteUrl) : string.Empty));
+ Session.WaitForElement (c => remoteTreeName (c).Contains (remoteName));
+
+ try {
+ Assert.IsTrue (Session.SelectElement (c => remoteTreeName (c).Contains (remoteName)));
+ } catch (AssertionException) {
+ ReproFailedStep (string.Format ("Remote Name '{0}' exists", remoteName), string.Format ("Remote Name '{0}' does not exists", remoteName));
+ throw;
+ }
+ if (remoteUrl != null) {
+ try {
+ Assert.IsTrue (Session.SelectElement (c => remoteTreeUrl (c).Contains (remoteUrl)));
+ } catch (AssertionException) {
+ ReproFailedStep (string.Format ("Remote URL '{0}' with Name '{1}' exists", remoteUrl, remoteName),
+ string.Format ("Remote URL '{0}' with Name '{1}' does not exist", remoteUrl, remoteName));
+ throw;
+ }
+ }
+ TakeScreenShot (string.Format ("{0}-Remote-Selected", remoteName));
+ }
+
+ protected void EditRemote (string newRemoteName, string remoteUrl, string remotePushUrl = null)
+ {
+ ReproStep ("Click on Edit");
+ AddEditRemote ("buttonEditRemote", newRemoteName, remoteUrl, remotePushUrl);
+ }
+
+ protected void AddRemote (string newRemoteName, string remoteUrl, string remotePushUrl = null)
+ {
+ ReproStep ("Click on Add");
+ AddEditRemote ("buttonAddRemote", newRemoteName, remoteUrl, remotePushUrl);
+ }
+
+ protected void FetchRemoteBranch (string remoteName)
+ {
+ SelectRemote (remoteName);
+
+ Assert.IsEmpty (Session.Query (c => remoteTreeFullName (c).Contains (remoteName+"/")));
+ Assert.IsTrue (Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Text ("Fetch")));
+ TakeScreenShot ("Fetch-Remote");
+
+ SelectRemoteBranch (remoteName);
+ }
+
+ protected void SelectRemoteBranch (string remoteName, string remoteBranchName = null)
+ {
+ Session.ClickElement (c => remoteTreeName (c).Contains (remoteName));
+ Assert.IsNotEmpty (Session.Query (c => remoteTreeFullName (c).Contains (remoteName+"/"+remoteBranchName)));
+
+ var expected = string.Format ("Select the Remote with Name '{0}' and Remote Branch Name '{1}'", remoteName, remoteBranchName);
+ try {
+ ReproStep (expected);
+ Assert.IsTrue (Session.SelectElement (c => remoteTreeFullName (c).Contains (remoteName + "/" + remoteBranchName).Index (0)));
+ } catch (AssertionException) {
+ ReproFailedStep (expected, "Could not "+expected);
+ throw;
+ }
+ TakeScreenShot (string.Format ("{0}-Remote-Branch-Selected", remoteBranchName ?? "First"));
+ }
+
+ void AddEditRemote (string buttonName, string newRemoteName, string remoteUrl, string remotePushUrl)
+ {
+ Assert.IsNotEmpty (Session.Query (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked (buttonName)));
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked (buttonName), false);
+ Session.WaitForElement (IdeQuery.EditRemoteDialog);
+
+ ReproStep (string.Format ("Enter Remote name as '{0}'", newRemoteName));
+ Func<AppQuery, AppQuery> EditRemoteDialogChildren = c => IdeQuery.EditRemoteDialog (c).Children ();
+ Assert.IsTrue (Session.EnterText (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryName"), newRemoteName));
+ Session.WaitForElement (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryName").Text (newRemoteName));
+
+ ReproStep (string.Format ("Enter Remote URL as '{0}'", remoteUrl));
+ Assert.IsTrue (Session.EnterText (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryUrl"), remoteUrl));
+ Session.WaitForElement (c => EditRemoteDialogChildren (c).Marked ("entryUrl").Text (remoteUrl));
+
+ ReproStep (string.Format ("Enter Remote Push URL as '{0}'", remotePushUrl ?? remoteUrl));
+ Assert.IsTrue (Session.EnterText (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryPushUrl"), remotePushUrl ?? remoteUrl));
+ Session.WaitForElement (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryPushUrl").Text (remotePushUrl ?? remoteUrl));
+ TakeScreenShot ("Remote-Details-Filled");
+
+ ReproStep ("Click on OK");
+ Assert.IsTrue (Session.ClickElement (c => EditRemoteDialogChildren (c).Button ().Marked ("buttonOk")));
+ Session.WaitForNoElement (IdeQuery.EditRemoteDialog);
+ Session.WaitForElement (IdeQuery.GitConfigurationDialog);
+ TakeScreenShot ("Remote-Edit-Dialog-Closed");
+ }
+
+ protected void DeleteRemote (string remoteName)
+ {
+ Session.WaitForElement (c => remoteTreeName (c).Contains (remoteName));
+ ReproStep ("Click on Remove");
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Text ("Remove"), false);
+ TakeScreenShot (string.Format ("Remove-Remote-{0}", remoteName));
+
+ ReproStep ("When prompted to confirm, click Delete");
+ Ide.ClickButtonAlertDialog ("Delete");
+ Session.WaitForElement (IdeQuery.GitConfigurationDialog);
+ }
+
+ #endregion
+
+ #region Tags
+
+ Func<AppQuery, AppQuery> tagTreeName = c => c.TreeView ().Marked ("listTags").Model ("storeTags__Name");
+
+ protected void AssertTagsButtonSensitivity (bool pushSensitivity, bool deleteSensitivity)
+ {
+ AssertButtonSensitivity ("New", true);
+ AssertButtonSensitivity ("Push", pushSensitivity);
+ AssertButtonSensitivity ("Delete", deleteSensitivity);
+ }
+
+ protected void SelectTag (string tagName)
+ {
+ WaitForElement (c => tagTreeName (c).Text (tagName),
+ string.Format ("Tag '{0}' should be available", tagName),
+ string.Format ("Tag '{0}' it not available", tagName));
+ try {
+ Assert.IsTrue (Session.SelectElement (c => tagTreeName (c).Text (tagName)), "Failed to select tag: " + tagName);
+ } catch (AssertionException) {
+ ReproFailedStep (string.Format ("Tag '{0}' should be selected", tagName),
+ string.Format ("Tag '{0}' cannot be selected", tagName));
+ throw;
+ }
+ TakeScreenShot (string.Format ("{0}-Tag-Selected", tagName));
+ }
+
+ protected void DeleteTag (string tagName)
+ {
+ SelectTag (tagName);
+ ReproStep ("Click Delete");
+ try {
+ Assert.IsTrue ((Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked ("buttonRemoveTag"))));
+ } catch (AssertionException) {
+ ReproFailedStep (string.Format ("Tag '{0}' should be removed", tagName), string.Format ("Tag '{0}' could not be removed", tagName));
+ throw;
+ }
+ Session.WaitForNoElement (c => tagTreeName (c).Text (tagName));
+ }
+
+ protected void AddNewTag (string tagName, string tagMessage = null, string commitMsg = null)
+ {
+ ReproStep ("Click on New");
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked ("buttonAddTag"), false);
+
+ ReproStep ("Wait for 'Select a Revision' dialog to open");
+ try {
+ Session.WaitForElement (c => c.Window ().Marked ("Select a revision"));
+ } catch (AssertionException) {
+ ReproFailedStep ("'Select a Revision' dialog should open", "'Select a Revision' dialog did not open");
+ throw;
+ }
+
+ ReproStep ("Enter the Tag Name");
+ Session.EnterText (c => c.Window ().Marked ("Select a revision").Children ().Textfield ().Index (0), tagName);
+ Session.WaitForElement (c => c.Window ().Marked ("Select a revision").Children ().Textfield ().Index (0).Text (tagName));
+ TakeScreenShot ("Tag-Name-Entered");
+
+ if (!string.IsNullOrEmpty (tagMessage)) {
+ ReproStep ("Enter a Tag Message");
+ Session.EnterText (c => c.Window ().Marked ("Select a revision").Children ().Textfield ().Index (1), tagMessage);
+ Session.WaitForElement (c => c.Window ().Marked ("Select a revision").Children ().Textfield ().Index (1).Text (tagMessage));
+ TakeScreenShot ("Tag-Message-Entered");
+ }
+
+ Func<AppQuery, AppQuery> revisionsTreeView = c => c.Window ().Marked ("Select a revision").Children ().TreeView ().Index (0).Model ().Children ();
+ if (!string.IsNullOrEmpty (commitMsg)) {
+ ReproStep (string.Format ("Select the commit with message '{0}'", commitMsg));
+ Session.SelectElement (c => revisionsTreeView (c).Text (commitMsg));
+ } else {
+ ReproStep ("Select the first commit");
+ Session.SelectElement (c => revisionsTreeView (c).Index (0));
+ }
+ TakeScreenShot ("Commit-Message-Selected");
+
+ ReproStep ("Click OK");
+ Session.ClickElement (c => c.Window ().Marked ("Select a revision").Children ().Button ().Text ("Ok"));
+ try {
+ Session.WaitForElement (IdeQuery.GitConfigurationDialog);
+ TakeScreenShot ("Git-User-Not-Configured");
+ EnterGitUserConfig ("John Doe", "john.doe@example.com");
+ } catch (TimeoutException e) { }
+ Session.WaitForElement (c => IdeQuery.GitConfigurationDialog (c));
+ TakeScreenShot ("Ok-Clicked");
+ }
+
+ #endregion
+
+ #region Branches
+
+ Func<AppQuery, AppQuery> branchDisplayName = c => c.TreeView ().Marked ("listBranches").Model ("storeBranches__DisplayName");
+
+ protected void AssertBranchesButtonSensitivity (bool editSensitivity, bool deleteSensitivity, bool switchSensitivity)
+ {
+ AssertButtonSensitivity ("New", true);
+ AssertButtonSensitivity ("Edit", editSensitivity);
+ AssertButtonSensitivity ("Delete", deleteSensitivity);
+ AssertButtonSensitivity ("Switch to Branch", switchSensitivity);
+ }
+
+ protected void CreateNewBranch (string newBranchName)
+ {
+ ReproStep ("Click New");
+ CreateEditBranch ("buttonAddBranch", newBranchName);
+ }
+
+ protected void EditBranch (string oldBranchName, string newBranchName)
+ {
+ SelectBranch (oldBranchName);
+ ReproStep ("Click Edit");
+ CreateEditBranch ("buttonEditBranch", newBranchName);
+ }
+
+ protected void CreateEditBranch (string buttonName, string newBranchName)
+ {
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Marked (buttonName), false);
+
+ ReproStep ("Wait for Branch Properties dialog");
+ WaitForElement (IdeQuery.EditBranchDialog, "Branch Properties dialog opens", "Branch Properties dialog does not open");
+ TakeScreenShot ("Edit-Branch-Dialog-Opened");
+
+ EnterBranchName (newBranchName);
+ Session.WaitForElement (IdeQuery.GitConfigurationDialog);
+ TakeScreenShot ("Edit-Branch-Dialog-Opened-Closed");
+ }
+
+ protected void EnterBranchName (string newBranchName)
+ {
+ ReproStep ("Enter branch name");
+ Session.EnterText (c => IdeQuery.EditBranchDialog (c).Children ().Textfield ().Marked ("entryName"), newBranchName);
+ Session.WaitForElement (c => IdeQuery.EditBranchDialog (c).Children ().Textfield ().Marked ("entryName").Text (newBranchName));
+ TakeScreenShot ("Branch-Name-Entered");
+
+ ReproStep ("Click OK");
+ Assert.IsTrue (Session.ClickElement (c => IdeQuery.EditBranchDialog (c).Children ().Button ().Marked ("buttonOk")));
+ }
+
+ protected void SwitchToBranch (string branchName)
+ {
+ SelectBranch (branchName);
+ TakeScreenShot (string.Format ("{0}-Branch-Selected", branchName));
+
+ ReproStep ("Click on 'Switch to Branch'");
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Text ("Switch to Branch"), false);
+ CheckIfNameEmailNeeded ();
+ CheckIfUserConflict ();
+ ReproStep ("Check if the selected branch is bold");
+ try {
+ Assert.IsTrue (IsBranchSwitched (branchName));
+ } catch (AssertionException) {
+ ReproFailedStep ("The selected branch should be bold", "The selected branch is not bold");
+ throw;
+ }
+ TakeScreenShot (string.Format ("Switched-To-{0}", branchName));
+ }
+
+ protected void SwitchTab (string tabName)
+ {
+ ReproStep (string.Format ("Select the '{0}' tab", tabName));
+ try {
+ Assert.IsTrue (Session.SelectElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Notebook ().Marked ("notebook1").Text (tabName)));
+ } catch (AssertionException) {
+ ReproFailedStep (string.Format ("Tab '{0}' is selected", tabName), string.Format ("Tab '{0}' is not selected", tabName));
+ throw;
+ }
+ TakeScreenShot (string.Format ("Tab-Changed-{0}", GenerateProjectName (tabName)));
+ }
+
+ protected void SelectBranch (string branchName)
+ {
+ ReproStep (string.Format ("Select the '{0}' branch", branchName));
+ try {
+ Assert.IsTrue (Session.SelectElement (c => branchDisplayName (c).Contains (branchName)));
+ } catch (AssertionException) {
+ ReproFailedStep (string.Format ("Branch '{0}' is selected", branchName), string.Format ("Branch '{0}' is not selected", branchName));
+ throw;
+ }
+ TakeScreenShot (string.Format ("Selected-Branch-{0}", branchName.ToPathSafeString ()));
+ }
+
+ protected void DeleteBranch (string branchName)
+ {
+ SelectBranch (branchName);
+ ReproStep ("Press Delete");
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Text ("Delete"), false);
+ TakeScreenShot (string.Format ("Delete-Branch-{0}", branchName));
+ ReproStep ("If prompted for confirmation, press Delete");
+ Ide.ClickButtonAlertDialog ("Delete");
+ Session.WaitForElement (IdeQuery.GitConfigurationDialog);
+ }
+
+ protected bool IsBranchSwitched (string branchName)
+ {
+ try {
+ WaitForElement (c => branchDisplayName (c).Text ("<b>" + branchName + "</b>"),
+ string.Format ("Branch '{0}' is checked out", branchName),
+ string.Format ("Branch '{0}' is not checked out", branchName));
+ return true;
+ } catch (TimeoutException) {
+ return false;
+ }
+ }
+
+ #endregion
+
+ protected void OpenRepositoryConfiguration (string selectTab = null)
+ {
+ ReproStep ("Click Version Control > Manage Branches and Remotes");
+ Session.ExecuteCommand (MonoDevelop.VersionControl.Git.Commands.ManageBranches);
+
+ WaitForElement (IdeQuery.GitConfigurationDialog,
+ "Git Repository Configuration Dialog should open",
+ "Git Repository Configuration Dialog did not open");
+ TakeScreenShot ("Repository-Configuration-Opened");
+
+ if (selectTab != null)
+ SwitchTab (selectTab);
+ }
+
+ protected void CloseRepositoryConfiguration ()
+ {
+ ReproStep ("Click on Close button of Git Repository Configuration Dialog");
+ Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Marked ("buttonOk"));
+ TakeScreenShot ("Git-Repository-Configuration-Closed");
+ Session.WaitForNoElement (IdeQuery.GitConfigurationDialog);
+ }
+
+ protected void AssertButtonSensitivity (string buttonLabel, bool sensitivity)
+ {
+ var expected = string.Format ("{0} button is {1} enabled", buttonLabel, !sensitivity ? notString : string.Empty);
+ var actual = string.Format ("{0} button is {1} enabled", buttonLabel, sensitivity ? notString : string.Empty);
+ try {
+ Assert.IsNotEmpty (Session.Query (c => c.Button ().Text (buttonLabel).Sensitivity (sensitivity)), actual);
+ } catch (AssertionException) {
+ ReproFailedStep (expected, actual);
+ throw;
+ }
+ }
+
+ #endregion
+
+ #region Stash Manager
+
+ protected Func<AppQuery, AppQuery> StashEntries = c => c.Window ().Marked (
+ "Stash Manager").Children ().TreeView ().Marked ("list").Model ().Children ();
+
+ protected void OpenStashManager ()
+ {
+ ReproStep ("Click on Version Control > Manage Stashes");
+ Session.ExecuteCommand ("MonoDevelop.VersionControl.Git.Commands.ManageStashes");
+ WaitForElement (c => c.Window ().Marked ("Stash Manager"), "Stash Manager dialog should open", "Stash Manager dialog did not open");
+ TakeScreenShot ("StashManager-Opened");
+ }
+
+ protected void CloseStashManager ()
+ {
+ ReproStep ("On Stash Manager, click Close button");
+ Session.ClickElement (c => c.Window ().Marked ("Stash Manager").Children ().Text ("Close"));
+ Session.WaitForElement (IdeQuery.TextArea);
+ TakeScreenShot ("StashManager-Closed");
+ }
+
+ protected void SelectStashEntry (int index = 0)
+ {
+ ReproStep ("Select the stash entry #{0}", index+1);
+ WaitForElement (c => StashEntries (c).Index (index), "Select stash entry: "+index+1, "Could not select that stash entry");
+ Session.SelectElement (c => StashEntries (c).Index (index));
+ }
+
+ protected void RemoveStash (int index)
+ {
+ SelectStashEntry (index);
+ TakeScreenShot ("About-To-Click-Remove");
+ try {
+ ReproStep ("Click on Remove");
+ Assert.IsTrue (Session.ClickElement (c => c.Window ().Marked ("Stash Manager").Children ().Button ().Text ("Remove")));
+ } catch (AssertionException) {
+ ReproFailedStep ("Stash should be removed", "Stash failed to remove");
+ throw;
+ }
+ Session.WaitForElement (c => c.Window ().Marked ("Stash Manager"));
+ }
+
+ protected void ApplyAndRemoveStash (int index)
+ {
+ SelectStashEntry (index);
+ TakeScreenShot ("About-To-Click-Apply-and-Remove");
+ try {
+ ReproStep ("Click on 'Apply and Remove'");
+ Assert.IsTrue (Session.ClickElement (c => c.Window ().Marked ("Stash Manager").Children ().Button ().Text ("Apply and Remove")));
+ } catch (AssertionException) {
+ ReproFailedStep ("Stash should be applied and removed from the list", "Stash failed to applied and removed from the list");
+ throw;
+ }
+ }
+
+ protected void ApplyStash (int index)
+ {
+ SelectStashEntry (index);
+ TakeScreenShot ("About-To-Click-Apply");
+ try {
+ ReproStep ("Click on Apply");
+ Assert.IsTrue (Session.ClickElement (c => c.Window ().Marked ("Stash Manager").Children ().Button ().Text ("Apply")));
+ } catch (AssertionException) {
+ ReproFailedStep ("Stash should be applied", "Stash failed to apply");
+ throw;
+ }
+ }
+
+ protected void ComvertToBranch (int index, string branchName)
+ {
+ SelectStashEntry (index);
+ TakeScreenShot ("About-To-Click-Convert-To-Branch");
+ ReproStep ("Click on 'Convert to Branch'");
+ Session.ClickElement (c => c.Window ().Marked ("Stash Manager").Children ().Button ().Text ("Convert to Branch"), false);
+ EnterBranchName (branchName);
+ Ide.WaitForStatusMessage (new [] { "Stash successfully applied" });
+ }
+
+ #endregion
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/VersionControlTests/Git/GitRepositoryConfigurationTests.cs b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitRepositoryConfigurationTests.cs
new file mode 100644
index 0000000000..1c5c9eb52a
--- /dev/null
+++ b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitRepositoryConfigurationTests.cs
@@ -0,0 +1,356 @@
+//
+// GitRepositoryConfigurationTests.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using NUnit.Framework;
+
+namespace UserInterfaceTests
+{
+ [TestFixture, Timeout(90000)]
+ [Category ("GitConfig")]
+ public class GitRepositoryConfigurationTests : GitBase
+ {
+ const string gtkSharpUrl = "https://github.com/mono/gtk-sharp.git";
+ const string monoHotdrawUrl = "https://github.com/mono/monocov.git";
+
+ #region Branch Tab
+
+ [Test]
+ [Description ("Check that Edit, Switch, Switch to Branch are enabled only when a branch is selected")]
+ public void CheckBranchButtonsSensitivity ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Branches");
+
+ TakeScreenShot ("Asserting-Edit-Delete-Switch-Button-Disabled");
+ AssertBranchesButtonSensitivity (false, false, false);
+ SelectBranch ("<b>master</b>");
+ TakeScreenShot ("Asserting-Edit-Switch-Button-Enabled");
+ AssertBranchesButtonSensitivity (true, false, false);
+ CreateNewBranch ("new-branch");
+ SelectBranch ("new-branch");
+ TakeScreenShot ("Asserting-Edit-Delete-Switch-Button-Enabled");
+ AssertBranchesButtonSensitivity (true, true, true);
+
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Create a New Branch")]
+ public void CreateNewBranchTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ();
+ CreateNewBranch ("new-branch");
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Create a New Branch and switch to it")]
+ public void GitSwitchBranchTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ();
+ CreateNewBranch ("new-branch");
+ SwitchToBranch ("new-branch");
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Create a New Branch, select it and edit the name and switch to it")]
+ public void GitEditBranchTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ();
+ CreateNewBranch ("new-branch");
+ SelectBranch ("new-branch");
+ EditBranch ("new-branch", "new-new-branch");
+ SwitchToBranch ("new-new-branch");
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Create a new branch, select it and delete it")]
+ public void GitDeleteBranchTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ();
+ CreateNewBranch ("new-branch");
+ SelectBranch ("new-branch");
+ DeleteBranch ("new-branch");
+
+ CloseRepositoryConfiguration ();
+ }
+
+ #endregion
+
+ #region Tag
+
+ [Test]
+ [Description ("Check that Push and Delete button are enabled only when a tag is selected")]
+ public void CheckTagButtonsSensitivity ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Tags");
+
+ TakeScreenShot ("Asserting-Push-Delete-Button-Disabled");
+ AssertTagsButtonSensitivity (false, false);
+ SelectTag ("1.0.10");
+ TakeScreenShot ("Asserting-Push-Delete-Button-Enabled");
+ AssertTagsButtonSensitivity (true, true);
+
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Create a new tag with tag name, tag message and by selecting a specific commit message")]
+ public void AddTag ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Tags");
+
+ AddNewTag ("bumped", "bumped tag", "build: Bump mono dependency to 3.2.8");
+ SelectTag ("bumped");
+ TakeScreenShot ("New-Tag-Selected");
+
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Clone a repo, open Tag tab, select a tag by name and delete it")]
+ public void DeleteTag ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Tags");
+ DeleteTag ("1.0.10");
+ CloseRepositoryConfiguration ();
+ }
+
+ #endregion
+
+ #region Remotes Tab
+
+ [Test]
+ [Description ("Check that Edit, Remove, Fetch button are enabled only when a remote is selected and 'Track in Local' only when a remote branch is selected")]
+ public void CheckRemoteButtonsSensitivity ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Remote Sources");
+
+ TakeScreenShot ("Asserting-Edit-Remove-Track--Fetch-Button-Disabled");
+ AssertRemotesButtonSensitivity (false, false, false, false);
+ SelectRemote ("origin");
+ TakeScreenShot ("Asserting-Edit-Switch-Button-Enabled");
+ AssertRemotesButtonSensitivity (true, true, false, true);
+ SelectRemoteBranch ("origin", "master");
+ TakeScreenShot ("Asserting-Edit-Switch-Button-Track-Enabled");
+ AssertRemotesButtonSensitivity (true, true, true, true);
+
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Clone a repo and select a remote")]
+ public void SelectRemoteTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Remote Sources");
+ SelectRemote ("origin");
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Clone a repo, add a new remote and select that added remote")]
+ public void AddGitRemoteTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ OpenRepositoryConfiguration ("Remote Sources");
+ AddRemote (newRemoteName, newRemoteUrl);
+ SelectRemote (newRemoteName, newRemoteUrl);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Clone a repo, add a new remote, select it and delete it")]
+ public void DeleteGitRemoteTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ OpenRepositoryConfiguration ("Remote Sources");
+ AddRemote (newRemoteName, newRemoteUrl);
+ SelectRemote (newRemoteName, newRemoteUrl);
+ DeleteRemote (newRemoteName);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Edit only Remote Name, don't edit URL or Push URL")]
+ public void EditGitRemoteNameTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Remote Sources");
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ AddRemote (newRemoteName, newRemoteUrl);
+ SelectRemote (newRemoteName, newRemoteUrl);
+
+ const string updatedRemoteName = "second-origin";
+ const string updatedRemoteUrl = monoHotdrawUrl;
+ EditRemote (updatedRemoteName, updatedRemoteUrl, updatedRemoteUrl);
+ SelectRemote (updatedRemoteName, updatedRemoteUrl);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Edit only Remote Name and URL, don't edit Push URL")]
+ public void EditGitRemoteNameAndUrlTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Remote Sources");
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ AddRemote (newRemoteName, newRemoteUrl);
+ SelectRemote (newRemoteName, newRemoteUrl);
+
+ const string updatedRemoteName = "second-origin";
+ const string updatedRemoteUrl = monoHotdrawUrl;
+ EditRemote (updatedRemoteName, updatedRemoteUrl, newRemoteUrl);
+ SelectRemote (updatedRemoteName, updatedRemoteUrl);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Edit only Remote Name and Push URL, don't edit URL")]
+ public void EditGitRemoteNameAndPushUrlTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Remote Sources");
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ AddRemote (newRemoteName, newRemoteUrl);
+ SelectRemote (newRemoteName, newRemoteUrl);
+
+ const string updatedRemoteName = "second-origin";
+ const string updatedRemoteUrl = monoHotdrawUrl;
+ EditRemote (updatedRemoteName, updatedRemoteUrl, monoHotdrawUrl);
+ SelectRemote (updatedRemoteName, updatedRemoteUrl);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Edit only Remote URL and Push URL, don't edit Name")]
+ public void EditGitRemoteUrlTest ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ OpenRepositoryConfiguration ("Remote Sources");
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ AddRemote (newRemoteName, newRemoteUrl);
+ SelectRemote (newRemoteName, newRemoteUrl);
+
+ const string updatedRemoteUrl = monoHotdrawUrl;
+ EditRemote (newRemoteName, updatedRemoteUrl, updatedRemoteUrl);
+ SelectRemote (newRemoteName, updatedRemoteUrl);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Clone a repo, add a new remote and fetch the remote branches for that remote")]
+ public void FetchRemoteBranches ()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ OpenRepositoryConfiguration ("Remote Sources");
+ AddRemote (newRemoteName, newRemoteUrl);
+ FetchRemoteBranch (newRemoteName);
+ CloseRepositoryConfiguration ();
+ }
+
+ [Test]
+ [Description ("Clone a repo, add a new remote, fetch the remote branch, chose a branch and track it in local. Select that branch in Branches tab")]
+ public void TrackRemoteBranchInLocalTest()
+ {
+ TestClone (gtkSharpUrl);
+ Ide.WaitForSolutionCheckedOut ();
+
+ const string newRemoteName = "second";
+ const string newRemoteUrl = monoHotdrawUrl;
+ OpenRepositoryConfiguration ("Remote Sources");
+ AddRemote (newRemoteName, newRemoteUrl);
+ FetchRemoteBranch (newRemoteName);
+ const string localBranch = "local-branch-random-uitest";
+ CreateEditBranch ("buttonTrackRemote", localBranch);
+ SwitchTab ("Branches");
+ SelectBranch (localBranch);
+ CloseRepositoryConfiguration ();
+ }
+
+ #endregion
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/VersionControlTests/Git/GitStashManagerTests.cs b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitStashManagerTests.cs
new file mode 100644
index 0000000000..71736ae25e
--- /dev/null
+++ b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitStashManagerTests.cs
@@ -0,0 +1,119 @@
+//
+// GitStashManagerTests.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using NUnit.Framework;
+using System;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Components.AutoTest;
+
+namespace UserInterfaceTests
+{
+ [TestFixture, Timeout(60000)]
+ [Category ("Git")]
+ [Category ("StashManager")]
+ public class GitStashManagerTests : GitBase
+ {
+ [Test]
+ [Description ("Create a project with git, commit changes. Make changes and stash. Remove stash from Stash Manager")]
+ public void GitRemoveStashTest ()
+ {
+ CreateProjectAndCommitAndStash ();
+
+ OpenStashManager ();
+ RemoveStash (0);
+ Assert.IsEmpty (Session.Query (StashEntries));
+ CloseStashManager ();
+ }
+
+ [Test]
+ [Description ("Create a project with git, commit changes. Make changes and stash. Apply and Remove stash from Stash Manager")]
+ public void GitApplyAndRemoveStashTest ()
+ {
+ CreateProjectAndCommitAndStash ();
+
+ OpenStashManager ();
+ ApplyAndRemoveStash (0);
+
+ Session.WaitForElement (IdeQuery.TextArea);
+ TakeScreenShot ("Stash-Applied");
+ OpenStashManager ();
+
+ TakeScreenShot ("Asserting-if-Not-Stash-Present");
+ Session.WaitForNoElement (StashEntries);
+ CloseStashManager ();
+ }
+
+ [Test]
+ [Description ("Create a project with git, commit changes. Make changes and stash. Apply stash from Stash Manager")]
+ public void GitApplyStashTest ()
+ {
+ CreateProjectAndCommitAndStash ();
+
+ OpenStashManager ();
+ ApplyStash (0);
+ OpenStashManager ();
+
+ TakeScreenShot ("Asserting-if-Stash-Still-Present");
+ Assert.IsNotEmpty (Session.Query (StashEntries));
+ CloseStashManager ();
+ }
+
+ [Test]
+ [Description ("Create a project with git, commit changes. Make changes and stash. Convert stash to branch from Stash Manager")]
+ public void GitStashConvertToBranchTest ()
+ {
+ CreateProjectAndCommitAndStash ();
+
+ var branchName = "sample-branch";
+ OpenStashManager ();
+ ComvertToBranch (0, branchName);
+ OpenStashManager ();
+ TakeScreenShot ("Asserting-if-Stash-Still-Present");
+ Assert.IsEmpty (Session.Query (StashEntries));
+ CloseStashManager ();
+
+ OpenRepositoryConfiguration ("Branches");
+ IsBranchSwitched (branchName);
+ CloseRepositoryConfiguration ();
+ }
+
+ void CreateProjectAndCommitAndStash ()
+ {
+ var templateOptions = new TemplateSelectionOptions {
+ CategoryRoot = OtherCategoryRoot,
+ Category = ".NET",
+ TemplateKindRoot = GeneralKindRoot,
+ TemplateKind = "Console Project"
+ };
+ GitCreateAndCommit (templateOptions, "First commit");
+ var changeDescription = MakeSomeChangesAndSaveAll ("Program.cs");
+ TestGitStash (changeDescription);
+ Session.WaitForElement (IdeQuery.TextArea, 20000);
+ TakeScreenShot ("After-Stash");
+ }
+ }
+}
+
diff --git a/main/tests/UserInterfaceTests/VersionControlTests/GitTests.cs b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitTests.cs
index 471b8a94ff..2bf26bcb52 100644
--- a/main/tests/UserInterfaceTests/VersionControlTests/GitTests.cs
+++ b/main/tests/UserInterfaceTests/VersionControlTests/Git/GitTests.cs
@@ -30,20 +30,22 @@ using NUnit.Framework;
namespace UserInterfaceTests
{
- [TestFixture]
+ [TestFixture, Timeout(60000)]
[Category ("Git")]
+ [Category ("GitBase")]
public class GitTests : VCSBase
{
- [Test]
- [TestCase ("git@github.com:mono/jurassic.git", TestName = "TestGitSSHClone")]
- [TestCase ("https://github.com/mono/jurassic.git", TestName = "TestGitHTTPSClone")]
+ [Test, Timeout(120000), Category("Smoke")]
+ [TestCase ("git@github.com:mono/gtk-sharp.git", TestName = "TestGitSSHClone", Description = "Clone Git repo over SSH")]
+ [TestCase ("https://github.com/mono/gtk-sharp.git", TestName = "TestGitHTTPSClone", Description = "Clone Git repo over HTTPS")]
public void TestGitClone (string url)
{
TestClone (url);
- Ide.WaitForSolutionCheckedOut ();
+ Ide.WaitForIdeIdle ();
}
- [Test]
+ [Test, Category("Smoke")]
+ [Description ("Create a new project with Git and commit the changes")]
public void TestCommit ()
{
var templateOptions = new TemplateSelectionOptions {
@@ -52,15 +54,11 @@ namespace UserInterfaceTests
TemplateKindRoot = GeneralKindRoot,
TemplateKind = "Console Project"
};
- CreateProject (templateOptions,
- new ProjectDetails (templateOptions),
- new GitOptions { UseGit = true, UseGitIgnore = true});
-
- Session.WaitForElement (IdeQuery.TextArea);
- TestCommit ("First commit");
+ GitCreateAndCommit (templateOptions, "First commit");
}
[Test]
+ [Description ("Create a new project and try to stash without any changes, it should not be allowed")]
public void TestNoChangesStashOperation ()
{
var templateOptions = new TemplateSelectionOptions {
@@ -81,6 +79,7 @@ namespace UserInterfaceTests
}
[Test]
+ [Description ("Create a new project and try to stash without HEAD commit, it should not be allowed")]
public void TestStashWithoutHeadCommit ()
{
var templateOptions = new TemplateSelectionOptions {
@@ -98,7 +97,8 @@ namespace UserInterfaceTests
TakeScreenShot ("Stash-Window-Doesnt-Show");
}
- [Test]
+ [Test, Category("Smoke")]
+ [Description ("Create a new project, make a commit, make changes. Stash and Unstash successfully")]
public void TestStashAndUnstashSuccessful ()
{
var templateOptions = new TemplateSelectionOptions {
@@ -107,23 +107,10 @@ namespace UserInterfaceTests
TemplateKindRoot = GeneralKindRoot,
TemplateKind = "Console Project"
};
- CreateProject (templateOptions,
- new ProjectDetails (templateOptions),
- new GitOptions { UseGit = true, UseGitIgnore = true });
-
- Session.WaitForElement (IdeQuery.TextArea);
- TestCommit ("First commit");
-
- Session.ExecuteCommand (FileCommands.CloseFile);
- Session.WaitForElement (IdeQuery.TextArea);
-
- Session.ExecuteCommand (TextEditorCommands.InsertNewLine);
- TakeScreenShot ("Inserted-Newline-Marked-Dirty");
- Session.ExecuteCommand (FileCommands.SaveAll);
- TakeScreenShot ("Inserted-Newline-SaveAll-Called");
-
- TestGitStash ("Entered new blank line");
+ GitCreateAndCommit (templateOptions, "First commit");
+ var changeDescription = MakeSomeChangesAndSaveAll ("Program.cs");
+ TestGitStash (changeDescription);
Session.WaitForElement (IdeQuery.TextArea);
TakeScreenShot ("After-Stash");
diff --git a/main/tests/UserInterfaceTests/VersionControlTests/GitRepositoryConfigurationTests.cs b/main/tests/UserInterfaceTests/VersionControlTests/GitRepositoryConfigurationTests.cs
deleted file mode 100644
index 166f0ac4ec..0000000000
--- a/main/tests/UserInterfaceTests/VersionControlTests/GitRepositoryConfigurationTests.cs
+++ /dev/null
@@ -1,310 +0,0 @@
-//
-// GitRepositoryConfigurationTests.cs
-//
-// Author:
-// Manish Sinha <manish.sinha@xamarin.com>
-//
-// Copyright (c) 2015 Xamarin Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using NUnit.Framework;
-using System;
-using MonoDevelop.Ide.Commands;
-using MonoDevelop.Components.AutoTest;
-
-namespace UserInterfaceTests
-{
- [TestFixture]
- [Category ("GitConfig")]
- public class GitRepositoryConfigurationTests : GitRepositoryConfigurationBase
- {
- #region Branch Tab
-
- [Test]
- public void CreateNewBranchTest ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- OpenRepositoryConfiguration ();
- CreateNewBranch ("new-branch");
- CloseRepositoryConfiguration ();
- }
-
- [Test]
- public void GitSwitchBranchTest ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- OpenRepositoryConfiguration ();
- CreateNewBranch ("new-branch");
- SwitchToBranch ("new-branch");
- CloseRepositoryConfiguration ();
- }
-
- [Test]
- public void GitEditBranchTest ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- OpenRepositoryConfiguration ();
- CreateNewBranch ("new-branch");
- SelectBranch ("new-branch");
- EditBranch ("new-branch", "new-new-branch");
- SwitchToBranch ("new-new-branch");
- CloseRepositoryConfiguration ();
- }
-
- #endregion
-
- #region Remotes Tab
-
- [Test]
- public void SelectRemoteTest ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- OpenRepositoryConfiguration ("Remote Sources");
- SelectRemote ("origin");
- CloseRepositoryConfiguration ();
- }
-
- [Test]
- public void AddGitRemoteTest ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- const string newRemoteName = "second";
- const string newRemoteUrl = "git@github.com:mono/monohotdraw.git";
- OpenRepositoryConfiguration ("Remote Sources");
- AddRemote (newRemoteName, newRemoteUrl);
- SelectRemote (newRemoteName, newRemoteUrl);
- CloseRepositoryConfiguration ();
- }
-
- [Test]
- [Ignore ("When OK is clicked on EditRemoteDialog, it doesn't update the list")]
- public void EditGitRemoteTest ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- OpenRepositoryConfiguration ("Remote Sources");
-
- const string newRemoteName = "second";
- const string newRemoteUrl = "git@github.com:mono/monohotdraw.git";
- AddRemote (newRemoteName, newRemoteUrl);
- SelectRemote (newRemoteName, newRemoteUrl);
-
- const string updatedRemoteName = "second-origin";
- const string updatedRemoteUrl = "git@github.com:mono/monohotdraw.git";
- EditRemote (updatedRemoteName, updatedRemoteUrl, "git@github.com:mono/monohotdraw-push.git");
- SelectRemote (updatedRemoteName, updatedRemoteUrl);
- CloseRepositoryConfiguration ();
- }
-
- [Test]
- public void FetchRemoteBranches ()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- const string newRemoteName = "second";
- const string newRemoteUrl = "git@github.com:mono/monohotdraw.git";
- OpenRepositoryConfiguration ("Remote Sources");
- AddRemote (newRemoteName, newRemoteUrl);
- FetchRemoteBranch (newRemoteName);
- CloseRepositoryConfiguration ();
- }
-
- [Test]
- public void TrackRemoteBranchInLocalTest()
- {
- TestClone ("git@github.com:mono/jurassic.git");
- Ide.WaitForSolutionCheckedOut ();
-
- const string newRemoteName = "second";
- const string newRemoteUrl = "git@github.com:mono/monohotdraw.git";
- OpenRepositoryConfiguration ("Remote Sources");
- AddRemote (newRemoteName, newRemoteUrl);
- FetchRemoteBranch (newRemoteName);
- const string localBranch = "local-branch-random-uitest";
- CreateEditBranch ("buttonTrackRemote", localBranch);
- SwitchTab ("Branches");
- SelectBranch (localBranch);
- CloseRepositoryConfiguration ();
- }
-
- #endregion
- }
-
- public abstract class GitRepositoryConfigurationBase : VCSBase
- {
- #region Remotes
-
- Func<AppQuery, AppQuery> remoteTreeName = c => c.TreeView ().Marked ("treeRemotes").Model ("storeRemotes__Name");
- Func<AppQuery, AppQuery> remoteTreeUrl = c => c.TreeView ().Marked ("treeRemotes").Model ("storeRemotes__Url");
- Func<AppQuery, AppQuery> remoteTreeFullName = c => c.TreeView ().Marked ("treeRemotes").Model ("storeRemotes__FullName");
-
- protected void SelectRemote (string remoteName, string remoteUrl = null)
- {
- Session.WaitForElement (c => remoteTreeName (c).Contains (remoteName));
- Assert.IsTrue (Session.SelectElement (c => remoteTreeName (c).Contains (remoteName)));
- if (remoteUrl != null) {
- Assert.IsTrue (Session.SelectElement (c => remoteTreeUrl (c).Contains (remoteUrl)));
- }
- TakeScreenShot (string.Format ("{0}-Remote-Selected", remoteName));
- }
-
- protected void EditRemote (string newRemoteName, string remoteUrl, string remotePushUrl = null)
- {
- AddEditRemote ("buttonEditRemote", newRemoteName, remoteUrl, remotePushUrl);
- }
-
- protected void AddRemote (string newRemoteName, string remoteUrl, string remotePushUrl = null)
- {
- AddEditRemote ("buttonAddRemote", newRemoteName, remoteUrl, remotePushUrl);
- }
-
- protected void FetchRemoteBranch (string remoteName)
- {
- SelectRemote (remoteName);
-
- Assert.IsEmpty (Session.Query (c => remoteTreeFullName (c).Contains (remoteName+"/")));
- Assert.IsTrue (Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked ("buttonFetch")));
- TakeScreenShot ("Fetch-Remote");
-
- Session.ClickElement (c => remoteTreeName (c).Contains (remoteName));
- Assert.IsNotEmpty (Session.Query (c => remoteTreeFullName (c).Contains (remoteName+"/")));
- Assert.IsTrue (Session.SelectElement (c => remoteTreeFullName (c).Contains (remoteName+"/").Index (0)));
- TakeScreenShot ("First-Remote-Branch-Selected");
- }
-
- void AddEditRemote (string buttonName, string newRemoteName, string remoteUrl, string remotePushUrl)
- {
- Assert.IsNotEmpty (Session.Query (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked (buttonName)));
- Session.ClickElement (c => IdeQuery.GitConfigurationDialog (c).Children ().Button ().Marked (buttonName), false);
- Session.WaitForElement (IdeQuery.EditRemoteDialog);
-
- Func<AppQuery, AppQuery> EditRemoteDialogChildren = c => IdeQuery.EditRemoteDialog (c).Children ();
- Assert.IsTrue (Session.EnterText (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryName"), newRemoteName));
- Session.WaitForElement (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryName").Text (newRemoteName));
-
- Assert.IsTrue (Session.EnterText (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryUrl"), remoteUrl));
- Session.WaitForElement (c => EditRemoteDialogChildren (c).Marked ("entryUrl").Text (remoteUrl));
-
- Assert.IsTrue (Session.EnterText (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryPushUrl"), remotePushUrl ?? remoteUrl));
- Session.WaitForElement (c => EditRemoteDialogChildren (c).Textfield ().Marked ("entryPushUrl").Text (remotePushUrl ?? remoteUrl));
- TakeScreenShot ("Remote-Details-Filled");
-
- Assert.IsTrue (Session.ClickElement (c => EditRemoteDialogChildren (c).Button ().Marked ("buttonOk")));
- Session.WaitForNoElement (IdeQuery.EditRemoteDialog);
- Session.WaitForElement (IdeQuery.GitConfigurationDialog);
- TakeScreenShot ("Remote-Edit-Dialog-Closed");
- }
-
- #endregion
-
- #region Branches
-
- Func<AppQuery, AppQuery> branchDisplayName = c => c.TreeView ().Marked ("listBranches").Model ("storeBranches__DisplayName");
-
- protected void CreateNewBranch (string newBranchName)
- {
- CreateEditBranch ("buttonAddBranch", newBranchName);
- }
-
- protected void EditBranch (string oldBranchName, string newBranchName)
- {
- SelectBranch (oldBranchName);
- CreateEditBranch ("buttonEditBranch", newBranchName);
- }
-
- protected void CreateEditBranch (string buttonName, string newBranchName)
- {
- Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Marked (buttonName), false);
- Session.WaitForElement (IdeQuery.EditBranchDialog);
- TakeScreenShot ("Edit-Branch-Dialog-Opened");
-
- Session.EnterText (c => IdeQuery.EditBranchDialog (c).Children ().Textfield ().Marked ("entryName"), newBranchName);
- Session.WaitForElement (c => IdeQuery.EditBranchDialog (c).Children ().Textfield ().Marked ("entryName").Text (newBranchName));
- TakeScreenShot ("Branch-Name-Entered");
-
- Assert.IsTrue (Session.ClickElement (c => IdeQuery.EditBranchDialog (c).Children ().Button ().Marked ("buttonOk")));
- Session.WaitForElement (IdeQuery.GitConfigurationDialog);
- TakeScreenShot ("Edit-Branch-Dialog-Opened-Closed");
- }
-
- protected void SwitchToBranch (string branchName)
- {
- SelectBranch (branchName);
- TakeScreenShot (string.Format ("{0}-Branch-Selected", branchName));
- Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Marked ("buttonSetDefaultBranch"), false);
-
- try {
- Session.WaitForElement (IdeQuery.GitConfigurationDialog);
- TakeScreenShot ("Git-User-Not-Configured");
- EnterGitUserConfig ("John Doe", "john.doe@example.com");
- } catch (TimeoutException e) { }
-
- Assert.IsTrue (IsBranchSwitched (branchName));
- TakeScreenShot (string.Format ("Switched-To-{0}", branchName));
- }
-
- protected void SwitchTab (string tabName)
- {
- Assert.IsTrue (Session.SelectElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Notebook ().Marked ("notebook1").Text (tabName)));
- TakeScreenShot (string.Format ("Tab-Changed-{0}", GenerateProjectName (tabName)));
- }
-
- protected void SelectBranch (string branchName)
- {
- Assert.IsTrue (Session.SelectElement (c => branchDisplayName (c).Contains (branchName)));
- TakeScreenShot (string.Format ("Selected-Branch-{0}", branchName));
- }
-
- protected bool IsBranchSwitched (string branchName)
- {
- return Session.SelectElement (c => branchDisplayName (c).Text ("<b>" + branchName + "</b>"));
- }
-
- #endregion
-
- protected void OpenRepositoryConfiguration (string selectTab = null)
- {
- Session.ExecuteCommand (MonoDevelop.VersionControl.Git.Commands.ManageBranches);
- Session.WaitForElement (IdeQuery.GitConfigurationDialog);
- TakeScreenShot ("Repository-Configuration-Opened");
- if (selectTab != null)
- SwitchTab (selectTab);
- }
-
- protected void CloseRepositoryConfiguration ()
- {
- Session.ClickElement (c => IdeQuery.GitConfigurationDialog(c).Children ().Button ().Marked ("buttonOk"));
- Session.WaitForNoElement (IdeQuery.GitConfigurationDialog);
- }
- }
-}
-
diff --git a/main/tests/UserInterfaceTests/VersionControlTests/VCSBase.cs b/main/tests/UserInterfaceTests/VersionControlTests/VCSBase.cs
index cf599626fd..e439d46580 100644
--- a/main/tests/UserInterfaceTests/VersionControlTests/VCSBase.cs
+++ b/main/tests/UserInterfaceTests/VersionControlTests/VCSBase.cs
@@ -26,7 +26,7 @@
using System;
using NUnit.Framework;
-using MonoDevelop.Components.AutoTest;
+using MonoDevelop.Ide.Commands;
namespace UserInterfaceTests
{
@@ -41,18 +41,34 @@ namespace UserInterfaceTests
protected string CheckoutOrClone (string repoUrl, string cloneToLocation = null, VersionControlType cvsType = VersionControlType.Git, int cloneTimeoutSecs = 180)
{
cloneToLocation = cloneToLocation ?? Util.CreateTmpDir ("clone");
+ ReproStep ("Click on Version Control > Checkout from Menu Bar");
Session.ExecuteCommand (MonoDevelop.VersionControl.Commands.Checkout);
- Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.SelectRepositoryDialog"));
+
+ WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.SelectRepositoryDialog"),
+ "Select Repository window should open",
+ "Select Reprository window did not open");
TakeScreenShot ("Checkout-Window-Ready");
+
+ ReproStep (string.Format ("Select Type to '{0}'", cvsType));
Assert.IsTrue (Session.SelectElement (c => c.Marked ("repCombo").Model ().Text (cvsType.ToString ())));
+
+ ReproStep (string.Format ("Enter URL as '{0}'", repoUrl));
Assert.IsTrue (Session.EnterText (c => c.Textfield ().Marked ("repositoryUrlEntry"), repoUrl));
+
Assert.IsTrue (Session.EnterText (c => c.Textfield ().Marked ("entryFolder"), cloneToLocation));
Session.WaitForElement (c => c.Textfield ().Marked ("entryFolder").Text (cloneToLocation));
+
TakeScreenShot ("Before-Clicking-OK");
+ ReproStep ("Click OK");
Assert.IsTrue (Session.ClickElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.SelectRepositoryDialog").Children ().Button ().Marked ("buttonOk")));
+
Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.Dialogs.ProgressDialog"), 15000);
TakeScreenShot ("CheckoutClone-In-Progress");
- Session.WaitForNoElement (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.Dialogs.ProgressDialog"), cloneTimeoutSecs * 1000);
+ ReproStep ("Wait for Clone to Finish");
+ WaitForElement (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.Dialogs.ProgressDialog"),
+ string.Format ("Clone should finish within {0} seconds", cloneTimeoutSecs),
+ string.Format ("Clone failed to finish within {0} seconds", cloneTimeoutSecs),
+ cloneTimeoutSecs * 1000);
return cloneToLocation;
}
@@ -65,38 +81,103 @@ namespace UserInterfaceTests
protected void TestGitStash (string stashMsg, int timeoutStashSecs = 10)
{
+ ReproStep ("Click on Version Control > Stash");
Session.ExecuteCommand (MonoDevelop.VersionControl.Git.Commands.Stash);
- Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.NewStashDialog"));
+
+ WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.NewStashDialog"), "Stash Dialog should open", "Stash Dialog did not open");
TakeScreenShot ("Stash-Dialog-Opened");
+
+ ReproStep ("Enter a stash message");
Session.EnterText (c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.NewStashDialog").Children ().Textfield ().Marked ("entryComment"), stashMsg);
Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.NewStashDialog").Children ().Textfield ().Marked ("entryComment").Text (stashMsg));
TakeScreenShot ("Stash-Message-Entered");
+
+ ReproStep ("Click on OK");
Session.ClickElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.NewStashDialog").Children ().Button ().Marked ("buttonOk"));
Ide.WaitForStatusMessage (new [] { "Changes successfully stashed" }, timeoutStashSecs);
}
protected void TestGitUnstash ()
{
+ ReproStep ("Click on Version Control > Pop Stash");
Session.ExecuteCommand (MonoDevelop.VersionControl.Git.Commands.StashPop);
- Ide.WaitForStatusMessage (new[] {"Stash successfully applied"}, 10);
+
+ WaitForElement (() => Ide.WaitForStatusMessage (new[] {"Stash successfully applied"}, 10), "Stash should apply successfully", "Stash failed to apply");
}
protected void TestCommit (string commitMsg)
{
+ ReproStep ("Click on Version Control > Review Solution and Commit from Menu Bar");
Session.ExecuteCommand (MonoDevelop.VersionControl.Commands.SolutionStatus);
+
+ ReproStep ("Wait for diff to be available");
+ WaitForElement (c => c.Button ().Marked ("buttonCommit").Sensitivity (true), "Commit button should become enabled", "Commit button was not enabled");
+
+ ReproStep ("Click on Commit Button");
Session.ClickElement (c => c.Button ().Marked ("buttonCommit"), false);
- Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.CommitDialog"));
+
+ WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.CommitDialog"), "Commit Dialog should open", "Commit Dialog did not open");
TakeScreenShot ("Commit-Dialog-Opened");
+
+ ReproStep ("Enter commit message and click on Commit");
Session.EnterText (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.CommitDialog").Children ().TextView ().Marked ("textview"), commitMsg);
TakeScreenShot ("Commit-Msg-Entered");
Session.ClickElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Dialogs.CommitDialog").Children ().Button ().Marked ("buttonCommit"), false);
+ CheckIfNameEmailNeeded ();
+ CheckIfUserConflict ();
+
+ WaitForElement (() => Ide.WaitForStatusMessage (new [] { "Commit operation completed." }),
+ "Status bar should show 'Commit operation completed.'",
+ "Status bar did not show 'Commit operation completed.'");
+ TakeScreenShot ("Commit-Completed");
+
+ ReproStep ("Close currently commit tab");
+ Session.ExecuteCommand (FileCommands.CloseFile);
+ Session.WaitForElement (IdeQuery.TextArea);
+ }
+
+ protected void GitCreateAndCommit (TemplateSelectionOptions templateOptions, string commitMessage)
+ {
+ CreateProject (templateOptions,
+ new ProjectDetails (templateOptions),
+ new GitOptions { UseGit = true, UseGitIgnore = true });
+
+ Session.WaitForElement (IdeQuery.TextArea);
+ TestCommit (commitMessage);
+ }
+
+ protected string MakeSomeChangesAndSaveAll (string waitForFile = null)
+ {
+ if (waitForFile != null) {
+ WaitForElement (c => c.Window ().Marked ("MonoDevelop.Ide.Gui.DefaultWorkbench").Property ("TabControl.CurrentTab.Text", waitForFile),
+ string.Format ("File '{0}' should open", waitForFile),
+ string.Format ("File {0} did not open", waitForFile));
+ }
+
+ Session.WaitForElement (IdeQuery.TextArea);
+ TakeScreenShot ("Ready-To-Make-Changes");
+ Session.SelectElement (IdeQuery.TextArea);
+ ReproStep ("Make some random changes to the file");
+ for (int i = 0; i < 10; i++) {
+ Session.ExecuteCommand (TextEditorCommands.InsertNewLine);
+ Session.ExecuteCommand (TextEditorCommands.InsertTab);
+ }
+ TakeScreenShot ("Made-Changes-To-Doc");
+
+ ReproStep ("Click on File > Save All from Menu Bar");
+ Session.ExecuteCommand (FileCommands.SaveAll);
+ TakeScreenShot ("Inserted-Newline-SaveAll-Called");
+
+ return "Entered new blank line";
+ }
+
+ protected void CheckIfNameEmailNeeded ()
+ {
try {
Session.WaitForElement (c => c.Window ().Marked ("MonoDevelop.VersionControl.Git.UserGitConfigDialog"));
TakeScreenShot ("Git-User-Not-Configured");
EnterGitUserConfig ("John Doe", "john.doe@example.com");
} catch (TimeoutException e) { }
- Ide.WaitForStatusMessage (new[] {"Commit operation completed."});
- TakeScreenShot ("Commit-Completed");
}
protected void EnterGitUserConfig (string gitUser, string gitEmail)
@@ -119,6 +200,15 @@ namespace UserInterfaceTests
}
}
+ protected void CheckIfUserConflict ()
+ {
+ try {
+ Session.WaitForElement (c => c.Window ().Marked ("User Information Conflict"));
+ Session.ClickElement (c => c.Window ().Marked ("User Information Conflict").Children ().Button ().Text ("OK"));
+ } catch (TimeoutException) {
+ }
+ }
+
protected override void OnBuildTemplate (int buildTimeoutInSecs = 180)
{
}
diff --git a/main/tests/UserInterfaceTests/Workbench.cs b/main/tests/UserInterfaceTests/Workbench.cs
new file mode 100644
index 0000000000..9ddb3bdf1a
--- /dev/null
+++ b/main/tests/UserInterfaceTests/Workbench.cs
@@ -0,0 +1,147 @@
+//
+// Workbench.cs
+//
+// Author:
+// Manish Sinha <manish.sinha@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Core;
+using MonoDevelop.Components.AutoTest;
+using System.Text.RegularExpressions;
+using MonoDevelop.Ide.Commands;
+using System.Linq;
+
+namespace UserInterfaceTests
+{
+ public static class Workbench
+ {
+ static AutoTestClientSession Session {
+ get { return TestService.Session; }
+ }
+
+ static readonly Regex buildRegex = new Regex (@"Build: (?<errors>\d*) error\D*, (?<warnings>\d*) warning\D*", RegexOptions.Compiled);
+
+ public static string GetStatusMessage (int timeout = 20000, bool waitForNonEmpty = true)
+ {
+ if (Platform.IsMac) {
+ if (waitForNonEmpty) {
+ Ide.WaitUntil (
+ () => Session.GetGlobalValue<string> ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.text") != string.Empty,
+ timeout
+ );
+ }
+ return (string)Session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.text");
+ }
+
+ if (waitForNonEmpty) {
+ Ide.WaitUntil (
+ () => Session.GetGlobalValue<int> ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.messageQueue.Count") == 0,
+ timeout,
+ timeoutMessage: ()=> "MessageQueue.Count="+Session.GetGlobalValue<int> ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.messageQueue.Count")
+ );
+ }
+ return (string) Session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.Workbench.RootWindow.StatusBar.renderArg.CurrentText");
+ }
+
+ public static bool IsBuildSuccessful (int timeoutInSecs)
+ {
+ bool isBuildSuccessful = false;
+ Ide.WaitUntil (() => {
+ var actualStatusMessage = Workbench.GetStatusMessage ();
+ if (actualStatusMessage == "Build successful.") {
+ isBuildSuccessful = true;
+ return true;
+ }
+ if (actualStatusMessage == "Build failed.") {
+ isBuildSuccessful = false;
+ return true;
+ }
+ var match = buildRegex.Match (actualStatusMessage);
+ if (match != null && match.Success) {
+ isBuildSuccessful = string.Equals (match.Groups ["errors"].ToString (), "0");
+ return true;
+ }
+ return false;
+ },
+ pollStep: 5 * 1000,
+ timeout: timeoutInSecs * 1000,
+ timeoutMessage: () => "GetStatusMessage=" + Workbench.GetStatusMessage ());
+
+ return isBuildSuccessful;
+ }
+
+ public static bool Run (int timeoutSeconds = 20, int pollStepSecs = 5)
+ {
+ Session.ExecuteCommand (ProjectCommands.Run);
+ try {
+ Ide.WaitUntil (
+ () => !Session.Query (c => IdeQuery.RunButton (c).Property ("Icon", "Stop")).Any (),
+ timeout: timeoutSeconds * 1000, pollStep: pollStepSecs * 1000);
+ return false;
+ } catch (TimeoutException) {
+ return true;
+ }
+ }
+
+ public static void OpenWorkspace (string solutionPath, UITestBase testContext = null)
+ {
+ if (testContext != null)
+ testContext.ReproStep (string.Format ("Open solution path '{0}'", solutionPath));
+ Action<string> takeScreenshot = GetScreenshotAction (testContext);
+ Session.GlobalInvoke ("MonoDevelop.Ide.IdeApp.Workspace.OpenWorkspaceItem", new FilePath (solutionPath), true);
+ Ide.WaitForIdeIdle ();
+ takeScreenshot ("Solution-Opened");
+ }
+
+ public static void CloseWorkspace (UITestBase testContext = null)
+ {
+ if (testContext != null)
+ testContext.ReproStep ("Close current workspace");
+ Action<string> takeScreenshot = GetScreenshotAction (testContext);
+ takeScreenshot ("About-To-Close-Workspace");
+ Session.ExecuteCommand (FileCommands.CloseWorkspace);
+ takeScreenshot ("Closed-Workspace");
+ }
+
+ public static string Configuration
+ {
+ get {
+ var configId = Session.GetGlobalValue ("MonoDevelop.Ide.IdeApp.Workspace.ActiveConfigurationId");
+ return configId != null ? (string)configId : null;
+ }
+ set {
+ Session.SetGlobalValue ("MonoDevelop.Ide.IdeApp.Workspace.ActiveConfigurationId", value);
+ Ide.WaitUntil (() => Workbench.Configuration == value, timeoutMessage: () => "Failed to set Configuration, Configuration=" + Workbench.Configuration + " value=" + value);
+ }
+ }
+
+ public static Action<string> GetScreenshotAction (UITestBase testContext)
+ {
+ Action<string> takeScreenshot = delegate {
+ };
+ if (testContext != null)
+ takeScreenshot = testContext.TakeScreenShot;
+
+ return takeScreenshot;
+ }
+ }
+}