1
0
Эх сурвалжийг харах

Started adding integration tests.

Steven Kirk 4 жил өмнө
parent
commit
c1dfc1f963

+ 5 - 0
.ncrunch/Avalonia.IntegrationTests.Win32.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/IntegrationTestApp.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 57 - 3
Avalonia.sln

@@ -226,11 +226,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.Events"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTestApp", "samples\IntegrationTestApp\IntegrationTestApp.csproj", "{676D6BFD-029D-4E43-BFC7-3892265CE251}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.IntegrationTests.Win32", "tests\Avalonia.IntegrationTests.Win32\Avalonia.IntegrationTests.Win32.csproj", "{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}"
 EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
@@ -2142,6 +2146,54 @@ Global
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.Build.0 = Release|Any CPU
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|Any CPU.Build.0 = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhone.Build.0 = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhone.Build.0 = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -2203,6 +2255,8 @@ Global
 		{11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{676D6BFD-029D-4E43-BFC7-3892265CE251} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

+ 7 - 0
samples/IntegrationTestApp/App.axaml

@@ -0,0 +1,7 @@
+<Application xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             x:Class="IntegrationTestApp.App">
+    <Application.Styles>
+        <FluentTheme Mode="Light"/>
+    </Application.Styles>
+</Application>

+ 24 - 0
samples/IntegrationTestApp/App.axaml.cs

@@ -0,0 +1,24 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+
+namespace IntegrationTestApp
+{
+    public class App : Application
+    {
+        public override void Initialize()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+
+        public override void OnFrameworkInitializationCompleted()
+        {
+            if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+            {
+                desktop.MainWindow = new MainWindow();
+            }
+
+            base.OnFrameworkInitializationCompleted();
+        }
+    }
+}

+ 10 - 0
samples/IntegrationTestApp/IntegrationTestApp.csproj

@@ -0,0 +1,10 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+  <Import Project="..\..\build\BuildTargets.targets" />
+  <Import Project="..\..\build\SampleApp.props" />
+  <Import Project="..\..\build\ReferenceCoreLibraries.props" />
+</Project>

+ 22 - 0
samples/IntegrationTestApp/MainWindow.axaml

@@ -0,0 +1,22 @@
+<Window xmlns="https://github.com/avaloniaui"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+        x:Class="IntegrationTestApp.MainWindow"
+        Title="IntegrationTestApp">
+  <TabControl TabStripPlacement="Left" AutomationProperties.AutomationId="MainTabs">
+    <TabItem Header="Button">
+      <StackPanel>
+        <Button AutomationProperties.AutomationId="BasicButton">
+            Basic Button
+        </Button>
+        <Button AutomationProperties.AutomationId="ButtonWithTextBlock">
+            <TextBlock>Button with TextBlock</TextBlock>
+        </Button>
+      </StackPanel>
+    </TabItem>
+    <TabItem Header="ComboBox">
+    </TabItem>
+  </TabControl>
+</Window>

+ 19 - 0
samples/IntegrationTestApp/MainWindow.axaml.cs

@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace IntegrationTestApp
+{
+    public class MainWindow : Window
+    {
+        public MainWindow()
+        {
+            InitializeComponent();
+        }
+
+        private void InitializeComponent()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+    }
+}

+ 22 - 0
samples/IntegrationTestApp/Program.cs

@@ -0,0 +1,22 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+
+namespace IntegrationTestApp
+{
+    class Program
+    {
+        // Initialization code. Don't use any Avalonia, third-party APIs or any
+        // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
+        // yet and stuff might break.
+        public static void Main(string[] args) => BuildAvaloniaApp()
+            .StartWithClassicDesktopLifetime(args);
+
+        // Avalonia configuration, don't remove; also used by visual designer.
+        public static AppBuilder BuildAvaloniaApp()
+            => AppBuilder.Configure<App>()
+                .UsePlatformDetect()
+                .LogToTrace();
+    }
+}

+ 11 - 0
samples/IntegrationTestApp/nuget.config

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 
+  To use the Avalonia CI feed to get unstable packages, move this file to the root of your solution.
+-->
+
+<configuration>
+  <packageSources>
+    <add key="AvaloniaCI" value="https://www.myget.org/F/avalonia-ci/api/v2" />
+  </packageSources>
+</configuration>

+ 3 - 0
src/Avalonia.Controls/Automation/Peers/ButtonAutomationPeer.cs

@@ -24,6 +24,9 @@ namespace Avalonia.Automation.Peers
         {
             return AutomationControlType.Button;
         }
+
+        protected override bool IsContentElementCore() => true;
+        protected override bool IsControlElementCore() => true;
     }
 }
 

+ 1 - 0
src/Avalonia.Controls/Properties/AssemblyInfo.cs

@@ -9,6 +9,7 @@ using Avalonia.Metadata;
 [assembly: InternalsVisibleTo("Avalonia.DesignerSupport")]
 #endif
 [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")]
+[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Automation")]
 [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
 [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Embedding")]
 [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Presenters")]

+ 13 - 0
tests/Avalonia.IntegrationTests.Win32/Avalonia.IntegrationTests.Win32.csproj

@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Appium.WebDriver" Version="4.3.1" />
+  </ItemGroup>
+
+  <Import Project="..\..\build\XUnit.props" />
+</Project>

+ 40 - 0
tests/Avalonia.IntegrationTests.Win32/ButtonTests.cs

@@ -0,0 +1,40 @@
+using OpenQA.Selenium.Appium.Windows;
+using Xunit;
+
+namespace Avalonia.IntegrationTests.Win32
+{
+    [Collection("IntegrationTestApp collection")]
+    public class ButtonTests
+    {
+        private WindowsDriver<WindowsElement> _session;
+        public ButtonTests(TestAppFixture fixture) => _session = fixture.Session;
+
+        [Fact]
+        public void BasicButton()
+        {
+            SelectButtonTab();
+            
+            var button = _session.FindElementByAccessibilityId("BasicButton");
+
+            Assert.Equal("Basic Button", button.Text);
+        }
+
+        [Fact]
+        public void ButtonWithTextBlock()
+        {
+            SelectButtonTab();
+
+            var button = _session.FindElementByAccessibilityId("ButtonWithTextBlock");
+
+            Assert.Equal("Button with TextBlock", button.Text);
+        }
+
+        private WindowsElement SelectButtonTab()
+        {
+            var tabs = _session.FindElementByAccessibilityId("MainTabs");
+            var buttonTab = tabs.FindElementByName("Button");
+            buttonTab.Click();
+            return (WindowsElement)buttonTab;
+        }
+    }
+}

+ 4 - 0
tests/Avalonia.IntegrationTests.Win32/Properties/AssemblyInfo.cs

@@ -0,0 +1,4 @@
+using Xunit;
+
+// Don't run tests in parallel.
+[assembly: CollectionBehavior(DisableTestParallelization = true)]

+ 9 - 0
tests/Avalonia.IntegrationTests.Win32/TestAppCollection.cs

@@ -0,0 +1,9 @@
+using Xunit;
+
+namespace Avalonia.IntegrationTests.Win32
+{
+    [CollectionDefinition("IntegrationTestApp collection")]
+    public class TestAppCollection : ICollectionFixture<TestAppFixture>
+    {
+    }
+}

+ 28 - 0
tests/Avalonia.IntegrationTests.Win32/TestAppFixture.cs

@@ -0,0 +1,28 @@
+using System;
+using System.IO;
+using OpenQA.Selenium.Appium;
+using OpenQA.Selenium.Appium.Windows;
+
+namespace Avalonia.IntegrationTests.Win32
+{
+    public class TestAppFixture : IDisposable
+    {
+        private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
+        private const string TestAppPath = @"..\..\..\..\..\samples\IntegrationTestApp\bin\Debug\netcoreapp3.1\IntegrationTestApp.exe";
+
+        public TestAppFixture()
+        {
+            var opts = new AppiumOptions();
+            var path = Path.GetFullPath(TestAppPath);
+            opts.AddAdditionalCapability("app", path);
+            opts.AddAdditionalCapability("deviceName", "WindowsPC");
+            Session = new WindowsDriver<WindowsElement>(
+                new Uri(WindowsApplicationDriverUrl),
+                opts);
+        }
+
+        public WindowsDriver<WindowsElement> Session { get; }
+
+        public void Dispose() => Session.Close();
+    }
+}

+ 3 - 0
tests/Avalonia.IntegrationTests.Win32/xunit.runner.json

@@ -0,0 +1,3 @@
+{
+  "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json"
+}