Browse Source
Even though we don't have automation there and so can't do integration testing, it's still useful for manual testing.pull/8415/head
12 changed files with 485 additions and 8 deletions
@ -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> |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
<PropertyGroup> |
|||
<OutputType>WinExe</OutputType> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<CFBundleName>IntegrationTestApp</CFBundleName> |
|||
<CFBundleIdentifier>net.avaloniaui.avalonia.integrationtestapp</CFBundleIdentifier> |
|||
<NSHighResolutionCapable>true</NSHighResolutionCapable> |
|||
<CFBundleShortVersionString>1.0.0</CFBundleShortVersionString> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Dotnet.Bundle" Version="0.9.13" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> |
|||
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<Import Project="..\..\build\BuildTargets.targets" /> |
|||
<Import Project="..\..\build\SampleApp.props" /> |
|||
<Import Project="..\..\build\ReferenceCoreLibraries.props" /> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,120 @@ |
|||
<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" |
|||
Name="MainWindow" |
|||
Title="IntegrationTestApp"> |
|||
<NativeMenu.Menu> |
|||
<NativeMenu> |
|||
<NativeMenuItem Header="File"> |
|||
<NativeMenu> |
|||
<NativeMenuItem Header="Open..."/> |
|||
</NativeMenu> |
|||
</NativeMenuItem> |
|||
<NativeMenuItem Header="View"> |
|||
<NativeMenu/> |
|||
</NativeMenuItem> |
|||
</NativeMenu> |
|||
</NativeMenu.Menu> |
|||
<DockPanel> |
|||
<NativeMenuBar DockPanel.Dock="Top"/> |
|||
|
|||
<TabControl TabStripPlacement="Left" Name="MainTabs"> |
|||
<TabItem Header="Automation"> |
|||
<StackPanel> |
|||
<TextBlock Name="TextBlockWithName">TextBlockWithName</TextBlock> |
|||
<TextBlock Name="NotTheAutomationId"> |
|||
TextBlockWithNameAndAutomationId |
|||
</TextBlock> |
|||
<TextBlock Name="TextBlockAsLabel">Label for TextBox</TextBlock> |
|||
<TextBox Name="LabeledByTextBox"> |
|||
Foo |
|||
</TextBox> |
|||
</StackPanel> |
|||
</TabItem> |
|||
|
|||
<TabItem Header="Button"> |
|||
<StackPanel> |
|||
<Button Name="DisabledButton" IsEnabled="False"> |
|||
Disabled Button |
|||
</Button> |
|||
<Button Name="BasicButton"> |
|||
Basic Button |
|||
</Button> |
|||
<Button Name="ButtonWithTextBlock"> |
|||
<TextBlock>Button with TextBlock</TextBlock> |
|||
</Button> |
|||
<Button Name="ButtonWithAcceleratorKey" HotKey="Ctrl+B">Button with Accelerator Key</Button> |
|||
</StackPanel> |
|||
</TabItem> |
|||
|
|||
<TabItem Header="CheckBox"> |
|||
<StackPanel> |
|||
<CheckBox Name="UncheckedCheckBox">Unchecked</CheckBox> |
|||
<CheckBox Name="CheckedCheckBox" IsChecked="True">Checked</CheckBox> |
|||
<CheckBox Name="ThreeStateCheckBox" IsThreeState="True" IsChecked="{x:Null}">ThreeState</CheckBox> |
|||
</StackPanel> |
|||
</TabItem> |
|||
|
|||
<TabItem Header="ComboBox"> |
|||
<StackPanel> |
|||
<ComboBox Name="BasicComboBox"> |
|||
<ComboBoxItem>Item 0</ComboBoxItem> |
|||
<ComboBoxItem>Item 1</ComboBoxItem> |
|||
</ComboBox> |
|||
<Button Name="ComboBoxSelectionClear">Clear Selection</Button> |
|||
<Button Name="ComboBoxSelectFirst">Select First</Button> |
|||
</StackPanel> |
|||
</TabItem> |
|||
|
|||
<TabItem Header="ListBox"> |
|||
<DockPanel> |
|||
<StackPanel DockPanel.Dock="Bottom"> |
|||
<Button Name="ListBoxSelectionClear">Clear Selection</Button> |
|||
</StackPanel> |
|||
<ListBox Name="BasicListBox" Items="{Binding ListBoxItems}" SelectionMode="Multiple"/> |
|||
</DockPanel> |
|||
</TabItem> |
|||
|
|||
<TabItem Header="Menu"> |
|||
<DockPanel> |
|||
<Menu DockPanel.Dock="Top"> |
|||
<MenuItem Name="RootMenuItem" Header="_Root"> |
|||
<MenuItem Name="Child1MenuItem" Header="_Child 1" InputGesture="Ctrl+O" Click="MenuClicked"/> |
|||
<MenuItem Name="Child2MenuItem" Header="C_hild 2"> |
|||
<MenuItem Name="GrandchildMenuItem" Header="_Grandchild" Click="MenuClicked"/> |
|||
</MenuItem> |
|||
</MenuItem> |
|||
</Menu> |
|||
<StackPanel> |
|||
<TextBlock Name="ClickedMenuItem">None</TextBlock> |
|||
<Button Name="MenuClickedMenuItemReset">Reset</Button> |
|||
<TextBox Name="MenuFocusTest"/> |
|||
</StackPanel> |
|||
</DockPanel> |
|||
</TabItem> |
|||
|
|||
<TabItem Header="Window"> |
|||
<StackPanel> |
|||
<TextBox Name="ShowWindowSize" Watermark="Window Size"/> |
|||
<ComboBox Name="ShowWindowMode" SelectedIndex="0"> |
|||
<ComboBoxItem>NonOwned</ComboBoxItem> |
|||
<ComboBoxItem>Owned</ComboBoxItem> |
|||
<ComboBoxItem>Modal</ComboBoxItem> |
|||
</ComboBox> |
|||
<ComboBox Name="ShowWindowLocation" SelectedIndex="0"> |
|||
<ComboBoxItem>Manual</ComboBoxItem> |
|||
<ComboBoxItem>CenterScreen</ComboBoxItem> |
|||
<ComboBoxItem>CenterOwner</ComboBoxItem> |
|||
</ComboBox> |
|||
<Button Name="ShowWindow">Show Window</Button> |
|||
<Button Name="SendToBack">Send to Back</Button> |
|||
<Button Name="ExitFullscreen">Exit Fullscreen</Button> |
|||
<Button Name="RestoreAll">Restore All</Button> |
|||
</StackPanel> |
|||
</TabItem> |
|||
</TabControl> |
|||
</DockPanel> |
|||
</Window> |
|||
@ -0,0 +1,135 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.ApplicationLifetimes; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace IntegrationTestApp |
|||
{ |
|||
public class MainWindow : Window |
|||
{ |
|||
public MainWindow() |
|||
{ |
|||
InitializeComponent(); |
|||
InitializeViewMenu(); |
|||
this.AttachDevTools(); |
|||
AddHandler(Button.ClickEvent, OnButtonClick); |
|||
ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList(); |
|||
DataContext = this; |
|||
} |
|||
|
|||
public List<string> ListBoxItems { get; } |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
|
|||
private void InitializeViewMenu() |
|||
{ |
|||
var mainTabs = this.FindControl<TabControl>("MainTabs"); |
|||
var viewMenu = (NativeMenuItem)NativeMenu.GetMenu(this).Items[1]; |
|||
|
|||
foreach (TabItem tabItem in mainTabs.Items) |
|||
{ |
|||
var menuItem = new NativeMenuItem |
|||
{ |
|||
Header = (string)tabItem.Header!, |
|||
IsChecked = tabItem.IsSelected, |
|||
ToggleType = NativeMenuItemToggleType.Radio, |
|||
}; |
|||
|
|||
menuItem.Click += (s, e) => tabItem.IsSelected = true; |
|||
viewMenu.Menu.Items.Add(menuItem); |
|||
} |
|||
} |
|||
|
|||
private void ShowWindow() |
|||
{ |
|||
var sizeTextBox = this.GetControl<TextBox>("ShowWindowSize"); |
|||
var modeComboBox = this.GetControl<ComboBox>("ShowWindowMode"); |
|||
var locationComboBox = this.GetControl<ComboBox>("ShowWindowLocation"); |
|||
var size = !string.IsNullOrWhiteSpace(sizeTextBox.Text) ? Size.Parse(sizeTextBox.Text) : (Size?)null; |
|||
var owner = (Window)this.GetVisualRoot()!; |
|||
|
|||
var window = new ShowWindowTest |
|||
{ |
|||
WindowStartupLocation = (WindowStartupLocation)locationComboBox.SelectedIndex, |
|||
}; |
|||
|
|||
if (size.HasValue) |
|||
{ |
|||
window.Width = size.Value.Width; |
|||
window.Height = size.Value.Height; |
|||
} |
|||
|
|||
sizeTextBox.Text = string.Empty; |
|||
|
|||
switch (modeComboBox.SelectedIndex) |
|||
{ |
|||
case 0: |
|||
window.Show(); |
|||
break; |
|||
case 1: |
|||
window.Show(owner); |
|||
break; |
|||
case 2: |
|||
window.ShowDialog(owner); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
private void SendToBack() |
|||
{ |
|||
var lifetime = (ClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!; |
|||
|
|||
foreach (var window in lifetime.Windows) |
|||
{ |
|||
window.Activate(); |
|||
} |
|||
} |
|||
|
|||
private void RestoreAll() |
|||
{ |
|||
var lifetime = (ClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!; |
|||
|
|||
foreach (var window in lifetime.Windows) |
|||
{ |
|||
if (window.WindowState == WindowState.Minimized) |
|||
window.WindowState = WindowState.Normal; |
|||
} |
|||
} |
|||
|
|||
private void MenuClicked(object? sender, RoutedEventArgs e) |
|||
{ |
|||
var clickedMenuItemTextBlock = this.FindControl<TextBlock>("ClickedMenuItem"); |
|||
clickedMenuItemTextBlock.Text = ((MenuItem)sender!).Header.ToString(); |
|||
} |
|||
|
|||
private void OnButtonClick(object? sender, RoutedEventArgs e) |
|||
{ |
|||
var source = e.Source as Button; |
|||
|
|||
if (source?.Name == "ComboBoxSelectionClear") |
|||
this.FindControl<ComboBox>("BasicComboBox").SelectedIndex = -1; |
|||
if (source?.Name == "ComboBoxSelectFirst") |
|||
this.FindControl<ComboBox>("BasicComboBox").SelectedIndex = 0; |
|||
if (source?.Name == "ListBoxSelectionClear") |
|||
this.FindControl<ListBox>("BasicListBox").SelectedIndex = -1; |
|||
if (source?.Name == "MenuClickedMenuItemReset") |
|||
this.FindControl<TextBlock>("ClickedMenuItem").Text = "None"; |
|||
if (source?.Name == "ShowWindow") |
|||
ShowWindow(); |
|||
if (source?.Name == "SendToBack") |
|||
SendToBack(); |
|||
if (source?.Name == "ExitFullscreen") |
|||
WindowState = WindowState.Normal; |
|||
if (source?.Name == "RestoreAll") |
|||
RestoreAll(); |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
<Window xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="IntegrationTestApp.ShowWindowTest" |
|||
Name="SecondaryWindow" |
|||
Title="Show Window Test"> |
|||
<Grid ColumnDefinitions="Auto,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"> |
|||
<Label Grid.Column="0" Grid.Row="1">Client Size</Label> |
|||
<TextBox Name="ClientSize" Grid.Column="1" Grid.Row="1" IsReadOnly="True" |
|||
Text="{Binding ClientSize, Mode=OneWay}"/> |
|||
|
|||
<Label Grid.Column="0" Grid.Row="2">Frame Size</Label> |
|||
<TextBox Name="FrameSize" Grid.Column="1" Grid.Row="2" IsReadOnly="True" |
|||
Text="{Binding FrameSize, Mode=OneWay}"/> |
|||
|
|||
<Label Grid.Column="0" Grid.Row="3">Position</Label> |
|||
<TextBox Name="Position" Grid.Column="1" Grid.Row="3" IsReadOnly="True"/> |
|||
|
|||
<Label Grid.Column="0" Grid.Row="4">Owner Rect</Label> |
|||
<TextBox Name="OwnerRect" Grid.Column="1" Grid.Row="4" IsReadOnly="True"/> |
|||
|
|||
<Label Grid.Column="0" Grid.Row="5">Screen Rect</Label> |
|||
<TextBox Name="ScreenRect" Grid.Column="1" Grid.Row="5" IsReadOnly="True"/> |
|||
|
|||
<Label Grid.Column="0" Grid.Row="6">Scaling</Label> |
|||
<TextBox Name="Scaling" Grid.Column="1" Grid.Row="6" IsReadOnly="True"/> |
|||
|
|||
<Label Grid.Column="0" Grid.Row="7">WindowState</Label> |
|||
<ComboBox Name="WindowState" Grid.Column="1" Grid.Row="7" SelectedIndex="{Binding WindowState}"> |
|||
<ComboBoxItem>Normal</ComboBoxItem> |
|||
<ComboBoxItem>Minimized</ComboBoxItem> |
|||
<ComboBoxItem>Maximized</ComboBoxItem> |
|||
<ComboBoxItem>Fullscreen</ComboBoxItem> |
|||
</ComboBox> |
|||
</Grid> |
|||
</Window> |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia.Rendering; |
|||
|
|||
namespace IntegrationTestApp |
|||
{ |
|||
public class ShowWindowTest : Window |
|||
{ |
|||
public ShowWindowTest() |
|||
{ |
|||
InitializeComponent(); |
|||
DataContext = this; |
|||
PositionChanged += (s, e) => this.GetControl<TextBox>("Position").Text = $"{Position}"; |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
|
|||
protected override void OnOpened(EventArgs e) |
|||
{ |
|||
base.OnOpened(e); |
|||
var scaling = PlatformImpl!.DesktopScaling; |
|||
this.GetControl<TextBox>("Position").Text = $"{Position}"; |
|||
this.GetControl<TextBox>("ScreenRect").Text = $"{Screens.ScreenFromVisual(this)?.WorkingArea}"; |
|||
this.GetControl<TextBox>("Scaling").Text = $"{scaling}"; |
|||
|
|||
if (Owner is not null) |
|||
{ |
|||
var ownerRect = this.GetControl<TextBox>("OwnerRect"); |
|||
var owner = (Window)Owner; |
|||
ownerRect.Text = $"{owner.Position}, {PixelSize.FromSize(owner.FrameSize!.Value, scaling)}"; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
cd $(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) |
|||
dotnet restore -r osx-arm64 |
|||
dotnet msbuild -t:BundleApp -p:RuntimeIdentifier=osx-arm64 -p:_AvaloniaUseExternalMSBuild=false |
|||
@ -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> |
|||
Loading…
Reference in new issue