Cherry pick Issue4597 fixes back to branch 4.0.0 (#6724)
authorShane Neuville <shane94@hotmail.com>
Mon, 1 Jul 2019 16:42:41 +0000 (10:42 -0600)
committerGitHub <noreply@github.com>
Mon, 1 Jul 2019 16:42:41 +0000 (10:42 -0600)
* Split up Issue4597 into separate testable chunks (#6654)

* split up tests

* fix tests for ios

* comment out tests for UWP for now

* - add delay for loading from uri
- rearrage components so switch is always visible

* add retry logic to url based tests so images can load

* fix automationid binding

* remove extra file

* fix tabs

Xamarin.Forms.ControlGallery.Android/Resources/drawable/xamarinlogo.png [new file with mode: 0644]
Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj
Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj
Xamarin.Forms.ControlGallery.WindowsUniversal/xamarinlogo.png [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue4597.cs
Xamarin.Forms.Core.UITests.Shared/Utilities/AppExtensions.cs
Xamarin.Forms.Platform.UAP/Resources.xaml

diff --git a/Xamarin.Forms.ControlGallery.Android/Resources/drawable/xamarinlogo.png b/Xamarin.Forms.ControlGallery.Android/Resources/drawable/xamarinlogo.png
new file mode 100644 (file)
index 0000000..a115e0f
Binary files /dev/null and b/Xamarin.Forms.ControlGallery.Android/Resources/drawable/xamarinlogo.png differ
index c8e1412..8c99715 100644 (file)
     <AndroidResource Include="Resources\drawable\newspaperflyout.png" />
     <AndroidResource Include="Resources\drawable\booksflyout.png" />
     <AndroidResource Include="Resources\drawable\homeflyout.png" />
+    <AndroidResource Include="Resources\drawable\xamarinlogo.png" />
   </ItemGroup>
   <ItemGroup>
     <AndroidResource Include="Resources\drawable\Icon.png" />
index dfd055d..572ac02 100644 (file)
       <DependentUpon>MainPage.xaml</DependentUpon>
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Content Include="xamarinlogo.png" />
   </ItemGroup>
   <ItemGroup>
     <AppxManifest Include="Package.appxmanifest">
diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/xamarinlogo.png b/Xamarin.Forms.ControlGallery.WindowsUniversal/xamarinlogo.png
new file mode 100644 (file)
index 0000000..a115e0f
Binary files /dev/null and b/Xamarin.Forms.ControlGallery.WindowsUniversal/xamarinlogo.png differ
index c2c0e1e..a3049eb 100644 (file)
@@ -5,6 +5,7 @@ using System.Text;
 using Xamarin.Forms.CustomAttributes;
 using Xamarin.Forms.Internals;
 using System.Linq;
+using System.Threading;
 
 #if UITEST
 using Xamarin.UITest;
@@ -29,24 +30,36 @@ namespace Xamarin.Forms.Controls.Issues
                Image _image;
                ListView _listView;
 
-               string _disappearText = "You should see 4 images. Clicking this should cause the images to all disappear";
-               string _appearText = "Clicking this should cause the images to all appear";
+               string _disappearText = "You should see an Image. Clicking this should cause the image to disappear";
+               string _appearText = "Clicking this should cause the image to reappear";
                string _theListView = "theListViewAutomationId";
-               string _fileName = "coffee.png";
-               string _uriImage = "https://raw.githubusercontent.com/xamarin/Xamarin.Forms/master/Xamarin.Forms.Controls/coffee.png";
+               string _fileName = "xamarinlogo.png";
+               string _fileNameAutomationId = "CoffeeAutomationId";
+               string _uriImage = "https://github.com/xamarin/Xamarin.Forms/blob/3216ce4ccd096f8b9f909bbeea572dcf2a8c4466/Xamarin.Forms.ControlGallery.iOS/Resources/xamarinlogo.png?raw=true";
                bool _isUri = false;
+               string _nextTestId = "NextTest";
+               string _activeTestId = "activeTestId";
+               string _switchUriId = "SwitchUri";
+               string _imageFromUri = "Image From Uri";
+               string _imageFromFile = "Image From File";
 
                protected override void Init()
                {
-                       _image = new Image() { Source = _fileName, AutomationId = _fileName, ClassId = "Something" };
-                       _button = new Button() { ImageSource = _fileName, AutomationId = _fileName };
-                       _imageButton = new ImageButton() { Source = _fileName, AutomationId = _fileName };
+                       Label labelActiveTest = new Label()
+                       {
+                               AutomationId = _activeTestId
+                       };
+
+                       _image = new Image() { Source = _fileName, AutomationId = _fileNameAutomationId };
+                       _button = new Button() { ImageSource = _fileName, AutomationId = _fileNameAutomationId };
+                       _imageButton = new ImageButton() { Source = _fileName, AutomationId = _fileNameAutomationId };
                        _listView = new ListView()
                        {
                                ItemTemplate = new DataTemplate(() =>
                                {
                                        var cell = new ImageCell();
                                        cell.SetBinding(ImageCell.ImageSourceProperty, ".");
+                                       cell.AutomationId = _fileNameAutomationId;
                                        return cell;
                                }),
                                AutomationId = _theListView,
@@ -55,6 +68,8 @@ namespace Xamarin.Forms.Controls.Issues
                                BackgroundColor = Color.Purple
                        };
 
+                       View[] imageControls = new View[] { _image, _button, _imageButton, _listView };
+
                        Button button = null;
                        button = new Button()
                        {
@@ -83,122 +98,215 @@ namespace Xamarin.Forms.Controls.Issues
 
                        var switchToUri = new Switch
                        {
-                               AutomationId = "SwitchUri",
-                               IsToggled = false
+                               AutomationId = _switchUriId,
+                               IsToggled = false,
+                               HeightRequest = 60
                        };
-                       switchToUri.Toggled += (_, e) => _isUri =       e.Value;
-                       var switchWithCaption = new Grid() { HeightRequest = 60 };
-                       switchWithCaption.AddChild(new Label { Text = "Image From Url" }, 0, 0);
-                       switchWithCaption.AddChild(switchToUri, 1, 0);
+                       var sourceLabel = new Label { Text = _imageFromFile };
+
+                       switchToUri.Toggled += (_, e) =>
+                       {
+                               _isUri = e.Value;
+
+                               // reset the images to visible
+                               button.Text = _appearText;
+                               button.SendClicked();
+
+                               if (_isUri)
+                                       sourceLabel.Text = _imageFromUri;
+                               else
+                                       sourceLabel.Text = _imageFromFile;
+                       };
+
+
+                       foreach(var view in imageControls)
+                       {
+                               view.BackgroundColor = Color.Red;
+                       }
 
-                       var layout = new StackLayout()
+                       StackLayout layout = null;
+                       layout = new StackLayout()
                        {
+                               AutomationId = "layoutContainer",
                                Children =
-                               {
+                               {                                       
+                                       new StackLayout()
+                                       {
+                                               Orientation = StackOrientation.Horizontal,
+                                               Children =
+                                               {
+                                                       labelActiveTest,
+                                                       switchToUri,
+                                                       sourceLabel                                             
+                                               }
+                                       },
                                        button,
-                                       switchWithCaption,
-                                       _image,
-                                       _button,
-                                       _imageButton,
-                                       _listView,
+                                       new Button()
+                                       {
+                                               Text = "Load Next Image Control to Test",
+                                               Command = new Command(() =>
+                                               {
+                                                       var activeImage = layout.Children.Last();
+                                                       int nextIndex = imageControls.IndexOf(activeImage) + 1;
+
+                                                       if(nextIndex >= imageControls.Length)
+                                                               nextIndex = 0;
+
+                                                       layout.Children.Remove(activeImage);
+                                                       layout.Children.Add(imageControls[nextIndex]);
+                                                       labelActiveTest.Text = imageControls[nextIndex].GetType().Name;
+
+                                                       // reset the images to visible
+                                                       button.Text = _appearText;
+                                                       button.SendClicked();
+                                               }),
+                                               AutomationId = _nextTestId
+                                       },
+                                       imageControls[0]
                                }
                        };
 
                        Content = layout;
+                       labelActiveTest.Text = imageControls[0].GetType().Name;
                }
 #if UITEST
+
+#if !__WINDOWS__
                [Test]
-               public void TestImagesDisappearCorrectly()
+               public void ImageFromFileSourceAppearsAndDisappearsCorrectly()
                {
-                       RunningApp.WaitForElement(_fileName);
-                       var elementsBefore = RunningApp.WaitForElement(_fileName);
-#if !__WINDOWS__
-                       var imageCell = RunningApp.Query(app => app.Marked(_theListView).Descendant()).Where(x => x.Class.Contains("Image")).FirstOrDefault();
-#endif
+                       RunTest(nameof(Image), false);
+               }
 
-#if __IOS__
-                       Assert.AreEqual(4, elementsBefore.Where(x => x.Class.Contains("Image")).Count());
-#elif __ANDROID__
-                       Assert.AreEqual(3, elementsBefore.Length);
-#else
-                       Assert.AreEqual(4, elementsBefore.Count());
-#endif
+               [Test]
+               public void ImageFromUriSourceAppearsAndDisappearsCorrectly()
+               {
+                       RunTest(nameof(Image), true);
+               }
 
 
-#if !__WINDOWS__
-                       Assert.IsNotNull(imageCell);
-#endif
+               [Test]
+               public void ButtonFromFileSourceAppearsAndDisappearsCorrectly()
+               {
+                       RunTest(nameof(Button), false);
+               }
 
-                       RunningApp.Tap("ClickMe");
-                       RunningApp.WaitForElement(_appearText);
-                       var elementsAfter = RunningApp.WaitForElement(_fileName);
+               [Test]
+               public void ButtonFromUriSourceAppearsAndDisappearsCorrectly()
+               {
+                       RunTest(nameof(Button), true);
+               }
 
-#if !__WINDOWS__
-                       var imageCellAfter = RunningApp.Query(app => app.Marked(_theListView).Descendant()).Where(x => x.Class.Contains("Image")).FirstOrDefault();
-                       Assert.IsNull(imageCellAfter);
-#endif
 
-#if __IOS__
-                       Assert.AreEqual(0, elementsAfter.Where(x => x.Class.Contains("Image")).Count());
-#elif __ANDROID__
-                       foreach (var newElement in elementsAfter)
+               [Test]
+               public void ImageButtonFromFileSourceAppearsAndDisappearsCorrectly()
+               {
+                       RunTest(nameof(ImageButton), false);
+               }
+
+               [Test]
+               public void ImageButtonFromUriSourceAppearsAndDisappearsCorrectly()
+               {
+                       RunTest(nameof(ImageButton), true);
+               }
+
+               [Test]
+               public void ImageCellFromFileSourceAppearsAndDisappearsCorrectly()
+               {
+                       ImageCellTest(true);
+               }
+
+               [Test]
+               public void ImageCellFromUriSourceAppearsAndDisappearsCorrectly()
+               {
+                       ImageCellTest(false);
+               }
+
+               void ImageCellTest(bool fileSource)
+               {
+                       string className = "ImageView";
+                       SetupTest(nameof(ListView), fileSource);
+
+                       var imageVisible =
+                               RunningApp.RetryUntilPresent(GetImage, 10, 2000);
+
+                       Assert.AreEqual(1, imageVisible.Length);
+                       SetImageSourceToNull();
+
+                       imageVisible = GetImage();
+
+                       UITest.Queries.AppResult[] GetImage()
                        {
-                               foreach(var oldElement in elementsBefore)
-                               {
-                                       if(newElement.Class == oldElement.Class)
-                                       {
-                                               Assert.IsTrue(newElement.Rect.Height < oldElement.Rect.Height);
-                                               continue;
-                                       }
-                               }
+                               return RunningApp
+                                       .Query(app => app.Marked(_theListView).Descendant())
+                                       .Where(x => x.Class != null && x.Class.Contains(className)).ToArray();
                        }
-#endif
-                       RunningApp.Tap("SwitchUri");
-                       RunningApp.Tap("ClickMe");
-                       RunningApp.WaitForElement(_disappearText);
-#if !__WINDOWS__
-                       imageCell = RunningApp.Query(app => app.Marked(_theListView).Descendant()).Where(x => x.Class.Contains("Image")).FirstOrDefault();
+               }
 #endif
 
-#if __IOS__
-                       Assert.AreEqual(4, elementsBefore.Where(x => x.Class.Contains("Image")).Count());
-#elif __ANDROID__
-                       Assert.AreEqual(3, elementsBefore.Length);
-#else
-                       Assert.AreEqual(4, elementsBefore.Count());
-#endif
+               void RunTest(string testName, bool fileSource)
+               {
+                       SetupTest(testName, fileSource);
+                       var foundImage = TestForImageVisible();
+                       SetImageSourceToNull();
+                       TestForImageNotVisible(foundImage);
+               }
 
 
-#if !__WINDOWS__
-                       Assert.IsNotNull(imageCell);
-#endif
+               void SetImageSourceToNull()
+               {
                        RunningApp.Tap("ClickMe");
                        RunningApp.WaitForElement(_appearText);
-                       elementsAfter = RunningApp.WaitForElement(_fileName);
-#if !__WINDOWS__
-                       imageCellAfter = RunningApp.Query(app => app.Marked(_theListView).Descendant()).Where(x => x.Class.Contains("Image")).FirstOrDefault();
-                       Assert.IsNull(imageCellAfter);
-#endif
+               }
 
-#if __IOS__
-                       Assert.AreEqual(0, elementsAfter.Where(x => x.Class.Contains("Image")).Count());
-#elif __ANDROID__
-                       foreach (var newElement in elementsAfter)
+               UITest.Queries.AppResult TestForImageVisible()
+               {
+                       var images = RunningApp.RetryUntilPresent(() =>
                        {
-                               foreach (var oldElement in elementsBefore)
-                               {
-                                       if (newElement.Class == oldElement.Class)
-                                       {
-                                               Assert.IsTrue(newElement.Rect.Height < oldElement.Rect.Height);
-                                               continue;
-                                       }
-                               }
+                               var result = RunningApp.WaitForElement(_fileNameAutomationId);
+
+                               if (result[0].Rect.Height > 1)
+                                       return result;
+
+                               return new UITest.Queries.AppResult[0];
+                       }, 10, 4000);
+
+                       Assert.AreEqual(1, images.Length);
+                       var imageVisible = images[0];
+                                               
+                       Assert.Greater(imageVisible.Rect.Height, 1);
+                       Assert.Greater(imageVisible.Rect.Width, 1);
+                       return imageVisible;
+               }
+
+               void TestForImageNotVisible(UITest.Queries.AppResult previousFinding)
+               {
+                       var imageVisible = RunningApp.Query(_fileNameAutomationId);
+
+                       if (imageVisible.Length > 0)
+                       {
+                               Assert.Less(imageVisible[0].Rect.Height, previousFinding.Rect.Height);
                        }
-#else
-                       //can't validate if images have vanished until this is resolved
-                       Assert.Inconclusive(@"https://github.com/xamarin/Xamarin.Forms/issues/4731");
-#endif
+               }
+
+               void SetupTest(string controlType, bool fileSource)
+               {
+                       RunningApp.WaitForElement(_nextTestId);
+                       string activeTest = null;
+                       while (RunningApp.Query(controlType).Length == 0)
+                       {
+                               activeTest = RunningApp.WaitForElement(_activeTestId)[0].ReadText();
+                               RunningApp.Tap(_nextTestId);
+                               RunningApp.WaitForNoElement(activeTest);
+                       }
+
+                       var currentSetting = RunningApp.WaitForElement(_switchUriId)[0].ReadText();
+
+                       if (fileSource && RunningApp.Query(_imageFromUri).Length == 0)
+                               RunningApp.Tap(_switchUriId);
+                       else if (!fileSource && RunningApp.Query(_imageFromFile).Length == 0)
+                               RunningApp.Tap(_switchUriId);
                }
 #endif
        }
-}
+}
\ No newline at end of file
index f5d8a0e..1b1eb55 100644 (file)
@@ -4,11 +4,32 @@ using System.Linq;
 using Xamarin.UITest;
 using Xamarin.UITest.Queries;
 using System.Text.RegularExpressions;
+using System.Threading;
 
 namespace Xamarin.Forms.Core.UITests
 {
        internal static class AppExtensions
        {
+               public static AppResult[] RetryUntilPresent(
+                       this IApp app,
+                       Func<AppResult[]> func,
+                       int retryCount,
+                       int delayInMs)
+               {
+                       var results = func();
+
+                       int counter = 0;
+                       while (results.Length == 0 && counter < retryCount)
+                       {
+                               Thread.Sleep(delayInMs);
+                               results = func();
+                               counter++;
+                       }
+
+                       return results;
+
+               }
+
                public static AppRect ScreenBounds(this IApp app)
                {
                        return app.Query(Queries.Root()).First().Rect;
index 4118d41..7fbade3 100644 (file)
        </DataTemplate>
 
        <DataTemplate x:Key="ImageCell">
-               <Grid>
+               <Grid AutomationProperties.AutomationId="{Binding AutomationId}">
                        <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition />
        </DataTemplate>
        
        <DataTemplate x:Key="SwitchCell">
-               <Grid HorizontalAlignment="Stretch" x:Name="ParentGrid">
+               <Grid HorizontalAlignment="Stretch" x:Name="ParentGrid"  AutomationProperties.AutomationId="{Binding AutomationId}">
                        <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
        </DataTemplate>
 
        <DataTemplate x:Key="EntryCell">
-        <uwp:EntryCellTextBox IsEnabled="{Binding IsEnabled}" Header="{Binding}" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextAlignment="{Binding HorizontalTextAlignment,Converter={StaticResource HorizontalTextAlignmentConverter}}" PlaceholderText="{Binding Placeholder}"  InputScope="{Binding Keyboard,Converter={StaticResource KeyboardConverter}}" HorizontalAlignment="Stretch">
+        <uwp:EntryCellTextBox  AutomationProperties.AutomationId="{Binding AutomationId}" IsEnabled="{Binding IsEnabled}" Header="{Binding}" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextAlignment="{Binding HorizontalTextAlignment,Converter={StaticResource HorizontalTextAlignmentConverter}}" PlaceholderText="{Binding Placeholder}"  InputScope="{Binding Keyboard,Converter={StaticResource KeyboardConverter}}" HorizontalAlignment="Stretch">
                        <uwp:EntryCellTextBox.HeaderTemplate>
                                <DataTemplate>
                     <TextBlock Text="{Binding Label}" IsHitTestVisible="False" Style="{ThemeResource BaseTextBlockStyle}" Foreground="{Binding LabelColor, Converter={StaticResource ColorConverter}, ConverterParameter=DefaultTextForegroundThemeBrush}" />