summaryrefslogtreecommitdiff
path: root/test/haketilo_test/profiles.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/haketilo_test/profiles.py')
-rwxr-xr-xtest/haketilo_test/profiles.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/test/haketilo_test/profiles.py b/test/haketilo_test/profiles.py
new file mode 100755
index 0000000..ae997fc
--- /dev/null
+++ b/test/haketilo_test/profiles.py
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""
+Browser profiles and Selenium driver initialization
+"""
+
+# This file is part of Haketilo.
+#
+# Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# I, Wojtek Kosior, thereby promise not to sue for violation of this file's
+# license. Although I request that you do not make use of this code in a
+# proprietary program, I am not going to enforce this in court.
+
+from selenium import webdriver
+from selenium.webdriver.firefox.options import Options
+import json
+from shutil import rmtree
+
+from .misc_constants import *
+
+class HaketiloFirefox(webdriver.Firefox):
+ """
+ This wrapper class around selenium.webdriver.Firefox facilitates removing
+ the temporary profile directory after Firefox quits.
+ """
+ def quit(self, *args, **kwargs):
+ profile_path = self.firefox_profile.path
+ super().quit(*args, **kwargs)
+ rmtree(profile_path, ignore_errors=True)
+
+def set_profile_proxy(profile, proxy_host, proxy_port):
+ """
+ Create a Firefox profile that uses the specified HTTP proxy for all
+ protocols.
+ """
+ # proxy type 1 designates "manual"
+ profile.set_preference('network.proxy.type', 1)
+ profile.set_preference('network.proxy.no_proxies_on', '')
+ profile.set_preference('network.proxy.share_proxy_settings', True)
+
+ for proto in ['http', 'ftp', 'socks', 'ssl']:
+ profile.set_preference(f'network.proxy.{proto}', proxy_host)
+ profile.set_preference(f'network.proxy.{proto}_port', proxy_port)
+ profile.set_preference(f'network.proxy.backup.{proto}', '')
+ profile.set_preference(f'network.proxy.backup.{proto}_port', 0)
+
+def set_profile_csp_enabled(profile):
+ """
+ By default, Firefox Driver disables CSP. The extension we're testing uses
+ CSP extensively, so we use this function to prepare a Firefox profile that
+ has it enabled.
+ """
+ profile.set_preference('security.csp.enable', True)
+
+# The function below seems not to work for extensions that are
+# temporarily-installed in Firefox safe mode. Testing is needed to see if it
+# works with non-temporary extensions (without safe mode).
+def set_webextension_uuid(profile, extension_id, uuid=default_extension_uuid):
+ """
+ Firefox would normally assign a unique, random UUID to installed extension.
+ This UUID is needed to easily navigate to extension's settings page (and
+ other extension's pages). Since there's no way to learn such UUID with
+ current WebDriver implementation, this function works around this by telling
+ Firefox to use a predefined UUID for a certain extension.
+ """
+ profile.set_preference('extensions.webextensions.uuids',
+ json.dumps({extension_id: uuid}))
+
+def firefox_safe_mode(firefox_binary=conf_settings['BROWSER_BINARY'],
+ proxy_host=default_proxy_host,
+ proxy_port=default_proxy_port):
+ """
+ Initialize a Firefox instance controlled by selenium. The instance is
+ started in safe mode.
+ """
+ profile = webdriver.FirefoxProfile()
+ set_profile_proxy(profile, proxy_host, proxy_port)
+ set_profile_csp_enabled(profile)
+
+ options = Options()
+ options.add_argument('--safe-mode')
+
+ return HaketiloFirefox(options=options, firefox_profile=profile,
+ firefox_binary=firefox_binary)
+
+def firefox_with_profile(firefox_binary=conf_settings['BROWSER_BINARY'],
+ profile_dir=conf_settings['CLEAN_PROFILE'],
+ proxy_host=default_proxy_host,
+ proxy_port=default_proxy_port):
+ """
+ Initialize a Firefox instance controlled by selenium. The instance is
+ started using an empty profile (either the default one or the one passed to
+ `configure` script). The empty profile is meant to make Firefox start with
+ globally-installed extensions disabled.
+ """
+ profile = webdriver.FirefoxProfile(profile_dir)
+ set_profile_proxy(profile, proxy_host, proxy_port)
+ set_profile_csp_enabled(profile)
+ set_webextension_uuid(profile, default_haketilo_id)
+
+ return HaketiloFirefox(firefox_profile=profile,
+ firefox_binary=firefox_binary)