Refactoring AutomationId at the accessible object classes #6603#7206
Conversation
...ows.Forms/tests/UnitTests/System/Windows/Forms/ButtonBase.ButtonBaseAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
...m.Windows.Forms/tests/UnitTests/System/Windows/Forms/Control.ControlAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/GroupBoxAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
...ows.Forms/tests/UnitTests/System/Windows/Forms/PictureBox.PictureBoxAccessibleObjectTests.cs
Show resolved
Hide resolved
...Windows.Forms/tests/UnitTests/System/Windows/Forms/TrackBar.TrackBarAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
4d49076 to
abdf697
Compare
Please describe what inspect and AccessibilityInsights show in cases when we return null for automation ID. This fix changes behavior of ControlAccessibleObject. Previously it was returning a null ID and now it returns Name. I wonder how this is manifested in accessibility tools. |
|
@vladimir-krestov, @dmitrii-drobotov - please review this change |
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/LabelAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
...s/tests/UnitTests/System/Windows/Forms/ListViewItem.ListViewItemBaseAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
@Tanya-Solyanik |
abdf697 to
043398e
Compare
dmitrii-drobotov
left a comment
There was a problem hiding this comment.
-
You can also remove
UiaCore.UIA.AutomationIdPropertyId => Owner.NameinPrintPreviewControlAccessibleObjectandSplitContainerAccessibleObject -
I see some other AOs which have custom
AutomationId, for exampleGridEntryAccessibleObject:
UiaCore.UIA.AutomationIdPropertyId => GetHashCode().ToString()
which I think better be changed to
private protected override string AutomationId => GetHashCode().ToString()
because otherwise there is an inconsistency between accessibleObject.AutomationId and accessibleObject.GetPropertyValue(UiaCore.UIA.AutomationIdPropertyId).
I also found it in following AOs:
TabPage.TabAccessibleObjectComboBoxChildEditUiaProviderComboBoxChildListUiaProvider
...ows.Forms/tests/UnitTests/System/Windows/Forms/TabControl.TabControlAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
043398e to
96c5608
Compare
Tanya-Solyanik
left a comment
There was a problem hiding this comment.
Looks good!. I added some nits and am waiting for a sign off from @dmitrii-drobotov
src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.ComboBoxChildEditUiaProvider.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/TabPage.TabAccessibleObject.cs
Outdated
Show resolved
Hide resolved
...s.Forms/src/System/Windows/Forms/PropertyGridInternal/GridEntry.GridEntryAccessibleObject.cs
Outdated
Show resolved
Hide resolved
96c5608 to
22c516f
Compare
These classes introduced after this branch were created (next time I will use cherry-pick to take changes of an old commit to a new branch created from most recent main). I propose we will create a new issue regarding these two classes? |
src/System.Windows.Forms/src/System/Windows/Forms/AccessibleObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.ComboBoxChildEditUiaProvider.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/TabPage.TabAccessibleObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/AccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
...ows.Forms/tests/UnitTests/System/Windows/Forms/ButtonBase.ButtonBaseAccessibleObjectTests.cs
Show resolved
Hide resolved
...m.Windows.Forms/tests/UnitTests/System/Windows/Forms/Control.ControlAccessibleObjectTests.cs
Show resolved
Hide resolved
....Windows.Forms/tests/UnitTests/System/Windows/Forms/DataGridViewCellAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/GroupBoxAccessibleObjectTests.cs
Show resolved
Hide resolved
I'm interesting, what happens with the rest controls, that have "string.Empty" now for |
22c516f to
4b29db8
Compare
|
This commit has been rebased on the most recent main. Conflicts have been resolved. |
Thank you for the experiment. This result matches the pattern that when managed accessible object return null for aq property, UIA reads the value from the default implementation in MSAA proxy. |
@Tanya-Solyanik |
I think this is an acceptable break as long as it is documented. |
...Windows.Forms/tests/UnitTests/System/Windows/Forms/TrackBar.TrackBarAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
...Windows.Forms/tests/UnitTests/System/Windows/Forms/TrackBar.TrackBarAccessibleObjectTests.cs
Outdated
Show resolved
Hide resolved
|
@Tanya-Solyanik I see you applied "Documentation breaking" label. Could you please elaborate what's breaking here? |
|
@Tanya-Solyanik |
83f06c1 to
4816d98
Compare
We are returning a different value for AutomationID property for some controls. What exactly is different, is not clear as we are getting conflicting results. Specifically the difference between button control with Name=null and ComboBox with Name=null is not clear. I expected that Name=null results in the default MSAA proxy-provided automation ID, but it does not seem to be the case. However AutomationId property is not a required one, and the default MSAA implementation is using control hashes, so this value could vary between app runs, unless explicitly set by the app. Winforms code does not expose this property to be easily overridden directly. More popular control use Control.Name property as AutomationId. As long as we are not breaking cases where devs were setting Name property explicitly and used it as an AutomationID, I think this is an acceptable break. |
|
@dkazennov - CTI test results are not quite what I expected. I'd like to understand why ComboBox.Name=null results in AutomationID as "property not available" instead of a numeric value. |
I see. I'll try to figure it out than. |
Ah, yes, it vaguely rings true for me. We had to subclass a type and its AccessibleObject to override the accessibility values: gitextensions/gitextensions#9887 (comment) |
|
@Tanya-Solyanik
So the exact source of the issue is the new property If the property returns Owner.Name (even if Owner.Name itself is set to null or string.Emtpy), it won't show a numeric value. |
Do we have tests for this? |
I've consulted with @vladimir-krestov and as I understand we can't check with a unit test if MSAA Proxy substitutes null with some native value. I haven't found a way to check for such native value with unit tests. |
|
Conclusion: If the property So on the Windows Forms layer the value is null (in all concluded unit tests Assert.Null(actual AutomationId) would be true ), but on the MSAA Proxy level (between MSAA Proxy and Accessibility Tools) this value is being replaced by a native hashcode. |
…Unit tests were added.
4816d98 to
a0bfe33
Compare
|
Rebased on the most recent main branch. |

Fixes #6603
This PR finishes #6641 (adds unit tests)
Proposed changes
Unit tests:
Combined existed NamePropertyId tests and new AutomationIdPropertyId tests:
{
TrackBarAccessibilityObject_GetPropertyValue_Invoke_ReturnsExpected
TabPageAccessibleObject_GetPropertyValue_Invoke_ReturnsExpected
TabControlAccessibleObject_GetPropertyValue_Invoke_ReturnsExpected
LabelAccessibleObject_GetPropertyValue_Invoke_ReturnsExpected
}
just like existing:
{
CheckBoxAccessibleObject_GetPropertyValue_Invoke_ReturnsExpected
PanelAccessibleObject_GetPropertyValue_Invoke_ReturnsExpected
PictureBoxAccessibleObject_GetPropertyValue_Invoke_ReturnsExpected
ListViewSubItemAccessibleObject_GetPropertyValue_returns_correct_values
ListViewAccessibleObject_GetPropertyValue_returns_correct_values
}
Customer Impact
Regression?
Risk
Test methodology
Test environment(s)
Microsoft Windows [Version 120.2212.4170.0]
.NET Core SDK: 7.0.100-preview.3.22179.4
Microsoft Reviewers: Open in CodeFlow