Backed out 2 changesets (bug 1900622) for causing Bug 1908553 and ktlint failure...
[gecko.git] / accessible / tests / browser / python_runner_wsh.py
bloba6b5ce615f59af3d1775c332793ba048ffd9a333
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 """A pywebsocket3 handler which runs arbitrary Python code and returns the
6 result.
7 This is used to test OS specific accessibility APIs which can't be tested in JS.
8 It is intended to be called from JS browser tests.
9 """
11 import json
12 import math
13 import os
14 import sys
15 import traceback
17 from mod_pywebsocket import msgutil
20 def web_socket_do_extra_handshake(request):
21 pass
24 def web_socket_transfer_data(request):
25 def send(*args):
26 """Send a response to the client as a JSON array."""
27 msgutil.send_message(request, json.dumps(args))
29 cleanNamespace = {}
30 testDir = None
31 if sys.platform == "win32":
32 testDir = "windows"
33 elif sys.platform == "linux":
34 testDir = "atk"
35 if testDir:
36 sys.path.append(
37 os.path.join(
38 os.getcwd(), "browser", "accessible", "tests", "browser", testDir
41 try:
42 import a11y_setup
44 cleanNamespace = a11y_setup.__dict__
45 setupExc = None
46 except Exception:
47 setupExc = traceback.format_exc()
48 sys.path.pop()
50 def info(message):
51 """Log an info message."""
52 send("info", str(message))
54 cleanNamespace["info"] = info
55 namespace = cleanNamespace.copy()
57 # Keep handling messages until the WebSocket is closed.
58 while True:
59 code = msgutil.receive_message(request)
60 if not code:
61 return
62 if code == "__reset__":
63 namespace = cleanNamespace.copy()
64 send("return", None)
65 continue
67 if setupExc:
68 # a11y_setup failed. Report an exception immediately.
69 send("exception", setupExc)
70 continue
72 # Wrap the code in a function called run(). This allows the code to
73 # return a result by simply using the return statement.
74 if "\n" not in code and not code.lstrip().startswith("return "):
75 # Single line without return. Assume this is an expression. We use
76 # a lambda to return the result.
77 code = f"run = lambda: {code}"
78 else:
79 lines = ["def run():"]
80 # Indent each line inside the function.
81 lines.extend(f" {line}" for line in code.splitlines())
82 code = "\n".join(lines)
83 try:
84 # Execute this Python code, which will define the run() function.
85 exec(code, namespace)
86 # Run the function we just defined.
87 ret = namespace["run"]()
88 if isinstance(ret, float) and math.isnan(ret):
89 # NaN can't be serialized by JSON.
90 ret = None
91 send("return", ret)
92 except Exception:
93 send("exception", traceback.format_exc())