diff options
Diffstat (limited to 'test/haketilo_test/profiles.py')
-rwxr-xr-x | test/haketilo_test/profiles.py | 116 |
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) |