1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
import pytest
from .helpers import (
Browser,
Geckodriver,
create_custom_profile,
get_pref,
get_profile_folder,
read_user_preferences,
set_pref,
)
@pytest.fixture(scope="module")
def browser(configuration, firefox_options):
"""Start a Firefox instance without using geckodriver.
geckodriver will automatically use the --remote-allow-hosts and
--remote.allow.origins command line arguments.
Starting Firefox without geckodriver allows to set those command line arguments
as needed. The fixture method returns the browser instance that should be used
to connect to a RemoteAgent supported protocol (CDP, WebDriver BiDi).
"""
current_browser = None
def _browser(
use_bidi=False,
use_cdp=False,
extra_args=None,
extra_prefs=None,
clone_profile=True,
):
nonlocal current_browser
# If the requested preferences and arguments match the ones for the
# already started firefox, we can reuse the current firefox instance,
# return the instance immediately.
if current_browser:
if (
current_browser.use_bidi == use_bidi
and current_browser.use_cdp == use_cdp
and current_browser.extra_args == extra_args
and current_browser.extra_prefs == extra_prefs
and current_browser.is_running
):
return current_browser
# Otherwise, if firefox is already started, terminate it because we need
# to create a new instance for the provided preferences.
current_browser.quit()
binary = configuration["browser"]["binary"]
env = configuration["browser"]["env"]
profile_path = get_profile_folder(firefox_options)
default_prefs = read_user_preferences(profile_path)
profile = create_custom_profile(
profile_path, default_prefs, clone=clone_profile
)
current_browser = Browser(
binary,
profile,
use_bidi=use_bidi,
use_cdp=use_cdp,
extra_args=extra_args,
extra_prefs=extra_prefs,
env=env,
)
current_browser.start()
return current_browser
yield _browser
# Stop firefox at the end of the test module.
if current_browser is not None:
current_browser.quit()
current_browser = None
@pytest.fixture(name="create_custom_profile")
def fixture_create_custom_profile(default_preferences, profile_folder):
profile = None
def _create_custom_profile(clone=True):
profile = create_custom_profile(
profile_folder, default_preferences, clone=clone
)
return profile
yield _create_custom_profile
# if profile is not None:
if profile:
profile.cleanup()
@pytest.fixture
def default_preferences(profile_folder):
return read_user_preferences(profile_folder)
@pytest.fixture(scope="session")
def firefox_options(configuration):
return configuration["capabilities"]["moz:firefoxOptions"]
@pytest.fixture
def geckodriver(configuration):
"""Start a geckodriver instance directly."""
driver = None
def _geckodriver(config=None, hostname=None, extra_args=None):
nonlocal driver
if config is None:
config = configuration
driver = Geckodriver(config, hostname, extra_args)
driver.start()
return driver
yield _geckodriver
if driver is not None:
driver.stop()
@pytest.fixture
def profile_folder(firefox_options):
return get_profile_folder(firefox_options)
@pytest.fixture
def use_pref(session):
"""Set a specific pref value."""
reset_values = {}
def _use_pref(pref, value):
if pref not in reset_values:
reset_values[pref] = get_pref(session, pref)
set_pref(session, pref, value)
yield _use_pref
for pref, reset_value in reset_values.items():
set_pref(session, pref, reset_value)
|