Files
tubestation/accessible/tests/browser/atk/a11y_setup.py
James Teh ecb8fd9708 Bug 1926214 part 1: Call CoInitialize for new threads in a11y Python test runner. r=nlapre
Each browser test file is run with a separate instance of shared-head.js and thus a distinct WebSocket connection to the a11y Python runner.
pywebsocket3 is multi-threaded and may thus choose different threads to handle different WebSocket requests.
Python comtypes implicitly initialises COM when it is imported, but COM initialisation is thread specific and Python modules are cached, so this only applies to the thread on which comtypes was imported.
These factors were causing problems such as event timeouts when running multiple IA2 test files because IA2 relies on COM being initialised.
To fix this, add a setup() function to a11y_setup.py which is called when a request is handled.
For Windows, this calls CoInitialize once in each thread in which it is run.

Differential Revision: https://phabricator.services.mozilla.com/D227143
2024-10-30 04:46:41 +00:00

70 lines
1.9 KiB
Python

# 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/.
"""Python environment for ATK a11y browser tests.
"""
import os
import subprocess
import sys
import psutil
# pyatspi can't be installed using pip. Rely on the system installation.
# Get the path to the system installation of pyatspi.
pyatspiFile = subprocess.check_output(
(
os.path.join(sys.base_prefix, "bin", "python3"),
"-c",
"import pyatspi; print(pyatspi.__file__)",
),
encoding="utf-8",
).rstrip()
sys.path.append(os.path.dirname(os.path.dirname(pyatspiFile)))
import pyatspi
sys.path.pop()
del pyatspiFile
def setup():
# We do all the setup we need at module level.
pass
def getDoc():
"""Get the Accessible for the document being tested."""
# We can compare the parent process ids to find the Firefox started by the
# test harness.
commonPid = psutil.Process().ppid()
for app in pyatspi.Registry.getDesktop(0):
if (
app.name == "Firefox"
and psutil.Process(app.get_process_id()).ppid() == commonPid
):
break
else:
raise LookupError("Couldn't find Firefox application Accessible")
root = app[0]
for embeds in root.getRelationSet():
if embeds.getRelationType() == pyatspi.RELATION_EMBEDS:
break
else:
raise LookupError("Firefox root doesn't have RELATION_EMBEDS")
doc = embeds.getTarget(0)
child = doc[0]
if child.get_attributes().get("id") == "default-iframe-id":
# This is an iframe or remoteIframe test.
doc = child[0]
return doc
def findByDomId(root, id):
for child in root:
if child.get_attributes().get("id") == id:
return child
descendant = findByDomId(child, id)
if descendant:
return descendant