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
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.
17 from mod_pywebsocket
import msgutil
20 def web_socket_do_extra_handshake(request
):
24 def web_socket_transfer_data(request
):
26 """Send a response to the client as a JSON array."""
27 msgutil
.send_message(request
, json
.dumps(args
))
31 if sys
.platform
== "win32":
33 elif sys
.platform
== "linux":
38 os
.getcwd(), "browser", "accessible", "tests", "browser", testDir
44 cleanNamespace
= a11y_setup
.__dict
__
47 setupExc
= traceback
.format_exc()
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.
59 code
= msgutil
.receive_message(request
)
62 if code
== "__reset__":
63 namespace
= cleanNamespace
.copy()
68 # a11y_setup failed. Report an exception immediately.
69 send("exception", setupExc
)
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}"
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
)
84 # Execute this Python code, which will define the run() function.
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.
93 send("exception", traceback
.format_exc())