Merge branch '4.7.0' into 4.8.0

This commit is contained in:
shane 2020-07-03 08:43:20 -05:00
Родитель 77e79f75c5 5c32c65285
Коммит 90917090b2
20 изменённых файлов: 534 добавлений и 174 удалений

Просмотреть файл

@ -27,6 +27,7 @@ namespace Xamarin.Forms.ControlGallery.WindowsUniversal
/// </summary>
sealed partial class App
{
public static bool RunningAsUITests { get; private set; }
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
@ -44,12 +45,12 @@ namespace Xamarin.Forms.ControlGallery.WindowsUniversal
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
/* uncomment if you want to run tests without preloading
* issues list or change other behavior based on if tests
* are running in UI Harness
* if (!String.IsNullOrWhiteSpace(e.Arguments) &&
if (!String.IsNullOrWhiteSpace(e.Arguments) &&
e.Arguments.Contains("RunningAsUITests"))
Controls.App.PreloadTestCasesIssuesList = false;*/
{
RunningAsUITests = true;
Controls.App.PreloadTestCasesIssuesList = false;
}
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{

Просмотреть файл

@ -29,13 +29,14 @@ namespace Xamarin.Forms.ControlGallery.WindowsUniversal
{
InitializeComponent();
// some tests need to window to be large enough to click on things
// can we make this only open to window size for UI Tests?
//var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
//var scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
//var size = new Windows.Foundation.Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
//ApplicationView.PreferredLaunchViewSize = size;
//ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
if (Xamarin.Forms.ControlGallery.WindowsUniversal.App.RunningAsUITests)
{
var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
var scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
var size = new Windows.Foundation.Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
ApplicationView.PreferredLaunchViewSize = size;
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
_app = new Controls.App();

Просмотреть файл

@ -65,7 +65,7 @@ namespace Xamarin.Forms.Controls.Issues
#if UITEST
[Test]
public void UpdatingSourceOfDisposedListViewDoesNotCrash()
public void WebViewEvalCrashesOnAndroidWithLongString()
{
RunningApp.WaitForElement("navigatedLabel");
}

Просмотреть файл

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Forms.Controls.Issues.Issue10908"
Title="Issue 10908">
<ContentPage.Content>
<ListView
x:Name ="lstView"
IsGroupingEnabled="true"
HasUnevenRows="True"
SeparatorVisibility="None"
GroupDisplayBinding="{Binding LongName}"
GroupShortNameBinding="{Binding ShortName}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItem
BackgroundColor="Red"
IconImageSource="icon.png"
Text="Delete"/>
</SwipeView.LeftItems>
<StackLayout
HeightRequest="60">
<Label Text="{Binding Name}" />
<Label Text="{Binding Comment}" />
</StackLayout>
</SwipeView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>

Просмотреть файл

@ -0,0 +1,77 @@
using System.Collections.ObjectModel;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 10908, "[Bug] [iOS]SwipeView not working on Grouped ListView", PlatformAffected.iOS)]
public partial class Issue10908 : ContentPage
{
public Issue10908()
{
#if APP
InitializeComponent ();
Grouped = new ObservableCollection<GroupedIssue10908Model>();
var veggieGroup = new GroupedIssue10908Model() { LongName = "vegetables", ShortName = "v" };
var fruitGroup = new GroupedIssue10908Model() { LongName = "fruit", ShortName = "f" };
var veggie1Group = new GroupedIssue10908Model() { LongName = "vegetables1", ShortName = "v1" };
var fruit1Group = new GroupedIssue10908Model() { LongName = "fruit1", ShortName = "f1" };
var veggie2Group = new GroupedIssue10908Model() { LongName = "vegetables2", ShortName = "v2" };
var fruit2Group = new GroupedIssue10908Model() { LongName = "fruit2", ShortName = "f2" };
veggieGroup.Add(new Issue10908Model() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
veggieGroup.Add(new Issue10908Model() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
veggieGroup.Add(new Issue10908Model() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
veggieGroup.Add(new Issue10908Model() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
fruitGroup.Add(new Issue10908Model() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
fruitGroup.Add(new Issue10908Model() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
fruitGroup.Add(new Issue10908Model() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
veggie1Group.Add(new Issue10908Model() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
veggie1Group.Add(new Issue10908Model() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
veggie1Group.Add(new Issue10908Model() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
veggie1Group.Add(new Issue10908Model() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
fruit1Group.Add(new Issue10908Model() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
fruit1Group.Add(new Issue10908Model() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
fruit1Group.Add(new Issue10908Model() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
veggie2Group.Add(new Issue10908Model() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
veggie2Group.Add(new Issue10908Model() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
veggie2Group.Add(new Issue10908Model() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
veggie2Group.Add(new Issue10908Model() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
fruit2Group.Add(new Issue10908Model() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
fruit2Group.Add(new Issue10908Model() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
fruit2Group.Add(new Issue10908Model() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
Grouped.Add(veggieGroup);
Grouped.Add(fruitGroup);
Grouped.Add(veggie1Group);
Grouped.Add(fruit1Group);
Grouped.Add(veggie2Group);
Grouped.Add(fruit2Group);
lstView.ItemsSource = Grouped;
#endif
}
ObservableCollection<GroupedIssue10908Model> Grouped { get; set; }
}
[Preserve(AllMembers = true)]
public class Issue10908Model
{
public string Name { get; set; }
public string Comment { get; set; }
public bool IsReallyAVeggie { get; set; }
public string Image { get; set; }
}
[Preserve(AllMembers = true)]
public class GroupedIssue10908Model : ObservableCollection<Issue10908Model>
{
public string LongName { get; set; }
public string ShortName { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,78 @@
using Xamarin.Forms.Internals;
using Xamarin.Forms.CustomAttributes;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.Label)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 11272,
"[Bug] Crash XF for Mac 4.7.0.1080",
PlatformAffected.macOS)]
public class Issue11272 : TestContentPage
{
public Issue11272()
{
}
protected override void Init()
{
Title = "Issue 11272";
var layout = new StackLayout();
var instructions = new Label
{
Padding = 12,
BackgroundColor = Color.Black,
TextColor = Color.White,
Text = "Without exception, this test has passed."
};
var errorLabel1 = new Label()
{
HorizontalOptions = LayoutOptions.Center,
FormattedText = new FormattedString
{
Spans =
{
new Span()
{
Text = "🔔🌀 Issue 11272",
}
}
}
};
var errorLabel2 = new Label()
{
HorizontalOptions = LayoutOptions.Center,
FormattedText = new FormattedString
{
Spans =
{
new Span()
{
TextColor = Color.Red,
Text = "🔔🌀 Issue 11272 (Using TextColor)",
}
}
}
};
layout.Children.Add(instructions);
layout.Children.Add(errorLabel1);
layout.Children.Add(errorLabel2);
Content = layout;
}
}
}

Просмотреть файл

@ -18,6 +18,7 @@ namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.ManualReview)]
[Category(UITestCategories.CarouselView)]
#endif
#if APP
[XamlCompilation(XamlCompilationOptions.Compile)]

Просмотреть файл

@ -446,6 +446,40 @@ namespace Xamarin.Forms.Controls
get { return _app.TestServer; }
}
public void TestSetup(Type testType, bool isolate)
{
if (isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(testType, this);
}
public void TestTearDown(bool isolate)
{
if (isolate)
{
AppSetup.EndIsolate();
}
#if __WINDOWS__
ScreenshotFailure();
#endif
}
#if __WINDOWS__
public void ScreenshotFailure()
{
(_app as Core.UITests.WinDriverApp).ScreenshotFailure();
}
#endif
#if __IOS__
public bool IsTablet

Просмотреть файл

@ -2,6 +2,7 @@
using System.Reflection;
using Xamarin.Forms.CustomAttributes;
using IOPath = System.IO.Path;
using NUnit.Framework.Interfaces;
#if UITEST
using Xamarin.Forms.Core.UITests;
@ -197,7 +198,7 @@ namespace Xamarin.Forms.Controls
app.Tap(q => q.Button("Go to Test Cases"));
app.WaitForElement(q => q.Raw("* marked:'TestCasesIssueList'"));
app.EnterText(q => q.Raw("* marked:'SearchBarGo'"), cellName);
app.EnterText(q => q.Raw("* marked:'SearchBarGo'"), $"{cellName}");
app.WaitForElement(q => q.Raw("* marked:'SearchButton'"));
app.Tap(q => q.Raw("* marked:'SearchButton'"));
@ -331,26 +332,13 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
#endif
@ -377,26 +365,13 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public virtual void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
#endif
@ -425,26 +400,13 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
#endif
@ -473,26 +435,13 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public virtual void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
#endif
@ -518,26 +467,13 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
#endif
@ -569,26 +505,13 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public virtual void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
#endif
@ -822,27 +745,15 @@ namespace Xamarin.Forms.Controls
[SetUp]
public void Setup()
{
if (Isolate)
{
AppSetup.BeginIsolate();
}
else
{
AppSetup.EnsureMemory();
AppSetup.EnsureConnection();
}
AppSetup.NavigateToIssue(GetType(), RunningApp);
(RunningApp as ScreenshotConditionalApp).TestSetup(GetType(), Isolate);
}
[TearDown]
public virtual void TearDown()
{
if (Isolate)
{
AppSetup.EndIsolate();
}
(RunningApp as ScreenshotConditionalApp).TestTearDown(Isolate);
}
public void ShowFlyout(string flyoutIcon = FlyoutIconAutomationId, bool usingSwipe = false, bool testForFlyoutIcon = true)
{
if (testForFlyoutIcon)

Просмотреть файл

@ -1437,10 +1437,12 @@
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue11031.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue10940.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue10908.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11132.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11113.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue10182.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11107.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11272.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
@ -1680,6 +1682,9 @@
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue9555.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue10908.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue11113.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>

Просмотреть файл

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xamarin.Forms.CustomAttributes;
using System.Threading.Tasks;
namespace Xamarin.Forms.Controls
{
@ -192,9 +193,15 @@ namespace Xamarin.Forms.Controls
FilterIssues(_filter);
}
public void FilterIssues(string filter = null)
public async void FilterIssues(string filter = null)
{
filter = filter?.Trim();
_filter = filter;
// Deeeee bounce
await Task.Delay(10);
if (_filter != filter)
return;
PageToAction.Clear();
if(String.IsNullOrWhiteSpace(filter) && !Controls.App.PreloadTestCasesIssuesList)
@ -281,7 +288,7 @@ namespace Xamarin.Forms.Controls
AutomationId = "SearchButton",
Command = new Command (() => {
try {
TestCaseScreen.PageToAction[searchBar.Text] ();
TestCaseScreen.PageToAction[searchBar.Text?.Trim()] ();
} catch (Exception e) {
System.Diagnostics.Debug.WriteLine (e.Message);
}

Просмотреть файл

@ -7,7 +7,10 @@ using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
@ -21,6 +24,7 @@ namespace Xamarin.Forms.Core.UITests
public class WinDriverApp : IApp
{
public const string AppName = "Xamarin.Forms.ControlGallery.WindowsUniversal";
public static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(15);
readonly Dictionary<string, string> _controlNameToTag = new Dictionary<string, string>
{
@ -57,6 +61,12 @@ namespace Xamarin.Forms.Core.UITests
Init(WindowsTestBase.CreateWindowsDriver());
}
public void RestartApp()
{
_session.CloseApp();
Init(WindowsTestBase.CreateWindowsDriver());
}
public void Back()
{
QueryWindows("Back").First().Click();
@ -64,7 +74,7 @@ namespace Xamarin.Forms.Core.UITests
public void ClearText(Func<AppQuery, AppQuery> query)
{
QueryWindows(query).First().Clear();
SwapInUsefulElement(QueryWindows(query).First()).Clear();
}
public void ClearText(Func<AppQuery, AppWebQuery> query)
@ -74,7 +84,7 @@ namespace Xamarin.Forms.Core.UITests
public void ClearText(string marked)
{
QueryWindows(marked).First().Clear();
SwapInUsefulElement(QueryWindows(marked).First()).Clear();
}
public void ClearText()
@ -126,16 +136,25 @@ namespace Xamarin.Forms.Core.UITests
.Perform();
}
static RemoteWebElement SwapInUsefulElement(WindowsElement element)
{
// AutoSuggestBox on UWP has some interaction issues with WebDriver
// The AutomationID is set on the control group not the actual TextBox
// This retrieves the actual TextBox which makes the behavior more consistent
var isAutoSuggest = element?.FindElementsByXPath("//*[contains(@AutomationId,'_AutoSuggestBox')]")?.FirstOrDefault();
return isAutoSuggest ?? element;
}
public void EnterText(Func<AppQuery, AppQuery> query, string text)
{
var result = QueryWindows(query).First();
result.SendKeys(text);
SwapInUsefulElement(result).SendKeys(text);
}
public void EnterText(string marked, string text)
{
var results = QueryWindows(marked).First();
results.SendKeys(text);
var result = QueryWindows(marked).First();
SwapInUsefulElement(result).SendKeys(text);
}
public void EnterText(Func<AppQuery, AppWebQuery> query, string text)
@ -287,6 +306,20 @@ namespace Xamarin.Forms.Core.UITests
throw new NotImplementedException();
}
public void ScreenshotFailure()
{
if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
{
string filename = $"{TestContext.CurrentContext.Test.FullName}.png";
Screenshot screenshot = _session.GetScreenshot();
screenshot.SaveAsFile(filename, ScreenshotImageFormat.Png);
var file = new FileInfo(filename);
TestContext.AddTestAttachment(file.FullName, TestContext.CurrentContext.Test.FullName);
}
}
public FileInfo Screenshot(string title)
{
// TODO hartez 2017/07/18 10:16:56 Verify that this is working; seems a bit too simple
@ -294,7 +327,10 @@ namespace Xamarin.Forms.Core.UITests
Screenshot screenshot = _session.GetScreenshot();
screenshot.SaveAsFile(filename, ScreenshotImageFormat.Png);
return new FileInfo(filename);
var file = new FileInfo(filename);
TestContext.AddTestAttachment(file.FullName, title);
return file;
}
public void ScrollDown(Func<AppQuery, AppQuery> withinQuery = null, ScrollStrategy strategy = ScrollStrategy.Auto,
@ -786,7 +822,12 @@ namespace Xamarin.Forms.Core.UITests
}
ReadOnlyCollection<WindowsElement> candidates = QueryWindows(AppName);
_viewPort = candidates[3]; // We really just want the viewport; skip the full window, title bar, min/max buttons...
// When you go full screen there are less candidates because certain elements go away on the window
if (candidates.Count >= 4)
_viewPort = candidates[3]; // We really just want the viewport; skip the full window, title bar, min/max buttons...
else
_viewPort = candidates.Last();
int xOffset = _viewPort.Coordinates.LocationInViewport.X;
@ -887,7 +928,7 @@ namespace Xamarin.Forms.Core.UITests
void ScrollTo(WinQuery toQuery, WinQuery withinQuery, TimeSpan? timeout = null, bool down = true)
{
timeout = timeout ?? TimeSpan.FromSeconds(5);
timeout = timeout ?? DefaultTimeout;
DateTime start = DateTime.Now;
while (true)
@ -969,7 +1010,7 @@ namespace Xamarin.Forms.Core.UITests
{
Rect = ToAppRect(windowsElement),
Label = windowsElement.Id, // Not entirely sure about this one
Description = windowsElement.Text, // or this one
Description = SwapInUsefulElement(windowsElement).Text, // or this one
Enabled = windowsElement.Enabled,
Id = windowsElement.Id
};
@ -980,7 +1021,7 @@ namespace Xamarin.Forms.Core.UITests
string timeoutMessage = null,
TimeSpan? timeout = null, TimeSpan? retryFrequency = null)
{
timeout = timeout ?? TimeSpan.FromSeconds(5);
timeout = timeout ?? DefaultTimeout;
retryFrequency = retryFrequency ?? TimeSpan.FromMilliseconds(500);
timeoutMessage = timeoutMessage ?? "Timed out on query.";
@ -994,7 +1035,7 @@ namespace Xamarin.Forms.Core.UITests
if (elapsed >= timeout.Value.Ticks)
{
Debug.WriteLine($">>>>> {elapsed} ticks elapsed, timeout value is {timeout.Value.Ticks}");
throw new TimeoutException(timeoutMessage);
}

Просмотреть файл

@ -78,6 +78,7 @@ namespace Xamarin.Forms.Material.iOS
{
base.LayoutSubviews();
if (Control == null) return;
// try get the radius for this size
var min = NMath.Min(Control.Bounds.Width, Control.Bounds.Height);
var stroke = min / _strokeRatio;
@ -145,4 +146,4 @@ namespace Xamarin.Forms.Material.iOS
Control.StopAnimating();
}
}
}
}

Просмотреть файл

@ -113,6 +113,7 @@ namespace Xamarin.Forms.Platform.UWP
UpdateIsSpellCheckEnabled();
UpdateInputScope();
UpdateMaxLength();
SetAutomationId(Element.AutomationId);
// If the Forms VisualStateManager is in play or the user wants to disable the Forms legacy
// color stuff, then the underlying textbox should just use the Forms VSM states
@ -121,6 +122,18 @@ namespace Xamarin.Forms.Platform.UWP
|| !Element.OnThisPlatform().GetIsLegacyColorModeEnabled();
}
protected override void SetAutomationId(string id)
{
base.SetAutomationId(id);
if (_queryTextBox == null)
return;
// This allow us to locate the actual TextBox for Automation purposes
// It's more reliable to interact directly with the TextBox
_queryTextBox.SetAutomationPropertiesAutomationId($"{id}_AutoSuggestBox");
}
void OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs e)
{
// Modifies the text of the control if it does not match the query.

Просмотреть файл

@ -154,7 +154,7 @@ namespace Xamarin.Forms.Platform.MacOS
#else
internal static readonly NSColor Black = NSColor.Black;
internal static readonly NSColor SeventyPercentGrey = NSColor.FromRgba(0.7f, 0.7f, 0.7f, 1);
internal static readonly NSColor LabelColor = NSColor.Black;
internal static readonly NSColor LabelColor = NSColor.Black.UsingColorSpace("NSCalibratedRGBColorSpace");
internal static readonly NSColor AccentColor = Color.FromRgba(50, 79, 133, 255).ToNSColor();
#endif

Просмотреть файл

@ -351,7 +351,7 @@ namespace Xamarin.Forms.Platform.iOS
{
if (panGestureRecognizer != null)
{
var point = panGestureRecognizer.LocationInView(Control);
CGPoint point = panGestureRecognizer.LocationInView(this);
var navigationController = GetUINavigationController(GetViewController());
switch (panGestureRecognizer.State)

Просмотреть файл

@ -452,19 +452,19 @@ namespace Xamarin.Forms.Platform.MacOS
hasClipShapeLayer =
uiview.Layer != null &&
uiview.Layer.Mask != null &&
uiview.Layer.Mask.Name.Equals(ClipShapeLayer);
uiview.Layer.Mask.Name == ClipShapeLayer;
else
{
hasClipShapeLayer =
uiview.MaskView != null &&
uiview.MaskView.Layer.Mask != null &&
uiview.MaskView.Layer.Mask.Name.Equals(ClipShapeLayer);
uiview.MaskView.Layer.Mask.Name == ClipShapeLayer;
}
#else
hasClipShapeLayer =
uiview.Layer != null &&
uiview.Layer.Mask != null &&
uiview.Layer.Mask.Name.Equals(ClipShapeLayer);
uiview.Layer.Mask.Name == ClipShapeLayer;
#endif
var formsGeometry = element.Clip;

Просмотреть файл

@ -14,11 +14,11 @@ variables:
- name: BuildVersion44
value: $[counter('xf-nuget-counter', 992000)]
- name: NUGET_VERSION
value: 5.4.0
value: 5.6.0
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: true
- name: DOTNET_VERSION
value: 3.1.100
value: 3.1.301
resources:
repositories:
@ -30,7 +30,7 @@ resources:
trigger:
branches:
include:
- master
- main
- 3.*
- 4.*
tags:
@ -44,7 +44,7 @@ pr:
autoCancel: false
branches:
include:
- master
- main
- 4.*
- 3.*
@ -53,7 +53,7 @@ schedules:
displayName: Daily midnight build
branches:
include:
- master
- main
stages:
- stage: windows
@ -64,7 +64,7 @@ stages:
workspace:
clean: all
displayName: Build Windows Phase
timeoutInMinutes: 120
timeoutInMinutes: 60
pool:
name: $(vs2019VmPool)
vmImage: $(vs2019VmImage)
@ -128,8 +128,8 @@ stages:
condition: ne(variables['vs2019VmPool'], 'Azure Pipelines')
workspace:
clean: all
displayName: Build Windows Phase
timeoutInMinutes: 120
displayName: Build Windows Phase Bots
timeoutInMinutes: 60
pool:
name: $(vs2019VmPool)
vmImage: $(vs2019VmImage)
@ -277,6 +277,32 @@ stages:
steps:
- template: build/steps/build-osx.yml
# My purpose is to enable quick testing of UI Tests when we need to debug
# why tests are failing. Full test suite runs as part of release
- stage: windows_tests
displayName: Run Windows Tests
condition: 'false'
dependsOn: []
jobs:
- job: win_hosted_tests
workspace:
clean: all
displayName: Run UWP Tests
timeoutInMinutes: 500
pool:
name: 'Azure Pipelines'
vmImage: 'windows-2019'
demands:
msbuild
strategy:
matrix:
debug:
BuildConfiguration: 'Debug'
steps:
- template: build/steps/run-windows-tests.yml
parameters:
provisionatorPath : 'build/provisioning/provisioning.csx'
# only sign using the private server
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
- stage: nuget_signing

Просмотреть файл

@ -48,13 +48,12 @@ var IOS_TEST_LIBRARY = Argument("IOS_TEST_LIBRARY", $"./Xamarin.Forms.Core.iOS.U
var IOS_IPA_PATH = Argument("IOS_IPA_PATH", $"./Xamarin.Forms.ControlGallery.iOS/bin/iPhoneSimulator/{configuration}/XamarinFormsControlGalleryiOS.app");
var IOS_BUNDLE_ID = "com.xamarin.quickui.controlgallery";
var IOS_BUILD_IPA = Argument("IOS_BUILD_IPA", (target == "cg-ios-deploy") ? true : (false || isCIBuild) );
var NUNIT_TEST_WHERE = Argument("NUNIT_TEST_WHERE", "cat == Issues && cat != ManualReview");
var UWP_PACKAGE_ID = "0d4424f6-1e29-4476-ac00-ba22c3789cb6";
var UWP_TEST_LIBRARY = Argument("UWP_TEST_LIBRARY", $"./Xamarin.Forms.Core.Windows.UITests/bin/{configuration}/Xamarin.Forms.Core.Windows.UITests.dll");
var UWP_TEST_LIBRARY = GetBuildVariable("UWP_TEST_LIBRARY", $"./Xamarin.Forms.Core.Windows.UITests/bin/{configuration}/Xamarin.Forms.Core.Windows.UITests.dll");
var UWP_PFX_PATH = Argument("UWP_PFX_PATH", "Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx");
var UWP_APP_PACKAGES_PATH = Argument("UWP_APP_PACKAGES_PATH", "*/AppPackages/");
var UWP_APP_DRIVER_INSTALL_PATH = Argument("UWP_APP_DRIVER_INSTALL_PATH", "https://github.com/microsoft/WinAppDriver/releases/download/v1.2-RC/WindowsApplicationDriver.msi");
var ANDROID_RENDERERS = Argument("ANDROID_RENDERERS", "FAST");
var XamarinFormsVersion = Argument("XamarinFormsVersion", "");
var packageVersion = Argument("packageVersion", "");
@ -62,7 +61,41 @@ var releaseChannelArg = Argument("CHANNEL", "Stable");
releaseChannelArg = EnvironmentVariable("CHANNEL") ?? releaseChannelArg;
var teamProject = Argument("TeamProject", "");
bool buildForVS2017 = Convert.ToBoolean(Argument("buildForVS2017", "false"));
bool isHostedAgent = agentName.StartsWith("Azure Pipelines");
bool isHostedAgent = agentName.StartsWith("Azure Pipelines") || agentName.StartsWith("Hosted Agent");
var NUNIT_TEST_WHERE = Argument("NUNIT_TEST_WHERE", "cat != Shell && cat != CollectionView && cat != UwpIgnore && cat != CarouselView");
var ExcludeCategory = GetBuildVariable("ExcludeCategory", "")?.Replace("\"", "");
var ExcludeCategory2 = GetBuildVariable("ExcludeCategory2", "")?.Replace("\"", "");
var IncludeCategory = GetBuildVariable("IncludeCategory", "")?.Replace("\"", "");
// Replace Azure devops syntax for unit tests to Nunit3 filters
if(!String.IsNullOrWhiteSpace(ExcludeCategory))
{
ExcludeCategory = String.Join(" && cat != ", ExcludeCategory.Split(new string[] { "--exclude-category" }, StringSplitOptions.None));
if(!ExcludeCategory.StartsWith("cat"))
ExcludeCategory = $" cat != {ExcludeCategory}";
NUNIT_TEST_WHERE = $"{NUNIT_TEST_WHERE} && {ExcludeCategory}";
}
if(!String.IsNullOrWhiteSpace(ExcludeCategory2))
{
ExcludeCategory2 = String.Join(" && cat != ", ExcludeCategory2.Split(new string[] { "--exclude-category" }, StringSplitOptions.None));
if(!ExcludeCategory2.StartsWith("cat"))
ExcludeCategory2 = $" cat != {ExcludeCategory2}";
NUNIT_TEST_WHERE = $"{NUNIT_TEST_WHERE} && {ExcludeCategory2}";
}
if(!String.IsNullOrWhiteSpace(IncludeCategory))
{
IncludeCategory = String.Join(" || cat == ", IncludeCategory.Split(new string[] { "--include-category" }, StringSplitOptions.None));
if(!IncludeCategory.StartsWith("cat"))
IncludeCategory = $" cat == {IncludeCategory}";
NUNIT_TEST_WHERE = $"({NUNIT_TEST_WHERE}) && ({IncludeCategory})";
}
var ANDROID_HOME = EnvironmentVariable("ANDROID_HOME") ??
(IsRunningOnWindows () ? "C:\\Program Files (x86)\\Android\\android-sdk\\" : "");
@ -454,6 +487,7 @@ Task ("cg-uwp-deploy")
// Install the appx
var dependencies = GetFiles(UWP_APP_PACKAGES_PATH + "*/Dependencies/x86/*.appx");
foreach (var dep in dependencies) {
try
{
@ -472,18 +506,48 @@ Task ("cg-uwp-deploy")
});
Task("cg-uwp-run-tests")
.IsDependentOn("provision-uitests-uwp")
.Does(() =>
{
NUnit3(new [] { UWP_TEST_LIBRARY },
new NUnit3Settings {
Params = new Dictionary<string, string>()
System.Diagnostics.Process process = null;
if(!isHostedAgent)
{
try
{
var info = new System.Diagnostics.ProcessStartInfo(@"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe")
{
},
Where = NUNIT_TEST_WHERE
});
};
process = System.Diagnostics.Process.Start(info);
}
catch(Exception exc)
{
Information("Failed: {0}", exc);
}
}
try
{
NUnit3(new [] { UWP_TEST_LIBRARY },
new NUnit3Settings {
Params = new Dictionary<string, string>()
{
},
Where = NUNIT_TEST_WHERE
});
}
finally
{
try
{
process?.Kill();
}
catch{}
}
});
Task("cg-uwp-run-tests-ci")
.IsDependentOn("provision-windowssdk")
.IsDependentOn("cg-uwp-deploy")
.IsDependentOn("cg-uwp-run-tests")
.Does(() =>
@ -491,29 +555,16 @@ Task("cg-uwp-run-tests-ci")
});
Task("provision-uitests-uwp")
.WithCriteria(IsRunningOnWindows() && !isHostedAgent)
.Description("Installs and Starts WindowsApplicationDriver. Use WinAppDriverPath to specify WinAppDriver Location.")
.Does(() =>
{
if(IsRunningOnWindows())
string installPath = Argument("WinAppDriverPath", @"C:\Program Files (x86)\");
string driverPath = System.IO.Path.Combine(installPath, "Windows Application Driver");
if(!DirectoryExists(driverPath))
{
string installPath = Argument("WinAppDriverPath", @"C:\Program Files (x86)\");
string driverPath = System.IO.Path.Combine(installPath, "Windows Application Driver");
if(!DirectoryExists(driverPath))
{
InstallMsi("https://github.com/microsoft/WinAppDriver/releases/download/v1.2-RC/WindowsApplicationDriver.msi", installPath);
}
var info = new System.Diagnostics.ProcessStartInfo
{
FileName = "WinAppDriver",
WorkingDirectory = driverPath
};
Information("Starting: {0}", driverPath);
System.Diagnostics.Process.Start(info);
InstallMsi(UWP_APP_DRIVER_INSTALL_PATH, installPath);
}
});
void InstallMsi(string msiFile, string installTo, string fileName = "InstallFile.msi")
@ -988,6 +1039,11 @@ Task("Default")
RunTarget(target);
T GetBuildVariable<T>(string key, T defaultValue)
{
return Argument(key, EnvironmentVariable(key, defaultValue));
}
void StartVisualStudio(string sln = "Xamarin.Forms.sln")
{
if(isCIBuild)

Просмотреть файл

@ -0,0 +1,72 @@
parameters:
name: '' # in the form type_platform_host
targetFolder: '' # the bootstrapper target
preBuildSteps: [] # any steps to run before the build
postBuildSteps: [] # any additional steps to run after the build
slnPath : 'Xamarin.Forms.sln'
csprojPath : 'Xamarin.Forms.Platform.UAP\Xamarin.Forms.Platform.UAP.csproj'
msbuildExtraArguments : ''
artifactsTargetFolder: '$(build.artifactstagingdirectory)'
artifactsName: 'win_build'
nunitTestAdapterFolder: 'packages/NUnitTestAdapter.AnyVersion/build/'
nunitTestFolder: '$(build.sourcesdirectory)'
includeUwp: 'true'
includeAndroid: 'true'
includeNonUwpAndNonAndroid: 'true'
steps:
- checkout: self
clean: true
- task: DotNetCoreCLI@2
displayName: 'Install Cake'
inputs:
command: custom
custom: tool
arguments: 'update cake.tool -g'
- script: build.cmd -Target provision
displayName: 'Cake Provision'
condition: eq(variables['provisioningCake'], 'true')
- task: xamops.azdevex.provisionator-task.provisionator@1
displayName: 'Provisionator'
condition: eq(variables['provisioning'], 'true')
inputs:
provisioning_script: ${{ parameters.provisionatorPath }}
provisioning_extra_args: ${{ parameters.provisionator.extraArguments }}
- task: NuGetToolInstaller@1
displayName: 'Use NuGet $(NUGET_VERSION)'
condition: ne(variables['NUGET_VERSION'], '')
inputs:
versionSpec: $(NUGET_VERSION)
- script: build.cmd -Target cg-uwp-build-tests -ScriptArgs '-BUILD_CONFIGURATION="$(BuildConfiguration)"'
condition: eq(variables['BuildConfiguration'], 'Debug')
displayName: 'Build Tests and APPX'
- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
condition: eq(variables['BuildConfiguration'], 'Debug')
displayName: 'Start - WinAppDriver'
- task: DotNetCoreCLI@2
displayName: 'Run UI Tests'
condition: eq(variables['BuildConfiguration'], 'Debug')
inputs:
command: custom
custom: cake
arguments: ' --target=cg-uwp-run-tests-ci --verbosity=diagnostic --NUNIT_TEST_WHERE="method == Issue2Test || method == Issue1Test || method == Bugzilla29128Test"'
- task: PublishTestResults@2
displayName: 'Publish Test Results **/TestResult.xml'
inputs:
testResultsFormat: NUnit
testResultsFiles: '**/TestResult.xml'
condition: always()
- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
displayName: 'Stop - WinAppDriver'
inputs:
OperationType: Stop
condition: always()