Cherry pick Issue4597 fixes back to branch 4.0.0 (#6724)
* 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
This commit is contained in:
Родитель
e22494884b
Коммит
e15ae8ca86
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 20 KiB |
|
@ -161,6 +161,7 @@
|
|||
<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" />
|
||||
|
|
|
@ -163,6 +163,7 @@
|
|||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="xamarinlogo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 20 KiB |
|
@ -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 };
|
||||
|
||||
var layout = new StackLayout()
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
RunTest(nameof(Image), false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImageFromUriSourceAppearsAndDisappearsCorrectly()
|
||||
{
|
||||
RunTest(nameof(Image), true);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void ButtonFromFileSourceAppearsAndDisappearsCorrectly()
|
||||
{
|
||||
RunTest(nameof(Button), false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ButtonFromUriSourceAppearsAndDisappearsCorrectly()
|
||||
{
|
||||
RunTest(nameof(Button), true);
|
||||
}
|
||||
|
||||
|
||||
[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()
|
||||
{
|
||||
return RunningApp
|
||||
.Query(app => app.Marked(_theListView).Descendant())
|
||||
.Where(x => x.Class != null && x.Class.Contains(className)).ToArray();
|
||||
}
|
||||
}
|
||||
#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);
|
||||
var elementsAfter = RunningApp.WaitForElement(_fileName);
|
||||
}
|
||||
|
||||
#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)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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
|
||||
var result = RunningApp.WaitForElement(_fileNameAutomationId);
|
||||
|
||||
#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
|
||||
if (result[0].Rect.Height > 1)
|
||||
return result;
|
||||
|
||||
return new UITest.Queries.AppResult[0];
|
||||
}, 10, 4000);
|
||||
|
||||
#if !__WINDOWS__
|
||||
Assert.IsNotNull(imageCell);
|
||||
#endif
|
||||
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
|
||||
Assert.AreEqual(1, images.Length);
|
||||
var imageVisible = images[0];
|
||||
|
||||
Assert.Greater(imageVisible.Rect.Height, 1);
|
||||
Assert.Greater(imageVisible.Rect.Width, 1);
|
||||
return imageVisible;
|
||||
}
|
||||
|
||||
#if __IOS__
|
||||
Assert.AreEqual(0, elementsAfter.Where(x => x.Class.Contains("Image")).Count());
|
||||
#elif __ANDROID__
|
||||
foreach (var newElement in elementsAfter)
|
||||
void TestForImageNotVisible(UITest.Queries.AppResult previousFinding)
|
||||
{
|
||||
var imageVisible = RunningApp.Query(_fileNameAutomationId);
|
||||
|
||||
if (imageVisible.Length > 0)
|
||||
{
|
||||
foreach (var oldElement in elementsBefore)
|
||||
{
|
||||
if (newElement.Class == oldElement.Class)
|
||||
{
|
||||
Assert.IsTrue(newElement.Rect.Height < oldElement.Rect.Height);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -270,7 +270,7 @@
|
|||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ImageCell">
|
||||
<Grid>
|
||||
<Grid AutomationProperties.AutomationId="{Binding AutomationId}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
|
@ -302,7 +302,7 @@
|
|||
</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" />
|
||||
|
@ -315,7 +315,7 @@
|
|||
</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}" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче