From d7572721a4221f7b5a71b009edf9e8abc02a3543 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Fri, 10 Jan 2025 21:13:37 +0800 Subject: [PATCH 1/4] test: add static a11y test. --- .../FormAccessibilityTests.cs | 27 +++++++++++++++++++ .../AccessibilityTests/StaticForm.axaml | 13 +++++++++ .../AccessibilityTests/StaticForm.axaml.cs | 13 +++++++++ .../HeadlessTest.Ursa.csproj | 1 - 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml.cs diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs new file mode 100644 index 0000000..e73e96e --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs @@ -0,0 +1,27 @@ +using Avalonia.Controls; +using Avalonia.Headless; +using Avalonia.Headless.XUnit; +using Avalonia.Input; + +namespace HeadlessTest.Ursa.Controls.FormTests.AccessibilityTests; + +public class FormAccessibilityTests +{ + [AvaloniaFact] + public void Form_Inner_Control_Accessible() + { + var window = new Window(); + var form = new StaticForm(); + window.Content = form; + window.Show(); + + Assert.False(form.NameBox.IsFocused); + Assert.False(form.EmailBox.IsFocused); + window.KeyPressQwerty(PhysicalKey.N, RawInputModifiers.Alt); + Assert.True(form.NameBox.IsFocused); + Assert.False(form.EmailBox.IsFocused); + window.KeyPressQwerty(PhysicalKey.E, RawInputModifiers.Alt); + Assert.False(form.NameBox.IsFocused); + Assert.True(form.EmailBox.IsFocused); + } +} \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml new file mode 100644 index 0000000..d20690b --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml @@ -0,0 +1,13 @@ + + + + + + diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml.cs new file mode 100644 index 0000000..d3729d0 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace HeadlessTest.Ursa.Controls.FormTests.AccessibilityTests; + +public partial class StaticForm : UserControl +{ + public StaticForm() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/HeadlessTest.Ursa.csproj b/tests/HeadlessTest.Ursa/HeadlessTest.Ursa.csproj index 977c521..63bbc71 100644 --- a/tests/HeadlessTest.Ursa/HeadlessTest.Ursa.csproj +++ b/tests/HeadlessTest.Ursa/HeadlessTest.Ursa.csproj @@ -4,7 +4,6 @@ net8.0 enable enable - false true From 47b39b9e743a057310cf6cfbd1bae6221dcd4545 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Fri, 10 Jan 2025 21:27:30 +0800 Subject: [PATCH 2/4] test: dynamic form a11y failure. --- .../AccessibilityTests/DynamicForm.axaml | 26 ++++++++++++++ .../AccessibilityTests/DynamicForm.axaml.cs | 31 ++++++++++++++++ .../FormAccessibilityTests.cs | 35 ++++++++++++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml.cs diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml new file mode 100644 index 0000000..9dbaba4 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml.cs new file mode 100644 index 0000000..822ff72 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/DynamicForm.axaml.cs @@ -0,0 +1,31 @@ +using System.Collections.ObjectModel; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace HeadlessTest.Ursa.Controls.FormTests.AccessibilityTests; + +public partial class DynamicForm : UserControl +{ + public DynamicForm() + { + InitializeComponent(); + this.DataContext = new DynamicFormViewModel(); + } +} + +public partial class DynamicFormViewModel: ObservableObject +{ + public ObservableCollection Items { get; set; } = + [ + new() { Label = "_Name" }, + new() { Label = "_Email" } + ]; +} + +public partial class FormTextViewModel : ObservableObject +{ + [ObservableProperty] private string? _label; + [ObservableProperty] private string? _value; +} \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs index e73e96e..f27102a 100644 --- a/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/FormAccessibilityTests.cs @@ -2,13 +2,15 @@ using Avalonia.Controls; using Avalonia.Headless; using Avalonia.Headless.XUnit; using Avalonia.Input; +using Avalonia.LogicalTree; +using Ursa.Controls; namespace HeadlessTest.Ursa.Controls.FormTests.AccessibilityTests; public class FormAccessibilityTests { [AvaloniaFact] - public void Form_Inner_Control_Accessible() + public void Static_Form_Inner_Control_Accessible() { var window = new Window(); var form = new StaticForm(); @@ -24,4 +26,35 @@ public class FormAccessibilityTests Assert.False(form.NameBox.IsFocused); Assert.True(form.EmailBox.IsFocused); } + + [AvaloniaFact] + public void Dynamic_Form_Inner_Control_Accessible() + { + var window = new Window(); + var form = new DynamicForm(); + window.Content = form; + window.Show(); + + var logicalChildren = form.form.GetLogicalChildren().ToList(); + Assert.Equal(2, logicalChildren.Count); + var first = logicalChildren[0] as FormItem; + var second = logicalChildren[1] as FormItem; + Assert.NotNull(first); + Assert.NotNull(second); + + var text1 = first.GetLogicalChildren().OfType().FirstOrDefault(); + var text2 = second.GetLogicalChildren().OfType().FirstOrDefault(); + + Assert.NotNull(text1); + Assert.NotNull(text2); + + Assert.False(text1.IsFocused); + Assert.False(text2.IsFocused); + window.KeyPressQwerty(PhysicalKey.N, RawInputModifiers.Alt); + Assert.True(text1.IsFocused); + Assert.False(text2.IsFocused); + window.KeyPressQwerty(PhysicalKey.E, RawInputModifiers.Alt); + Assert.False(text1.IsFocused); + Assert.True(text2.IsFocused); + } } \ No newline at end of file From b707a2ebdaf324e3a4f859feb1656faf84e98ad3 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Fri, 10 Jan 2025 21:49:56 +0800 Subject: [PATCH 3/4] fix: fix accessibility for dynamic generated form. --- src/Ursa.Themes.Semi/Controls/Form.axaml | 4 +- src/Ursa/Controls/Form/FormItem.cs | 40 ++++++++++++++++++- .../FormAccessibilityTests.cs | 18 +++++++++ .../AccessibilityTests/StaticForm.axaml | 2 +- .../AccessibilityTests/StaticForm2.axaml | 17 ++++++++ .../AccessibilityTests/StaticForm2.axaml.cs | 13 ++++++ 6 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm2.axaml create mode 100644 tests/HeadlessTest.Ursa/Controls/FormTests/AccessibilityTests/StaticForm2.axaml.cs diff --git a/src/Ursa.Themes.Semi/Controls/Form.axaml b/src/Ursa.Themes.Semi/Controls/Form.axaml index 2449459..ee33650 100644 --- a/src/Ursa.Themes.Semi/Controls/Form.axaml +++ b/src/Ursa.Themes.Semi/Controls/Form.axaml @@ -59,6 +59,7 @@ HorizontalAlignment="{TemplateBinding LabelAlignment}" Orientation="Horizontal">