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