Add iOS UI Testing support
This commit is contained in:
Родитель
15efcff14e
Коммит
cfcc68f1d2
|
@ -235,3 +235,4 @@ Resource.Designer.cs
|
|||
/build/*.nupkg
|
||||
|
||||
src/nuget_override.props
|
||||
.DS_Store
|
||||
|
|
39
.vsts-ci.yml
39
.vsts-ci.yml
|
@ -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
|
||||
|
|
|
@ -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,6 +39,12 @@ 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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
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)))
|
||||
.ChromeDriverLocation(Path.Combine(TestContext.CurrentContext.TestDirectory,
|
||||
DriverPath.Replace('\\', Path.DirectorySeparatorChar)))
|
||||
.ScreenShotsPath(TestContext.CurrentContext.TestDirectory)
|
||||
#if DEBUG
|
||||
.Headless(false)
|
||||
.SeleniumArgument("--remote-debugging-port=9222")
|
||||
#endif
|
||||
.StartApp();
|
||||
|
||||
return app;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine(ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static IApp CreateAndroidApp(bool alreadyRunningApp)
|
||||
{
|
||||
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");
|
||||
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>
|
||||
<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,7 +11,7 @@
|
|||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string></string>
|
||||
<string>11.0</string>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
|
@ -51,5 +49,9 @@
|
|||
<string>Portait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{320, 568}</string>
|
||||
<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,12 +4,12 @@ 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>();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче