Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/test/selenium/webdriver/common/bidi_webextension_tests.py
1865 views
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
import base64
19
import os
20
import shutil
21
import tempfile
22
23
import pytest
24
from python.runfiles import Runfiles
25
26
from selenium import webdriver
27
from selenium.webdriver.common.by import By
28
from selenium.webdriver.support.wait import WebDriverWait
29
30
EXTENSION_ID = "[email protected]"
31
EXTENSION_PATH = "webextensions-selenium-example-signed"
32
EXTENSION_ARCHIVE_PATH = "webextensions-selenium-example.xpi"
33
34
# Use bazel Runfiles to locate the test extension directory
35
r = Runfiles.Create()
36
extensions = r.Rlocation("selenium/py/test/extensions")
37
38
39
def install_extension(driver, **kwargs):
40
result = driver.webextension.install(**kwargs)
41
assert result.get("extension") == EXTENSION_ID
42
return result
43
44
45
def verify_extension_injection(driver, pages):
46
pages.load("blank.html")
47
injected = WebDriverWait(driver, timeout=2).until(
48
lambda dr: dr.find_element(By.ID, "webextensions-selenium-example")
49
)
50
assert injected.text == "Content injected by webextensions-selenium-example"
51
52
53
def uninstall_extension_and_verify_extension_uninstalled(driver, extension_info):
54
driver.webextension.uninstall(extension_info)
55
56
context_id = driver.current_window_handle
57
driver.browsing_context.reload(context_id)
58
assert len(driver.find_elements(By.ID, "webextensions-selenium-example")) == 0
59
60
61
def test_webextension_initialized(driver):
62
"""Test that the webextension module is initialized properly."""
63
assert driver.webextension is not None
64
65
66
@pytest.mark.xfail_chrome
67
@pytest.mark.xfail_edge
68
class TestFirefoxWebExtension:
69
"""Firefox-specific WebExtension tests."""
70
71
def test_install_extension_path(self, driver, pages):
72
"""Test installing an extension from a directory path."""
73
74
path = os.path.join(extensions, EXTENSION_PATH)
75
ext_info = install_extension(driver, path=path)
76
verify_extension_injection(driver, pages)
77
uninstall_extension_and_verify_extension_uninstalled(driver, ext_info)
78
79
def test_install_archive_extension_path(self, driver, pages):
80
"""Test installing an extension from an archive path."""
81
82
path = os.path.join(extensions, EXTENSION_ARCHIVE_PATH)
83
ext_info = install_extension(driver, archive_path=path)
84
verify_extension_injection(driver, pages)
85
uninstall_extension_and_verify_extension_uninstalled(driver, ext_info)
86
87
def test_install_base64_extension_path(self, driver, pages):
88
"""Test installing an extension from a base64 encoded string."""
89
90
path = os.path.join(extensions, EXTENSION_ARCHIVE_PATH)
91
with open(path, "rb") as file:
92
base64_encoded = base64.b64encode(file.read()).decode("utf-8")
93
ext_info = install_extension(driver, base64_value=base64_encoded)
94
# TODO: the extension is installed but the script is not injected, check and fix
95
# verify_extension_injection(driver, pages)
96
uninstall_extension_and_verify_extension_uninstalled(driver, ext_info)
97
98
def test_install_unsigned_extension(self, driver, pages):
99
"""Test installing an unsigned extension."""
100
101
path = os.path.join(extensions, "webextensions-selenium-example")
102
ext_info = install_extension(driver, path=path)
103
verify_extension_injection(driver, pages)
104
uninstall_extension_and_verify_extension_uninstalled(driver, ext_info)
105
106
def test_install_with_extension_id_uninstall(self, driver, pages):
107
"""Test uninstalling an extension using just the extension ID."""
108
109
path = os.path.join(extensions, EXTENSION_PATH)
110
ext_info = install_extension(driver, path=path)
111
extension_id = ext_info.get("extension")
112
# Uninstall using the extension ID
113
uninstall_extension_and_verify_extension_uninstalled(driver, extension_id)
114
115
116
@pytest.mark.xfail_firefox
117
class TestChromiumWebExtension:
118
"""Chrome/Edge-specific WebExtension tests with custom driver."""
119
120
@pytest.fixture
121
def pages_chromium(self, webserver, chromium_driver):
122
class Pages:
123
def load(self, name):
124
chromium_driver.get(webserver.where_is(name, localhost=False))
125
126
return Pages()
127
128
@pytest.fixture
129
def chromium_driver(self, chromium_options, request):
130
"""Create a Chrome/Edge driver with webextension support enabled."""
131
driver_option = request.config.option.drivers[0].lower()
132
133
if driver_option == "chrome":
134
browser_class = webdriver.Chrome
135
browser_service = webdriver.ChromeService
136
elif driver_option == "edge":
137
browser_class = webdriver.Edge
138
browser_service = webdriver.EdgeService
139
140
temp_dir = tempfile.mkdtemp(prefix="chromium-profile-")
141
142
chromium_options.enable_bidi = True
143
chromium_options.enable_webextensions = True
144
chromium_options.add_argument(f"--user-data-dir={temp_dir}")
145
chromium_options.add_argument("--no-sandbox")
146
chromium_options.add_argument("--disable-dev-shm-usage")
147
148
binary = request.config.option.binary
149
if binary:
150
chromium_options.binary_location = binary
151
152
executable = request.config.option.executable
153
if executable:
154
service = browser_service(executable_path=executable)
155
else:
156
service = browser_service()
157
158
chromium_driver = browser_class(options=chromium_options, service=service)
159
160
yield chromium_driver
161
chromium_driver.quit()
162
163
# delete the temp directory
164
if os.path.exists(temp_dir):
165
shutil.rmtree(temp_dir)
166
167
def test_install_extension_path(self, chromium_driver, pages_chromium):
168
"""Test installing an extension from a directory path."""
169
path = os.path.join(extensions, EXTENSION_PATH)
170
ext_info = chromium_driver.webextension.install(path=path)
171
172
verify_extension_injection(chromium_driver, pages_chromium)
173
uninstall_extension_and_verify_extension_uninstalled(chromium_driver, ext_info)
174
175
def test_install_unsigned_extension(self, chromium_driver, pages_chromium):
176
"""Test installing an unsigned extension."""
177
path = os.path.join(extensions, "webextensions-selenium-example")
178
ext_info = chromium_driver.webextension.install(path=path)
179
180
verify_extension_injection(chromium_driver, pages_chromium)
181
uninstall_extension_and_verify_extension_uninstalled(chromium_driver, ext_info)
182
183
def test_install_with_extension_id_uninstall(self, chromium_driver):
184
"""Test uninstalling an extension using just the extension ID."""
185
path = os.path.join(extensions, EXTENSION_PATH)
186
ext_info = chromium_driver.webextension.install(path=path)
187
extension_id = ext_info.get("extension")
188
# Uninstall using the extension ID
189
uninstall_extension_and_verify_extension_uninstalled(chromium_driver, extension_id)
190
191