osn-selenium 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. osn_selenium/__init__.py +1 -0
  2. osn_selenium/browsers_handler/__init__.py +70 -0
  3. osn_selenium/browsers_handler/_windows.py +130 -0
  4. osn_selenium/browsers_handler/types.py +20 -0
  5. osn_selenium/captcha_workers/__init__.py +26 -0
  6. osn_selenium/dev_tools/__init__.py +1 -0
  7. osn_selenium/dev_tools/_types.py +22 -0
  8. osn_selenium/dev_tools/domains/__init__.py +63 -0
  9. osn_selenium/dev_tools/domains/abstract.py +378 -0
  10. osn_selenium/dev_tools/domains/fetch.py +1295 -0
  11. osn_selenium/dev_tools/domains_default/__init__.py +1 -0
  12. osn_selenium/dev_tools/domains_default/fetch.py +155 -0
  13. osn_selenium/dev_tools/errors.py +89 -0
  14. osn_selenium/dev_tools/logger.py +558 -0
  15. osn_selenium/dev_tools/manager.py +1551 -0
  16. osn_selenium/dev_tools/utils.py +509 -0
  17. osn_selenium/errors.py +16 -0
  18. osn_selenium/types.py +118 -0
  19. osn_selenium/webdrivers/BaseDriver/__init__.py +1 -0
  20. osn_selenium/webdrivers/BaseDriver/_utils.py +37 -0
  21. osn_selenium/webdrivers/BaseDriver/flags.py +644 -0
  22. osn_selenium/webdrivers/BaseDriver/protocols.py +2135 -0
  23. osn_selenium/webdrivers/BaseDriver/trio_wrapper.py +71 -0
  24. osn_selenium/webdrivers/BaseDriver/webdriver.py +2626 -0
  25. osn_selenium/webdrivers/Blink/__init__.py +1 -0
  26. osn_selenium/webdrivers/Blink/flags.py +1349 -0
  27. osn_selenium/webdrivers/Blink/protocols.py +330 -0
  28. osn_selenium/webdrivers/Blink/webdriver.py +637 -0
  29. osn_selenium/webdrivers/Chrome/__init__.py +1 -0
  30. osn_selenium/webdrivers/Chrome/flags.py +192 -0
  31. osn_selenium/webdrivers/Chrome/protocols.py +228 -0
  32. osn_selenium/webdrivers/Chrome/webdriver.py +394 -0
  33. osn_selenium/webdrivers/Edge/__init__.py +1 -0
  34. osn_selenium/webdrivers/Edge/flags.py +192 -0
  35. osn_selenium/webdrivers/Edge/protocols.py +228 -0
  36. osn_selenium/webdrivers/Edge/webdriver.py +394 -0
  37. osn_selenium/webdrivers/Yandex/__init__.py +1 -0
  38. osn_selenium/webdrivers/Yandex/flags.py +192 -0
  39. osn_selenium/webdrivers/Yandex/protocols.py +211 -0
  40. osn_selenium/webdrivers/Yandex/webdriver.py +350 -0
  41. osn_selenium/webdrivers/__init__.py +1 -0
  42. osn_selenium/webdrivers/_functions.py +504 -0
  43. osn_selenium/webdrivers/js_scripts/check_element_in_viewport.js +18 -0
  44. osn_selenium/webdrivers/js_scripts/get_document_scroll_size.js +4 -0
  45. osn_selenium/webdrivers/js_scripts/get_element_css.js +6 -0
  46. osn_selenium/webdrivers/js_scripts/get_element_rect_in_viewport.js +9 -0
  47. osn_selenium/webdrivers/js_scripts/get_random_element_point_in_viewport.js +59 -0
  48. osn_selenium/webdrivers/js_scripts/get_viewport_position.js +4 -0
  49. osn_selenium/webdrivers/js_scripts/get_viewport_rect.js +6 -0
  50. osn_selenium/webdrivers/js_scripts/get_viewport_size.js +4 -0
  51. osn_selenium/webdrivers/js_scripts/open_new_tab.js +1 -0
  52. osn_selenium/webdrivers/js_scripts/stop_window_loading.js +1 -0
  53. osn_selenium/webdrivers/types.py +390 -0
  54. osn_selenium-0.0.0.dist-info/METADATA +710 -0
  55. osn_selenium-0.0.0.dist-info/RECORD +57 -0
  56. osn_selenium-0.0.0.dist-info/WHEEL +5 -0
  57. osn_selenium-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,644 @@
1
+ from typing import (
2
+ Any,
3
+ Optional,
4
+ TypedDict,
5
+ Union
6
+ )
7
+ from osn_selenium.webdrivers.types import (
8
+ FlagDefinition,
9
+ FlagNotDefined,
10
+ FlagType,
11
+ _any_webdriver_option_type
12
+ )
13
+ from osn_selenium.webdrivers._functions import (
14
+ bool_adding_validation_function,
15
+ optional_bool_adding_validation_function
16
+ )
17
+
18
+
19
+ class ArgumentValue(TypedDict):
20
+ """
21
+ Typed dictionary representing a single command-line argument and its value.
22
+
23
+ Attributes:
24
+ command_line (str): The command-line string for the argument.
25
+ value (Any): The value associated with the argument.
26
+ """
27
+
28
+ command_line: str
29
+ value: Any
30
+
31
+
32
+ def _argument_to_flag(argument: ArgumentValue) -> str:
33
+ """
34
+ Formats a command-line argument from an ArgumentValue dictionary.
35
+
36
+ If the command string contains '{value}', it will be replaced by the argument's value.
37
+ Otherwise, the command string is returned as is.
38
+
39
+ Args:
40
+ argument (ArgumentValue): A dictionary containing the command-line string and its value.
41
+
42
+ Returns:
43
+ str: The formatted command-line argument string.
44
+ """
45
+
46
+ argument_command = argument["command_line"]
47
+ argument_value = argument["value"]
48
+
49
+ if "{value}" in argument_command:
50
+ return argument_command.format(value=argument_value)
51
+ else:
52
+ return argument_command
53
+
54
+
55
+ class ExperimentalOptionValue(TypedDict):
56
+ """
57
+ Typed dictionary representing a single experimental option and its value.
58
+
59
+ Attributes:
60
+ option_name (str): The name of the experimental option.
61
+ value (Any): The value of the experimental option.
62
+ """
63
+
64
+ option_name: str
65
+ value: Any
66
+
67
+
68
+ class AttributeValue(TypedDict):
69
+ """
70
+ Typed dictionary representing a single WebDriver attribute and its value.
71
+
72
+ Attributes:
73
+ attribute_name (str): The name of the attribute.
74
+ value (Any): The value of the attribute.
75
+ """
76
+
77
+ attribute_name: str
78
+ value: Any
79
+
80
+
81
+ class FlagTypeNotDefined:
82
+ """A sentinel class to indicate that a flag type definition was not found."""
83
+
84
+ pass
85
+
86
+
87
+ class BrowserExperimentalOptions(TypedDict, total=False):
88
+ """
89
+ Typed dictionary for browser-agnostic experimental options.
90
+ """
91
+
92
+ pass
93
+
94
+
95
+ class BrowserAttributes(TypedDict, total=False):
96
+ """
97
+ Typed dictionary for browser-agnostic WebDriver attributes.
98
+
99
+ Attributes:
100
+ enable_bidi (Optional[bool]): Enables/disables BiDi (Bidirectional) protocol mapper.
101
+ """
102
+
103
+ enable_bidi: Optional[bool]
104
+
105
+
106
+ class BrowserArguments(TypedDict, total=False):
107
+ """
108
+ Typed dictionary for browser-agnostic command-line arguments.
109
+
110
+ Attributes:
111
+ se_downloads_enabled (bool): Enables/disables Selenium downloads.
112
+ """
113
+
114
+ se_downloads_enabled: bool
115
+
116
+
117
+ class BrowserFlags(TypedDict, total=False):
118
+ """
119
+ Typed dictionary representing a collection of all flag types.
120
+
121
+ Attributes:
122
+ argument (BrowserArguments): Command-line arguments for the browser.
123
+ experimental_option (BrowserExperimentalOptions): Experimental options for WebDriver.
124
+ attribute (BrowserAttributes): WebDriver attributes.
125
+ """
126
+
127
+ argument: BrowserArguments
128
+ experimental_option: BrowserExperimentalOptions
129
+ attribute: BrowserAttributes
130
+
131
+
132
+ class BrowserFlagsManager:
133
+ """
134
+ Manages browser flags, including arguments, experimental options, and attributes for a generic WebDriver.
135
+
136
+ This class provides a structured way to define, set, and build browser options
137
+ for various Selenium WebDriver instances.
138
+
139
+ Attributes:
140
+ _flags_types (dict[str, FlagType]): A dictionary mapping flag types to their handler functions.
141
+ _flags_definitions (dict[str, FlagDefinition]): A dictionary of all available flag definitions.
142
+ _flags_definitions_by_types (dict[str, dict[str, FlagDefinition]]): Flags definitions grouped by type.
143
+ _arguments (dict[str, ArgumentValue]): Stores the configured command-line arguments.
144
+ _experimental_options (dict[str, ExperimentalOptionValue]): Stores the configured experimental options.
145
+ _attributes (dict[str, AttributeValue]): Stores the configured WebDriver attributes.
146
+ """
147
+
148
+ def __init__(
149
+ self,
150
+ flags_types: Optional[dict[str, FlagType]] = None,
151
+ flags_definitions: Optional[dict[str, FlagDefinition]] = None
152
+ ):
153
+ """
154
+ Initializes the BrowserFlagsManager.
155
+
156
+ Args:
157
+ flags_types (Optional[dict[str, FlagType]]): Custom flag types and their corresponding functions.
158
+ flags_definitions (Optional[dict[str, FlagDefinition]]): Custom flag definitions to add or override.
159
+ """
160
+
161
+ inner_flags_types = {
162
+ "argument": FlagType(
163
+ set_flag_function=self.set_argument,
164
+ remove_flag_function=self.remove_argument,
165
+ set_flags_function=self.set_arguments,
166
+ update_flags_function=self.update_arguments,
167
+ clear_flags_function=self.clear_arguments,
168
+ build_options_function=self.build_options_arguments,
169
+ build_start_args_function=self.build_start_args_arguments
170
+ ),
171
+ "experimental_option": FlagType(
172
+ set_flag_function=self.set_experimental_option,
173
+ remove_flag_function=self.remove_experimental_option,
174
+ set_flags_function=self.set_experimental_options,
175
+ update_flags_function=self.update_experimental_options,
176
+ clear_flags_function=self.clear_experimental_options,
177
+ build_options_function=self.build_options_experimental_options,
178
+ build_start_args_function=lambda: []
179
+ ),
180
+ "attribute": FlagType(
181
+ set_flag_function=self.set_attribute,
182
+ remove_flag_function=self.remove_attribute,
183
+ set_flags_function=self.set_attributes,
184
+ update_flags_function=self.update_attributes,
185
+ clear_flags_function=self.clear_attributes,
186
+ build_options_function=self.build_options_attributes,
187
+ build_start_args_function=lambda: []
188
+ ),
189
+ }
190
+
191
+ if flags_types is not None:
192
+ inner_flags_types.update(flags_types)
193
+
194
+ inner_flags_definitions = {
195
+ "se_downloads_enabled": FlagDefinition(
196
+ name="se_downloads_enabled",
197
+ command="se:downloadsEnabled",
198
+ type="argument",
199
+ mode="webdriver_option",
200
+ adding_validation_function=bool_adding_validation_function
201
+ ),
202
+ "enable_bidi": FlagDefinition(
203
+ name="enable_bidi",
204
+ command="enable_bidi",
205
+ type="attribute",
206
+ mode="webdriver_option",
207
+ adding_validation_function=optional_bool_adding_validation_function
208
+ ),
209
+ }
210
+
211
+ if flags_definitions is not None:
212
+ inner_flags_definitions.update(flags_definitions)
213
+
214
+ self._flags_types = inner_flags_types
215
+ self._flags_definitions = inner_flags_definitions
216
+
217
+ self._flags_definitions_by_types: dict[str, dict[str, FlagDefinition]] = {
218
+ option_type: dict(
219
+ filter(lambda di: di[1]["type"] == option_type, self._flags_definitions.items())
220
+ )
221
+ for option_type in self._flags_types.keys()
222
+ }
223
+
224
+ self._arguments: dict[str, ArgumentValue] = {}
225
+ self._experimental_options: dict[str, ExperimentalOptionValue] = {}
226
+ self._attributes: dict[str, AttributeValue] = {}
227
+
228
+ def build_options_attributes(self, options: _any_webdriver_option_type) -> _any_webdriver_option_type:
229
+ """
230
+ Applies configured attributes to the WebDriver options object.
231
+
232
+ Only attributes with `mode` set to 'webdriver_option' or 'both' are applied.
233
+
234
+ Args:
235
+ options (_any_webdriver_option_type): The WebDriver options object to modify.
236
+
237
+ Returns:
238
+ _any_webdriver_option_type: The modified WebDriver options object.
239
+ """
240
+
241
+ for name, value in self._attributes.items():
242
+ if self._flags_definitions_by_types["attribute"][name]["mode"] in ["webdriver_option", "both"]:
243
+ setattr(options, value["attribute_name"], value["value"])
244
+
245
+ return options
246
+
247
+ def clear_attributes(self):
248
+ """Clears all configured browser attributes."""
249
+
250
+ self._attributes = {}
251
+
252
+ def remove_attribute(self, attribute_name: str):
253
+ """
254
+ Removes a browser attribute by its attribute name.
255
+
256
+ Browser attributes are properties of the WebDriver options object that
257
+ control certain aspects of the browser session. This method removes a previously set attribute.
258
+
259
+ Args:
260
+ attribute_name (str): Attribute name of the attribute to remove.
261
+ """
262
+
263
+ self._attributes.pop(attribute_name, None)
264
+
265
+ def set_attribute(self, attribute: FlagDefinition, value: Any):
266
+ """
267
+ Sets a browser attribute. If the attribute already exists, it is overwritten.
268
+
269
+ Args:
270
+ attribute (FlagDefinition): The definition of the attribute to set.
271
+ value (Any): The value to assign to the attribute.
272
+ """
273
+
274
+ attribute_name = attribute["name"]
275
+ attribute_command = attribute["command"]
276
+ adding_validation_function = attribute["adding_validation_function"]
277
+
278
+ self.remove_attribute(attribute_name)
279
+
280
+ if adding_validation_function(value):
281
+ self._attributes[attribute_name] = AttributeValue(attribute_name=attribute_command, value=value)
282
+
283
+ def update_attributes(self, attributes: Union[BrowserAttributes, dict[str, Any]]):
284
+ """
285
+ Updates browser attributes from a dictionary without clearing existing ones.
286
+
287
+ Args:
288
+ attributes (Union[BrowserAttributes, dict[str, Any]]): A dictionary of attributes to set or update.
289
+
290
+ Raises:
291
+ ValueError: If an unknown attribute key is provided.
292
+ """
293
+
294
+ for key, value in attributes.items():
295
+ flag_definition = self._flags_definitions_by_types["attribute"].get(key, FlagNotDefined())
296
+
297
+ if isinstance(flag_definition, FlagNotDefined):
298
+ raise ValueError(f"Unknown attribute: {key}.")
299
+
300
+ self.set_attribute(flag_definition, value)
301
+
302
+ def set_attributes(self, attributes: Union[BrowserAttributes, dict[str, Any]]):
303
+ """
304
+ Clears existing and sets new browser attributes from a dictionary.
305
+
306
+ Args:
307
+ attributes (Union[BrowserAttributes, dict[str, Any]]): A dictionary of attributes to set.
308
+
309
+ Raises:
310
+ ValueError: If an unknown attribute key is provided.
311
+ """
312
+
313
+ self.clear_attributes()
314
+ self.update_attributes(attributes)
315
+
316
+ def build_options_experimental_options(self, options: _any_webdriver_option_type) -> _any_webdriver_option_type:
317
+ """
318
+ Adds configured experimental options to the WebDriver options object.
319
+
320
+ Only options with `mode` set to 'webdriver_option' or 'both' are added.
321
+
322
+ Args:
323
+ options (_any_webdriver_option_type): The WebDriver options object to modify.
324
+
325
+ Returns:
326
+ _any_webdriver_option_type: The modified WebDriver options object.
327
+ """
328
+
329
+ for name, value in self._experimental_options.items():
330
+ if self._flags_definitions_by_types["experimental_option"][name]["mode"] in ["webdriver_option", "both"]:
331
+ options.add_experimental_option(value["option_name"], value["value"])
332
+
333
+ return options
334
+
335
+ def clear_experimental_options(self):
336
+ """Clears all configured experimental options."""
337
+
338
+ self._experimental_options = {}
339
+
340
+ def remove_experimental_option(self, experimental_option_name: str):
341
+ """
342
+ Removes an experimental browser option by its attribute name.
343
+
344
+ Experimental options are specific features or behaviors that are not
345
+ part of the standard WebDriver API and may be browser-specific or unstable.
346
+ This method allows for removing such options that were previously set.
347
+
348
+ Args:
349
+ experimental_option_name (str): Attribute name of the experimental option to remove.
350
+ """
351
+
352
+ self._experimental_options.pop(experimental_option_name, None)
353
+
354
+ def set_experimental_option(self, experimental_option: FlagDefinition, value: Any):
355
+ """
356
+ Sets an experimental browser option. If the option already exists, it is overwritten.
357
+
358
+ Args:
359
+ experimental_option (FlagDefinition): The definition of the experimental option to set.
360
+ value (Any): The value to assign to the option.
361
+ """
362
+
363
+ experimental_option_name = experimental_option["name"]
364
+ experimental_option_command = experimental_option["command"]
365
+ adding_validation_function = experimental_option["adding_validation_function"]
366
+
367
+ self.remove_experimental_option(experimental_option_name)
368
+
369
+ if adding_validation_function(value):
370
+ self._experimental_options[experimental_option_name] = ExperimentalOptionValue(option_name=experimental_option_command, value=value)
371
+
372
+ def update_experimental_options(
373
+ self,
374
+ experimental_options: Union[BrowserExperimentalOptions, dict[str, Any]]
375
+ ):
376
+ """
377
+ Updates experimental options from a dictionary without clearing existing ones.
378
+
379
+ Args:
380
+ experimental_options (Union[BrowserExperimentalOptions, dict[str, Any]]): A dictionary of experimental options to set or update.
381
+
382
+ Raises:
383
+ ValueError: If an unknown experimental option key is provided.
384
+ """
385
+
386
+ for key, value in experimental_options.items():
387
+ flag_definition = self._flags_definitions_by_types["experimental_option"].get(key, FlagNotDefined())
388
+
389
+ if isinstance(flag_definition, FlagNotDefined):
390
+ raise ValueError(f"Unknown experimental option: {key}.")
391
+
392
+ self.set_experimental_option(flag_definition, value)
393
+
394
+ def set_experimental_options(
395
+ self,
396
+ experimental_options: Union[BrowserExperimentalOptions, dict[str, Any]]
397
+ ):
398
+ """
399
+ Clears existing and sets new experimental options from a dictionary.
400
+
401
+ Args:
402
+ experimental_options (Union[BrowserExperimentalOptions, dict[str, Any]]): A dictionary of experimental options to set.
403
+
404
+ Raises:
405
+ ValueError: If an unknown experimental option key is provided.
406
+ """
407
+
408
+ self.clear_experimental_options()
409
+ self.update_experimental_options(experimental_options)
410
+
411
+ def build_start_args_arguments(self) -> list[str]:
412
+ """
413
+ Builds a list of command-line arguments intended for browser startup.
414
+
415
+ Only arguments with `mode` set to 'startup_argument' or 'both' are included.
416
+
417
+ Returns:
418
+ list[str]: A list of formatted command-line argument strings.
419
+ """
420
+
421
+ return [
422
+ _argument_to_flag(value)
423
+ for name, value in self._arguments.items()
424
+ if self._flags_definitions_by_types["argument"][name]["mode"] in ["startup_argument", "both"]
425
+ ]
426
+
427
+ def build_options_arguments(self, options: _any_webdriver_option_type) -> _any_webdriver_option_type:
428
+ """
429
+ Adds configured command-line arguments to the WebDriver options object.
430
+
431
+ Only arguments with `mode` set to 'webdriver_option' or 'both' are added.
432
+
433
+ Args:
434
+ options (_any_webdriver_option_type): The WebDriver options object to modify.
435
+
436
+ Returns:
437
+ _any_webdriver_option_type: The modified WebDriver options object.
438
+ """
439
+
440
+ for name, value in self._arguments.items():
441
+ if self._flags_definitions_by_types["argument"][name]["mode"] in ["webdriver_option", "both"]:
442
+ options.add_argument(_argument_to_flag(value))
443
+
444
+ return options
445
+
446
+ def clear_arguments(self):
447
+ """Clears all configured browser arguments."""
448
+
449
+ self._arguments = {}
450
+
451
+ def remove_argument(self, argument_name: str):
452
+ """
453
+ Removes a browser argument by its attribute name.
454
+
455
+ Browser arguments are command-line flags that can modify the browser's behavior
456
+ at startup. This method removes an argument that was previously added to the browser options.
457
+
458
+ Args:
459
+ argument_name (str): Attribute name of the argument to remove.
460
+ """
461
+
462
+ self._arguments.pop(argument_name, None)
463
+
464
+ def set_argument(self, argument: FlagDefinition, value: Any):
465
+ """
466
+ Sets a command-line argument. If the argument already exists, it is overwritten.
467
+
468
+ Args:
469
+ argument (FlagDefinition): The definition of the argument to set.
470
+ value (Any): The value for the argument. This may be a boolean for a simple flag or a string/number for a valued flag.
471
+ """
472
+
473
+ argument_name = argument["name"]
474
+ argument_command = argument["command"]
475
+ adding_validation_function = argument["adding_validation_function"]
476
+
477
+ self.remove_argument(argument_name)
478
+
479
+ if adding_validation_function(value):
480
+ self._arguments[argument_name] = ArgumentValue(command_line=argument_command, value=value)
481
+
482
+ def update_arguments(self, arguments: Union[BrowserArguments, dict[str, Any]]):
483
+ """
484
+ Updates command-line arguments from a dictionary without clearing existing ones.
485
+
486
+ Args:
487
+ arguments (Union[BrowserArguments, dict[str, Any]]): A dictionary of arguments to set or update.
488
+
489
+ Raises:
490
+ ValueError: If an unknown argument key is provided.
491
+ """
492
+
493
+ for key, value in arguments.items():
494
+ flag_definition = self._flags_definitions_by_types["argument"].get(key, FlagNotDefined())
495
+
496
+ if isinstance(flag_definition, FlagNotDefined):
497
+ raise ValueError(f"Unknown argument: {key}.")
498
+
499
+ self.set_argument(flag_definition, value)
500
+
501
+ def set_arguments(self, arguments: Union[BrowserArguments, dict[str, Any]]):
502
+ """
503
+ Clears existing and sets new command-line arguments from a dictionary.
504
+
505
+ Args:
506
+ arguments (Union[BrowserArguments, dict[str, Any]]): A dictionary of arguments to set.
507
+
508
+ Raises:
509
+ ValueError: If an unknown argument key is provided.
510
+ """
511
+
512
+ self.clear_arguments()
513
+ self.update_arguments(arguments)
514
+
515
+ def clear_flags(self):
516
+ """Clears all configured flags of all types (arguments, options, attributes)."""
517
+
518
+ for type_name, type_functions in self._flags_types.items():
519
+ type_functions["clear_flags_function"]()
520
+
521
+ def _renew_webdriver_options(self) -> _any_webdriver_option_type:
522
+ """
523
+ Abstract method to renew WebDriver options. Must be implemented in child classes.
524
+
525
+ This method is intended to be overridden in subclasses to provide
526
+ browser-specific WebDriver options instances (e.g., ChromeOptions, FirefoxOptions).
527
+
528
+ Returns:
529
+ _any_webdriver_option_type: A new instance of WebDriver options (e.g., ChromeOptions, FirefoxOptions).
530
+
531
+ Raises:
532
+ NotImplementedError: If the method is not implemented in a subclass.
533
+ """
534
+
535
+ raise NotImplementedError("This function must be implemented in child classes.")
536
+
537
+ @property
538
+ def options(self) -> _any_webdriver_option_type:
539
+ """
540
+ Builds and returns a WebDriver options object with all configured flags applied.
541
+
542
+ Returns:
543
+ _any_webdriver_option_type: A configured WebDriver options object.
544
+ """
545
+
546
+ options = self._renew_webdriver_options()
547
+
548
+ for type_name, type_functions in self._flags_types.items():
549
+ options = type_functions["build_options_function"](options)
550
+
551
+ return options
552
+
553
+ def remove_option(self, option: FlagDefinition):
554
+ """
555
+ Removes a browser option by its configuration object.
556
+
557
+ This method removes a browser option, whether it's a normal argument,
558
+ an experimental option, or an attribute, based on the provided `WebdriverOption` configuration.
559
+ It determines the option type and calls the appropriate removal method.
560
+
561
+ Args:
562
+ option (WebdriverOption): The configuration object defining the option to be removed.
563
+
564
+ Raises:
565
+ ValueError: If the option type is not recognized.
566
+ """
567
+
568
+ for type_name, type_functions in self._flags_types.items():
569
+ if option["type"] == type_name:
570
+ type_functions["remove_flag_function"](option["name"])
571
+
572
+ raise ValueError(f"Unknown option type ({option}).")
573
+
574
+ def set_flags(self, flags: Union[BrowserFlags, dict[str, dict[str, Any]]]):
575
+ """
576
+ Clears all existing flags and sets new ones from a comprehensive dictionary.
577
+
578
+ This method iterates through the provided flag types (e.g., 'arguments', 'experimental_options')
579
+ and calls the corresponding `set_*` function for each type, effectively replacing all
580
+ previously configured flags for that type.
581
+
582
+ Args:
583
+ flags (Union[BrowserFlags, dict[str, dict[str, Any]]]): A dictionary where keys are flag types
584
+ and values are dictionaries of flags to set for that type.
585
+
586
+ Raises:
587
+ ValueError: If an unknown flag type is provided in the `flags` dictionary.
588
+ """
589
+
590
+ for type_name, type_flags in flags.items():
591
+ flags_type_definition = self._flags_types.get(type_name, FlagTypeNotDefined())
592
+
593
+ if isinstance(flags_type_definition, FlagTypeNotDefined):
594
+ raise ValueError(f"Unknown flag type: {type_name}.")
595
+
596
+ flags_type_definition["set_flags_function"](type_flags)
597
+
598
+ def set_option(self, option: FlagDefinition, value: Any):
599
+ """
600
+ Sets a browser option based on its configuration object.
601
+
602
+ This method configures a browser option, handling normal arguments,
603
+ experimental options, and attributes as defined in the provided `FlagDefinition`.
604
+ It uses the option's type to determine the appropriate method for setting the option with the given value.
605
+
606
+ Args:
607
+ option (FlagDefinition): A dictionary-like object containing the configuration for the option to be set.
608
+ value (Any): The value to be set for the option. The type and acceptable values depend on the specific browser option being configured.
609
+
610
+ Raises:
611
+ ValueError: If the option type is not recognized.
612
+ """
613
+
614
+ for type_name, type_functions in self._flags_types.items():
615
+ if option["type"] == type_name:
616
+ type_functions["set_flag_function"](option, value)
617
+
618
+ raise ValueError(
619
+ f"Unknown option type ({option}). Acceptable types are: {', '.join(self._flags_types.keys())}."
620
+ )
621
+
622
+ def update_flags(self, flags: Union[BrowserFlags, dict[str, dict[str, Any]]]):
623
+ """
624
+ Updates all flags from a comprehensive dictionary without clearing existing ones.
625
+
626
+ This method iterates through the provided flag types (e.g., 'arguments', 'experimental_options')
627
+ and calls the corresponding `update_*` function for each type, adding or overwriting
628
+ flags without affecting other existing flags.
629
+
630
+ Args:
631
+ flags (Union[BrowserFlags, dict[str, dict[str, Any]]]): A dictionary where keys are flag types
632
+ and values are dictionaries of flags to update for that type.
633
+
634
+ Raises:
635
+ ValueError: If an unknown flag type is provided in the `flags` dictionary.
636
+ """
637
+
638
+ for type_name, type_flags in flags.items():
639
+ flags_type_definition = self._flags_types.get(type_name, FlagTypeNotDefined())
640
+
641
+ if isinstance(flags_type_definition, FlagTypeNotDefined):
642
+ raise ValueError(f"Unknown flag type: {type_name}.")
643
+
644
+ flags_type_definition["update_flags_function"](type_flags)