"""Read-only review protocol checks in an isolated Wine prefix/session bus.""" import argparse import os from pathlib import Path import subprocess import sys import time from gi.repository import Gio, GLib from wine_test_environment import add_test_options, run_wine_test, wine_test_directory parser = argparse.ArgumentParser() parser.add_argument('--build-dir', default='build') parser.add_argument('--32-bit', dest='is32', action='store_true') parser.add_argument('--session', action='store_true') parser.add_argument('--reader', choices=('cthulhu', 'orca')) parser.add_argument('--extension-endpoint', action='store_true') add_test_options(parser) args = parser.parse_args() build = Path(args.build_dir).resolve() if not args.session: sys.exit(run_wine_test(['dbus-run-session', '--', sys.executable, __file__, '--session', '--build-dir', str(build), *(['--extension-endpoint'] if args.extension_endpoint else []), *(['--reader', args.reader] if args.reader else []), *(['--32-bit'] if args.is32 else [])], build, "review_integration", keep=args.keep, keepOnFailure=args.keepOnFailure)) busName = 'org.gnome.Orca1.Service' if args.reader == 'orca' else 'org.stormux.Cthulhu1.Service' iface = busName.rsplit('.', 1)[0] + '.WineAccess' if args.extension_endpoint else busName path = '/' + busName.replace('.', '/') + ('/WineAccess' if args.extension_endpoint else '') readerArguments = ['--reader', args.reader] if args.reader else [] if args.extension_endpoint: readerArguments += ['--reader-path', path, '--reader-interface', iface] capture_iface = 'org.stormux.Cthulhu1.WineReview' capture_path = '/org/stormux/Cthulhu1/WineReview' def interface_xml(review=True): methods = {'PresentAccessibleEvent': ['s']*7+['i','i','s'], 'SpeakText': ['s','b'], 'CancelSpeech': []} if review: methods.update(RegisterWineReviewProvider=['o','u'], PresentWineReviewFocus=['s','s','s','t','s','s','b','(iiii)']) return ''+''.join( ''+''.join('' for kind in kinds)+ '' for name,kinds in methods.items())+'' providers, focuses, events = {}, {}, [] def record(conn, sender, object_path, interface, method, params, invocation): data = params.unpack() accepted = True if method == 'RegisterWineReviewProvider': accepted = data == (capture_path, 1) if accepted: providers[sender] = data elif method == 'PresentWineReviewFocus': accepted = sender in providers if accepted: focuses[sender] = data else: events.append(data) invocation.return_value(GLib.Variant('(b)', (accepted,))) connection = Gio.bus_get_sync(Gio.BusType.SESSION, None) registration = connection.register_object(path, Gio.DBusNodeInfo.new_for_xml(interface_xml()).interfaces[0], record, None, None) connection.call_sync('org.freedesktop.DBus','/org/freedesktop/DBus','org.freedesktop.DBus','RequestName', GLib.Variant('(su)',(busName,0)),None,Gio.DBusCallFlags.NONE,1000,None) def pump_until(predicate, seconds=5): end = time.monotonic()+seconds while not predicate() and time.monotonic()