Bug 1852190 part 4: Add Windows UIA interfaces, constants and utility functions to the Python environment. r=eeejay

This also adds a simple control type test which shows all of this working.

Differential Revision: https://phabricator.services.mozilla.com/D187756
This commit is contained in:
James Teh 2023-10-04 23:58:46 +00:00
parent 232e8c986c
commit 07a83e875e
5 changed files with 87 additions and 0 deletions

View file

@ -49,6 +49,7 @@ BROWSER_CHROME_MANIFESTS += [
"tests/browser/text/browser.toml",
"tests/browser/tree/browser.toml",
"tests/browser/windows/ia2/browser.toml",
"tests/browser/windows/uia/browser.toml",
]
with Files("**"):

View file

@ -45,6 +45,17 @@ globals().update((k, getattr(ia2Mod, k)) for k in ia2Mod.__all__)
IAccessible2 = ia2Mod.IAccessible2
del ia2Mod
uiaMod = comtypes.client.GetModule("UIAutomationCore.dll")
globals().update((k, getattr(uiaMod, k)) for k in uiaMod.__all__)
uiaClient = comtypes.CoCreateInstance(
uiaMod.CUIAutomation._reg_clsid_,
interface=uiaMod.IUIAutomation,
clsctx=comtypes.CLSCTX_INPROC_SERVER,
)
TreeScope_Descendants = uiaMod.TreeScope_Descendants
UIA_AutomationIdPropertyId = uiaMod.UIA_AutomationIdPropertyId
del uiaMod
def AccessibleObjectFromWindow(hwnd, objectID=OBJID_CLIENT):
p = POINTER(IAccessible)()
@ -114,3 +125,21 @@ def findIa2ByDomId(root, id):
descendant = findIa2ByDomId(child, id)
if descendant:
return descendant
def getDocUia():
"""Get the IUIAutomationElement for the document being tested."""
# We start with IAccessible2 because there's no efficient way to
# find the document we want with UIA.
ia2 = getDocIa2()
return uiaClient.ElementFromIAccessible(ia2, CHILDID_SELF)
def findUiaByDomId(root, id):
cond = uiaClient.CreatePropertyCondition(UIA_AutomationIdPropertyId, id)
# FindFirst ignores elements in the raw tree, so we have to use
# FindFirstBuildCache to override that, even though we don't want to cache
# anything.
request = uiaClient.CreateCacheRequest()
request.TreeFilter = uiaClient.RawViewCondition
return root.FindFirstBuildCache(TreeScope_Descendants, cond, request)

View file

@ -0,0 +1,9 @@
[DEFAULT]
subsuite = "a11y"
skip-if = [
"os != 'win'",
"headless",
]
support-files = ["head.js"]
["browser_controlType.js"]

View file

@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* eslint-disable camelcase */
const UIA_ButtonControlTypeId = 50000;
const UIA_DocumentControlTypeId = 50030;
/* eslint-enable camelcase */
addAccessibleTask(
`
<button id="button">button</button>
`,
async function (browser, docAcc) {
let controlType = await runPython(`
global doc
doc = getDocUia()
return doc.CurrentControlType
`);
is(controlType, UIA_DocumentControlTypeId, "doc has correct control type");
controlType = await runPython(`
button = findUiaByDomId(doc, "button")
return button.CurrentControlType
`);
is(controlType, UIA_ButtonControlTypeId, "button has correct control type");
},
{ chrome: true, topLevel: true, iframe: true, remoteIframe: true }
);

View file

@ -0,0 +1,18 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js",
this
);
// Loading and common.js from accessible/tests/mochitest/ for all tests, as
// well as promisified-events.js.
loadScripts(
{ name: "common.js", dir: MOCHITESTS_DIR },
{ name: "promisified-events.js", dir: MOCHITESTS_DIR }
);