Project

General

Profile

Download (4.7 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / test / haketilo_test / profiles.py @ aec5c9ae

1
# SPDX-License-Identifier: GPL-3.0-or-later
2

    
3
"""
4
Browser profiles and Selenium driver initialization
5
"""
6

    
7
# This file is part of Haketilo.
8
#
9
# Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org>
10
#
11
# This program is free software: you can redistribute it and/or modify
12
# it under the terms of the GNU General Public License as published by
13
# the Free Software Foundation, either version 3 of the License, or
14
# (at your option) any later version.
15
#
16
# This program is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
# GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License
22
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
#
24
# I, Wojtek Kosior, thereby promise not to sue for violation of this file's
25
# license. Although I request that you do not make use of this code in a
26
# proprietary program, I am not going to enforce this in court.
27

    
28
from selenium import webdriver
29
from selenium.webdriver.firefox.options import Options
30
import json
31
from shutil import rmtree
32

    
33
from .misc_constants import *
34

    
35
class HaketiloFirefox(webdriver.Firefox):
36
    """
37
    This wrapper class around selenium.webdriver.Firefox facilitates removing
38
    the temporary profile directory after Firefox quits.
39
    """
40
    def quit(self, *args, **kwargs):
41
        profile_path = self.firefox_profile.path
42
        super().quit(*args, **kwargs)
43
        rmtree(profile_path, ignore_errors=True)
44

    
45
def set_profile_proxy(profile, proxy_host, proxy_port):
46
    """
47
    Create a Firefox profile that uses the specified HTTP proxy for all
48
    protocols.
49
    """
50
    # proxy type 1 designates "manual"
51
    profile.set_preference('network.proxy.type',                 1)
52
    profile.set_preference('network.proxy.no_proxies_on',        '')
53
    profile.set_preference('network.proxy.share_proxy_settings', True)
54

    
55
    for proto in ['http', 'ftp', 'socks', 'ssl']:
56
        profile.set_preference(f'network.proxy.{proto}',             proxy_host)
57
        profile.set_preference(f'network.proxy.{proto}_port',        proxy_port)
58
        profile.set_preference(f'network.proxy.backup.{proto}',      '')
59
        profile.set_preference(f'network.proxy.backup.{proto}_port', 0)
60

    
61
def set_profile_csp_enabled(profile):
62
    """
63
    By default, Firefox Driver disables CSP. The extension we're testing uses
64
    CSP extensively, so we use this function to prepare a Firefox profile that
65
    has it enabled.
66
    """
67
    profile.set_preference('security.csp.enable', True)
68

    
69
# The function below seems not to work for extensions that are
70
# temporarily-installed in Firefox safe mode. Testing is needed to see if it
71
# works with non-temporary extensions (without safe mode).
72
def set_webextension_uuid(profile, extension_id, uuid=default_extension_uuid):
73
    """
74
    Firefox would normally assign a unique, random UUID to installed extension.
75
    This UUID is needed to easily navigate to extension's settings page (and
76
    other extension's pages). Since there's no way to learn such UUID with
77
    current WebDriver implementation, this function works around this by telling
78
    Firefox to use a predefined UUID for a certain extension.
79
    """
80
    profile.set_preference('extensions.webextensions.uuids',
81
                           json.dumps({extension_id: uuid}))
82

    
83
def firefox_safe_mode(proxy_port, proxy_host=default_proxy_host,
84
                      firefox_binary=conf_settings['BROWSER_BINARY']):
85
    """
86
    Initialize a Firefox instance controlled by selenium. The instance is
87
    started in safe mode.
88
    """
89
    profile = webdriver.FirefoxProfile()
90
    set_profile_proxy(profile, proxy_host, proxy_port)
91
    set_profile_csp_enabled(profile)
92

    
93
    options = Options()
94
    options.add_argument('--safe-mode')
95

    
96
    return HaketiloFirefox(options=options, firefox_profile=profile,
97
                           firefox_binary=firefox_binary)
98

    
99
def firefox_with_profile(proxy_port, proxy_host=default_proxy_host,
100
                         firefox_binary=conf_settings['BROWSER_BINARY'],
101
                         profile_dir=conf_settings['CLEAN_PROFILE']):
102
    """
103
    Initialize a Firefox instance controlled by selenium. The instance is
104
    started using an empty profile (either the default one or the one passed to
105
    `configure` script). The empty profile is meant to make Firefox start with
106
    globally-installed extensions disabled.
107
    """
108
    profile = webdriver.FirefoxProfile(profile_dir)
109
    set_profile_proxy(profile, proxy_host, proxy_port)
110
    set_profile_csp_enabled(profile)
111
    set_webextension_uuid(profile, default_haketilo_id)
112

    
113
    return HaketiloFirefox(firefox_profile=profile,
114
                           firefox_binary=firefox_binary)
(6-6/11)