diff options
author | Rui Marinho <me@ruimarinho.net> | 2017-03-23 11:03:48 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-23 11:03:48 +0000 |
commit | 2be80a55a514a050ab5ab07a201d13c111f49f63 (patch) | |
tree | a9cc64903a830e4b754ae6eee3fcc2ebb3ba200d /Xamarin.Forms.Core.UITests.Shared | |
parent | 16fcac8cf52ab960e7354a52864b0a72aefdfc1f (diff) | |
download | xamarin-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')
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 |