summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Core.UITests.Shared
diff options
context:
space:
mode:
authorRui Marinho <me@ruimarinho.net>2017-03-23 11:03:48 +0000
committerGitHub <noreply@github.com>2017-03-23 11:03:48 +0000
commit2be80a55a514a050ab5ab07a201d13c111f49f63 (patch)
treea9cc64903a830e4b754ae6eee3fcc2ebb3ba200d /Xamarin.Forms.Core.UITests.Shared
parent16fcac8cf52ab960e7354a52864b0a72aefdfc1f (diff)
downloadxamarin-forms-2be80a55a514a050ab5ab07a201d13c111f49f63.tar.gz
xamarin-forms-2be80a55a514a050ab5ab07a201d13c111f49f63.tar.bz2
xamarin-forms-2be80a55a514a050ab5ab07a201d13c111f49f63.zip
[UITests]Add Xamarin.Forms.Core.UITests.Shared (#711)
* [UITests]Add Xamarin.Forms.Core.UITests.Shared * fix * [UITests]Use shared UITest project on macOS * [UITests] Add correct platform queries * [Controls] Add missing Preserve
Diffstat (limited to 'Xamarin.Forms.Core.UITests.Shared')
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/BaseTestFixture.cs138
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/PlatformQueries.cs278
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Queries.cs107
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Remotes/BaseViewContainerRemote.cs353
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Remotes/EventViewContainerRemote.cs21
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Remotes/LayeredViewContainerRemote.cs25
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Remotes/StateViewContainerRemote.cs27
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Remotes/ViewContainerRemote.cs11
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ActionSheetUITests.cs167
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ActivityIndicatorUITests.cs69
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/AppearingUITests.cs66
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/AutomationIDUITests.cs76
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/BoxViewUITests.cs57
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ButtonUITests.cs172
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ContextActionsUITests.cs121
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/DatePickerUITests.cs50
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/DisplayAlertUITests.cs58
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/EditorUITests.cs50
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/EntryUITests.cs63
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/FrameUITests.cs57
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ImageUITests.cs61
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/LabelUITests.cs54
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-CellsUITests.cs290
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-UnevenListTests.cs37
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/PickerUITests.cs42
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ProgressBarUITests.cs54
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/RootGalleryUITests.cs93
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ScrollViewUITests.cs67
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/SearchBarUITests.cs40
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/SliderUITests.cs48
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/StepperUITests.cs48
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/SwitchUITests.cs48
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/TimePickerUITests.cs51
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ToolbarItemTests.cs151
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/ViewUITests.cs247
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Tests/WebViewUITests.cs111
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs36
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/AppExtensions.cs35
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/Drag.cs171
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/Gestures.cs109
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/Logger.cs69
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/NumericExtensions.cs114
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/ParsingUtils.cs77
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/UITestCustomExceptions.cs95
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Utilities/ViewInspector.cs344
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.Shared.shproj13
-rw-r--r--Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.projitems58
47 files changed, 4529 insertions, 0 deletions
diff --git a/Xamarin.Forms.Core.UITests.Shared/BaseTestFixture.cs b/Xamarin.Forms.Core.UITests.Shared/BaseTestFixture.cs
new file mode 100644
index 00000000..78f9858d
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/BaseTestFixture.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Diagnostics;
+using NUnit.Framework;
+using Xamarin.Forms.Controls;
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal abstract class BaseTestFixture
+ {
+ // TODO: Landscape tests
+
+ public static IApp App { get; set; }
+
+ public string PlatformViewType { get; protected set; }
+
+ public static AppRect ScreenBounds { get; set; }
+
+ [TestFixtureTearDown]
+ protected virtual void FixtureTeardown()
+ {
+ }
+
+ static int s_testsrun;
+ const int ConsecutiveTestLimit = 10;
+
+ // Until we get more of our memory leak issues worked out, restart the app
+ // after a specified number of tests so we don't get bogged down in GC
+ // (or booted by jetsam)
+ public void EnsureMemory()
+ {
+ s_testsrun += 1;
+
+ if (s_testsrun >= ConsecutiveTestLimit)
+ {
+ s_testsrun = 0;
+
+ CoreUITestsSetup.LaunchApp();
+
+ FixtureSetup();
+ }
+ }
+
+ [SetUp]
+ protected virtual void TestSetup()
+ {
+ EnsureMemory();
+ }
+
+ [TearDown]
+ protected virtual void TestTearDown()
+ {
+ }
+
+ protected abstract void NavigateToGallery();
+
+#pragma warning disable 618
+ [TestFixtureSetUp]
+#pragma warning restore 618
+ protected virtual void FixtureSetup()
+ {
+ ResetApp();
+
+ int maxAttempts = 2;
+ int attempts = 0;
+
+ while (attempts < maxAttempts)
+ {
+ attempts += 1;
+ try
+ {
+ NavigateToGallery();
+ return;
+ }
+ catch (Exception ex)
+ {
+ var debugMessage = $"NavigateToGallery failed: {ex}";
+
+ Debug.WriteLine(debugMessage);
+ Console.WriteLine(debugMessage);
+
+ if (attempts < maxAttempts)
+ {
+ // Something has failed and we're stuck in a place where we can't navigate
+ // to the test. Usually this is because we're getting network/HTTP errors
+ // communicating with the server on the device. So we'll try restarting the app.
+ CoreUITestsSetup.LaunchApp();
+ }
+ else
+ {
+ // But if it's still not working after [maxAttempts], we've got assume this is a legit
+ // problem that restarting won't fix
+ throw;
+ }
+ }
+ }
+ }
+
+ protected void ResetApp()
+ {
+#if __IOS__
+ App.Invoke("reset:", string.Empty);
+#endif
+#if __ANDROID__
+ App.Invoke("Reset");
+#endif
+ }
+ }
+}
+
+#if UITEST
+
+namespace Xamarin.Forms.Core.UITests
+{
+ using NUnit.Framework;
+
+ [SetUpFixture]
+ public class CoreUITestsSetup
+ {
+ [SetUp]
+ public void RunBeforeAnyTests()
+ {
+ LaunchApp();
+ }
+
+ public static void LaunchApp()
+ {
+ BaseTestFixture.App = null;
+ BaseTestFixture.App = AppSetup.Setup();
+
+ BaseTestFixture.App.SetOrientationPortrait();
+ BaseTestFixture.ScreenBounds = BaseTestFixture.App.RootViewRect();
+ }
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/PlatformQueries.cs b/Xamarin.Forms.Core.UITests.Shared/PlatformQueries.cs
new file mode 100644
index 00000000..aeaaf556
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/PlatformQueries.cs
@@ -0,0 +1,278 @@
+using System;
+using System.Collections.Generic;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class PlatformMethodQueries
+ {
+#if __IOS__ || __MACOS__
+ public static readonly Dictionary<BindableProperty, Tuple<string[], bool>> PropertyPlatformMethodDictionary = new Dictionary<BindableProperty, Tuple<string[], bool>> {
+ { ActivityIndicator.ColorProperty, Tuple.Create (new[] { "color" }, false) },
+ { ActivityIndicator.IsRunningProperty, Tuple.Create (new[] { "isAnimating" }, false) },
+ { Button.BorderRadiusProperty, Tuple.Create (new[] { "layer", "cornerRadius" }, false) },
+ { Button.BorderWidthProperty, Tuple.Create (new[] { "layer", "borderWidth" }, false) },
+ { Button.FontProperty, Tuple.Create (new[] { "titleLabel", "font" }, false) },
+ { Button.TextProperty, Tuple.Create (new[] { "titleLabel", "text" }, false) },
+ { Button.TextColorProperty, Tuple.Create (new[] { "titleLabel", "textColor" }, false) },
+ { View.AnchorXProperty, Tuple.Create (new[] { "layer", "transform" }, true) },
+ { View.AnchorYProperty, Tuple.Create (new[] { "layer", "transform" }, true) },
+ { View.BackgroundColorProperty, Tuple.Create (new[] { "backgroundColor" }, false) },
+ { View.IsEnabledProperty, Tuple.Create (new[] { "isEnabled" }, false) },
+ { View.OpacityProperty, Tuple.Create (new [] { "alpha" }, true) },
+ { View.RotationProperty, Tuple.Create (new[] { "layer", "transform" }, true) },
+ { View.RotationXProperty, Tuple.Create (new[] { "layer", "transform" }, true) },
+ { View.RotationYProperty, Tuple.Create (new[] { "layer", "transform" }, true) },
+ { View.ScaleProperty, Tuple.Create (new[] { "layer", "transform" }, true) },
+ };
+
+#elif __ANDROID__ || __WINDOWS__
+ public static readonly Dictionary<BindableProperty, Tuple<string[], bool>> PropertyPlatformMethodDictionary = new Dictionary
+ <BindableProperty, Tuple<string[], bool>>
+ {
+ { ActivityIndicator.ColorProperty, Tuple.Create(new[] { "getProgressDrawable", "getColor" }, false) },
+ { ActivityIndicator.IsRunningProperty, Tuple.Create(new[] { "isIndeterminate" }, false) },
+ { Button.BorderColorProperty, Tuple.Create(new[] { "getBackground" }, false) },
+ { Button.BorderRadiusProperty, Tuple.Create(new[] { "getBackground" }, false) },
+ { Button.BorderWidthProperty, Tuple.Create(new[] { "getBackground" }, false) },
+ { Button.ImageProperty, Tuple.Create(new[] { "getBackground" }, false) },
+ { Button.FontProperty, Tuple.Create(new[] { "getTypeface", "isBold" }, false) },
+ { Button.TextProperty, Tuple.Create(new[] { "getText" }, false) },
+ { Button.TextColorProperty, Tuple.Create(new[] { "getCurrentTextColor" }, false) },
+ { View.AnchorXProperty, Tuple.Create(new[] { "getPivotX" }, true) },
+ { View.AnchorYProperty, Tuple.Create(new[] { "getPivotY" }, true) },
+ { View.BackgroundColorProperty, Tuple.Create(new[] { "getBackground", "getColor" }, true) },
+ { View.IsEnabledProperty, Tuple.Create(new[] { "isEnabled" }, false) },
+ { View.OpacityProperty, Tuple.Create(new[] { "getAlpha" }, true) },
+ { View.RotationProperty, Tuple.Create(new[] { "getRotation" }, true) },
+ { View.RotationXProperty, Tuple.Create(new[] { "getRotationX" }, true) },
+ { View.RotationYProperty, Tuple.Create(new[] { "getRotationY" }, true) },
+ { View.ScaleProperty, Tuple.Create(new[] { "getScaleX", "getScaleY" }, true) },
+ };
+#endif
+ }
+
+ internal static class PlatformViews
+ {
+#if __IOS__ || __MACOS__
+ public static readonly string ActivityIndicator = "UIActivityIndicatorView";
+ public static readonly string BoxView = "Xamarin_Forms_Platform_iOS_BoxRenderer";
+ public static readonly string Button = "UIButton";
+ public static readonly string DatePicker = "UITextField";
+ public static readonly string Editor = "UITextView";
+ public static readonly string Entry = "UITextField";
+ public static readonly string Frame = "view:'Xamarin_Forms_Platform_iOS_FrameRenderer'";
+ public static readonly string Image = "UIImageView";
+ public static readonly string Label = "UILabel";
+ public static readonly string ListView = "UITableView";
+ public static readonly string OpenGLView = "GLKView";
+ public static readonly string Picker = "UITextField";
+ public static readonly string ProgressBar = "UIProgressView";
+ public static readonly string SearchBar = "UISearchBar";
+ public static readonly string Slider = "UISlider";
+ public static readonly string Stepper = "UIStepper";
+ public static readonly string Switch = "UISwitch";
+ public static readonly string TableView = "UITableView";
+ public static readonly string TimePicker = "UITextField";
+ public static readonly string WebView = "UIWebView";
+#elif __ANDROID__ || __WINDOWS__
+ public static readonly string ActivityIndicator = "android.widget.ProgressBar";
+ public static readonly string BoxView = "xamarin.forms.platform.android.BoxRenderer";
+ public static readonly string Button = "android.widget.Button";
+ public static readonly string DatePicker = "android.widget.EditText";
+ public static readonly string Editor = "xamarin.forms.platform.android.EditorEditText";
+ public static readonly string Entry = "xamarin.forms.platform.android.EntryEditText";
+ public static readonly string Frame = "xamarin.forms.platform.android.appcompat.FrameRenderer";
+ public static readonly string Image = "android.widget.ImageView";
+ public static readonly string Label = "android.widget.TextView";
+ public static readonly string ListView = "android.widget.ListView";
+ public static readonly string OpenGLView = "android.widget.GLSurfaceView";
+ public static readonly string Picker = "android.widget.EditText";
+ public static readonly string ProgressBar = "android.widget.ProgressBar";
+ public static readonly string SearchBar = "android.widget.SearchView";
+ public static readonly string Slider = "android.widget.SeekBar";
+ public static readonly string Stepper = "button marked:'+'";
+ public static readonly string Switch = "android.widget.Switch";
+ public static readonly string TableView = "android.widget.ListView";
+ public static readonly string TimePicker = "android.widget.EditText";
+ public static readonly string WebView = "android.widget.WebView";
+#endif
+ }
+
+ internal static class PlatformQueries
+ {
+#if __IOS__ || __MACOS__
+ public static readonly Func<AppQuery, AppQuery> Root = q => q.Class("UIWindow");
+ public static readonly Func<AppQuery, AppQuery> RootPageListView = q => q.Class("Xamarin_Forms_Platform_iOS_ListViewRenderer index:0");
+ public static readonly Func<AppQuery, AppQuery> GalleryListView = q => q.Class("Xamarin_Forms_Platform_iOS_ListViewRenderer index:1");
+ public static readonly Func<AppQuery, AppQuery> PageWithoutNavigationBar = q => q.Raw("*").Index(7);
+ public static readonly Func<AppQuery, AppQuery> NavigationBarBackButton = q => q.Class("UINavigationItemButtonView");
+
+#elif __ANDROID__ || __WINDOWS__
+ public static readonly Func<AppQuery, AppQuery> Root = q => q.Id("content");
+ public static readonly Func<AppQuery, AppQuery> RootPageListView = q => q.Raw("ListViewRenderer index:0");
+ public static readonly Func<AppQuery, AppQuery> GalleryListView = q => q.Raw("ListViewRenderer index:1");
+ public static readonly Func<AppQuery, AppQuery> PageWithoutNavigationBar = q => q.Raw("* id:'content' index:0");
+
+ public static readonly Func<AppQuery, AppQuery> NavigationBarBackButton =
+ q => q.Class("android.support.v7.widget.Toolbar").Child("android.widget.ImageButton");
+#endif
+
+ // Controls
+ public static readonly Func<AppQuery, AppQuery> ActivityIndicator = q => q.ClassFull(PlatformViews.ActivityIndicator);
+ public static readonly Func<AppQuery, AppQuery> Button = q => q.ClassFull(PlatformViews.Button);
+
+#if __ANDROID__
+ public static Func<AppQuery, AppQuery> EntryWithPlaceholder(string text)
+ {
+ return q => q.Raw(string.Format("EntryEditText hint:'{0}'", text));
+ }
+ public static Func<AppQuery, AppQuery> EntryCellWithPlaceholder(string text)
+ {
+ return q => q.Raw(string.Format("EntryCellEditText hint:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryWithText(string text)
+ {
+ return q => q.Raw(string.Format("EntryEditText text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryCellWithText(string text)
+ {
+ return q => q.Raw(string.Format("EntryCellEditText text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EditorsWithText(string text)
+ {
+ return q => q.Raw(string.Format("EditorEditText text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("EntryEditText index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> SearchBarWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("SearchView index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> LabelWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("TextView index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> LabelWithText(string text)
+ {
+ return q => q.Raw(string.Format("TextView text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> LabelWithId(string id)
+ {
+ return q => q.Raw(string.Format("TextView id:'{0}'", id));
+ }
+
+ public static Func<AppQuery, AppQuery> PickerEntryWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("EditText index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> PickerEntryWithPlaceholder(string placeholder)
+ {
+ return q => q.Raw(string.Format("EditText hint:'{0}'", placeholder));
+ }
+
+ public static Func<AppQuery, AppQuery> PickerEntryWithText(string text)
+ {
+ return q => q.Raw(string.Format("EditText text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> SwitchWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("Switch index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> StepperWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("button marked:'+' index:{0}", index));
+ }
+
+#else
+ public static Func<AppQuery, AppQuery> EntryWithPlaceholder(string text)
+ {
+ return q => q.Raw(string.Format("TextField placeholder:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryWithText(string text)
+ {
+ return q => q.Raw(string.Format("TextField text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryCellWithPlaceholder(string text)
+ {
+ return q => q.Raw(string.Format("UITextFieldLabel text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryCellWithText(string text)
+ {
+ return q => q.Raw(string.Format("TextField text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EditorsWithText(string text)
+ {
+ return q => q.Raw(string.Format("TextView text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> EntryWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("TextField index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> SearchBarWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("SearchBar index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> LabelWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("Label index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> LabelWithText(string text)
+ {
+ return q => q.Raw(string.Format("Label text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> LabelWithId(string id)
+ {
+ return q => q.Raw(string.Format("Label id:'{0}'", id));
+ }
+
+ public static Func<AppQuery, AppQuery> PickerEntryWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("TextField index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> PickerEntryWithPlaceholder(string placeholder)
+ {
+ return q => q.Raw(string.Format("TextField placeholder:'{0}'", placeholder));
+ }
+
+ public static Func<AppQuery, AppQuery> PickerEntryWithText(string text)
+ {
+ return q => q.Raw(string.Format("TextField text:'{0}'", text));
+ }
+
+ public static Func<AppQuery, AppQuery> SwitchWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("Switch index:{0}", index));
+ }
+
+ public static Func<AppQuery, AppQuery> StepperWithIndex(int index)
+ {
+ return q => q.Raw(string.Format("Stepper index:{0}", index));
+ }
+#endif
+
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Queries.cs b/Xamarin.Forms.Core.UITests.Shared/Queries.cs
new file mode 100644
index 00000000..199b3f25
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Queries.cs
@@ -0,0 +1,107 @@
+using System;
+using System.CodeDom;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class GalleryQueries
+ {
+ public const string AutomationIDGallery = "* marked:'AutomationID Gallery'";
+ public const string ActivityIndicatorGallery = "* marked:'ActivityIndicator Gallery'";
+ public const string BoxViewGallery = "* marked:'BoxView Gallery'";
+ public const string ButtonGallery = "* marked:'Button Gallery'";
+ public const string ContextActionsListGallery = "* marked:'ContextActions List Gallery'";
+ public const string ContextActionsTableGallery = "* marked:'ContextActions Table Gallery'";
+ public const string DatePickerGallery = "* marked:'DatePicker Gallery'";
+ public const string EditorGallery = "* marked:'Editor Gallery'";
+ public const string EntryGallery = "* marked:'Entry Gallery'";
+ public const string FrameGallery = "* marked:'Frame Gallery'";
+ public const string ImageGallery = "* marked:'Image Gallery'";
+ public const string LabelGallery = "* marked:'Label Gallery'";
+ public const string ListViewGallery = "* marked:'ListView Gallery'";
+ public const string OpenGLViewGallery = "* marked:'OpenGLView Gallery'";
+ public const string PickerGallery = "* marked:'Picker Gallery'";
+ public const string ProgressBarGallery = "* marked:'ProgressBar Gallery'";
+ public const string ScrollViewGallery = "* marked:'ScrollView Gallery'";
+ public const string ScrollViewGalleryHorizontal = "* marked:'ScrollView Gallery Horizontal'";
+ public const string SearchBarGallery = "* marked:'SearchBar Gallery'";
+ public const string SliderGallery = "* marked:'Slider Gallery'";
+ public const string StepperGallery = "* marked:'Stepper Gallery'";
+ public const string SwitchGallery = "* marked:'Switch Gallery'";
+ public const string TableViewGallery = "* marked:'TableView Gallery'";
+ public const string TimePickerGallery = "* marked:'TimePicker Gallery'";
+ public const string WebViewGallery = "* marked:'WebView Gallery'";
+ public const string ToolbarItemGallery = "* marked:'ToolbarItems Gallery'";
+ public const string DisplayAlertGallery = "* marked:'DisplayAlert Gallery'";
+ public const string ActionSheetGallery = "* marked:'ActionSheet Gallery'";
+ public const string RootPagesGallery = "* marked:'RootPages Gallery'";
+
+ public const string AppearingGallery = "* marked:'Appearing Gallery'";
+
+ // Legacy galleries
+ public const string CellsGalleryLegacy = "* marked:'Cells Gallery - Legacy'";
+ public const string UnevenListGalleryLegacy = "* marked:'UnevenList Gallery - Legacy'";
+ }
+
+ internal static class Queries
+ {
+ #region Platform queries
+
+ public static Func<AppQuery, AppQuery> NavigationBarBackButton ()
+ {
+ return PlatformQueries.NavigationBarBackButton;
+ }
+
+ public static Func<AppQuery, AppQuery> PageWithoutNavigationBar ()
+ {
+ return PlatformQueries.PageWithoutNavigationBar;
+ }
+
+ public static Func<AppQuery, AppQuery> Root ()
+ {
+ return PlatformQueries.Root;
+ }
+
+ #endregion
+
+ }
+
+ internal static class Views
+ {
+ public static readonly string ActivityIndicator = PlatformViews.ActivityIndicator;
+ public static readonly string BoxView = PlatformViews.BoxView;
+ public static readonly string Button = PlatformViews.Button;
+ public static readonly string DatePicker = PlatformViews.DatePicker;
+ public static readonly string Editor = PlatformViews.Editor;
+ public static readonly string Entry = PlatformViews.Entry;
+ public static readonly string Frame = PlatformViews.Frame;
+ public static readonly string Image = PlatformViews.Image;
+ public static readonly string Label = PlatformViews.Label;
+ public static readonly string ListView = PlatformViews.ListView;
+ public static readonly string OpenGLView = PlatformViews.OpenGLView;
+ public static readonly string Picker = PlatformViews.Picker;
+ public static readonly string ProgressBar = PlatformViews.ProgressBar;
+ public static readonly string SearchBar = PlatformViews.SearchBar;
+ public static readonly string Slider = PlatformViews.Slider;
+ public static readonly string Stepper = PlatformViews.Stepper;
+ public static readonly string Switch = PlatformViews.Switch;
+ public static readonly string TableView = PlatformViews.TableView;
+ public static readonly string TimePicker = PlatformViews.TimePicker;
+ public static readonly string WebView = PlatformViews.WebView;
+ }
+
+ internal static class Rects
+ {
+ public static AppRect RootViewRect (this IApp app)
+ {
+ return app.Query (q => q.Raw ("* index:0"))[0].Rect;
+ }
+ }
+}
diff --git a/Xamarin.Forms.Core.UITests.Shared/Remotes/BaseViewContainerRemote.cs b/Xamarin.Forms.Core.UITests.Shared/Remotes/BaseViewContainerRemote.cs
new file mode 100644
index 00000000..6a784e20
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Remotes/BaseViewContainerRemote.cs
@@ -0,0 +1,353 @@
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal abstract class BaseViewContainerRemote
+ {
+ //bool requiresDismissal;
+ protected IApp App { get; private set; }
+
+ public string ViewQuery { get; private set; }
+
+ public string PlatformViewType { get; set; }
+
+ public string ContainerQuery { get; private set; }
+
+ public string ContainerDescendents { get; private set; }
+
+ public string EventLabelQuery { get; set; }
+
+ public string StateLabelQuery { get; private set; }
+
+ public string StateButtonQuery { get; private set; }
+
+ public string LayeredHiddenButtonQuery { get; private set; }
+
+ public string LayeredLabelQuery { get; private set; }
+
+ protected BaseViewContainerRemote(IApp app, Enum formsType, string platformViewType)
+ {
+ App = app;
+ PlatformViewType = platformViewType;
+
+ // Currently tests are failing because the ViewInitilized is setting the renderer and control, fix and then remove index one
+
+ ContainerQuery = string.Format("* marked:'{0}Container'", formsType);
+ ContainerDescendents = string.Format("* marked:'{0}Container' child *", formsType);
+
+ ViewQuery = string.Format("* marked:'{0}VisualElement'", formsType);
+
+ EventLabelQuery = string.Format("* marked:'{0}EventLabel'", formsType);
+ StateLabelQuery = string.Format("* marked:'{0}StateLabel'", formsType);
+ StateButtonQuery = string.Format("* marked:'{0}StateButton'", formsType);
+ LayeredHiddenButtonQuery = string.Format("* marked:'{0}LayeredHiddenButton'", formsType);
+ LayeredLabelQuery = string.Format("* marked:'{0}LayeredLabel'", formsType);
+
+ if (platformViewType == PlatformViews.DatePicker)
+ {
+ //requiresDismissal = true;
+ }
+ }
+
+ public virtual void GoTo([CallerMemberName] string callerMemberName = "")
+ {
+ var scrollBounds = App.Query(Queries.PageWithoutNavigationBar()).First().Rect;
+
+ // Scroll using gutter to the right of view, avoid scrolling inside of WebView
+ if (PlatformViewType == PlatformViews.WebView)
+ {
+ scrollBounds = new AppRect
+ {
+ X = scrollBounds.Width - 20,
+ CenterX = scrollBounds.Width - 10,
+ Y = scrollBounds.Y,
+ CenterY = scrollBounds.CenterY,
+ Width = 20,
+ Height = scrollBounds.Height,
+ };
+ }
+
+ while (true)
+ {
+#if __MACOS__
+ var result = App.Query(o => o.Raw(ViewQuery));
+#else
+ var result = App.Query (o => o.Raw(ContainerQuery));
+#endif
+
+ if (result.Any())
+ break;
+ App.Tap(o => o.Raw("* marked:'MoveNextButton'"));
+ }
+
+ //Assert.True (App.ScrollForElement (
+ // ContainerQuery, new Drag (scrollBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium)
+ //), "Failed to find element in: " + callerMemberName);
+
+ App.Screenshot("Go to element");
+ }
+
+ public void TapView()
+ {
+ App.Tap(q => q.Raw(ViewQuery));
+ }
+
+ public void DismissPopOver()
+ {
+ App.Screenshot("About to dismiss pop over");
+ App.Tap(q => q.Button("Done"));
+ App.Screenshot("Pop over dismissed");
+ }
+
+ public AppResult GetView()
+ {
+ return App.Query(q => q.Raw(ViewQuery)).First();
+ }
+
+ public AppResult[] GetViews()
+ {
+ return App.Query(q => q.Raw(ViewQuery));
+ }
+
+ public AppResult[] GetContainerDescendants()
+ {
+ return App.Query(q => q.Raw(ContainerDescendents));
+ }
+
+ public T GetProperty<T>(BindableProperty formProperty)
+ {
+ Tuple<string[], bool> property = formProperty.GetPlatformPropertyQuery();
+ string[] propertyPath = property.Item1;
+ bool isOnParentRenderer = property.Item2;
+
+ var query = ViewQuery;
+ if (isOnParentRenderer &&
+ PlatformViewType != PlatformViews.BoxView &&
+ PlatformViewType != PlatformViews.Frame)
+ {
+ query = query + " parent * index:0";
+ }
+
+ object prop = null;
+ bool found = false;
+
+ bool isEdgeCase = false;
+#if __ANDROID__
+ isEdgeCase = (formProperty == View.ScaleProperty);
+#endif
+ if (!isEdgeCase)
+ {
+ found =
+ MaybeGetProperty<string>(App, query, propertyPath, out prop) ||
+ MaybeGetProperty<float>(App, query, propertyPath, out prop) ||
+ MaybeGetProperty<bool>(App, query, propertyPath, out prop) ||
+ MaybeGetProperty<object>(App, query, propertyPath, out prop);
+ }
+#if __MACOS__
+ if (!found)
+ {
+
+ if (formProperty == View.IsEnabledProperty)
+ {
+ var view = App.Query((arg) => arg.Raw(query)).FirstOrDefault();
+ found = view != null;
+ prop = view.Enabled;
+ }
+
+ if (formProperty == Button.TextProperty)
+ {
+ var view = App.Query((arg) => arg.Raw(query)).FirstOrDefault();
+ found = view != null;
+ prop = view.Text;
+ }
+ }
+#endif
+
+#if __ANDROID__
+ if (formProperty == View.ScaleProperty) {
+ var matrix = new Matrix ();
+ matrix.M00 = App.Query (q => q.Raw (query).Invoke (propertyPath[0]).Value<float> ()).First ();
+ matrix.M11 = App.Query (q => q.Raw (query).Invoke (propertyPath[1]).Value<float> ()).First ();
+ matrix.M22 = 0.5f;
+ matrix.M33 = 1.0f;
+ return (T)((object)matrix);
+ }
+#endif
+
+ if (!found || prop == null)
+ {
+ throw new NullReferenceException("null property");
+ }
+
+ if (prop.GetType() == typeof(T))
+ return (T)prop;
+
+ if (prop.GetType() == typeof(string) && typeof(T) == typeof(Matrix))
+ {
+ Matrix matrix = ParsingUtils.ParseCATransform3D((string)prop);
+ return (T)((object)matrix);
+ }
+
+ if (typeof(T) == typeof(Color))
+ {
+#if __IOS__
+ Color color = ParsingUtils.ParseUIColor((string)prop);
+ return (T)((object)color);
+#else
+ uint intColor = (uint)((float)prop);
+ Color color = Color.FromUint (intColor);
+ return (T)((object)color);
+#endif
+ }
+
+#if __IOS__
+ if (prop.GetType() == typeof(string) && typeof(T) == typeof(Font))
+ {
+ Font font = ParsingUtils.ParseUIFont((string)prop);
+ return (T)((object)font);
+ }
+#endif
+
+ T result = default(T);
+
+ var stringToBoolConverter = new StringToBoolConverter();
+ var floatToBoolConverter = new FloatToBoolConverter();
+
+ if (stringToBoolConverter.CanConvertTo(prop, typeof(bool)))
+ {
+ result = (T)stringToBoolConverter.ConvertTo(prop, typeof(bool));
+ }
+ else if (floatToBoolConverter.CanConvertTo(prop, typeof(bool)))
+ {
+ result = (T)floatToBoolConverter.ConvertTo(prop, typeof(bool));
+ }
+
+ return result;
+ }
+
+ static bool MaybeGetProperty<T>(IApp app, string query, string[] propertyPath, out object result)
+ {
+ try
+ {
+ switch (propertyPath.Length)
+ {
+ case 1:
+ result = app.Query(q => q.Raw(query).Invoke(propertyPath[0]).Value<T>()).First();
+ break;
+ case 2:
+ result = app.Query(q => q.Raw(query).Invoke(propertyPath[0]).Invoke(propertyPath[1]).Value<T>()).First();
+ break;
+ case 3:
+ result =
+ app.Query(q => q.Raw(query).Invoke(propertyPath[0]).Invoke(propertyPath[1]).Invoke(propertyPath[2]).Value<T>())
+ .First();
+ break;
+ case 4:
+ result =
+ app.Query(
+ q =>
+ q.Raw(query)
+ .Invoke(propertyPath[0])
+ .Invoke(propertyPath[1])
+ .Invoke(propertyPath[2])
+ .Invoke(propertyPath[3])
+ .Value<T>()).First();
+ break;
+ default:
+ result = null;
+ return false;
+ }
+ }
+ catch
+ {
+ result = null;
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ internal class StringToBoolConverter : TypeConverter
+ {
+ public override bool CanConvertTo(object source, Type targetType)
+ {
+ if (targetType != typeof(bool) || !(source is string))
+ return false;
+
+ var str = (string)source;
+ str = str.ToLowerInvariant();
+
+ switch (str)
+ {
+ case "0":
+ case "1":
+ case "false":
+ case "true":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public override object ConvertTo(object source, Type targetType)
+ {
+ var str = (string)source;
+ str = str.ToLowerInvariant();
+
+ switch (str)
+ {
+ case "1":
+ case "true":
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+ internal class FloatToBoolConverter : TypeConverter
+ {
+ public override bool CanConvertTo(object source, Type targetType)
+ {
+ if (targetType != typeof(bool) || !(source is float))
+ return false;
+
+ var flt = (float)source;
+ var epsilon = 0.0001;
+ if (Math.Abs(flt - 1.0f) < epsilon || Math.Abs(flt - 0.0f) < epsilon)
+ return true;
+ else
+ return false;
+ }
+
+ public override object ConvertTo(object source, Type targetType)
+ {
+ var flt = (float)source;
+ var epsilon = 0.0001;
+ if (Math.Abs(flt - 1.0f) < epsilon)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ internal abstract class TypeConverter
+ {
+ public abstract bool CanConvertTo(object source, Type targetType);
+
+ public abstract object ConvertTo(object source, Type targetType);
+ }
+
+ internal static class PlatformMethods
+ {
+ public static Tuple<string[], bool> GetPlatformPropertyQuery(this BindableProperty bindableProperty)
+ {
+ return PlatformMethodQueries.PropertyPlatformMethodDictionary[bindableProperty];
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Remotes/EventViewContainerRemote.cs b/Xamarin.Forms.Core.UITests.Shared/Remotes/EventViewContainerRemote.cs
new file mode 100644
index 00000000..66d5602b
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Remotes/EventViewContainerRemote.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Linq;
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal sealed class EventViewContainerRemote : BaseViewContainerRemote
+ {
+ public EventViewContainerRemote(IApp app, Enum formsType, string platformViewType)
+ : base(app, formsType, platformViewType)
+ {
+ }
+
+ public AppResult GetEventLabel()
+ {
+ App.WaitForElement(q => q.Raw(EventLabelQuery));
+ return App.Query(q => q.Raw(EventLabelQuery)).First();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Remotes/LayeredViewContainerRemote.cs b/Xamarin.Forms.Core.UITests.Shared/Remotes/LayeredViewContainerRemote.cs
new file mode 100644
index 00000000..d0ef9f63
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Remotes/LayeredViewContainerRemote.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Linq;
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal sealed class LayeredViewContainerRemote : BaseViewContainerRemote
+ {
+ public LayeredViewContainerRemote(IApp app, Enum formsType, string platformViewType)
+ : base(app, formsType, platformViewType)
+ {
+ }
+
+ public AppResult GetLayeredLabel()
+ {
+ return App.Query(q => q.Raw(LayeredLabelQuery)).First();
+ }
+
+ public void TapHiddenButton()
+ {
+ App.Tap(q => q.Raw(LayeredHiddenButtonQuery));
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Remotes/StateViewContainerRemote.cs b/Xamarin.Forms.Core.UITests.Shared/Remotes/StateViewContainerRemote.cs
new file mode 100644
index 00000000..053fe3d8
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Remotes/StateViewContainerRemote.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Linq;
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal sealed class StateViewContainerRemote : BaseViewContainerRemote
+ {
+ public StateViewContainerRemote(IApp app, Enum formsType, string platformViewType)
+ : base(app, formsType, platformViewType)
+ {
+ }
+
+ public void TapStateButton()
+ {
+ App.Screenshot("Before state change");
+ App.Tap(q => q.Raw(StateButtonQuery));
+ App.Screenshot("After state change");
+ }
+
+ public AppResult GetStateLabel()
+ {
+ return App.Query(q => q.Raw(StateLabelQuery)).First();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Remotes/ViewContainerRemote.cs b/Xamarin.Forms.Core.UITests.Shared/Remotes/ViewContainerRemote.cs
new file mode 100644
index 00000000..98b7cacc
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Remotes/ViewContainerRemote.cs
@@ -0,0 +1,11 @@
+using System;
+using Xamarin.UITest;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal sealed class ViewContainerRemote : BaseViewContainerRemote
+ {
+ public ViewContainerRemote (IApp app, Enum formsType, string platformViewType)
+ : base (app, formsType, platformViewType) { }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ActionSheetUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ActionSheetUITests.cs
new file mode 100644
index 00000000..88d280e5
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ActionSheetUITests.cs
@@ -0,0 +1,167 @@
+using NUnit.Framework;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.ActionSheet)]
+ internal class ActionSheetUITests : BaseTestFixture
+ {
+ AppRect screenSize;
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.ActionSheetGallery);
+ }
+
+ static void CheckExtras()
+ {
+ App.WaitForElement(c => c.Marked("Extra One"));
+ App.WaitForElement(c => c.Marked("Extra Six"));
+ }
+
+ protected override void TestSetup()
+ {
+ base.TestSetup();
+#if !__MACOS__
+ screenSize = App.Query(q => q.Marked("ActionSheetPage"))[0].Rect;
+#endif
+ }
+
+ [Test]
+ public void TestDisplayActionSheet()
+ {
+ ScrollAndTap("ActionSheet Extras");
+ CheckExtras();
+ App.Tap(c => c.Marked("Extra One"));
+ }
+
+ [Test]
+ public void TestDisplayActionSheetCancel()
+ {
+ ScrollAndTap("ActionSheet Cancel");
+ // iPad does not have a Cancel button for action sheet
+ if (App.Query(q => q.Marked("Cancel")).Length > 0)
+ App.Tap(c => c.Marked("Cancel"));
+ else
+ App.TapCoordinates(20, screenSize.Height / 2);
+ }
+
+ [Test]
+ public void TestDisplayActionSheetCancelDestruction()
+ {
+ ScrollAndTap("ActionSheet Cancel Destruction");
+ App.WaitForNoElement(c => c.Marked("Extra One"));
+ App.WaitForElement(c => c.Marked("Destruction"));
+ if (App.Query(q => q.Marked("Cancel")).Length > 0)
+ App.Tap(c => c.Marked("Cancel"));
+ else
+ App.TapCoordinates(20, screenSize.Height / 2);
+ }
+
+ [Test]
+ public void TestDisplayActionSheetCancelExtras()
+ {
+ ScrollAndTap("ActionSheet Cancel Extras");
+ CheckExtras();
+ if (App.Query(q => q.Marked("Cancel")).Length > 0)
+ App.Tap(c => c.Marked("Cancel"));
+ else
+ App.TapCoordinates(20, screenSize.Height / 2);
+ }
+
+ [Test]
+ public void TestDisplayActionSheetCancelExtrasDestruction()
+ {
+ ScrollAndTap("ActionSheet Cancel Destruction Extras");
+ CheckExtras();
+ App.WaitForElement(c => c.Marked("Destruction"));
+ if (App.Query(q => q.Marked("Cancel")).Length > 0)
+ App.Tap(c => c.Marked("Cancel"));
+ else
+ App.TapCoordinates(20, screenSize.Height / 2);
+ }
+
+ [Test]
+ public void TestDisplayActionSheetDestruction()
+ {
+ ScrollAndTap("ActionSheet Destruction");
+ App.WaitForNoElement(c => c.Marked("Extra One"));
+ App.Tap(c => c.Marked("Destruction"));
+ }
+
+ [Test]
+ public void TestDisplayActionSheetDestructionExtras()
+ {
+ ScrollAndTap("ActionSheet Destruction Extras");
+ CheckExtras();
+ App.Tap(c => c.Marked("Extra One"));
+ }
+
+ [Test]
+ public void TestDisplayActionSheetTitleCancel()
+ {
+ ScrollAndTap("ActionSheet Title Cancel");
+ App.WaitForElement(c => c.Marked("Title"));
+ if (App.Query(q => q.Marked("Cancel")).Length > 0)
+ App.Tap(c => c.Marked("Cancel"));
+ else
+ App.TapCoordinates(20, screenSize.Height / 2);
+ }
+
+ [Test]
+ public void TestDisplayActionSheetTitleCancelDestruction()
+ {
+ ScrollAndTap("ActionSheet Title Cancel Destruction");
+ App.WaitForElement(c => c.Marked("Title"));
+ App.WaitForNoElement(c => c.Marked("Extra One"));
+ App.Tap(c => c.Marked("Destruction"));
+ }
+
+ [Test]
+ public void TestDisplayActionSheetTitleCancelDestructionExtras()
+ {
+ ScrollAndTap("ActionSheet Title Cancel Destruction Extras");
+ App.WaitForElement(c => c.Marked("Title"));
+ CheckExtras();
+ App.Tap(c => c.Marked("Destruction"));
+ }
+
+ [Test]
+ public void TestDisplayActionSheetTitleDestruction()
+ {
+ ScrollAndTap("ActionSheet Title Destruction");
+ App.WaitForElement(c => c.Marked("Title"));
+ App.WaitForNoElement(c => c.Marked("Extra One"));
+ App.Tap(c => c.Marked("Destruction"));
+ }
+
+ [Test]
+ public void TestDisplayActionSheetTitleDestructionExtras()
+ {
+ ScrollAndTap("ActionSheet Title Destruction Extras");
+ App.WaitForElement(c => c.Marked("Title"));
+ CheckExtras();
+ App.Tap(c => c.Marked("Destruction"));
+ }
+
+
+ [Test]
+ public void TestDisplayActionSheetTitleExtras()
+ {
+ ScrollAndTap("ActionSheet Title Extras");
+ CheckExtras();
+ App.Tap(c => c.Marked("Extra One"));
+ }
+
+ void ScrollAndTap(string actionSheet)
+ {
+#if !__MACOS__
+ App.ScrollForElement(string.Format("* text:'{0}'", actionSheet), new Drag(App.Query(q => q.Marked("ActionSheetPage"))[0].Rect, Drag.Direction.BottomToTop, Drag.DragLength.Long));
+#endif
+ App.Tap(q => q.Raw(string.Format("* text:'{0}'", actionSheet)));
+ }
+
+ }
+}
+
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ActivityIndicatorUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ActivityIndicatorUITests.cs
new file mode 100644
index 00000000..1667aa34
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ActivityIndicatorUITests.cs
@@ -0,0 +1,69 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.ActivityIndicator)]
+ internal class ActivityIndicatorUITests : _ViewUITests
+ {
+ public ActivityIndicatorUITests()
+ {
+ PlatformViewType = Views.ActivityIndicator;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.ActivityIndicatorGallery);
+ }
+
+ // View tests
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ public override void _GestureRecognizers()
+ {
+ // TODO Can implement this
+ var remote = new ViewContainerRemote(App, Test.View.GestureRecognizers, PlatformViewType);
+ remote.GoTo();
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsEnabled()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // ActivityIndicator tests
+ [Test]
+ [UiTest(typeof(ActivityIndicator), "IsRunning")]
+ public void IsRunning()
+ {
+ var remote = new ViewContainerRemote(App, Test.ActivityIndicator.IsRunning, PlatformViewType);
+ remote.GoTo();
+#if __MACOS__
+ Assert.Inconclusive("Not tested yet");
+#else
+ var isRunning = remote.GetProperty<bool> (ActivityIndicator.IsRunningProperty);
+ Assert.IsTrue (isRunning);
+#endif
+ }
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/AppearingUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/AppearingUITests.cs
new file mode 100644
index 00000000..b38fd418
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/AppearingUITests.cs
@@ -0,0 +1,66 @@
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Core.UITests
+{
+#if __MACOS__
+ [Ignore("Not tested on the MAC")]
+#endif
+ [Category(UITestCategories.LifeCycle)]
+ internal class AppearingUITests : BaseTestFixture
+ {
+ public AppearingUITests()
+ {
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.AppearingGallery);
+ }
+
+ protected override void TestTearDown()
+ {
+ base.TestTearDown();
+ ResetApp();
+ NavigateToGallery();
+ }
+
+ [Test]
+ public void AppearingNavigationPage()
+ {
+ App.Tap(t => t.Marked("NavAppearingPage"));
+ App.WaitForElement("Appearing NavAppearingPage");
+ App.WaitForElement("Appearing Page 1");
+ App.Tap(t => t.Marked("Push new Page"));
+ App.WaitForElement("Disappearing Page 1");
+ App.WaitForElement("Appearing Page 2");
+ App.Tap(t => t.Marked("Change Main Page"));
+ App.WaitForElement("Disappearing Page 2");
+ App.WaitForElement("Disappearing NavAppearingPage");
+ App.WaitForElement("Appearing Page 3");
+ }
+
+ [Test]
+ public void AppearingCarouselPage()
+ {
+ App.Tap(t => t.Marked("CarouselAppearingPage"));
+ App.WaitForElement("Appearing CarouselAppearingPage");
+ App.WaitForElement("Appearing Page 1");
+ }
+
+ [Test]
+ public void AppearingTabbedPage()
+ {
+ App.Tap(t => t.Marked("TabbedAppearingPage"));
+ App.WaitForElement("Appearing TabbedAppearingPage");
+ App.WaitForElement("Appearing Page 1");
+ }
+
+ [Test]
+ public void AppearingMasterDetailPage()
+ {
+ App.Tap(t => t.Marked("MasterAppearingPage"));
+ App.WaitForElement("Appearing MasterAppearingPage");
+ App.WaitForElement("Appearing Page 1");
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/AutomationIDUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/AutomationIDUITests.cs
new file mode 100644
index 00000000..9b814a92
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/AutomationIDUITests.cs
@@ -0,0 +1,76 @@
+using NUnit.Framework;
+using Xamarin.UITest;
+using System;
+using System.Threading;
+using Xamarin.UITest.Queries;
+using System.Threading.Tasks;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.AutomationId)]
+ internal class AutomationIDUITests : BaseTestFixture
+ {
+ protected override void NavigateToGallery ()
+ {
+ App.NavigateToGallery (GalleryQueries.AutomationIDGallery);
+ }
+
+ [Test]
+ public void Test1 ()
+ {
+ App.WaitForElement(c => c.Marked("btnTest1"));
+ App.Tap (c => c.Marked ("btnTest1"));
+ App.WaitForElement (c => c.Marked ("stckMain"));
+ App.WaitForElement (c => c.Marked ("actHello"));
+ App.WaitForElement (c => c.Marked ("bxvHello"));
+ App.Tap (c => c.Marked ("btnHello"));
+ App.WaitForElement (c => c.Marked ("dtPicker"));
+ App.WaitForElement (c => c.Marked ("tPicker"));
+
+ var label = App.Query ("lblHello") [0];
+ Assert.AreEqual (label.Text, "Hello Label");
+
+ var editor = App.Query ("editorHello") [0];
+ Assert.AreEqual (editor.Text, "Hello Editor");
+
+ var entry = App.Query ("entryHello") [0];
+ Assert.AreEqual (entry.Text, "Hello Entry");
+
+ App.Tap (c => c.Marked ("popModal"));
+ }
+
+
+ [Test]
+ public async void Test2()
+ {
+ await Task.Delay(1000);
+ App.WaitForElement(c => c.Marked("btnTest2"));
+ App.Tap (c => c.Marked ("btnTest2"));
+ App.WaitForElement (c => c.Marked ("imgHello"));
+ App.WaitForElement (c => c.Marked ("lstView"));
+ App.WaitForElement (c => c.Marked ("pickerHello"));
+ App.WaitForElement (c => c.Marked ("progressHello"));
+ App.ScrollDownTo (c => c.Marked ("progressHello"));
+ App.WaitForElement (c => c.Marked ("srbHello"));
+ App.WaitForElement (c => c.Marked ("sliHello"));
+ App.WaitForElement (c => c.Marked ("stepperHello"));
+ App.WaitForElement (c => c.Marked ("switchHello"));
+ //App.WaitForElement (c => c.Marked ("webviewHello"));
+ App.Tap (c => c.Marked ("popModal"));
+ }
+
+ [Test]
+ [Ignore("only works on ios")]
+ public void TestToolbarItem ()
+ {
+ App.Tap (c => c.Marked ("tbItemHello"));
+ App.WaitForElement (x => x.Marked ("Hello"));
+ App.Tap (c => c.Marked ("ok"));
+ App.Tap (c => c.Marked ("tbItemHello2"));
+ App.WaitForElement (x => x.Marked ("Hello2"));
+ App.Tap (c => c.Marked ("ok"));
+ }
+ }
+}
+
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/BoxViewUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/BoxViewUITests.cs
new file mode 100644
index 00000000..a99363dc
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/BoxViewUITests.cs
@@ -0,0 +1,57 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+#if __MACOS__
+ [Ignore("Not tested on the MAC")]
+#endif
+ [Category(UITestCategories.BoxView)]
+ internal class BoxViewUITests : _ViewUITests
+ {
+ public BoxViewUITests()
+ {
+ PlatformViewType = Views.BoxView;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.BoxViewGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsEnabled()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ButtonUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ButtonUITests.cs
new file mode 100644
index 00000000..83dff100
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ButtonUITests.cs
@@ -0,0 +1,172 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Button)]
+ internal class ButtonUITests : _ViewUITests
+ {
+ public ButtonUITests()
+ {
+ PlatformViewType = Views.Button;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.ButtonGallery);
+ }
+
+ // View Tests
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // Button Tests
+ [Test]
+ [UiTest(typeof(Button), "BorderColor")]
+ [UiTestBroken(BrokenReason.CalabashAndroidUnsupported, "Figure out how to get Android Drawables")]
+ [UiTestBroken(BrokenReason.CalabashiOSUnsupported, "iOS nil result")]
+ public void BorderColor()
+ {
+ //TODO iOS
+ var remote = new ViewContainerRemote(App, Test.Button.BorderColor, PlatformViewType);
+ remote.GoTo();
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "BorderRadius")]
+ [UiTestBroken(BrokenReason.CalabashAndroidUnsupported, "Figure out how to get Android Drawables")]
+ public void BorderRadius()
+ {
+ var remote = new ViewContainerRemote(App, Test.Button.BorderRadius, PlatformViewType);
+ remote.GoTo();
+
+#if __IOS__
+ var borderRadius = remote.GetProperty<float>(Button.BorderRadiusProperty);
+ Assert.AreEqual(20.0f, borderRadius);
+#endif
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "BorderWidth")]
+ [UiTestBroken(BrokenReason.CalabashAndroidUnsupported, "Figure out how to get Android Drawables")]
+ public void BorderWidth()
+ {
+ var remote = new ViewContainerRemote(App, Test.Button.BorderWidth, PlatformViewType);
+ remote.GoTo();
+
+#if __IOS__
+ var borderWidth = remote.GetProperty<float>(Button.BorderWidthProperty);
+ Assert.AreEqual(15.0f, borderWidth);
+#endif
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "Clicked")]
+ public void Clicked()
+ {
+ var remote = new EventViewContainerRemote(App, Test.Button.Clicked, PlatformViewType);
+ remote.GoTo();
+
+ var textBeforeClick = remote.GetEventLabel().Text;
+ Assert.AreEqual("Event: Clicked (none)", textBeforeClick);
+
+ // Click Button
+ remote.TapView();
+
+ var textAfterClick = remote.GetEventLabel().Text;
+ Assert.AreEqual("Event: Clicked (fired 1)", textAfterClick);
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "Command")]
+ public void Command()
+ {
+ var remote = new ViewContainerRemote(App, Test.Button.Command, PlatformViewType);
+ remote.GoTo();
+
+ remote.TapView();
+
+ App.WaitForElement(q => q.Marked("Hello Command"));
+ App.Tap(q => q.Marked("Destroy"));
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "Font")]
+ public void Font()
+ {
+ //TODO iOS
+ var remote = new ViewContainerRemote(App, Test.Button.Font, PlatformViewType);
+ remote.GoTo();
+
+#if __ANDROID__
+ var isBold = remote.GetProperty<bool> (Button.FontProperty);
+ Assert.True (isBold);
+#elif __MACOS__
+ Assert.Inconclusive("needs testing");
+#else
+ var font = remote.GetProperty<Font>(Button.FontProperty);
+ Assert.True(font.FontAttributes.HasFlag(FontAttributes.Bold));
+#endif
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "Image")]
+ [UiTestExempt(ExemptReason.TimeConsuming, "Need way to check Android resources")]
+ public void Image()
+ {
+ //TODO iOS
+ var remote = new ViewContainerRemote(App, Test.Button.Image, PlatformViewType);
+ remote.GoTo();
+ }
+
+ [Test]
+ [UiTest(typeof(Button), "Text")]
+ public void Text()
+ {
+ var remote = new ViewContainerRemote(App, Test.Button.Text, PlatformViewType);
+ remote.GoTo();
+
+ var buttonText = remote.GetProperty<string>(Button.TextProperty);
+ Assert.AreEqual("Text", buttonText);
+ }
+
+ //TODO iOS
+
+#if __ANDROID__
+ [Test]
+ [UiTest (typeof (Button), "TextColor")]
+ public void TextColor ()
+ {
+ var remote = new ViewContainerRemote (App, Test.Button.TextColor, PlatformViewType);
+ remote.GoTo ();
+
+ var buttonTextColor = remote.GetProperty<Color> (Button.TextColorProperty);
+ Assert.AreEqual (Color.Pink, buttonTextColor);
+ }
+#endif
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ContextActionsUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ContextActionsUITests.cs
new file mode 100644
index 00000000..cd0b3643
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ContextActionsUITests.cs
@@ -0,0 +1,121 @@
+using NUnit.Framework;
+using Xamarin.UITest;
+using System;
+using System.Threading;
+
+using Xamarin.UITest.Android;
+using Xamarin.UITest.iOS;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Cells)]
+ internal class ContextActionsListUITests : BaseTestFixture
+ {
+
+ public ContextActionsListUITests ()
+ {
+ }
+
+ protected override void NavigateToGallery ()
+ {
+ App.NavigateToGallery (GalleryQueries.ContextActionsListGallery);
+ }
+
+ const string cell0 = "Subject Line 0";
+ const string cell1 = "Subject Line 1";
+ const string move = "Move";
+ const string delete = "Delete";
+ const string clear = "Clear Items";
+ const string mark = "Mark";
+
+
+#if __ANDROID__ || __MACOS__
+ [Test]
+ public void ContextActionsShow ()
+ {
+ // mark is an icon on android
+ App.TouchAndHold (q => q.Marked (cell0));
+ App.WaitForElement (q => q.Marked (delete));
+ App.Screenshot ("I have actions!");
+ }
+
+ [Test]
+ public void ContextActionsDelete ()
+ {
+ // mark is an icon on android
+ App.TouchAndHold (q => q.Marked (cell1));
+ App.WaitForElement (q => q.Marked (delete));
+ App.Screenshot ("I have actions!");
+
+ App.Tap (q => q.Marked (delete));
+ App.WaitForNoElement (q => q.Marked (cell1));
+ App.Screenshot ("Deleted cell 0");
+ }
+#endif
+
+#if __IOS__
+ [Test]
+ public void PopoverDismiss()
+ {
+ var device = App.Device as iOSDevice;
+
+ if (device == null)
+ {
+ return;
+ }
+
+ if (device.IsTablet) {
+ var screenBounds = App.Query (PlatformQueries.Root)[0].Rect;
+ var cellBounds = App.Query (q => q.Marked (cell0))[0].Rect;
+ App.DragCoordinates (screenBounds.Width - 10, cellBounds.CenterY, 10, cellBounds.CenterY);
+ App.Screenshot("I see context actions");
+ App.Tap (q => q.Marked ("More"));
+ App.Screenshot ("Should see Popover");
+ App.TapCoordinates (50, 50);
+ App.Screenshot ("I should not crash");
+ } else {
+ Assert.Inconclusive("Not testing iOS Phone");
+ }
+ }
+#endif
+ }
+ [TestFixture]
+ [Category(UITestCategories.Cells)]
+ internal class ContextActionsTableUITests : BaseTestFixture
+ {
+ public ContextActionsTableUITests ()
+ {
+ }
+
+ protected override void NavigateToGallery ()
+ {
+ App.NavigateToGallery (GalleryQueries.ContextActionsTableGallery);
+ }
+
+ const string cell0 = "Subject Line 0";
+ const string cell1 = "Subject Line 1";
+ const string move = "Move";
+ const string delete = "Delete";
+ const string clear = "Clear Items";
+ const string mark = "Mark";
+ const string cellWithNoContextActions = "I have no ContextActions";
+
+#if __ANDROID__ || __MACOS__
+ [Test]
+ public void ContextActionsShowAndReset ()
+ {
+ // mark is an icon on android
+ App.TouchAndHold (q => q.Marked (cell0));
+ App.WaitForElement (q => q.Marked (delete));
+ App.Screenshot ("I have actions!");
+
+ App.Tap (q => q.Marked (cellWithNoContextActions));
+ App.WaitForNoElement (q => q.Marked (delete));
+ App.Screenshot ("Actions should be gone");
+ }
+#endif
+ }
+}
+
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/DatePickerUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/DatePickerUITests.cs
new file mode 100644
index 00000000..4e176df2
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/DatePickerUITests.cs
@@ -0,0 +1,50 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.DatePicker)]
+ internal class DatePickerUITests : _ViewUITests
+ {
+ public DatePickerUITests()
+ {
+ PlatformViewType = Views.DatePicker;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.DatePickerGallery);
+ }
+
+ // View Tests
+ // TODO
+ public override void _Focus()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers()
+ {
+ }
+
+ // TODO
+ public override void _IsFocused()
+ {
+ }
+
+ // TODO
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/DisplayAlertUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/DisplayAlertUITests.cs
new file mode 100644
index 00000000..ce935dc9
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/DisplayAlertUITests.cs
@@ -0,0 +1,58 @@
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.DisplayAlert)]
+ internal class DisplayAlertUITests : BaseTestFixture
+ {
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.DisplayAlertGallery);
+ }
+
+ [Test]
+ public void TestWithCancelButton()
+ {
+ App.Tap(c => c.Marked("Alert Override1"));
+ App.Screenshot("Display Alert");
+ App.WaitForElement(c => c.Marked("TheAlertTitle"));
+ App.WaitForElement(c => c.Marked("TheAlertMessage"));
+ App.WaitForElement(c => c.Marked("TheCancelButton"));
+ App.Screenshot("Display Alert Closed");
+ App.Tap(c => c.Marked("TheCancelButton"));
+ App.WaitForNoElement(c => c.Marked("TheAlertTitle"));
+ }
+
+ [Test]
+ public void TestWithCancelAndOkButton()
+ {
+ App.Tap(c => c.Marked("Alert Override2"));
+ App.Screenshot("Display Alert");
+ App.WaitForElement(c => c.Marked("TheAlertTitle"));
+ App.WaitForElement(c => c.Marked("TheAlertMessage"));
+ App.WaitForElement(c => c.Marked("TheAcceptButton"));
+ App.WaitForElement(c => c.Marked("TheCancelButton"));
+ App.Tap(c => c.Marked("TheCancelButton"));
+ App.Screenshot("Display Alert Closed");
+ App.WaitForNoElement(c => c.Marked("TheAlertTitle"));
+ }
+
+ [Test]
+ public void TestOkAndCancelResults()
+ {
+ App.Tap(c => c.Marked("Alert Override2"));
+ App.Screenshot("Display Alert");
+ App.WaitForElement(c => c.Marked("TheCancelButton"));
+ App.Tap(c => c.Marked("TheCancelButton"));
+ App.Screenshot("Display Alert Closed with cancel");
+ App.WaitForElement(c => c.Marked("Result: False"));
+ App.Tap(c => c.Marked("test2"));
+ App.Screenshot("Display Alert");
+ App.WaitForElement(c => c.Marked("TheAcceptButton"));
+ App.Tap(c => c.Marked("TheAcceptButton"));
+ App.Screenshot("Display Alert Closed with True");
+ App.WaitForElement(c => c.Marked("Result: True"));
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/EditorUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/EditorUITests.cs
new file mode 100644
index 00000000..b2739b5c
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/EditorUITests.cs
@@ -0,0 +1,50 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Editor)]
+ internal class EditorUITests : _ViewUITests
+ {
+ public EditorUITests()
+ {
+ PlatformViewType = Views.Editor;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.EditorGallery);
+ }
+
+ // View Tests
+ // TODO
+ public override void _Focus()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers()
+ {
+ }
+
+ // TODO
+ public override void _IsFocused()
+ {
+ }
+
+ // TODO
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/EntryUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/EntryUITests.cs
new file mode 100644
index 00000000..80d2095f
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/EntryUITests.cs
@@ -0,0 +1,63 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Entry)]
+ internal class EntryUITests : _ViewUITests
+ {
+ public EntryUITests()
+ {
+ PlatformViewType = Views.Entry;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.EntryGallery);
+ }
+
+ // TODO
+ public override void _Focus()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers()
+ {
+ }
+
+ // TODO
+ public override void _IsFocused()
+ {
+ }
+
+ // TODO
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+ [Test]
+ [UiTest(typeof(Entry), "Completed")]
+ public void Completed()
+ {
+ var remote = new EventViewContainerRemote(App, Test.Entry.Completed, PlatformViewType);
+ remote.GoTo();
+
+ App.EnterText(q => q.Raw(remote.ViewQuery), "Test");
+
+ App.PressEnter();
+
+ var eventLabelText = remote.GetEventLabel().Text;
+ Assert.AreEqual(eventLabelText, "Event: Completed (fired 1)");
+ }
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/FrameUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/FrameUITests.cs
new file mode 100644
index 00000000..469c8a5a
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/FrameUITests.cs
@@ -0,0 +1,57 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+#if __MACOS__
+ [Ignore("Not tested on the MAC")]
+#endif
+ [TestFixture]
+ [Category(UITestCategories.Frame)]
+ internal class FrameUITests : _ViewUITests
+ {
+ public FrameUITests()
+ {
+ PlatformViewType = Views.Frame;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.FrameGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsEnabled()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ImageUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ImageUITests.cs
new file mode 100644
index 00000000..0b2aa849
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ImageUITests.cs
@@ -0,0 +1,61 @@
+using System.Threading;
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Image)]
+ internal class ImageUITests : _ViewUITests
+ {
+ public ImageUITests()
+ {
+ PlatformViewType = Views.Image;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.ImageGallery);
+
+ // let remote images load
+ Thread.Sleep(2000);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsEnabled()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ // TODO
+ // Tests for remote images
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/LabelUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/LabelUITests.cs
new file mode 100644
index 00000000..8b0dd311
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/LabelUITests.cs
@@ -0,0 +1,54 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Label)]
+ internal class LabelUITests : _ViewUITests
+ {
+ public LabelUITests()
+ {
+ PlatformViewType = Views.Label;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.LabelGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsEnabled()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-CellsUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-CellsUITests.cs
new file mode 100644
index 00000000..45b3436c
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-CellsUITests.cs
@@ -0,0 +1,290 @@
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+#if __MACOS__
+ [Ignore("Not tested on the MAC")]
+#endif
+ [TestFixture]
+ [Category(UITestCategories.Cells)]
+ internal class CellsGalleryTests : BaseTestFixture
+ {
+ // TODO find a way to test individula elements of cells
+ // TODO port to new framework
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.CellsGalleryLegacy);
+ }
+
+ [Test]
+ [Description("ListView with TextCells, all are present")]
+ [UiTest(typeof(ListView))]
+ [UiTest(typeof(TextCell))]
+ public void CellsGalleryTextCellList()
+ {
+ App.ScrollForElement("* marked:'TextCell List'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+ App.Tap(q => q.Marked("TextCell List"));
+ App.WaitForElement(q => q.Marked("Text 0"), "Timeout : Text 0");
+
+ App.Screenshot("At TextCell List Gallery");
+
+ App.ScrollForElement("* marked:'Detail 99'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.WaitForElement(q => q.Marked("Detail 99"), "Timeout : Detail 99");
+
+ App.Screenshot("All TextCells are present");
+ }
+
+ [Test]
+ [Description("TableView with TextCells, all are present")]
+ [UiTest(typeof(TableView))]
+ [UiTest(typeof(TextCell))]
+ public void CellsGalleryTextCellTable()
+ {
+ App.ScrollForElement("* marked:'TextCell Table'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("TextCell Table"));
+ App.WaitForElement(q => q.Marked("Text 1"), "Timeout : Text 1");
+
+ App.Screenshot("At TextCell Table Gallery");
+
+ App.ScrollForElement("* marked:'Detail 12'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.WaitForElement(q => q.Marked("Detail 12"), "Timeout : Detail 12");
+
+ App.Screenshot("All TextCells are present");
+ }
+
+ [Test]
+ [Description("ListView with ImageCells, all are present")]
+ [UiTest(typeof(ListView))]
+ [UiTest(typeof(ImageCell))]
+ public void CellsGalleryImageCellList()
+ {
+ Thread.Sleep(2000);
+
+ App.ScrollForElement("* marked:'ImageCell List'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ Thread.Sleep(2000);
+
+ App.Tap(q => q.Marked("ImageCell List"));
+ App.WaitForElement(q => q.Marked("Text 0"), "Timeout : Text 0");
+
+ App.Screenshot("At ImageCell List Gallery");
+
+ var scollBounds = App.Query(q => q.Marked("ImageCellListView")).First().Rect;
+ App.ScrollForElement("* marked:'Detail 99'",
+ new Drag(scollBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.WaitForElement(q => q.Marked("Detail 99"), "Timeout : Detail 99");
+
+ App.Screenshot("All ImageCells are present");
+
+ var numberOfImages = App.Query(q => q.Raw(PlatformViews.Image)).Length;
+ // Check that there are images present. In Android,
+ // have to make sure that there are more than 2 for navigation.
+ Assert.IsTrue(numberOfImages > 2);
+
+ App.Screenshot("Images are present");
+ }
+
+ [Test]
+ [Ignore("Ignore because is only failing on iOS10 at XTC")]
+ [Description("ListView with ImageCells, file access problems")]
+ [UiTest(typeof(ListView))]
+ [UiTest(typeof(ImageCell))]
+ public async Task CellsGalleryImageUrlCellList()
+ {
+ App.ScrollForElement("* marked:'ImageCell Url List'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("ImageCell Url List"));
+
+ //var scollBounds = App.Query(q => q.Marked("ImageUrlCellListView")).First().Rect;
+ //App.ScrollForElement("* marked:'Detail 200'", new Drag(scollBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+ //App.ScrollUp();
+ //App.WaitForElement(q => q.Marked("Detail 200"), "Timeout : Detail 200");
+
+ App.Screenshot("All ImageCells are present");
+
+ int numberOfImages = 0;
+
+ // Most of the time, 1 second is long enough to wait for the images to load, but depending on network conditions
+ // it may take longer
+ for (int n = 0; n < 30; n++)
+ {
+ await Task.Delay(1000);
+ numberOfImages = App.Query(q => q.Raw(PlatformViews.Image)).Length;
+ if (numberOfImages > 2)
+ {
+ break;
+ }
+ }
+
+ // Check that there are images present. In Android,
+ // have to make sure that there are more than 2 for navigation.
+ Assert.IsTrue(numberOfImages > 2);
+
+ App.Screenshot("Images are present");
+ }
+
+ [Test]
+ [Description("TableView with ImageCells, all are present")]
+ [UiTest(typeof(TableView))]
+ [UiTest(typeof(ImageCell))]
+ public void CellsGalleryImageCellTable()
+ {
+ App.ScrollForElement("* marked:'ImageCell Table'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("ImageCell Table"));
+ App.WaitForElement(q => q.Marked("Text 1"), "Timeout : Text 1");
+
+ App.Screenshot("At ImageCell Table Gallery");
+
+ App.ScrollForElement("* marked:'Detail 12'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.WaitForElement(q => q.Marked("Detail 12"), "Timeout : Detail 12");
+
+ App.Screenshot("All ImageCells are present");
+
+ var numberOfImages = App.Query(q => q.Raw(PlatformViews.Image)).Length;
+ // Check that there are images present. In Android,
+ // have to make sure that there are more than 2 for navigation.
+ Assert.IsTrue(numberOfImages > 2);
+
+ App.Screenshot("Images are present");
+ }
+
+ [Test]
+ [Description("ListView with SwitchCells, all are present")]
+ [UiTest(typeof(ListView))]
+ [UiTest(typeof(SwitchCell))]
+ public void CellsGallerySwitchCellList()
+ {
+ App.ScrollForElement("* marked:'SwitchCell List'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("SwitchCell List"));
+ App.WaitForElement(q => q.Marked("Label 0"), "Timeout : Label 0");
+
+ App.Screenshot("At SwitchCell List Gallery");
+
+ App.ScrollForElement("* marked:'Label 99'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ var numberOfSwitches = App.Query(q => q.Raw(PlatformViews.Switch)).Length;
+ Assert.IsTrue(numberOfSwitches > 2);
+
+ App.Screenshot("Switches are present");
+ }
+
+ [Test]
+ [Description("TableView with SwitchCells, all are present")]
+ [UiTest(typeof(TableView))]
+ [UiTest(typeof(SwitchCell))]
+ public void CellsGallerySwitchCellTable()
+ {
+ App.ScrollForElement("* marked:'SwitchCell Table'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("SwitchCell Table"));
+ App.WaitForElement(q => q.Marked("text 1"), "Timeout : text 1");
+
+ App.Screenshot("At SwitchCell Table Gallery");
+
+ App.ScrollForElement("* marked:'text 32'", new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ var numberOfSwitches = App.Query(q => q.Raw(PlatformViews.Switch)).Length;
+ Assert.IsTrue(numberOfSwitches > 2);
+
+ App.Screenshot("Switches are present");
+ }
+
+ [Test]
+ [Description("ListView with EntryCells, all are present")]
+ [UiTest(typeof(ListView))]
+ [UiTest(typeof(EntryCell))]
+ public void CellsGalleryEntryCellList()
+ {
+ App.ScrollForElement("* marked:'EntryCell List'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("EntryCell List"));
+ App.WaitForElement(q => q.Marked("Label 0"), "Timeout : Label 0");
+
+ App.Screenshot("At EntryCell List Gallery");
+
+ App.ScrollForElement("* marked:'Label 99'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Screenshot("All EntryCells are present");
+ }
+
+ [Test]
+ [Description("TableView with EntryCells, all are present")]
+ [UiTest(typeof(TableView))]
+ [UiTest(typeof(EntryCell))]
+ public void CellsGalleryEntryCellTable()
+ {
+ App.ScrollForElement("* marked:'EntryCell Table'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("EntryCell Table"));
+ App.WaitForElement(q => q.Marked("Text 2"), "Timeout : Text 2");
+
+ App.Screenshot("At EntryCell Table Gallery");
+
+ App.ScrollForElement("* marked:'Text 32'", new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Screenshot("All EntryCells are present");
+ }
+
+ [Test]
+ [Category("EntryCell")]
+ [Description("EntryCell fires .Completed event")]
+ [UiTest(typeof(EntryCell), "Completed")]
+ public void CellsGalleryEntryCellCompleted()
+ {
+ App.ScrollForElement("* marked:'EntryCell Table'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Tap(q => q.Marked("EntryCell Table"));
+ App.WaitForElement(q => q.Marked("Text 2"), "Timeout : Text 2");
+
+ App.Screenshot("At EntryCell Table Gallery");
+ App.ScrollForElement("* marked:'Enter text'",
+ new Drag(ScreenBounds, Drag.Direction.BottomToTop, Drag.DragLength.Medium));
+
+ App.Screenshot("Before clicking Entry");
+
+#if !__IOS__
+ App.Tap(PlatformQueries.EntryCellWithPlaceholder("I am a placeholder"));
+ App.EnterText(PlatformQueries.EntryCellWithPlaceholder("I am a placeholder"), "Hi");
+ App.Screenshot("Entered Text");
+ App.PressEnter();
+
+ App.WaitForElement(q => q.Marked("Entered: 1"));
+ App.Screenshot("Completed should have changed label's text");
+
+#endif
+ }
+
+ protected override void TestTearDown()
+ {
+ App.NavigateBack();
+ base.TestTearDown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-UnevenListTests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-UnevenListTests.cs
new file mode 100644
index 00000000..34ca2a9a
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/Legacy-UnevenListTests.cs
@@ -0,0 +1,37 @@
+using NUnit.Framework;
+using Xamarin.UITest;
+using Xamarin.UITest.iOS;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category("Cells")]
+ internal class UnevenListTests : BaseTestFixture
+ {
+ public UnevenListTests()
+ {
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.UnevenListGalleryLegacy);
+ }
+
+ [Test]
+ public void UnevenListCellTest()
+ {
+ if (UnevenListTests.ShouldRunTest(App))
+ {
+ var element = App.Query(q => q.Marked("unevenCellListGalleryDynamic").Descendant(("UITableViewCellContentView")))[0];
+
+ Assert.GreaterOrEqual(element.Rect.Height, 100);
+ }
+ }
+
+ public static bool ShouldRunTest(IApp app)
+ {
+ var appAs = app as iOSApp;
+ return (appAs != null && appAs.Device.IsPhone);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/PickerUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/PickerUITests.cs
new file mode 100644
index 00000000..9628c4a0
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/PickerUITests.cs
@@ -0,0 +1,42 @@
+using NUnit.Framework;
+
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Picker)]
+ internal class PickerUITests : _ViewUITests
+ {
+ public PickerUITests ()
+ {
+ PlatformViewType = Views.Picker;
+ }
+
+ protected override void NavigateToGallery ()
+ {
+ App.NavigateToGallery (GalleryQueries.PickerGallery);
+ }
+
+ // TODO
+ public override void _Focus () {}
+
+ [UiTestExempt (ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers () {}
+
+ // TODO
+ public override void _IsFocused () {}
+
+ // TODO
+ public override void _UnFocus () {}
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown ()
+ {
+ App.NavigateBack ();
+ base.FixtureTeardown ();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ProgressBarUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ProgressBarUITests.cs
new file mode 100644
index 00000000..63eceb60
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ProgressBarUITests.cs
@@ -0,0 +1,54 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.ProgressBar)]
+ internal class ProgressBarUITests : _ViewUITests
+ {
+ public ProgressBarUITests()
+ {
+ PlatformViewType = Views.ProgressBar;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.ProgressBarGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsEnabled()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/RootGalleryUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/RootGalleryUITests.cs
new file mode 100644
index 00000000..b55fc23e
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/RootGalleryUITests.cs
@@ -0,0 +1,93 @@
+using NUnit.Framework;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal sealed class RootPageModel
+ {
+ public string ButtonId { get; private set; }
+
+ public string PageId { get; private set; }
+
+ public bool IsModal { get; private set; }
+
+ public RootPageModel(string buttonId, string pageId, bool isModal = false)
+ {
+ ButtonId = buttonId;
+ PageId = pageId;
+ IsModal = isModal;
+ }
+ }
+
+ [TestFixture]
+ [Category(UITestCategories.RootGallery)]
+ internal class RootGalleryUITests : BaseTestFixture
+ {
+ readonly IEnumerable<RootPageModel> rootPages;
+
+ public RootGalleryUITests()
+ {
+ string[] ids =
+ {
+ "Content",
+ "Nav->Content",
+ "MDP->Nav->Content",
+ "Tab->Content",
+ "Tab->MDP->Nav->Content",
+ "Tab->Nav->Content",
+ "Tab(Many)->Nav->Content",
+ "Nav->Tab->Content(BAD IDEA)",
+ "Nav->Tab(Many)->Content(BAD IDEA)",
+ "MDP->Nav->Tab->Content(BAD IDEA)"
+ };
+ string[] modalIds =
+ {
+ "(Modal)Content",
+ "(Modal)Nav->Content",
+ "(Modal)MDP->Nav->Content",
+ "(Modal)Tab->Content",
+ "(Modal)Tab->MDP->Nav->Content",
+ "(Modal)Tab->Nav->Content",
+ "(Modal)Tab(Many)->Nav->Content",
+ "(Modal)Nav->Tab->Content(BAD IDEA)",
+ "(Modal)Nav->Tab(Many)->Content(BAD IDEA)",
+ "(Modal)MDP->Nav->Tab->Content(BAD IDEA)",
+ };
+
+ rootPages =
+ (from id in ids
+ select new RootPageModel(id + "ButtonId", id + "PageId")).Union(
+ from id in modalIds
+ select new RootPageModel(id + "ButtonId", id + "PageId", true));
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.RootPagesGallery);
+ }
+
+ [Test]
+ [Ignore("Ignore while we dont't have a response from XTC team why this fails some times")]
+ public void VisitEachPage()
+ {
+ foreach (var page in rootPages)
+ {
+ var scrollViewArea = App.Query(q => q.Marked("ChoosePageScrollView")).First().Rect;
+ App.ScrollForElement(string.Format("* marked:'{0}'", page.ButtonId),
+ new Drag(scrollViewArea, Drag.Direction.BottomToTop, Drag.DragLength.Long));
+ App.Tap(q => q.Marked(page.ButtonId));
+
+ bool ios = false;
+#if __IOS__
+ ios = true;
+#endif
+
+ if (!page.IsModal || ios)
+ App.WaitForElement(q => q.Marked(page.PageId));
+
+ App.Screenshot("Page: " + page.PageId);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ScrollViewUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ScrollViewUITests.cs
new file mode 100644
index 00000000..fa057636
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ScrollViewUITests.cs
@@ -0,0 +1,67 @@
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.ScrollView)]
+ internal class ScrollViewGalleryTests : BaseTestFixture
+ {
+ public ScrollViewGalleryTests ()
+ {
+ }
+
+ protected override void NavigateToGallery ()
+ {
+ App.NavigateToGallery (GalleryQueries.ScrollViewGallery);
+ }
+
+ [Test]
+ [Description ("Scroll element to the start")]
+ public void ScrollToElement1Start ()
+ {
+ //var scroller = App.Query (c => c.Marked ("thescroller"))[0];
+ //need to extract the contentOffset on iOS
+ App.Tap(c=> c.Marked("Start"));
+ App.WaitForElement (c => c.Marked ("the scrollto button"));
+ //Assert.Equals (App.Query (c => c.Marked ("the before")).Length, 0);
+ App.Screenshot ("Element is on the top");
+ }
+
+ [Test]
+ [Description ("Scroll element to the center")]
+ public void ScrollToElement2Center ()
+ {
+ App.Tap(c=> c.Marked("Center"));
+ App.WaitForElement (c => c.Marked ("the scrollto button"));
+ App.WaitForElement (c => c.Marked ("the before"));
+ App.WaitForElement (c => c.Marked ("the after"));
+ App.Screenshot ("Element is in the center");
+ }
+
+ [Test]
+ [Description ("Scroll element to the end")]
+ public void ScrollToElement3End ()
+ {
+ App.Tap(c=> c.Marked("End"));
+ App.WaitForElement (c => c.Marked ("the scrollto button"));
+ //Assert.Equals (App.Query (c => c.Marked ("the after")).Length, 0);
+ App.Screenshot ("Element is in the end");
+ }
+
+ [Test]
+ [Description ("ScrollTo Y = 100")]
+ public void ScrollToY ()
+ {
+ App.Tap(c=> c.Marked("Scroll to 100"));
+ }
+
+ [Test]
+ [Description ("ScrollTo Y = 100 no animation")]
+ public void ScrollToYNoAnim ()
+ {
+ App.ScrollDown ();
+ App.ScrollDown ();
+ App.Tap (c => c.Marked ("Scroll to 100 no anim"));
+ }
+ }
+}
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/SearchBarUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/SearchBarUITests.cs
new file mode 100644
index 00000000..2b25d275
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/SearchBarUITests.cs
@@ -0,0 +1,40 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.SearchBar)]
+ internal class SearchBarUITests : _ViewUITests
+ {
+ public SearchBarUITests ()
+ {
+ PlatformViewType = Views.SearchBar;
+ }
+
+ protected override void NavigateToGallery ()
+ {
+ App.NavigateToGallery (GalleryQueries.SearchBarGallery);
+ }
+
+ // TODO
+ public override void _Focus () {}
+
+ [UiTestExempt (ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers () {}
+
+ // TODO
+ public override void _IsFocused () {}
+
+ // TODO
+ public override void _UnFocus () {}
+
+ // TODO
+ // Implement control specific ui tests
+ protected override void FixtureTeardown ()
+ {
+ App.NavigateBack ();
+ base.FixtureTeardown ();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/SliderUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/SliderUITests.cs
new file mode 100644
index 00000000..eceed80b
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/SliderUITests.cs
@@ -0,0 +1,48 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Slider)]
+ internal class SliderUITests : _ViewUITests
+ {
+ public SliderUITests()
+ {
+ PlatformViewType = Views.Slider;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.SliderGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/StepperUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/StepperUITests.cs
new file mode 100644
index 00000000..1aa69af8
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/StepperUITests.cs
@@ -0,0 +1,48 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Stepper)]
+ internal class StepperUITests : _ViewUITests
+ {
+ public StepperUITests()
+ {
+ PlatformViewType = Views.Stepper;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.StepperGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/SwitchUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/SwitchUITests.cs
new file mode 100644
index 00000000..f2e1fe25
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/SwitchUITests.cs
@@ -0,0 +1,48 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.Switch)]
+ internal class SwitchUITests : _ViewUITests
+ {
+ public SwitchUITests()
+ {
+ PlatformViewType = Views.Switch;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.SwitchGallery);
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _IsFocused()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/TimePickerUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/TimePickerUITests.cs
new file mode 100644
index 00000000..db093dc8
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/TimePickerUITests.cs
@@ -0,0 +1,51 @@
+using System.Threading;
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.TimePicker)]
+ internal class TimePickerUITests : _ViewUITests
+ {
+ public TimePickerUITests()
+ {
+ PlatformViewType = Views.TimePicker;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.TimePickerGallery);
+
+ Thread.Sleep(4000);
+ }
+
+ // TODO
+ public override void _Focus()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction")]
+ public override void _GestureRecognizers()
+ {
+ }
+
+ // TODO
+ public override void _IsFocused()
+ {
+ }
+
+ // TODO
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ToolbarItemTests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ToolbarItemTests.cs
new file mode 100644
index 00000000..0231ca57
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ToolbarItemTests.cs
@@ -0,0 +1,151 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.ToolbarItem)]
+ internal class ToolbarItemTests : BaseTestFixture
+ {
+ string btn1Id = "tb1";
+ string btn4Id = "tb4";
+#if __ANDROID__
+ static bool isSecondaryMenuOpen = false;
+#endif
+ static void ShouldShowMenu()
+ {
+#if __ANDROID__
+ isSecondaryMenuOpen = true;
+ //show secondary menu
+ App.Tap(c => c.Class("android.support.v7.widget.ActionMenuPresenter$OverflowMenuButton"));
+#endif
+ }
+
+ static void ShouldHideMenu()
+ {
+#if __ANDROID__
+ if (isSecondaryMenuOpen)
+ {
+ isSecondaryMenuOpen = false;
+ App.Back();
+ }
+#endif
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.ToolbarItemGallery);
+#if __IOS__
+ btn1Id = "menuIcon";
+ btn4Id = "tb4";
+#endif
+ }
+
+ [Test]
+ public void ToolbarButtonsClick()
+ {
+ ShouldHideMenu();
+#if __MACOS__
+ App.Tap(c => c.Button().Index(4));
+#else
+ App.Tap(c => c.Marked(btn1Id));
+#endif
+ var textLabel = App.Query((arg) => arg.Marked("label_id"))[0];
+ Assert.False(textLabel.Text == "tb1");
+ Assert.True(textLabel.Text == "Hello ContentPage");
+ }
+
+ [Test]
+ public void ToolbarButtonsCommand()
+ {
+ ShouldShowMenu();
+#if __ANDROID__
+ //App.Query (c => c.Marked (btn4Id))[0];
+#else
+ App.Tap(c => c.Marked(btn4Id));
+ var textLabel = App.Query((arg) => arg.Marked("label_id"))[0];
+ Assert.False(textLabel.Text == "tb4");
+#if __MACOS__
+ App.Tap(c => c.Button().Index(6));
+#else
+ App.Tap(c => c.Marked("tb3"));
+#endif
+ App.Tap(c => c.Marked(btn4Id));
+ textLabel = App.Query((arg) => arg.Marked("label_id"))[0];
+ Assert.IsTrue(textLabel.Text == "tb4");
+#if __MACOS__
+ App.Tap(c => c.Button().Index(6));
+#else
+ App.Tap(c => c.Marked("tb3"));
+#endif
+#endif
+ }
+
+ [Test]
+ public void ToolbarButtonsDisable()
+ {
+ ShouldHideMenu();
+#if __MACOS__
+ var result = App.Query(c => c.Button());
+ var btn1 = result[4];
+ var btn2 = App.Query(c => c.Marked(btn4Id))[0];
+ Assert.False(btn2.Enabled, "Toolbar Item should be disable");
+#else
+ var btn1 = App.Query(c => c.Marked(btn1Id))[0];
+ ShouldShowMenu();
+ //var btn2 = App.Query (c => c.Marked (btn4Id)) [0];
+ //TODO: how to check Enable for the textview
+ //Assert.False (btn2.Enabled, "Toolbar Item should be disable");
+#endif
+ Assert.False(btn1.Enabled, "Toolbar Item should be disable");
+ }
+
+ [Test]
+ public void ToolbarButtonsExist()
+ {
+ ShouldHideMenu();
+#if __MACOS__
+ var existsPrimary = App.Query(c => c.Button())[4];
+ Assert.True(existsPrimary != null, "Toolbar Item 1 no name, not found");
+#else
+ var existsPrimary = App.Query(c => c.Marked(btn1Id)).Length;
+ Assert.True(existsPrimary > 0, "Toolbar Item 1 no name, not found");
+#endif
+ var existsPrimary2 = App.Query(c => c.Marked("tb2")).Length;
+ Assert.True(existsPrimary2 > 0, "Toolbar Item 2, not found");
+ ShouldShowMenu();
+
+#if __MACOS__
+ var existsSecondary = App.Query(c => c.Button())[7];
+ Assert.True(existsSecondary != null, "Toolbar Item 3 no name, not found");
+#else
+ var existsSecondary = App.Query(c => c.Marked("tb3")).Length;
+ Assert.True(existsSecondary > 0, "Toolbar Item 1 no name, not found");
+#endif
+ var existsSecondary2 = App.Query(c => c.Marked(btn4Id)).Length;
+ Assert.True(existsSecondary2 > 0, "Toolbar Item 4, not found");
+ }
+
+ [Test]
+ public void ToolbarButtonsOrder()
+ {
+ ShouldHideMenu();
+#if __MACOS__
+ var btn1 = App.Query(c => c.Button())[4];
+#else
+ var btn1 = App.Query(c => c.Marked(btn1Id))[0];
+#endif
+ ShouldShowMenu();
+ var btn2 = App.Query(c => c.Marked("tb4"))[0];
+#if __IOS__
+ Assert.True(btn1.Rect.CenterY < btn2.Rect.CenterY);
+#elif __MACOS__
+ Assert.True(btn1.Rect.CenterX < btn2.Rect.CenterX);
+#endif
+ }
+
+ }
+}
+
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/ViewUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/ViewUITests.cs
new file mode 100644
index 00000000..9029f2aa
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/ViewUITests.cs
@@ -0,0 +1,247 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Net.Configuration;
+
+using NUnit.Framework;
+
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.UITest.Android;
+using Xamarin.UITest.iOS;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [Category("ViewBaseTests")]
+ internal abstract class _ViewUITests : BaseTestFixture
+ {
+ /* Under score prefixes ensure inherited properties run first in test suite */
+ //[Test]
+ //[Category ("View")]
+ //[UiTestBroken (BrokenReason.UITestBug, "Issue #115 - when trying to get anchorPoint, iOS")]
+ //[UiTest (Test.VisualElement.AnchorX)]
+ public virtual void _AnchorX ()
+ {
+
+ }
+
+ // [Test]
+ // [UiTest (Test.VisualElement.AnchorY)]
+ // TODO: working on some views, others not
+ public virtual void _AnchorY ()
+ {
+
+ }
+
+ // [Test]
+ // [UiTest (Test.VisualElement.BackgroundColor)]
+ // [UiTestBroken (BrokenReason.UITestBug, "UITest Issue #107")]
+ public virtual void _BackgroundColor ()
+ {
+ //TODO: this was failing and is changing in next version of calabash (UI-Test-pre nuget) to a json rgb
+// var remote = RemoteFactory.CreateRemote<ViewContainerRemote> (App, "BackgroundColor", PlatformViewType);
+// remote.GoTo ();
+// if (App is iOSApp) {
+// var backgroundColor = remote.GetProperty<Color> (View.BackgroundColorProperty);
+// Assert.AreEqual (Color.Blue, backgroundColor);
+// }
+
+ }
+
+ [Test]
+ [UiTest (typeof(VisualElement), "Focus")]
+ public abstract void _Focus ();
+
+ [Test]
+ [UiTest (typeof (VisualElement), "GestureRecognizers")]
+ public abstract void _GestureRecognizers ();
+
+ //[Test]
+ [UiTest (typeof (VisualElement), "InputTransparent")]
+ public virtual void _InputTransparent ()
+ {
+ //var remote = new LayeredViewContainerRemote (App, Test.VisualElement.InputTransparent, PlatformViewType);
+ //remote.GoTo ();
+
+ //var hiddenButtonClickedLabelTextPre = remote.GetLayeredLabel ().Text;
+ //Assert.AreEqual ("Hidden Button (Not Clicked)", hiddenButtonClickedLabelTextPre);
+
+ //remote.TapHiddenButton ();
+
+ //var hiddenButtonClickedLabelTextPost = remote.GetLayeredLabel ().Text;
+ //var hiddenButtonClicked = hiddenButtonClickedLabelTextPost == "Hidden Button (Clicked)";
+
+ //// Allow tests to continue by dismissing DatePicker that should not show
+ //// Remove when InputTransparency works
+ //if (!hiddenButtonClicked && PlatformViewType == PlatformViews.DatePicker)
+ // remote.DismissPopOver ();
+
+ //Assert.True (hiddenButtonClicked);
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "IsEnabled")]
+ public virtual void _IsEnabled ()
+ {
+ //var propName = Test.VisualElement.IsEnabled.ToString ();
+ var remote = new StateViewContainerRemote (App, Test.VisualElement.IsEnabled, PlatformViewType);
+ remote.GoTo ();
+
+ var enabled = remote.GetProperty<bool> (View.IsEnabledProperty);
+ Assert.IsTrue (enabled);
+
+ remote.TapStateButton ();
+
+ enabled = remote.GetProperty<bool> (View.IsEnabledProperty);
+ Assert.IsFalse (enabled);
+
+ remote.TapStateButton ();
+
+ var isEnabled = remote.GetStateLabel ().Text;
+ Assert.AreEqual ("True", isEnabled);
+
+ remote.TapStateButton ();
+
+ var isDisabled = remote.GetStateLabel ().Text;
+ Assert.AreEqual ("False", isDisabled);
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "IsFocused")]
+ public abstract void _IsFocused ();
+
+ [Test]
+ [UiTest (typeof (VisualElement), "IsVisible")]
+ public virtual void _IsVisible ()
+ {
+ var remote = new StateViewContainerRemote (App, Test.VisualElement.IsVisible, PlatformViewType);
+ remote.GoTo ();
+
+ var viewPre = remote.GetViews ();
+
+#if __MACOS__
+ Assert.GreaterOrEqual(viewPre.Length, 1);
+#else
+ Assert.AreEqual (1, viewPre.Length);
+#endif
+
+ remote.TapStateButton ();
+
+ var viewPost = remote.GetViews ();
+
+ Assert.AreEqual (0, viewPost.Length);
+ }
+
+ [UiTestExemptAttribute (ExemptReason.None, "Not sure how to test at the moment")]
+ public virtual void _Layout (){}
+
+ [UiTestExemptAttribute (ExemptReason.None, "Not sure how to test at the moment")]
+ public virtual void _Navigation () {}
+
+ [Test]
+ [UiTest (typeof (VisualElement), "Opacity")]
+ public virtual void _Opacity ()
+ {
+ var remote = new ViewContainerRemote(App, Test.VisualElement.Opacity, PlatformViewType);
+ remote.GoTo();
+#if __MACOS__
+ Assert.Inconclusive("needs testing");
+#else
+ float opacity = -1f;
+ opacity = remote.GetProperty<float> (View.OpacityProperty);
+ Assert.AreEqual (0.5f, opacity);
+#endif
+ }
+
+ [Test]
+ [UiTest (typeof(VisualElement), "Rotation")]
+ [UiTestBroken (BrokenReason.CalabashBug, "Calabash bug")]
+ public virtual void _Rotation ()
+ {
+ var remote = new ViewContainerRemote (App, Test.VisualElement.Rotation, PlatformViewType);
+ remote.GoTo ();
+
+#if __ANDROID__
+ var rotation = remote.GetProperty<float> (View.RotationProperty);
+ Assert.AreEqual (10.0f, rotation);
+#endif
+#if __IOS__
+ var rotationMatrix = remote.GetProperty<Matrix> (View.RotationProperty);
+ Matrix generatedMatrix = NumericExtensions.CalculateRotationMatrixForDegrees (10, Axis.Z);
+ Assert.AreEqual (generatedMatrix, rotationMatrix);
+#endif
+}
+
+ [Test]
+ [UiTest (typeof (VisualElement), "RotationX")]
+ public virtual void _RotationX ()
+ {
+ var remote = new ViewContainerRemote (App, Test.VisualElement.RotationX, PlatformViewType);
+ remote.GoTo ();
+
+#if __ANDROID__
+ var rotationX = remote.GetProperty<float> (View.RotationXProperty);
+ Assert.AreEqual (33.0f, rotationX);
+#endif
+#if __IOS__
+ var rotationXMatrix = remote.GetProperty<Matrix> (View.RotationXProperty);
+ Matrix matrix = NumericExtensions.CalculateRotationMatrixForDegrees (33.0f, Axis.X);
+ Assert.AreEqual (matrix, rotationXMatrix);
+#endif
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "RotationY")]
+ public virtual void _RotationY ()
+ {
+ var remote = new ViewContainerRemote (App, Test.VisualElement.RotationY, PlatformViewType);
+ remote.GoTo ();
+
+#if __ANDROID__
+ var rotationY = remote.GetProperty<float> (View.RotationYProperty);
+ Assert.AreEqual (10.0f, rotationY);
+#endif
+#if __IOS__
+ var rotationYMatrix = remote.GetProperty<Matrix> (View.RotationYProperty);
+ Matrix matrix = NumericExtensions.CalculateRotationMatrixForDegrees (10.0f, Axis.Y);
+ Assert.AreEqual (matrix, rotationYMatrix);
+#endif
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "Scale")]
+ public virtual void _Scale ()
+ {
+ var remote = new ViewContainerRemote(App, Test.VisualElement.Scale, PlatformViewType);
+ remote.GoTo();
+#if __MACOS__
+ Assert.Inconclusive("needs testing");
+#else
+ var scaleMatrix = remote.GetProperty<Matrix>(View.ScaleProperty);
+ Matrix generatedMatrix = NumericExtensions.BuildScaleMatrix(0.5f);
+ Assert.AreEqual(generatedMatrix, scaleMatrix);
+#endif
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "TranslationX")]
+ [Category(UITestCategories.ManualReview)]
+ public virtual void _TranslationX ()
+ {
+ var remote = new ViewContainerRemote (App, Test.VisualElement.TranslationX, PlatformViewType);
+ remote.GoTo ();
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "TranslationY")]
+ [Category(UITestCategories.ManualReview)]
+ public virtual void _TranslationY ()
+ {
+ var remote = new ViewContainerRemote (App, Test.VisualElement.TranslationY, PlatformViewType);
+ remote.GoTo ();
+ }
+
+ [Test]
+ [UiTest (typeof (VisualElement), "Unfocus")]
+ public abstract void _UnFocus ();
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Tests/WebViewUITests.cs b/Xamarin.Forms.Core.UITests.Shared/Tests/WebViewUITests.cs
new file mode 100644
index 00000000..08ff5146
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Tests/WebViewUITests.cs
@@ -0,0 +1,111 @@
+using NUnit.Framework;
+using Xamarin.Forms.CustomAttributes;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ [TestFixture]
+ [Category(UITestCategories.WebView)]
+ internal class WebViewUITests : _ViewUITests
+ {
+ public WebViewUITests()
+ {
+ PlatformViewType = Views.WebView;
+ }
+
+ protected override void NavigateToGallery()
+ {
+ App.NavigateToGallery(GalleryQueries.WebViewGallery);
+ }
+
+ [Category(UITestCategories.ManualReview)]
+ public override void _IsEnabled()
+ {
+ Assert.Inconclusive("Does not make sense for WebView");
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _IsVisible()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction with Label")]
+ public override void _Focus()
+ {
+ }
+
+ // TODO
+ public override void _GestureRecognizers()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction with Label")]
+ public override void _IsFocused()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _Opacity()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _Rotation()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _RotationX()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _RotationY()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _TranslationX()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _TranslationY()
+ {
+ }
+
+ [Test]
+ [Category(UITestCategories.ManualReview)]
+ [Ignore("Keep empty test from failing in Test Cloud")]
+ public override void _Scale()
+ {
+ }
+
+ [UiTestExempt(ExemptReason.CannotTest, "Invalid interaction with Label")]
+ public override void _UnFocus()
+ {
+ }
+
+ // TODO
+ // Implement control specific ui tests
+
+ protected override void FixtureTeardown()
+ {
+ App.NavigateBack();
+ base.FixtureTeardown();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs b/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs
new file mode 100644
index 00000000..28a6fff4
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs
@@ -0,0 +1,36 @@
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class UITestCategories
+ {
+ public const string ActionSheet = "ActionSheet";
+ public const string ActivityIndicator = "ActivityIndicator";
+ public const string AutomationId = "AutomationID";
+ public const string BoxView = "BoxView";
+ public const string Button = "Button";
+ public const string Cells = "Cells";
+ public const string DatePicker = "DatePicker";
+ public const string DisplayAlert = "DisplayAlert";
+ public const string Editor = "Editor";
+ public const string Entry = "Entry";
+ public const string Frame = "Frame";
+ public const string Image = "Image";
+ public const string Label = "Label";
+ public const string ListView = "ListView";
+ public const string LifeCycle = "Lifecycle";
+ public const string MasterDetailPage = "MasterDetailPage";
+ public const string Picker = "Picker";
+ public const string ProgressBar = "ProgressBar";
+ public const string RootGallery = "RootGallery";
+ public const string ScrollView = "ScrollView";
+ public const string SearchBar = "SearchBar";
+ public const string Slider = "Slider";
+ public const string Stepper = "Stepper";
+ public const string Switch = "Switch";
+ public const string TimePicker = "TimePicker";
+ public const string ToolbarItem = "ToolbarItem";
+ public const string WebView = "WebView";
+ public const string Maps = "Maps";
+
+ public const string ManualReview = "ManualReview";
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/AppExtensions.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/AppExtensions.cs
new file mode 100644
index 00000000..b5f52b9c
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/AppExtensions.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Linq;
+
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+using System.Text.RegularExpressions;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class AppExtensions
+ {
+ public static AppRect ScreenBounds (this IApp app)
+ {
+ return app.Query (Queries.Root ()).First().Rect;
+ }
+
+ public static void NavigateBack (this IApp app)
+ {
+ app.Tap (Queries.NavigationBarBackButton ());
+ }
+
+ public static void NavigateToGallery (this IApp app, string page)
+ {
+ const string goToTestButtonQuery = "* marked:'GoToTestButton'";
+
+ var text = Regex.Match (page, "'(?<text>[^']*)'").Groups["text"].Value;
+ app.EnterText (q => q.Raw ("* marked:'SearchBar'"), text);
+
+ app.WaitForElement(q => q.Raw(goToTestButtonQuery), "Timed out waiting for Go To Test button to disappear", TimeSpan.FromSeconds(10));
+
+ app.Tap (q => q.Raw (goToTestButtonQuery));
+ app.WaitForNoElement (o => o.Raw (goToTestButtonQuery), "Timed out waiting for Go To Test button to disappear", TimeSpan.FromMinutes(2));
+ }
+ }
+}
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/Drag.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/Drag.cs
new file mode 100644
index 00000000..59f54819
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/Drag.cs
@@ -0,0 +1,171 @@
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal class Drag
+ {
+ internal enum DragLength
+ {
+ Long,
+ Medium,
+ Short
+ }
+
+ internal enum Direction
+ {
+ TopToBottom,
+ BottomToTop,
+ RightToLeft,
+ LeftToRight
+ }
+
+ AppRect dragBounds;
+ float xStart;
+ float yStart;
+ float xEnd;
+ float yEnd;
+ Direction dragDirection;
+ Direction oppositeDirection;
+ DragLength dragLength;
+
+ public Drag (AppRect dragbounds, float xStart, float yStart, float xEnd, float yEnd, Direction direction)
+ {
+ dragBounds = dragbounds;
+ this.xStart = xStart;
+ this.yStart = yStart;
+ this.xEnd = xEnd;
+ this.yEnd = yEnd;
+ dragDirection = direction;
+ oppositeDirection = GetOppositeDirection (direction);
+ }
+
+ public Drag (AppRect dragBounds, Direction direction, DragLength dragLength)
+ {
+ this.dragBounds = dragBounds;
+ dragDirection = direction;
+ this.dragLength = dragLength;
+ SetDragForBounds (dragDirection, dragLength);
+ }
+
+ void SetDragForBounds (Direction direction, DragLength dragLength)
+ {
+ // percentage of bounds to scroll centered in element
+ float scrollPercentage;
+
+ switch (dragLength) {
+ case DragLength.Long:
+ scrollPercentage = 0.8f;
+ break;
+ case DragLength.Medium:
+ scrollPercentage = 0.5f;
+ break;
+ default:
+ scrollPercentage = 0.2f;
+ break;
+ }
+
+ if (direction == Direction.LeftToRight) {
+ yStart = dragBounds.CenterY;
+ yEnd = dragBounds.CenterY;
+ float xDisplacement = (dragBounds.CenterX + (dragBounds.Width / 2)) - dragBounds.X;
+ float insetForScroll = (xDisplacement - (xDisplacement * scrollPercentage)) / 2;
+ xStart = dragBounds.X + insetForScroll;
+ xEnd = (dragBounds.CenterX + (dragBounds.Width / 2)) - insetForScroll;
+ } else if (direction == Direction.RightToLeft) {
+ yStart = dragBounds.CenterY;
+ yEnd = dragBounds.CenterY;
+ float xDisplacement = (dragBounds.CenterX + (dragBounds.Width / 2)) - dragBounds.X;
+ float insetForScroll = (xDisplacement - (xDisplacement * scrollPercentage)) / 2;
+ xStart = (dragBounds.CenterX + (dragBounds.Width / 2)) - insetForScroll;
+ xEnd = dragBounds.X + insetForScroll;
+ } else if (direction == Direction.TopToBottom) {
+ xStart = dragBounds.CenterX;
+ xEnd = dragBounds.CenterX;
+ float yDisplacement = (dragBounds.CenterY + (dragBounds.Height / 2)) - dragBounds.Y;
+ float insetForScroll = (yDisplacement - (yDisplacement * scrollPercentage)) / 2;
+ yStart = dragBounds.Y + insetForScroll;
+ yEnd = (dragBounds.CenterY + (dragBounds.Height / 2)) - insetForScroll;
+ } else if (direction == Direction.BottomToTop) {
+ xStart = dragBounds.CenterX;
+ xEnd = dragBounds.CenterX;
+ float yDisplacement = (dragBounds.CenterY + (dragBounds.Height / 2)) - dragBounds.Y;
+ float insetForScroll = (yDisplacement - (yDisplacement * scrollPercentage)) / 2;
+ yStart = (dragBounds.CenterY + (dragBounds.Height / 2)) - insetForScroll;
+ yEnd = dragBounds.Y + insetForScroll;
+
+ }
+ }
+
+ Direction GetOppositeDirection (Direction direction)
+ {
+ switch (direction) {
+ case Direction.TopToBottom:
+ return Direction.BottomToTop;
+ case Direction.BottomToTop:
+ return Direction.TopToBottom;
+ case Direction.RightToLeft:
+ return Direction.LeftToRight;
+ case Direction.LeftToRight:
+ return Direction.RightToLeft;
+ default:
+ return Direction.TopToBottom;
+ }
+ }
+
+ public AppRect DragBounds
+ {
+ get { return dragBounds; }
+ }
+
+ public float XStart
+ {
+ get { return xStart; }
+ }
+
+ public float YStart
+ {
+ get { return yStart; }
+ }
+
+ public float XEnd
+ {
+ get { return xEnd; }
+ }
+
+ public float YEnd
+ {
+ get { return yEnd; }
+ }
+
+ public Direction DragDirection
+ {
+ get { return dragDirection; }
+ set
+ {
+ if (dragDirection == value)
+ return;
+
+ dragDirection = value;
+ oppositeDirection = GetOppositeDirection (dragDirection);
+ OnDragDirectionChanged ();
+ }
+ }
+
+ void OnDragDirectionChanged ()
+ {
+ SetDragForBounds (dragDirection, dragLength);
+ }
+
+ public Direction OppositeDirection
+ {
+ get { return oppositeDirection; }
+ private set
+ {
+ if (oppositeDirection == value)
+ return;
+
+ oppositeDirection = value;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/Gestures.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/Gestures.cs
new file mode 100644
index 00000000..f998267b
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/Gestures.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Linq;
+using Xamarin.UITest;
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class Gestures
+ {
+ public static bool ScrollForElement (this IApp app, string query, Drag drag, int maxSteps = 25)
+ {
+ int count = 0;
+
+ int centerTolerance = 50;
+
+ Func<AppQuery, AppQuery> elementQuery = q => q.Raw (query);
+
+ // Visible elements
+ if (app.Query (elementQuery).Length > 1) {
+ throw new UITestQueryMultipleResultsException (query);
+ }
+
+ // check to see if the element is visible already
+ if (app.Query (elementQuery).Length == 1) {
+ // centering an element whos CenterX is close to the bounding rectangle's center X can sometime register the swipe as a tap
+ float elementDistanceToDragCenter = Math.Abs (app.Query (elementQuery).First ().Rect.CenterY - drag.DragBounds.CenterY);
+ if (elementDistanceToDragCenter > centerTolerance)
+ app.CenterElementInView (elementQuery, drag.DragBounds, drag.DragDirection);
+ return true;
+ }
+
+ // loop until element is seen
+ while (app.Query (elementQuery).Length == 0 && count < maxSteps) {
+ app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
+ count++;
+ }
+
+ if (count != maxSteps) {
+ // centering an element whos CenterX is close to the bounding rectangle's center X can sometime register the swipe as a tap
+ float elementDistanceToDragCenter = Math.Abs (app.Query (elementQuery).First ().Rect.CenterY - drag.DragBounds.CenterY);
+ if (elementDistanceToDragCenter > centerTolerance)
+ app.CenterElementInView (elementQuery, drag.DragBounds, drag.DragDirection);
+ return true;
+ }
+
+ count = 0;
+ drag.DragDirection = drag.OppositeDirection;
+
+ while (app.Query (elementQuery).Length == 0 && count < maxSteps) {
+ app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
+ count++;
+ }
+
+ if (count != maxSteps) {
+ app.CenterElementInView (elementQuery, drag.DragBounds, drag.DragDirection);
+ return true;
+ }
+
+ return false;
+ }
+
+ static void CenterElementInView (this IApp app, Func<AppQuery, AppQuery> element, AppRect containingView, Drag.Direction direction)
+ {
+ // TODO Implement horizontal centering
+
+ if (direction == Drag.Direction.BottomToTop || direction == Drag.Direction.TopToBottom) {
+
+ var elementBounds = app.Query (element).First ().Rect;
+
+ bool elementCenterBelowContainerCenter = elementBounds.CenterY > containingView.CenterY;
+ bool elementCenterAboveContainerCenter = elementBounds.CenterY < containingView.CenterY;
+
+ var displacementToCenter = Math.Abs (elementBounds.CenterY - containingView.CenterY) / 2;
+
+ // avoid drag as touch
+ if (displacementToCenter < 50)
+ return;
+
+ if (elementCenterBelowContainerCenter) {
+
+ var drag = new Drag (
+ containingView,
+ containingView.CenterX, containingView.CenterY + displacementToCenter,
+ containingView.CenterX, containingView.CenterY - displacementToCenter,
+ Drag.Direction.BottomToTop
+ );
+
+ app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
+
+ } else if (elementCenterAboveContainerCenter) {
+
+ var drag = new Drag (
+ containingView,
+ containingView.CenterX, containingView.CenterY - displacementToCenter,
+ containingView.CenterX, containingView.CenterY + displacementToCenter,
+ Drag.Direction.TopToBottom
+ );
+
+ app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
+ }
+ }
+ }
+
+ public static void Pan (this IApp app, Drag drag)
+ {
+ app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/Logger.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/Logger.cs
new file mode 100644
index 00000000..fe5e5d77
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/Logger.cs
@@ -0,0 +1,69 @@
+using System.IO;
+
+using Xamarin.UITest.Queries;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class Logger
+ {
+ static StreamWriter queryWriter;
+
+ public static void Init ()
+ {
+ queryWriter = new StreamWriter ("../../Xamarin.Forms.Core-UITest-queries.log", false);
+ }
+
+ public static void Log (string text)
+ {
+ queryWriter.Write (text);
+ }
+
+ public static void LogLine (string text = "")
+ {
+ queryWriter.WriteLine (text);
+ }
+
+ public static void Close ()
+ {
+ queryWriter.Flush ();
+ queryWriter.Close ();
+ }
+
+ public static void LogQueryResult (AppResult[] resultsForQuery)
+ {
+ foreach (AppResult result in resultsForQuery)
+ WriteAppResult (result);
+ }
+
+ static void WriteAppResult (AppResult appResult)
+ {
+ var classText = string.Format (" {0, -10} : {1}", "Class", appResult.Class);
+ var descriptionText = string.Format (" {0, -10} : {1}", "Description", appResult.Description);
+ var enabledText = string.Format (" {0, -10} : {1}", "Enabled", appResult.Enabled);
+ var idText = string.Format (" {0, -10} : {1}", "Id", appResult.Id);
+ var labelText = string.Format (" {0, -10} : {1}", "Label", appResult.Id);
+ var textText = string.Format (" {0, -10} : {1}", "Text", appResult.Text);
+
+ var rectText = string.Format (" {0, -10}", "Rect");
+ var rectContentsText = string.Format (" [X:{0} Y:{1} W:{2} H:{3}] [CX:{4} CY:{5}]",
+ appResult.Rect.X,
+ appResult.Rect.Y,
+ appResult.Rect.Width,
+ appResult.Rect.Height,
+ appResult.Rect.CenterX,
+ appResult.Rect.CenterY
+ );
+
+ queryWriter.WriteLine (classText);
+ queryWriter.WriteLine (descriptionText);
+ queryWriter.WriteLine (enabledText);
+ queryWriter.WriteLine (idText);
+ queryWriter.WriteLine (labelText);
+ queryWriter.WriteLine (textText);
+ queryWriter.WriteLine (rectText);
+ queryWriter.WriteLine (rectContentsText);
+ queryWriter.WriteLine();
+ }
+
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/NumericExtensions.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/NumericExtensions.cs
new file mode 100644
index 00000000..353856d1
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/NumericExtensions.cs
@@ -0,0 +1,114 @@
+using System;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal class Matrix : Object
+ {
+ public double M00, M01, M02, M03;
+ public double M10, M11, M12, M13;
+ public double M20, M21, M22, M23;
+ public double M30, M31, M32, M33;
+
+ public void Log () {
+
+ //Logger.LogLine ();
+
+ //Logger.LogLine (string.Format ("{0,-3}, {1,-3}, {2,-3}, {3,-3}", M00, M01, M02, M03));
+ //Logger.LogLine (string.Format ("{0,-3}, {1,-3}, {2,-3}, {3,-3}", M10, M11, M12, M13));
+ //Logger.LogLine (string.Format ("{0,-3}, {1,-3}, {2,-3}, {3,-3}", M20, M21, M22, M23));
+ //Logger.LogLine (string.Format ("{0,-3}, {1,-3}, {2,-3}, {3,-3}", M30, M31, M32, M33));
+
+ //Logger.LogLine ();
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj == null)
+ return false;
+
+ var transform = obj as Matrix;
+ if ((Object)transform == null)
+ return false;
+
+ const double tolerance = 0.01;
+ bool result =
+ Math.Abs (M00 - transform.M00) < tolerance &&
+ Math.Abs (M01 - transform.M01) < tolerance &&
+ Math.Abs (M02 - transform.M02) < tolerance &&
+ Math.Abs (M03 - transform.M03) < tolerance &&
+ Math.Abs (M10 - transform.M10) < tolerance &&
+ Math.Abs (M11 - transform.M11) < tolerance &&
+ Math.Abs (M12 - transform.M12) < tolerance &&
+ Math.Abs (M13 - transform.M13) < tolerance &&
+ Math.Abs (M20 - transform.M20) < tolerance &&
+ Math.Abs (M21 - transform.M21) < tolerance &&
+ Math.Abs (M22 - transform.M22) < tolerance &&
+ Math.Abs (M23 - transform.M23) < tolerance &&
+ Math.Abs (M30 - transform.M30) < tolerance &&
+ Math.Abs (M31 - transform.M31) < tolerance &&
+ Math.Abs (M32 - transform.M32) < tolerance &&
+ Math.Abs (M33 - transform.M33) < tolerance;
+
+ return result;
+ }
+
+ public override int GetHashCode ()
+ {
+ return 0;
+ }
+ }
+
+ internal enum Axis
+ {
+ X,
+ Y,
+ Z
+ }
+
+ internal static class NumericExtensions
+ {
+ public static double ToRadians(this float val)
+ {
+ return (Math.PI / 180.0) * val;
+ }
+
+ public static Matrix CalculateRotationMatrixForDegrees (float degrees, Axis rotationAxis)
+ {
+ var angle = degrees.ToRadians ();
+
+ var transform = new Matrix ();
+ if (rotationAxis == Axis.X) {
+ transform.M00 = 1; transform.M01 = 0; transform.M02 = 0; transform.M03 = 0;
+ transform.M10 = 0; transform.M11 = (float) Math.Cos (angle); transform.M12 = (float) Math.Sin (angle); transform.M13 = 0;
+ transform.M20 = 0; transform.M21 = -(float) Math.Sin (angle); transform.M22 = (float) Math.Cos (angle); transform.M23 = 0;
+ transform.M30 = 0; transform.M31 = 0; transform.M32 = 0; transform.M33 = 1;
+ } else if (rotationAxis == Axis.Y) {
+ transform.M00 = (float) Math.Cos (angle); transform.M01 = 0; transform.M02 = -(float) Math.Sin (angle); transform.M03 = 0;
+ transform.M10 = 0; transform.M11 = 1; transform.M12 = 0; transform.M13 = 0;
+ transform.M20 = (float) Math.Sin (angle); transform.M21 = 0; transform.M22 = (float) Math.Cos (angle); transform.M23 = 0;
+ transform.M30 = 0; transform.M31 = 0; transform.M32 = 0; transform.M33 = 1;
+ } else {
+ transform.M00 = (float) Math.Cos (angle); transform.M01 = (float) Math.Sin (angle); transform.M02 = 0; transform.M03 = 0;
+ transform.M10 = -(float) Math.Sin (angle); transform.M11 = (float) Math.Cos (angle); transform.M12 = 0; transform.M13 = 0;
+ transform.M20 = 0; transform.M21 = 0; transform.M22 = 1; transform.M23 = 0;
+ transform.M30 = 0; transform.M31 = 0; transform.M32 = 0; transform.M33 = 1;
+ }
+
+ return transform;
+ }
+
+ public static Matrix BuildScaleMatrix (float scale)
+ {
+ var transform = new Matrix ();
+
+ transform.M00 = scale; transform.M01 = 0; transform.M02 = 0; transform.M03 = 0;
+ transform.M10 = 0; transform.M11 = scale; transform.M12 = 0; transform.M13 = 0;
+ transform.M20 = 0; transform.M21 = 0; transform.M22 = scale; transform.M23 = 0;
+ transform.M30 = 0; transform.M31 = 0; transform.M32 = 0; transform.M33 = 1;
+
+ return transform;
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/ParsingUtils.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/ParsingUtils.cs
new file mode 100644
index 00000000..95568fd8
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/ParsingUtils.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+namespace Xamarin.Forms.Core.UITests
+{
+
+ internal static class ParsingUtils
+ {
+ public static Font ParseUIFont (string font)
+ {
+ FontAttributes fontAttrs = FontAttributes.None;
+
+ // Logger.LogLine ("TEST PARSING");
+
+ if (font.Contains ("font-weight: bold;")) {
+ // Logger.LogLine ("Found Bold");
+ fontAttrs = FontAttributes.Bold;
+ }
+
+ return new Font ().WithAttributes (fontAttrs);
+ }
+
+ public static Color ParseUIColor (string backgroundColor)
+ {
+ var delimiters = new char[] { ' ' };
+ string[] words = backgroundColor.Split (delimiters, StringSplitOptions.RemoveEmptyEntries);
+ return new Color (double.Parse (words[1]), double.Parse (words[2]), double.Parse (words[3]), double.Parse (words[4]));
+ }
+
+ public static Point ParseCGPoint (object CGPoint) {
+ var point = new Point { X = 0, Y = 0 };
+ return point;
+ }
+
+ public static Matrix ParseCATransform3D (string CATransform3D)
+ {
+ // Logger.Log (CATransform3D);
+ char[] delimiters = { '<', ' ', '>' };
+ string[] words = CATransform3D.Split (delimiters, StringSplitOptions.RemoveEmptyEntries);
+
+ List<double> numbers = new List<double> ();
+
+ // Each number is represented by 2 blocks returned by server
+ for (int i = 0; i < (words.Length - 1); i += 2) {
+ string word = words[i] + words[i + 1];
+ var number = Int64.Parse (word, NumberStyles.HexNumber);
+ byte[] bytes = BitConverter.GetBytes (number);
+ byte[] reversedBytes = bytes.Reverse ().ToArray ();
+ double value = BitConverter.ToDouble (reversedBytes, 0);
+ numbers.Add (value);
+ }
+
+ var transformationMatrix = new Matrix ();
+ transformationMatrix.M00 = numbers[0];
+ transformationMatrix.M01 = numbers[1];
+ transformationMatrix.M02 = numbers[2];
+ transformationMatrix.M03 = numbers[3];
+ transformationMatrix.M10 = numbers[4];
+ transformationMatrix.M11 = numbers[5];
+ transformationMatrix.M12 = numbers[6];
+ transformationMatrix.M13 = numbers[7];
+ transformationMatrix.M20 = numbers[8];
+ transformationMatrix.M21 = numbers[9];
+ transformationMatrix.M22 = numbers[10];
+ transformationMatrix.M23 = numbers[11];
+ transformationMatrix.M30 = numbers[12];
+ transformationMatrix.M31 = numbers[13];
+ transformationMatrix.M32 = numbers[14];
+ transformationMatrix.M33 = numbers[15];
+
+ return transformationMatrix;
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/UITestCustomExceptions.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/UITestCustomExceptions.cs
new file mode 100644
index 00000000..3d17a99c
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/UITestCustomExceptions.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal class UITestQueryNoResultException : Exception
+ {
+ readonly string message;
+
+ public UITestQueryNoResultException (string query)
+ {
+ message = string.Format ("Found no elements for query with target: {0}", query);
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+ }
+
+ internal class UITestQuerySingleResultException : Exception
+ {
+ readonly string message;
+
+ public UITestQuerySingleResultException (string query)
+ {
+ message = string.Format ("Found single element for query with target: {0}", query);
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+ }
+
+ internal class UITestQueryMultipleResultsException : Exception
+ {
+ readonly string message;
+
+ public UITestQueryMultipleResultsException (string query)
+ {
+ message = string.Format ("Found muliple elements for query with target: {0}", query);
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+ }
+
+ internal class UITestRemoteException : Exception
+ {
+ readonly string message;
+
+ public UITestRemoteException (string message)
+ {
+ this.message = message;
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+ }
+
+ internal class UITestRemoteQueryException : Exception
+ {
+ readonly string message;
+
+ public UITestRemoteQueryException (string query)
+ {
+ message = string.Format ("Error for query with target: {0}", query);
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+ }
+
+ internal class UITestErrorException : Exception
+ {
+ readonly string message;
+
+ public UITestErrorException (string message, [CallerMemberName] string caller = null)
+ {
+ message = string.Format ("Test error: {0}, {1}", caller, message);
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+ }
+}
diff --git a/Xamarin.Forms.Core.UITests.Shared/Utilities/ViewInspector.cs b/Xamarin.Forms.Core.UITests.Shared/Utilities/ViewInspector.cs
new file mode 100644
index 00000000..38f42da8
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Utilities/ViewInspector.cs
@@ -0,0 +1,344 @@
+using Xamarin.UITest;
+using System.Linq;
+
+namespace Xamarin.Forms.Core.UITests
+{
+ internal static class ViewInspector
+ {
+ public static void LogPropertiesForView (this IApp app, string query, bool isOnParent = false)
+ {
+#if __ANDROID__
+ LogPropertiesForAndroidView (app, query, isOnParent);
+#endif
+#if __IOS__
+
+ LogPropertiesForUIView(app, query, isOnParent);
+ LogPropertiesForCALayer (app, query, isOnParent);
+#endif
+ }
+
+ static void LogPropertiesForUIView (this IApp app, string query, bool isOnParent = false) {
+
+ //Logger.LogLine ("--- UIView Properties ---");
+
+ var properties = new [] {
+ // just getters with no params, bools
+ "alpha",
+ "autoresizesSubviews",
+ "autoresizingMask",
+ "backgroundColor",
+ "bounds",
+ "center",
+ "clearsContextBeforeDrawing",
+ "clipsToBounds",
+ "contentMode",
+ "contentScaleFactor",
+ "exclusiveTouch",
+ "frame",
+ "gestureRecognizers",
+ "hidden",
+ "layer",
+ "motionEffects",
+ "multipleTouchEnabled",
+ "opaque",
+ "restorationIdentifier",
+ "subviews",
+ "superview",
+ "tag",
+ "tintAdjustmentMode",
+ "tintColor",
+ "transform",
+ "userInteractionEnabled",
+ "window"
+ };
+
+ if (isOnParent)
+ query = query + " parent * index:0";
+
+ foreach (var property in properties) {
+ object prop;
+ bool found =
+ MaybeGetProperty<string> (app, query, property, out prop) ||
+ MaybeGetProperty<int> (app, query, property, out prop) ||
+ MaybeGetProperty<float> (app, query, property, out prop) ||
+ MaybeGetProperty<bool> (app, query, property, out prop);
+
+ if (found)
+ continue;
+ // Logger.LogLine (string.Format ("{0,-30}: {1}", property, prop));
+ }
+
+ //Logger.LogLine();
+
+ }
+
+ static void LogPropertiesForCALayer(this IApp app, string query, bool isOnParent = false)
+ {
+ // Logger.LogLine ("--- UIView.Layer Properties ---");
+
+ var properties = new[] {
+ "actions",
+ "anchorPoint",
+ "anchorPointZ",
+ "backgroundColor",
+ "backgroundFilters",
+ "borderColor",
+ "borderWidth",
+ "bounds",
+ "compositingFilter",
+ "contents",
+ "contentsCenter",
+ "contentsGravity",
+ "contentsRect",
+ "contentsScale",
+ "cornerRadius",
+ "delegate",
+ "doubleSided",
+ "drawsAsynchronously",
+ "edgeAntialiasingMask",
+ "filters",
+ "frame",
+ "geometryFlipped",
+ "hidden",
+ "magnificationFilter",
+ "mask",
+ "masksToBounds",
+ "minificationFilter",
+ "minificationFilterBias",
+ "name",
+ "needsDisplayOnBoundsChange",
+ "opacity",
+ "opaque",
+ "position",
+ "rasterizationScale",
+ "shadowColor",
+ "shadowOffset",
+ "shadowOpacity",
+ "shadowPath",
+ "shadowRadius",
+ "shouldRasterize",
+ "style",
+ "sublayers",
+ "sublayerTransform",
+ "superlayer",
+ "transform",
+ "visibleRect",
+ "zPosition"
+ };
+
+ if (isOnParent)
+ query = query + " parent * index:0";
+
+ foreach (var property in properties)
+ {
+ object prop;
+ bool found =
+ MaybeGetLayerProperty<string>(app, query, property, out prop) ||
+ MaybeGetLayerProperty<int>(app, query, property, out prop) ||
+ MaybeGetLayerProperty<bool>(app, query, property, out prop);
+
+ if (found)
+ continue;
+ //if (found)
+ // Logger.LogLine(string.Format("{0,-30}: {1}", property, prop));
+ }
+
+ //Logger.LogLine();
+
+ }
+
+ static void LogPropertiesForAndroidView (this IApp app, string query, bool isOnParent = false)
+ {
+ // Logger.LogLine( "--- Android View Properties ---");
+
+ var properties = new [] {
+ // just getters with no params, bools
+ //"getAccessibilityLiveRegion",
+ //"getAccessibilbityNodeProvider",
+ //"getAlpha",
+ //"getAnimation",
+ //"getApplicationWindowToken",
+ //"getBackground",
+ //"getBaseline",
+ //"getBottom",
+ //"getCameraDistance",
+ //"getClipBounds",
+ //"getContentDescription",
+ //"getContext",
+ //"getDefaultSize",
+ //"getDisplay",
+ //"getDrawableState",
+ //"getDrawingCache",
+ //"getDrawingCacheBackgroundColor",
+ //"getDrawingRect",
+ //"getDrawingTime",
+ //"getFilterTouchesWhenObscurred",
+ //"getFitsSystemWindows",
+ //"getFocusables",
+ //"getHandler",
+ //"getHeight",
+ //"getHitRect",
+ //"getHorizontalFadingEdgeLength",
+ //"getId",
+ //"getImportantForAccessibility",
+ //"getKeepScreenOn",
+ //"getKeyDispatcherState",
+ //"getLabelFor",
+ //"getLayerType",
+ //"getLayoutDirection",
+ //"getLayourParams",
+ //"getLeft",
+ "getMatrix",
+ //"getMeasuredHeight",
+ //"getMeasuredHeightAndState",
+ //"getMeasuredState",
+ //"getMeasuredWidth",
+ //"getMeasuredWidthAndState",
+ //"getMinimumHeight",
+ //"getMinimumWidth",
+ //"getNextFocusDownId",
+ //"getNextFocusForwardId",
+ //"getNextFocusLeftId",
+ //"getNextFocusRightId",
+ //"getNextFocusUpId",
+ //"getOnFocusChangedListener",
+ //"getOverScrollMethod",
+ //"getOverlay",
+ //"getPaddingBottom",
+ //"getPaddingEnd",
+ //"getPaddingLeft",
+ //"getPaddingRight",
+ //"getPaddingStart",
+ //"getPaddingTop",
+ //"getParent",
+ //"getParentForAccessibility",
+ //"getPivotX",
+ //"getPivotY",
+ //"getResources",
+ //"getRight",
+ //"getRootView",
+ //"getRotation",
+ //"getRotationX",
+ //"getRotationY",
+ "getScaleX",
+ "getScaleY",
+ //"getScrollBarDefaultDelayBeforeFade",
+ //"getScrollBarFadeDuration",
+ //"getScrollBarSize",
+ //"getScrollBarStyle",
+ //"getScrollX",
+ //"getScrollY",
+ //"getSolidColor",
+ //"getSystemUiVisibility",
+ //"getTag",
+ //"getTextAlignment",
+ //"getTextDirection",
+ //"getTop",
+ //"getTouchDelegate",
+ //"getTouchables",
+ //"getTranslationX",
+ //"getTranslationY",
+ //"getVerticalFadingEdgeLength",
+ //"getVerticalScrollbarPosition",
+ //"getVerticalScrollbarWidth",
+ //"getViewTreeObserver",
+ //"getVisibility",
+ //"getWidth",
+ //"getWindowId",
+ //"getWindowSystemUiVisbility",
+ //"getWindowToken",
+ //"getWindowVisibility",
+ //"getX",
+ //"getY",
+ //"hasFocus",
+ //"hasFocusable",
+ //"hasOnClickListener",
+ //"hasOverlappingRendering",
+ //"hasTransientState",
+ //"hasWindowFocus",
+ //"isActivated",
+ //"isAttachedToWindow",
+ //"isClickable",
+ //"isDirty",
+ //"isDrawingCacheEnabled",
+ //"isDuplicateParentStateEnabled",
+ //"isEnabled",
+ //"isFocusable",
+ //"isFocusableInTouchWindow",
+ //"isFocused",
+ //"isHapticFeedbackEnabled",
+ //"isHardwareAccelerated",
+ //"isHorizontalFadingEdgeEnabled",
+ //"isHovered",
+ //"idInEditMode",
+ //"isInLayout",
+ //"isInTouchMode",
+ //"isLaidOut",
+ //"isLayoutDirectionResolved",
+ //"isLayoutRequested",
+ //"isLongClickable",
+ //"isOpaque",
+ //"isPaddingRelative",
+ //"isPressed",
+ //"isSaveEnabled",
+ //"isSaveFromParentEnabled",
+ //"isScrollContainer",
+ //"isScrollBarFadingEnabled",
+ //"isSelected",
+ //"isShown",
+ //"isSoundEffectsEnabled",
+ //"isTextAlignmentResolved",
+ //"isTextDirectionResolved",
+ //"isVerticalFadingEdgeEnabled",
+ //"isVerticalScrollBarEnabled"
+ };
+
+ if (isOnParent)
+ query = query + " parent * index:0";
+
+ foreach (var property in properties) {
+ object prop;
+ bool found =
+ MaybeGetProperty<string> (app, query, property, out prop) ||
+ //MaybeGetProperty<int> (app, query, property, out prop) ||
+ MaybeGetProperty<float> (app, query, property, out prop) ||
+ MaybeGetProperty<bool> (app, query, property, out prop);
+
+ if (found)
+ continue;
+ //if (found)
+ // Logger.LogLine (string.Format ("{0,-30}: {1}", property, prop));
+ }
+
+ //Logger.LogLine();
+
+ }
+
+ static bool MaybeGetLayerProperty<T> (IApp app, string query, string property, out object result)
+ {
+
+ try {
+ result = app.Query (q => q.Raw (query).Invoke ("layer").Invoke (property).Value<T> ()).First ();
+ } catch {
+ result = null;
+ return false;
+ }
+
+ return true;
+ }
+
+ static bool MaybeGetProperty<T> (IApp app, string query, string property, out object result)
+ {
+
+ try {
+ result = app.Query (q => q.Raw (query).Invoke (property).Value<T> ()).First ();
+ } catch {
+ result = null;
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
+
diff --git a/Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.Shared.shproj b/Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.Shared.shproj
new file mode 100644
index 00000000..891616fc
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.Shared.shproj
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>e175485b-3c8c-47d7-8dd5-f7fed627eb25</ProjectGuid>
+ <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
+ <PropertyGroup />
+ <Import Project="Xamarin.Forms.Core.UITests.projitems" Label="Shared" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
+</Project>
diff --git a/Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.projitems b/Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.projitems
new file mode 100644
index 00000000..4168b071
--- /dev/null
+++ b/Xamarin.Forms.Core.UITests.Shared/Xamarin.Forms.Core.UITests.projitems
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <SharedGUID>e175485b-3c8c-47d7-8dd5-f7fed627eb25</SharedGUID>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <Import_RootNamespace>Xamarin.Forms.Core.UITests.Shared</Import_RootNamespace>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)BaseTestFixture.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)PlatformQueries.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Queries.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Remotes\BaseViewContainerRemote.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Remotes\EventViewContainerRemote.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Remotes\LayeredViewContainerRemote.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Remotes\StateViewContainerRemote.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Remotes\ViewContainerRemote.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ActionSheetUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ActivityIndicatorUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\AppearingUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\AutomationIDUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\BoxViewUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ButtonUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ContextActionsUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\DatePickerUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\DisplayAlertUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\EditorUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\EntryUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\FrameUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ImageUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\LabelUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\Legacy-CellsUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\Legacy-UnevenListTests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\PickerUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ProgressBarUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\RootGalleryUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ScrollViewUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\SearchBarUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\SliderUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\StepperUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\SwitchUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\TimePickerUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ToolbarItemTests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\ViewUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Tests\WebViewUITests.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)UITestCategories.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\AppExtensions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\Drag.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\Gestures.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\Logger.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\NumericExtensions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\ParsingUtils.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\UITestCustomExceptions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Utilities\ViewInspector.cs" />
+ </ItemGroup>
+</Project> \ No newline at end of file