Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test runs only with pattern: os == 'mac'
- Manifest: toolkit/xre/test/marionette/manifest.toml
# 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
"""
The original bug: on macOS, the early-startup code in
`toolkit/xre/nsAppRunner.cpp` spun the event loop (via
`ReceiveNextEvent`) before NSApplication was fully initialized. Any
external observer of `NSWorkspaceDidLaunchApplicationNotification` would
receive the launch notification before Firefox's accessibility responder
was wired up, so an assistive technology like VoiceControl that queried
Firefox's AX tree at that moment would silently fail.
This test launches Firefox from a separate Python process and, from
that process, verifies that `AXTitle` / `AXRole` queries on the new
Firefox pid succeed as soon as the launch notification fires.
comment 3.
"""
import os
import platform
import subprocess
import sys
from marionette_harness import MarionetteTestCase
class TestExternalA11yAfterLaunch(MarionetteTestCase):
def test_external_observer_can_query_ax(self):
if platform.system() != "Darwin":
binary = self.marionette.bin
helper = os.path.join(os.path.dirname(__file__), "external_a11y_helper.py")
# The helper has to register the workspace observer before our
# subject Firefox launches, so let the helper own the spawn.
# Quit the marionette-controlled Firefox first so it doesn't
# race the helper-launched one for the notification window.
self.marionette.quit(in_app=False)
try:
proc = subprocess.run(
[sys.executable, helper, binary],
capture_output=True,
text=True,
timeout=90,
check=False,
)
finally:
self.marionette.start_session()
if proc.returncode == 77:
self.skipTest(
f"PyObjC unavailable in test environment: {proc.stdout.strip()}"
)
self.assertEqual(
proc.returncode,
0,
msg=(
f"external_a11y_helper exited with rc={proc.returncode}\n"
f"stdout:\n{proc.stdout}\n"
f"stderr:\n{proc.stderr}"
),
)