Skip to content

Commit f4eac70

Browse files
[py] Use generated Bidi files instead of hand curated ones
1 parent 0330927 commit f4eac70

10 files changed

Lines changed: 117 additions & 438 deletions

File tree

py/BUILD.bazel

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,11 @@ py_library(
262262
# BiDi protocol support
263263
py_library(
264264
name = "bidi",
265-
srcs = glob(["selenium/webdriver/common/bidi/**/*.py"]),
266-
data = [":mutation-listener"],
265+
srcs = [],
266+
data = [
267+
":create-bidi-src",
268+
":mutation-listener",
269+
],
267270
imports = ["."],
268271
visibility = ["//visibility:public"],
269272
deps = [
@@ -617,7 +620,7 @@ generate_devtools_latest(
617620
browser_versions = BROWSER_VERSIONS,
618621
)
619622

620-
# Pilot BiDi code generation from CDDL specification
623+
# Generate BiDi source files from CDDL specification
621624
generate_bidi(
622625
name = "create-bidi-src",
623626
cddl_file = "//common/bidi/spec:all.cddl",

py/private/cdp.py

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
# Licensed to the Software Freedom Conservancy (SFC) under one
2-
# or more contributor license agreements. See the NOTICE file
3-
# distributed with this work for additional information
4-
# regarding copyright ownership. The SFC licenses this file
5-
# to you under the Apache License, Version 2.0 (the
6-
# "License"); you may not use this file except in compliance
7-
# with the License. You may obtain a copy of the License at
1+
# The MIT License(MIT)
82
#
9-
# http://www.apache.org/licenses/LICENSE-2.0
3+
# Copyright(c) 2018 Hyperion Gray
104
#
11-
# Unless required by applicable law or agreed to in writing,
12-
# software distributed under the License is distributed on an
13-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14-
# KIND, either express or implied. See the License for the
15-
# specific language governing permissions and limitations
16-
# under the License.
17-
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files(the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
#
23+
# This code comes from https://github.com/HyperionGray/trio-chrome-devtools-protocol/tree/master/trio_cdp
1824

1925
import contextvars
2026
import importlib
@@ -54,7 +60,11 @@ def import_devtools(ver):
5460
# because cdp has been updated but selenium python has not been released yet.
5561
devtools_path = pathlib.Path(__file__).parents[1].joinpath("devtools")
5662
versions = tuple(f.name for f in devtools_path.iterdir() if f.is_dir())
57-
available_versions = tuple(x for x in versions if x == "latest" or (x.startswith("v") and x[1:].isdigit()))
63+
available_versions = tuple(
64+
x
65+
for x in versions
66+
if x == "latest" or (x.startswith("v") and x[1:].isdigit())
67+
)
5868
numeric_versions = tuple(x[1:] for x in available_versions if x.startswith("v"))
5969
if not numeric_versions:
6070
raise
@@ -65,7 +75,9 @@ def import_devtools(ver):
6575
return devtools
6676

6777

68-
_connection_context: contextvars.ContextVar = contextvars.ContextVar("connection_context")
78+
_connection_context: contextvars.ContextVar = contextvars.ContextVar(
79+
"connection_context"
80+
)
6981
_session_context: contextvars.ContextVar = contextvars.ContextVar("session_context")
7082

7183

@@ -120,7 +132,9 @@ def set_global_connection(connection):
120132
certain use cases such as running inside Jupyter notebook.
121133
"""
122134
global _connection_context
123-
_connection_context = contextvars.ContextVar("_connection_context", default=connection)
135+
_connection_context = contextvars.ContextVar(
136+
"_connection_context", default=connection
137+
)
124138

125139

126140
def set_global_session(session):
@@ -217,7 +231,9 @@ async def execute(self, cmd: Generator[dict, T, Any]) -> T:
217231
logger.debug(f"Received CDP message: {response}")
218232
if isinstance(response, Exception):
219233
if logger.isEnabledFor(logging.DEBUG):
220-
logger.debug(f"Exception raised by {cmd_event} message: {type(response).__name__}")
234+
logger.debug(
235+
f"Exception raised by {cmd_event} message: {type(response).__name__}"
236+
)
221237
raise response
222238
return response
223239

@@ -233,7 +249,9 @@ def listen(self, *event_types, buffer_size=10):
233249
return receiver
234250

235251
@asynccontextmanager
236-
async def wait_for(self, event_type: type[T], buffer_size=10) -> AsyncGenerator[CmEventProxy, None]:
252+
async def wait_for(
253+
self, event_type: type[T], buffer_size=10
254+
) -> AsyncGenerator[CmEventProxy, None]:
237255
"""Wait for an event of the given type and return it.
238256
239257
This is an async context manager, so you should open it inside
@@ -274,7 +292,9 @@ def _handle_cmd_response(self, data: dict):
274292
try:
275293
cmd, event = self.inflight_cmd.pop(cmd_id)
276294
except KeyError:
277-
logger.warning("Got a message with a command ID that does not exist: %s", data)
295+
logger.warning(
296+
"Got a message with a command ID that does not exist: %s", data
297+
)
278298
return
279299
if "error" in data:
280300
# If the server reported an error, convert it to an exception and do
@@ -285,7 +305,9 @@ def _handle_cmd_response(self, data: dict):
285305
# into a CDP object.
286306
try:
287307
_ = cmd.send(data["result"])
288-
raise InternalError("The command's generator function did not exit when expected!")
308+
raise InternalError(
309+
"The command's generator function did not exit when expected!"
310+
)
289311
except StopIteration as exit:
290312
return_ = exit.value
291313
self.inflight_result[cmd_id] = return_
@@ -299,15 +321,19 @@ def _handle_event(self, data: dict):
299321
"""
300322
global devtools
301323
if devtools is None:
302-
raise RuntimeError("CDP devtools module not loaded. Call import_devtools() first.")
324+
raise RuntimeError(
325+
"CDP devtools module not loaded. Call import_devtools() first."
326+
)
303327
event = devtools.util.parse_json_event(data)
304328
logger.debug("Received event: %s", event)
305329
to_remove = set()
306330
for sender in self.channels[type(event)]:
307331
try:
308332
sender.send_nowait(event)
309333
except trio.WouldBlock:
310-
logger.error('Unable to send event "%r" due to full channel %s', event, sender)
334+
logger.error(
335+
'Unable to send event "%r" due to full channel %s', event, sender
336+
)
311337
except trio.BrokenResourceError:
312338
to_remove.add(sender)
313339
if to_remove:
@@ -425,8 +451,12 @@ async def connect_session(self, target_id) -> "CdpSession":
425451
"""Returns a new :class:`CdpSession` connected to the specified target."""
426452
global devtools
427453
if devtools is None:
428-
raise RuntimeError("CDP devtools module not loaded. Call import_devtools() first.")
429-
session_id = await self.execute(devtools.target.attach_to_target(target_id, True))
454+
raise RuntimeError(
455+
"CDP devtools module not loaded. Call import_devtools() first."
456+
)
457+
session_id = await self.execute(
458+
devtools.target.attach_to_target(target_id, True)
459+
)
430460
session = CdpSession(self.ws, session_id, target_id)
431461
self.sessions[session_id] = session
432462
return session
@@ -438,7 +468,9 @@ async def _reader_task(self):
438468
"""
439469
global devtools
440470
if devtools is None:
441-
raise RuntimeError("CDP devtools module not loaded. Call import_devtools() first.")
471+
raise RuntimeError(
472+
"CDP devtools module not loaded. Call import_devtools() first."
473+
)
442474
while True:
443475
try:
444476
message = await self.ws.get_message()
@@ -451,7 +483,13 @@ async def _reader_task(self):
451483
try:
452484
data = json.loads(message)
453485
except json.JSONDecodeError:
454-
raise BrowserError({"code": -32700, "message": "Client received invalid JSON", "data": message})
486+
raise BrowserError(
487+
{
488+
"code": -32700,
489+
"message": "Client received invalid JSON",
490+
"data": message,
491+
}
492+
)
455493
logger.debug("Received message %r", data)
456494
if "sessionId" in data:
457495
session_id = devtools.target.SessionID(data["sessionId"])

py/selenium/webdriver/common/bidi/__init__.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)