Skip to content

Commit 20b9d93

Browse files
committed
add bidi webextension module
1 parent ff55efd commit 20b9d93

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
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+
18+
from typing import Dict, Union
19+
20+
from selenium.webdriver.common.bidi.common import command_builder
21+
22+
23+
class WebExtension:
24+
"""
25+
BiDi implementation of the webExtension module.
26+
"""
27+
28+
def __init__(self, conn):
29+
self.conn = conn
30+
31+
def install(self, path=None, archive_path=None, base64_value=None) -> Dict:
32+
"""Installs a web extension in the remote end.
33+
34+
You must provide exactly one of the parameters.
35+
36+
Parameters:
37+
-----------
38+
path: Path to an extension directory
39+
archive_path: Path to an extension archive file
40+
base64_value: Base64 encoded string of the extension archive
41+
42+
Returns:
43+
-------
44+
Dict: A dictionary containing the extension ID.
45+
"""
46+
if sum(x is not None for x in (path, archive_path, base64_value)) != 1:
47+
raise ValueError("Exactly one of path, archive_path, or base64_value must be provided")
48+
49+
if path is not None:
50+
extension_data = {"type": "path", "path": path}
51+
elif archive_path is not None:
52+
extension_data = {"type": "archivePath", "path": archive_path}
53+
elif base64_value is not None:
54+
extension_data = {"type": "base64", "value": base64_value}
55+
56+
params = {"extensionData": extension_data}
57+
result = self.conn.execute(command_builder("webExtension.install", params))
58+
return result
59+
60+
def uninstall(self, extension_id_or_result: Union[str, Dict]) -> None:
61+
"""Uninstalls a web extension from the remote end.
62+
63+
Parameters:
64+
-----------
65+
extension_id_or_result: Either the extension ID as a string or the result dictionary
66+
from a previous install() call containing the extension ID.
67+
"""
68+
if isinstance(extension_id_or_result, dict):
69+
extension_id = extension_id_or_result.get("extension")
70+
else:
71+
extension_id = extension_id_or_result
72+
73+
params = {"extension": extension_id}
74+
self.conn.execute(command_builder("webExtension.uninstall", params))

py/selenium/webdriver/remote/webdriver.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from selenium.webdriver.common.bidi.script import Script
5151
from selenium.webdriver.common.bidi.session import Session
5252
from selenium.webdriver.common.bidi.storage import Storage
53+
from selenium.webdriver.common.bidi.webextension import WebExtension
5354
from selenium.webdriver.common.by import By
5455
from selenium.webdriver.common.options import ArgOptions
5556
from selenium.webdriver.common.options import BaseOptions
@@ -269,6 +270,7 @@ def __init__(
269270
self._bidi_session = None
270271
self._browsing_context = None
271272
self._storage = None
273+
self._webextension = None
272274

273275
def __repr__(self):
274276
return f'<{type(self).__module__}.{type(self).__name__} (session="{self.session_id}")>'
@@ -1343,6 +1345,28 @@ def storage(self):
13431345

13441346
return self._storage
13451347

1348+
@property
1349+
def webextension(self):
1350+
"""Returns a webextension module object for BiDi webextension commands.
1351+
1352+
Returns:
1353+
--------
1354+
WebExtension: an object containing access to BiDi webextension commands.
1355+
1356+
Examples:
1357+
---------
1358+
>>> extension_path = "/path/to/extension"
1359+
>>> extension_result = driver.webextension.install(path=extension_path)))
1360+
>>> driver.webextension.uninstall(extension_result)
1361+
"""
1362+
if not self._websocket_connection:
1363+
self._start_bidi()
1364+
1365+
if self._webextension is None:
1366+
self._webextension = WebExtension(self._websocket_connection)
1367+
1368+
return self._webextension
1369+
13461370
def _get_cdp_details(self):
13471371
import json
13481372

0 commit comments

Comments
 (0)