This commit is contained in:
Jerome Laban 2019-09-07 19:57:08 -04:00
Родитель 15efcff14e
Коммит cfcc68f1d2
25 изменённых файлов: 295 добавлений и 121 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -235,3 +235,4 @@ Resource.Designer.cs
/build/*.nupkg
src/nuget_override.props
.DS_Store

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

@ -138,3 +138,42 @@ jobs:
PathtoPublish: $(build.artifactstagingdirectory)
ArtifactName: uno-uitest-tests
ArtifactType: Container
- job: iOS_Tests
variables:
CI_Build: true
SourceLinkEnabled: false
pool:
vmImage: 'macOS-10.14'
steps:
- checkout: self
clean: true
- bash: /bin/bash -c "sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_18_1"
displayName: Select Xamarin Version
- bash: |
chmod +x $(build.sourcesdirectory)/build/build-ios.sh
$(build.sourcesdirectory)/build/build-ios.sh
displayName: Build and Test
env:
BUILD_SOURCESDIRECTORY: "$(build.sourcesdirectory)"
BUILD_ARTIFACTSTAGINGDIRECTORY: "$(build.artifactstagingdirectory)"
- task: PublishTestResults@2
condition: always()
inputs:
testRunTitle: 'iOS Test Run'
testResultsFormat: 'NUnit'
testResultsFiles: '$(build.sourcesdirectory)/build/TestResult.xml'
- task: PublishBuildArtifacts@1
condition: always()
inputs:
PathtoPublish: $(build.artifactstagingdirectory)
ArtifactName: uno-uitest-tests
ArtifactType: Container

23
build/build-ios.sh Normal file
Просмотреть файл

@ -0,0 +1,23 @@
#!/bin/bash
echo "Lising iOS simulators"
xcrun simctl list devices --json
/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator &
cd $BUILD_SOURCESDIRECTORY
msbuild /r /p:Configuration=Release $BUILD_SOURCESDIRECTORY/src/Sample/Sample.UITests/Sample.UITests.csproj
msbuild /r /p:Configuration=Release "/p:Platform=iPhoneSimulator" $BUILD_SOURCESDIRECTORY/src/Sample/Sample.iOS/Sample.iOS.csproj
cd $BUILD_SOURCESDIRECTORY/build
mono nuget.exe install NUnit.ConsoleRunner -Version 3.10.0
export UNO_UITEST_PLATFORM=iOS
export UNO_UITEST_IOSBUNDLE_PATH=$BUILD_SOURCESDIRECTORY/src/Sample/Sample.iOS/bin/iPhoneSimulator/Release/Sample.app
export UNO_UITEST_SCREENSHOT_PATH=$BUILD_ARTIFACTSTAGINGDIRECTORY/screenshots/ios
mkdir -p $UNO_UITEST_SCREENSHOT_PATH
mono $BUILD_SOURCESDIRECTORY/build/NUnit.ConsoleRunner.3.10.0/tools/nunit3-console.exe --inprocess --agents=1 --workers=1 $BUILD_SOURCESDIRECTORY/src/Sample/Sample.UITests/bin/Release/net47/Sample.UITests.dll > $BUILD_ARTIFACTSTAGINGDIRECTORY/screenshots/ios/nunit-log.txt 2>&1

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

@ -16,10 +16,11 @@ export UNO_UITEST_DRIVERPATH_CHROME=$BUILD_SOURCESDIRECTORY/build/node_modules/c
export UNO_UITEST_CHROME_BINARY_PATH=$BUILD_SOURCESDIRECTORY/build/node_modules/puppeteer/.local-chromium/linux-637110/chrome-linux/chrome
export UNO_UITEST_SCREENSHOT_PATH=$BUILD_ARTIFACTSTAGINGDIRECTORY/screenshots/wasm
export UNO_UITEST_PLATFORM=Browser
export UNO_UITEST_CHROME_CONTAINER_MODE=true
mkdir -p $UNO_UITEST_SCREENSHOT_PATH
## The python server serves the current working directory, and may be changed by the nunit runner
bash -c "cd $BUILD_SOURCESDIRECTORY/src/Sample/Sample.Wasm/bin/Release/netstandard2.0/dist/; python server.py &"
mono $BUILD_SOURCESDIRECTORY/build/NUnit.ConsoleRunner.3.10.0/tools/nunit3-console.exe $BUILD_SOURCESDIRECTORY/src/Sample/Sample.UITests/bin/Release/net47/Sample.UITests.dll
mono $BUILD_SOURCESDIRECTORY/build/NUnit.ConsoleRunner.3.10.0/tools/nunit3-console.exe --trace=Verbose --inprocess --agents=1 --workers=1 $BUILD_SOURCESDIRECTORY/src/Sample/Sample.UITests/bin/Release/net47/Sample.UITests.dll

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

@ -15,7 +15,6 @@
<AndroidApplication>true</AndroidApplication>
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>False</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<AndroidUseIntermediateDesignerFile>True</AndroidUseIntermediateDesignerFile>
@ -34,10 +33,6 @@
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
<BundleAssemblies>false</BundleAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>portable</DebugType>
@ -52,11 +47,7 @@
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidCreatePackagePerAbi>true</AndroidCreatePackagePerAbi>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
<BundleAssemblies>false</BundleAssemblies>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
</PropertyGroup>
<ItemGroup>

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

@ -39,8 +39,14 @@ namespace Sample
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if __IOS__
// requires Xamarin Test Cloud Agent
Xamarin.Calabash.Start();
#endif
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
if(System.Diagnostics.Debugger.IsAttached)
{
// this.DebugSettings.EnableFrameRateCounter = true;
}

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

@ -13,12 +13,12 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0">
<ItemsControl ItemsSource="{x:Bind TestControls}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<HyperlinkButton Content="{Binding Name}" Click="HyperlinkButton_Click" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl>
<HyperlinkButton x:Uid="ComboBox01" Content="ComboBox 1" Click="HyperlinkButton_Click" Tag="Sample.Shared.Tests.ComboBox_Tests" />
<HyperlinkButton x:Uid="CheckBox01" Content="CheckBox 1" Click="HyperlinkButton_Click" Tag="Sample.Shared.Tests.CheckBox_Tests" />
<HyperlinkButton x:Uid="RadioButton01" Content="RadioButton 01" Click="HyperlinkButton_Click" Tag="Sample.Shared.Tests.RadioButton_Tests_01" />
<HyperlinkButton x:Uid="TextBox01" Content="TextBox 01" Click="HyperlinkButton_Click" Tag="Sample.Shared.Tests.TextBox_Tests_01" />
<HyperlinkButton x:Uid="DragCoordinates01" Content="DragCoordinates 01" Click="HyperlinkButton_Click" Tag="Sample.Shared.Tests.DragCoordinates_Tests" />
</ItemsControl>
</ScrollViewer>
<Border Grid.Column="1" Margin="12">

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

@ -26,21 +26,13 @@ namespace Sample
public MainPage()
{
this.InitializeComponent();
TestControls.Add(new TestControl("ComboBox 1", "Sample.Shared.Tests.ComboBox_Tests"));
TestControls.Add(new TestControl("CheckBox 1", "Sample.Shared.Tests.CheckBox_Tests"));
TestControls.Add(new TestControl("RadioButton 01", "Sample.Shared.Tests.RadioButton_Tests_01"));
TestControls.Add(new TestControl("TextBox 01", "Sample.Shared.Tests.TextBox_Tests_01"));
TestControls.Add(new TestControl("DragCoordinates 01", "Sample.Shared.Tests.DragCoordinates_Tests"));
}
public ObservableCollection<TestControl> TestControls { get; } = new ObservableCollection<TestControl>();
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
if(sender is HyperlinkButton button && button.DataContext is TestControl tc)
if(sender is HyperlinkButton button && button.Tag is string typeName)
{
var type = Type.GetType(tc.Type);
var type = Type.GetType(typeName);
var instance = Activator.CreateInstance(type) as FrameworkElement;
@ -51,17 +43,4 @@ namespace Sample
}
}
}
[Bindable]
public class TestControl
{
public TestControl(string name, string type)
{
Name = name;
Type = type;
}
public string Name { get; }
public string Type { get; }
}
}

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

@ -1,6 +1,9 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using Sample.UITests;
using Uno.UITest;
@ -13,12 +16,23 @@ namespace SamplesApp.UITests
{
public const string UITestPlatform = "UNO_UITEST_PLATFORM";
public const string UITEST_IOSBUNDLE_PATH = "UNO_UITEST_IOSBUNDLE_PATH";
public const string UITEST_IOSDEVICE_ID = "UITEST_IOSDEVICE_ID";
public const string UITEST_ANDROIDAPK_PATH = "UNO_UITEST_ANDROIDAPK_PATH";
public const string UITEST_SCREENSHOT_PATH = "UNO_UITEST_SCREENSHOT_PATH";
private const string DriverPath = @"..\..\..\..\..\..\build\node_modules\chromedriver\lib\chromedriver";
private static IApp _currentApp;
public static IApp StartApp(bool alreadyRunningApp)
public static IApp ColdStartApp()
=> Xamarin.UITest.TestEnvironment.Platform == Xamarin.UITest.TestPlatform.Local
? StartApp(alreadyRunningApp: false)
: null;
public static IApp AttachToApp()
// If the retry count is set, the test already failed. Retry the test with restarting the app.
=> StartApp(alreadyRunningApp: TestContext.CurrentContext.CurrentRepeatCount == 0);
private static IApp StartApp(bool alreadyRunningApp)
{
Console.WriteLine($"Starting app ({alreadyRunningApp})");
@ -47,7 +61,15 @@ namespace SamplesApp.UITests
return CreateiOSApp(alreadyRunningApp);
case Platform.Browser:
return CreateBrowserApp();
if(alreadyRunningApp)
{
return CreateBrowserApp(alreadyRunningApp);
}
else
{
// Skip cold app start, there's no notion of reuse active browser yet.
return null;
}
default:
throw new Exception($"Platform {localPlatform} is not enabled.");
@ -55,22 +77,52 @@ namespace SamplesApp.UITests
}
}
private static IApp CreateBrowserApp() => Uno.UITest.Selenium.ConfigureApp
.WebAssembly
.Uri(new Uri(Constants.DefaultUri))
.ChromeDriverLocation(Path.Combine(TestContext.CurrentContext.TestDirectory, DriverPath.Replace('\\', Path.DirectorySeparatorChar)))
.ScreenShotsPath(TestContext.CurrentContext.TestDirectory)
private static IApp CreateBrowserApp(bool alreadyRunningApp)
{
if(_currentApp != null)
{
if(!alreadyRunningApp)
{
_currentApp.Dispose();
}
else
{
return _currentApp;
}
}
try
{
var app = _currentApp = Uno.UITest.Selenium.ConfigureApp
.WebAssembly
.Uri(new Uri(Constants.DefaultUri))
.ChromeDriverLocation(Path.Combine(TestContext.CurrentContext.TestDirectory,
DriverPath.Replace('\\', Path.DirectorySeparatorChar)))
.ScreenShotsPath(TestContext.CurrentContext.TestDirectory)
#if DEBUG
.Headless(false)
.Headless(false)
.SeleniumArgument("--remote-debugging-port=9222")
#endif
.StartApp();
.StartApp();
return app;
}
catch(Exception ex)
{
Console.Error.WriteLine(ex.Message);
throw;
}
}
private static IApp CreateAndroidApp(bool alreadyRunningApp)
{
// To set in case of Xamarin.UITest errors
//
// Environment.SetEnvironmentVariable("ANDROID_HOME", @"C:\Program Files (x86)\Android\android-sdk");
// Environment.SetEnvironmentVariable("JAVA_HOME", @"C:\Program Files\Android\Jdk\microsoft_dist_openjdk_1.8.0.25");
if(string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ANDROID_HOME")))
{
// To set in case of Xamarin.UITest errors
//
Environment.SetEnvironmentVariable("ANDROID_HOME", @"C:\Program Files (x86)\Android\android-sdk");
Environment.SetEnvironmentVariable("JAVA_HOME", @"C:\Program Files\Android\Jdk\microsoft_dist_openjdk_1.8.0.25");
}
var androidConfig = Xamarin.UITest.ConfigureApp
.Android
@ -90,49 +142,76 @@ namespace SamplesApp.UITests
? androidConfig.ConnectToApp()
: androidConfig.StartApp();
ApplyScreenShotPath();
return app.ToUnoApp();
}
private static void ApplyScreenShotPath()
{
var value = Environment.GetEnvironmentVariable(UITEST_SCREENSHOT_PATH);
if(!string.IsNullOrWhiteSpace(value))
{
Environment.CurrentDirectory = value;
}
else
{
Environment.CurrentDirectory = Path.GetDirectoryName(new Uri(typeof(AppInitializer).Assembly.Location).LocalPath);
}
}
private static IApp CreateiOSApp(bool alreadyRunningApp)
{
var iOSConfig = Xamarin.UITest.ConfigureApp
.iOS
.Debug()
.DeviceIdentifier(GetiOSDeviceId())
.LogDirectory(Environment.GetEnvironmentVariable(UITEST_SCREENSHOT_PATH))
.EnableLocalScreenshots();
if(GetiOSAppBundlePath() is string bundlePath)
{
Console.WriteLine($"Using AppBundle Path: {bundlePath}");
iOSConfig = iOSConfig.AppBundle(bundlePath);
}
else
{
iOSConfig = iOSConfig.InstalledApp(Constants.AndroidAppName);
Console.WriteLine($"Using Installed App: {Constants.iOSAppName}");
iOSConfig = iOSConfig.InstalledApp(Constants.iOSAppName);
}
var app = alreadyRunningApp
? iOSConfig.ConnectToApp()
: iOSConfig.StartApp();
ApplyScreenShotPath();
: iOSConfig.StartApp(Xamarin.UITest.Configuration.AppDataMode.DoNotClear);
return app.ToUnoApp();
}
private static string GetiOSDeviceId()
{
var environmentDeviceId = Environment.GetEnvironmentVariable(UITEST_IOSDEVICE_ID) ?? "";
if(!Guid.TryParse(environmentDeviceId, out var deviceId))
{
var deviceName = !string.IsNullOrEmpty(environmentDeviceId) ? environmentDeviceId : Constants.iOSDeviceNameOrId;
Process process = new Process();
process.StartInfo.FileName = "xcrun";
process.StartInfo.Arguments = $"simctl list devices -j \"{deviceName}\" available";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
var deviceList = JsonConvert.DeserializeObject(process.StandardOutput.ReadToEnd()) as JObject;
if(deviceList != null
&& deviceList["devices"] is JObject systems)
{
foreach(var system in systems.Values())
{
if(system is JArray devices)
{
foreach(var device in devices)
{
if(device is JObject dev)
{
return device["udid"].ToString();
}
}
}
}
}
process.WaitForExit();
}
return environmentDeviceId;
}
private static string GetAndroidApkPath()
{
var value = Environment.GetEnvironmentVariable(UITEST_ANDROIDAPK_PATH);

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

@ -14,7 +14,7 @@ namespace Sample.UITests
[Test]
public void CheckBox01()
{
Query checkBoxSelector = q => q.Text("CheckBox 1");
Query checkBoxSelector = q => q.Marked("CheckBox01");
App.WaitForElement(checkBoxSelector);
App.Tap(checkBoxSelector);

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

@ -11,8 +11,9 @@ namespace Sample.UITests
{
public const string DefaultUri = "http://localhost:51669/";
public const string ChromeDriver = @"C:\s\ChromeDriver\74.0.3729.6";
public readonly static string iOSAppName;
public readonly static string iOSAppName = "uno.platform.uitestsample";
public readonly static string AndroidAppName = "uno.platform.uitestsample";
public readonly static string iOSDeviceNameOrId = "iPad Pro (12.9-inch) (3rd generation)";
public readonly static Platform CurrentPlatform = Platform.Browser;
}

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

@ -15,7 +15,7 @@ namespace Sample.UITests
[Test]
public void DragBorder01()
{
Query testSelector = q => q.Text("DragCoordinates 01");
Query testSelector = q => q.Marked("DragCoordinates01");
Query rootCanvas = q => q.Marked("rootCanvas");
Query myBorder = q => q.Marked("myBorder");
@ -43,12 +43,17 @@ namespace Sample.UITests
App.Screenshot("DragBorder01 - Step 2");
if(Xamarin.UITest.TestEnvironment.Platform == Xamarin.UITest.TestPlatform.TestCloudAndroid
|| SamplesApp.UITests.AppInitializer.GetLocalPlatform() == Platform.Android)
|| SamplesApp.UITests.AppInitializer.GetLocalPlatform() == Platform.Android
|| Xamarin.UITest.TestEnvironment.Platform == Xamarin.UITest.TestPlatform.TestCloudiOS
|| SamplesApp.UITests.AppInitializer.GetLocalPlatform() == Platform.iOS)
{
// PointerEvents don't fire properly on Android, causing this test to fail https://github.com/unoplatform/uno/issues/1257
// PointerEvents are reporting an off by one value. May be fixed by https://github.com/unoplatform/uno/issues/1256
return;
}
var value = App.Query(q => topValue(q).GetDependencyPropertyValue("Text").Value<string>()).First();
App.WaitForDependencyPropertyValue(topValue, "Text", "50");
App.WaitForDependencyPropertyValue(leftValue, "Text", "50");

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

@ -14,7 +14,7 @@ namespace Sample.UITests
[Test]
public void RadioButton01()
{
Query testSelector = q => q.Text("RadioButton 01");
Query testSelector = q => q.Marked("RadioButton01");
App.WaitForElement(testSelector);
App.Tap(testSelector);

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

@ -7,8 +7,9 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
</ItemGroup>
<ItemGroup>

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

@ -8,26 +8,34 @@ namespace Sample.UITests
{
public class TestBase
{
private IApp _app;
static TestBase()
{
// Start the app only once, so the tests runs don't restart it
// and gain some time for the tests.
AppInitializer.StartApp(alreadyRunningApp: false);
AppInitializer.ColdStartApp();
}
protected IApp App { get; private set; }
protected IApp App
{
get => _app;
private set
{
_app = value;
Uno.UITest.Helpers.Queries.Helpers.App = value;
}
}
[SetUp]
public void StartApp()
{
App = AppInitializer.StartApp(alreadyRunningApp: true);
Uno.UITest.Helpers.Queries.Helpers.App = App;
App = AppInitializer.AttachToApp();
}
[TearDown]
public void CloseApp()
{
App.Dispose();
}
}
}

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

@ -15,7 +15,7 @@ namespace Sample.UITests
[Test]
public void TextBox01()
{
Query testSelector = q => q.Text("TextBox 01");
Query testSelector = q => q.Marked("TextBox01");
Query tb01 = q => q.Marked("tb01");
StringQuery textSelector = q =>
tb01(q).GetDependencyPropertyValue("Text").Value<string>();

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

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<dict>
<key>CFBundleDisplayName</key>
<string>UnoQuickStart.iOS</string>
<key>CFBundleIdentifier</key>
<string>com.companyname.Sample</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
@ -13,35 +11,35 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string></string>
<string>11.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
<string>arm64</string>
<string>armv7</string>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIAppFonts</key>
<array>
<string>Fonts/winjs-symbols.ttf</string>
<string>Fonts/winjs-symbols.ttf</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
@ -51,5 +49,9 @@
<string>Portait</string>
<key>UILaunchImageSize</key>
<string>{320, 568}</string>
</dict>
<key>CFBundleIdentifier</key>
<string>uno.platform.uitestsample</string>
<key>CFBundleName</key>
<string>Uno.UI Test Samples</string>
</dict>
</plist>

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

@ -13,6 +13,9 @@
</NuGetPackageImportStamp>
<ResourcesDirectory>..\Sample.Shared\Strings</ResourcesDirectory>
</PropertyGroup>
<PropertyGroup>
<IsUiAutomationMappingEnabled>true</IsUiAutomationMappingEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
@ -116,6 +119,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Uno.UI" Version="1.46.0-dev.1991" />
<PackageReference Include="Xamarin.TestCloud.Agent">
<Version>0.21.8</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Media.xcassets\AppIcons.appiconset\Contents.json">

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

@ -24,7 +24,6 @@ namespace Uno.UITest.Selenium
public SeleniumApp(ChromeAppConfigurator config)
{
// --whitelisted-ips
var targetUri = GetEnvironmentVariable("UNO_UITEST_TARGETURI", config.SiteUri.OriginalString);
var driverPath = GetEnvironmentVariable("UNO_UITEST_DRIVERPATH_CHROME", config.ChromeDriverPath);
var screenShotPath = GetEnvironmentVariable("UNO_UITEST_SCREENSHOT_PATH", config.InternalScreenShotsPath);
@ -52,7 +51,7 @@ namespace Uno.UITest.Selenium
//
// When InternalDetectDockerEnvironment is set, tell the daemon to listen on
// all available interfaces
Console.WriteLine($"Detected docker environment, adding whitelisted-ips");
Console.WriteLine($"Container mode enabled, adding whitelisted-ips");
options.AddArguments("--whitelisted-ips");
}
}
@ -86,6 +85,20 @@ namespace Uno.UITest.Selenium
return hasValue ? value : defaultValue;
}
private bool GetEnvironmentVariable(string variableName, bool defaultValue)
{
var value = Environment.GetEnvironmentVariable(variableName);
var hasValue = bool.TryParse(value, out var varValue);
if(hasValue)
{
Console.WriteLine($"Overriding value with {variableName} = {value}");
}
return hasValue ? varValue : defaultValue;
}
void PerformActions(Action<Actions> action)
{
var actions = new OpenQA.Selenium.Interactions.Actions(_driver);

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

@ -7,10 +7,26 @@ namespace Uno.UITest.Xamarin.Extensions
{
public static class AppTypedSelectorExtensions
{
public static IAppTypedSelector<T> AsGenericAppTypedSelector<T>(this AppTypedSelector<T> selector)
public static IAppTypedSelector<T> AsGenericAppTypedSelector<T>(this AppTypedSelector<object> selector)
=> new XamarinAppTypedSelector<T>(selector);
public static AppTypedSelector<T> ToXamarinAppTypedSelector<T>(this IAppTypedSelector<T> selector)
=> selector is XamarinAppTypedSelector<T> ts ? ts.Source : throw new InvalidOperationException();
public static IAppTypedSelector<string> AsGenericAppTypedSelector(this AppTypedSelector<string> selector)
=> new XamarinAppTypedSelector<string>(selector.Value<object>());
public static AppTypedSelector<object> ToXamarinAppTypedSelector<T>(this IAppTypedSelector<T> selector)
{
if(selector is XamarinAppTypedSelector<T> tso)
{
return tso.Source;
}
else if(selector is XamarinAppTypedSelector<string> tss)
{
return tss.Source;
}
else
{
throw new InvalidOperationException();
}
}
}
}

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

@ -20,7 +20,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.UITest" Version="3.0.0" />
<PackageReference Include="Xamarin.UITest" Version="3.0.4-dev1" />
</ItemGroup>
<ItemGroup>

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

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@ -164,7 +165,9 @@ namespace Uno.UITest.Xamarin
public T[] Query<T>(Func<IAppQuery, IAppTypedSelector<T>> query)
=> _source.Query(
q => query(q.AsGenericAppQuery()).ToXamarinAppTypedSelector()
);
)
.Select(o => (T)Convert.ChangeType(o, typeof(T), CultureInfo.InvariantCulture))
.ToArray();
public void Repl()
=> _source.Repl();

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

@ -47,22 +47,22 @@ namespace Uno.UITest.Xamarin.Extensions
=> SourceQuery.Index(index).AsGenericAppQuery();
IAppTypedSelector<object> IAppQuery.Invoke(string methodName)
=> SourceQuery.Invoke(methodName).AsGenericAppTypedSelector();
=> SourceQuery.Invoke(methodName).AsGenericAppTypedSelector<object>();
IAppTypedSelector<object> IAppQuery.Invoke(string methodName, object arg1)
=> SourceQuery.Invoke(methodName, arg1).AsGenericAppTypedSelector();
=> SourceQuery.Invoke(methodName, arg1).AsGenericAppTypedSelector<object>();
IAppTypedSelector<object> IAppQuery.Invoke(string methodName, object arg1, object arg2)
=> SourceQuery.Invoke(methodName, arg1, arg2).AsGenericAppTypedSelector();
=> SourceQuery.Invoke(methodName, arg1, arg2).AsGenericAppTypedSelector<object>();
IAppTypedSelector<object> IAppQuery.Invoke(string methodName, object arg1, object arg2, object arg3)
=> SourceQuery.Invoke(methodName, arg1, arg2, arg3).AsGenericAppTypedSelector();
=> SourceQuery.Invoke(methodName, arg1, arg2, arg3).AsGenericAppTypedSelector<object>();
IAppTypedSelector<object> IAppQuery.Invoke(string methodName, object arg1, object arg2, object arg3, object arg4)
=> SourceQuery.Invoke(methodName, arg1, arg2, arg3, arg4).AsGenericAppTypedSelector();
=> SourceQuery.Invoke(methodName, arg1, arg2, arg3, arg4).AsGenericAppTypedSelector<object>();
IAppTypedSelector<object> IAppQuery.Invoke(string methodName, object arg1, object arg2, object arg3, object arg4, object arg5)
=> SourceQuery.Invoke(methodName, arg1, arg2, arg3, arg4, arg5).AsGenericAppTypedSelector();
=> SourceQuery.Invoke(methodName, arg1, arg2, arg3, arg4, arg5).AsGenericAppTypedSelector<object>();
IInvokeJSAppQuery IAppQuery.InvokeJS(string javascript)
=> SourceQuery.InvokeJS(javascript).AsGenericInvokeJSAppQuery();

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

@ -4,13 +4,13 @@ namespace Uno.UITest.Xamarin
{
internal class XamarinAppTypedSelector<T> : IAppTypedSelector<T>
{
private AppTypedSelector<T> _source;
private AppTypedSelector<object> _source;
public XamarinAppTypedSelector(AppTypedSelector<T> selector)
public XamarinAppTypedSelector(AppTypedSelector<object> selector)
=> _source = selector;
public AppTypedSelector<T> Source => _source;
public AppTypedSelector<object> Source => _source;
IAppTypedSelector<object> IAppTypedSelector<T>.Invoke(string methodName)
=> new XamarinAppTypedSelector<object>(_source.Invoke(methodName));
@ -30,6 +30,6 @@ namespace Uno.UITest.Xamarin
=> new XamarinAppTypedSelector<object>(_source.Invoke(methodName, arg1, arg2, arg3, arg4, arg5));
IAppTypedSelector<TResult> IAppTypedSelector<T>.Value<TResult>()
=> new XamarinAppTypedSelector<TResult>(_source.Value<TResult>());
=> new XamarinAppTypedSelector<TResult>(_source.Value<object>());
}
}

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

@ -21,6 +21,6 @@ namespace Uno.UITest.Xamarin
IAppQuery IPropertyAppQuery.StartsWith(string text) => _source.StartsWith(text).AsGenericAppQuery();
IAppTypedSelector<T> IPropertyAppQuery.Value<T>() => _source.Value<T>().AsGenericAppTypedSelector();
IAppTypedSelector<T> IPropertyAppQuery.Value<T>() => _source.Value<object>().AsGenericAppTypedSelector<T>();
}
}