rpa-suite 1.5.2__py3-none-any.whl → 1.5.4__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.
- rpa_suite/__init__.py +57 -56
- rpa_suite/core/__init__.py +3 -2
- rpa_suite/core/asyncrun.py +31 -33
- rpa_suite/core/browser.py +110 -81
- rpa_suite/core/clock.py +115 -118
- rpa_suite/core/date.py +36 -40
- rpa_suite/core/dir.py +70 -54
- rpa_suite/core/email.py +55 -53
- rpa_suite/core/file.py +88 -76
- rpa_suite/core/log.py +26 -10
- rpa_suite/core/parallel.py +106 -96
- rpa_suite/core/print.py +42 -70
- rpa_suite/core/regex.py +29 -22
- rpa_suite/core/validate.py +89 -86
- rpa_suite/functions/__create_ss_dir.py +24 -20
- rpa_suite/functions/__init__.py +1 -1
- rpa_suite/functions/_printer.py +20 -20
- rpa_suite/suite.py +71 -101
- rpa_suite/utils/system.py +7 -5
- {rpa_suite-1.5.2.dist-info → rpa_suite-1.5.4.dist-info}/METADATA +76 -59
- rpa_suite-1.5.4.dist-info/RECORD +25 -0
- rpa_suite-1.5.2.dist-info/RECORD +0 -25
- {rpa_suite-1.5.2.dist-info → rpa_suite-1.5.4.dist-info}/WHEEL +0 -0
- {rpa_suite-1.5.2.dist-info → rpa_suite-1.5.4.dist-info}/licenses/LICENSE +0 -0
- {rpa_suite-1.5.2.dist-info → rpa_suite-1.5.4.dist-info}/top_level.txt +0 -0
rpa_suite/__init__.py
CHANGED
@@ -1,65 +1,66 @@
|
|
1
1
|
# rpa_suite/__init__.py
|
2
2
|
|
3
3
|
"""
|
4
|
-
|
5
|
-
|
6
|
-
To use the module, import it as follows:
|
7
|
-
>>> from rpa_suite import rpa
|
8
|
-
|
9
|
-
Example of usage:
|
10
|
-
>>> from rpa_suite import rpa
|
11
|
-
>>> rpa.email.send_smtp(
|
12
|
-
... email_user="your@email.com",
|
13
|
-
... email_password="your_password",
|
14
|
-
... email_to="destination@email.com",
|
15
|
-
... subject_title="Test",
|
16
|
-
... body_message="<p>Test message</p>"
|
17
|
-
... )
|
18
|
-
>>> rpa.alert_print("Hello World")
|
19
|
-
|
20
|
-
Available modules:
|
21
|
-
``clock``: Utilities for time and stopwatch manipulation
|
22
|
-
``date``: Functions for date manipulation
|
23
|
-
``email``: Functionalities for sending emails via SMTP
|
24
|
-
``directory``: Operations with directories
|
25
|
-
``file``: File manipulation
|
26
|
-
``log``: Logging system
|
27
|
-
``printer``: Functions for formatted output
|
28
|
-
``regex``: Operations with regular expressions
|
29
|
-
``validate``: Data validation functions
|
30
|
-
``Browser``: Object Browser automation functions (neeeds Selenium and Webdriver_Manager)
|
4
|
+
RPA Suite is a Python module that provides a set of tools for process automation.
|
31
5
|
|
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
|
-
|
6
|
+
To use the module, import it as follows:
|
7
|
+
>>> from rpa_suite import rpa
|
8
|
+
|
9
|
+
Example of usage:
|
10
|
+
>>> from rpa_suite import rpa
|
11
|
+
>>> rpa.email.send_smtp(
|
12
|
+
... email_user="your@email.com",
|
13
|
+
... email_password="your_password",
|
14
|
+
... email_to="destination@email.com",
|
15
|
+
... subject_title="Test",
|
16
|
+
... body_message="<p>Test message</p>"
|
17
|
+
... )
|
18
|
+
>>> rpa.alert_print("Hello World")
|
19
|
+
|
20
|
+
Available modules:
|
21
|
+
``clock``: Utilities for time and stopwatch manipulation
|
22
|
+
``date``: Functions for date manipulation
|
23
|
+
``email``: Functionalities for sending emails via SMTP
|
24
|
+
``directory``: Operations with directories
|
25
|
+
``file``: File manipulation
|
26
|
+
``log``: Logging system
|
27
|
+
``printer``: Functions for formatted output
|
28
|
+
``regex``: Operations with regular expressions
|
29
|
+
``validate``: Data validation functions
|
30
|
+
``Browser``: Object Browser automation functions (neeeds Selenium and Webdriver_Manager)
|
31
|
+
|
32
|
+
pt-br
|
33
|
+
-----
|
34
|
+
RPA Suite é um módulo Python que fornece um conjunto de ferramentas para automação de processos.
|
35
|
+
|
36
|
+
Para utilizar o módulo, importe-o da seguinte forma:
|
37
|
+
>>> from rpa_suite import rpa
|
38
|
+
|
39
|
+
Exemplo de uso:
|
40
|
+
>>> from rpa_suite import rpa
|
41
|
+
>>> rpa.email.send_smtp(
|
42
|
+
... email_user="seu@email.com",
|
43
|
+
... email_password="sua_senha",
|
44
|
+
... email_to="destino@email.com",
|
45
|
+
... subject_title="Teste",
|
46
|
+
... body_message="<p>Mensagem de teste</p>"
|
47
|
+
... )
|
48
|
+
>>> rpa.alert_print("Hello World")
|
49
|
+
|
50
|
+
Módulos disponíveis:
|
51
|
+
``clock``: Utilitários para manipulação de tempo e cronômetro
|
52
|
+
``date``: Funções para manipulação de datas
|
53
|
+
``email``: Funcionalidades para envio de emails via SMTP
|
54
|
+
``directory``: Operações com diretórios
|
55
|
+
``file``: Manipulação de arquivos
|
56
|
+
``log``: Sistema de logging
|
57
|
+
``printer``: Funções para output formatado
|
58
|
+
``regex``: Operações com expressões regulares
|
59
|
+
``validate``: Funções de validação de dados
|
60
|
+
``Browser``: Objeto de Automação de Navegadores (necessario Selenium e Webdriver_Manager)
|
61
61
|
"""
|
62
62
|
|
63
63
|
# allows importing the rpa_suite module without the package name
|
64
64
|
from .suite import rpa
|
65
|
+
|
65
66
|
rpa
|
rpa_suite/core/__init__.py
CHANGED
@@ -36,11 +36,12 @@ from .parallel import ParallelRunner
|
|
36
36
|
from .asyncrun import AsyncRunner
|
37
37
|
|
38
38
|
|
39
|
-
|
40
39
|
# On this case, we are importing the Browser class only if the selenium and webdriver_manager modules are installed.
|
41
40
|
# This is useful to avoid unnecessary imports and dependencies if the user does not need the Browser functionality.
|
42
41
|
import importlib.util
|
43
42
|
|
44
43
|
# from .browser import Browser
|
45
|
-
if importlib.util.find_spec("selenium") and importlib.util.find_spec(
|
44
|
+
if importlib.util.find_spec("selenium") and importlib.util.find_spec(
|
45
|
+
"webdriver_manager"
|
46
|
+
):
|
46
47
|
from .browser import Browser
|
rpa_suite/core/asyncrun.py
CHANGED
@@ -8,17 +8,17 @@ import traceback
|
|
8
8
|
from functools import wraps
|
9
9
|
|
10
10
|
|
11
|
-
T = TypeVar(
|
11
|
+
T = TypeVar("T")
|
12
12
|
|
13
13
|
|
14
14
|
class AsyncRunner(Generic[T]):
|
15
15
|
"""
|
16
16
|
Class to execute asynchronous functions while maintaining the main application flow.
|
17
|
-
|
17
|
+
|
18
18
|
Allows executing asynchronous functions and retrieving their results later.
|
19
19
|
Optimized for I/O bound operations (network, files, etc).
|
20
20
|
"""
|
21
|
-
|
21
|
+
|
22
22
|
def __init__(self):
|
23
23
|
"""Start AsyncRunner."""
|
24
24
|
self._task = None
|
@@ -29,24 +29,26 @@ class AsyncRunner(Generic[T]):
|
|
29
29
|
def _to_async(func: Callable) -> Callable:
|
30
30
|
"""
|
31
31
|
Converts a synchronous function into an asynchronous one if necessary.
|
32
|
-
|
32
|
+
|
33
33
|
Args:
|
34
34
|
func: The function to be converted.
|
35
|
-
|
35
|
+
|
36
36
|
Returns:
|
37
37
|
A callable that is asynchronous.
|
38
38
|
"""
|
39
|
+
|
39
40
|
@wraps(func)
|
40
41
|
async def wrapper(*args, **kwargs):
|
41
42
|
if asyncio.iscoroutinefunction(func):
|
42
43
|
return await func(*args, **kwargs)
|
43
44
|
return await asyncio.to_thread(func, *args, **kwargs)
|
45
|
+
|
44
46
|
return wrapper
|
45
47
|
|
46
48
|
async def _execute_function(self, function, args, kwargs):
|
47
49
|
"""
|
48
50
|
Executes the function and manages results/errors.
|
49
|
-
|
51
|
+
|
50
52
|
Args:
|
51
53
|
function: The function to be executed.
|
52
54
|
args: Positional arguments for the function.
|
@@ -55,46 +57,42 @@ class AsyncRunner(Generic[T]):
|
|
55
57
|
try:
|
56
58
|
async_func = self._to_async(function)
|
57
59
|
result = await async_func(*args, **kwargs)
|
58
|
-
|
59
|
-
self._result = {
|
60
|
-
|
61
|
-
'result': result,
|
62
|
-
'success': True
|
63
|
-
}
|
64
|
-
|
60
|
+
|
61
|
+
self._result = {"status": "success", "result": result, "success": True}
|
62
|
+
|
65
63
|
except Exception as e:
|
66
64
|
self._result = {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
"status": "error",
|
66
|
+
"error": str(e),
|
67
|
+
"traceback": traceback.format_exc(),
|
68
|
+
"success": False,
|
71
69
|
}
|
72
70
|
|
73
|
-
def run(self, function: Callable[..., T], *args, **kwargs) ->
|
71
|
+
def run(self, function: Callable[..., T], *args, **kwargs) -> "AsyncRunner[T]":
|
74
72
|
"""
|
75
73
|
Starts the execution of the function asynchronously.
|
76
|
-
|
74
|
+
|
77
75
|
Args:
|
78
76
|
function: The function to be executed.
|
79
77
|
*args: Positional arguments for the function.
|
80
78
|
**kwargs: Keyword arguments for the function.
|
81
|
-
|
79
|
+
|
82
80
|
Returns:
|
83
81
|
self: Returns the instance itself.
|
84
82
|
"""
|
85
83
|
self._result.clear()
|
86
84
|
self._start_time = time.time()
|
87
|
-
|
85
|
+
|
88
86
|
# Creates and schedules the asynchronous task
|
89
87
|
loop = asyncio.get_event_loop()
|
90
88
|
self._task = loop.create_task(self._execute_function(function, args, kwargs))
|
91
|
-
|
89
|
+
|
92
90
|
return self
|
93
91
|
|
94
92
|
def is_running(self) -> bool:
|
95
93
|
"""
|
96
94
|
Checks if the task is still running.
|
97
|
-
|
95
|
+
|
98
96
|
Returns:
|
99
97
|
True if the task is running, False otherwise.
|
100
98
|
"""
|
@@ -103,33 +101,33 @@ class AsyncRunner(Generic[T]):
|
|
103
101
|
async def get_result(self, timeout: Optional[float] = None) -> Dict[str, Any]:
|
104
102
|
"""
|
105
103
|
Retrieves the result of the asynchronous execution.
|
106
|
-
|
104
|
+
|
107
105
|
Args:
|
108
106
|
timeout: Maximum time (in seconds) to wait.
|
109
|
-
|
107
|
+
|
110
108
|
Returns:
|
111
109
|
A dictionary with the result or error information.
|
112
110
|
"""
|
113
111
|
if self._task is None:
|
114
112
|
return {
|
115
|
-
|
116
|
-
|
117
|
-
|
113
|
+
"success": False,
|
114
|
+
"error": "No task has been started",
|
115
|
+
"execution_time": 0,
|
118
116
|
}
|
119
117
|
|
120
118
|
try:
|
121
119
|
await asyncio.wait_for(self._task, timeout=timeout)
|
122
|
-
|
120
|
+
|
123
121
|
except asyncio.TimeoutError:
|
124
122
|
self._task.cancel()
|
125
123
|
return {
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
"success": False,
|
125
|
+
"error": f"Operation canceled due to timeout after {time.time() - self._start_time:.2f} seconds",
|
126
|
+
"execution_time": time.time() - self._start_time,
|
129
127
|
}
|
130
128
|
|
131
129
|
result = dict(self._result)
|
132
|
-
result[
|
130
|
+
result["execution_time"] = time.time() - self._start_time
|
133
131
|
return result
|
134
132
|
|
135
133
|
def cancel(self) -> None:
|
rpa_suite/core/browser.py
CHANGED
@@ -16,28 +16,27 @@ from time import sleep
|
|
16
16
|
import os, requests
|
17
17
|
|
18
18
|
|
19
|
-
class Browser
|
20
|
-
|
19
|
+
class Browser:
|
21
20
|
"""
|
22
21
|
Browser Object for Automation (Work in Progress)
|
23
|
-
This class provides an interface for automating browser interactions using
|
24
|
-
Google Chrome with a debugging port. It includes methods for starting,
|
25
|
-
configuring, navigating, and interacting with the browser. The implementation
|
22
|
+
This class provides an interface for automating browser interactions using
|
23
|
+
Google Chrome with a debugging port. It includes methods for starting,
|
24
|
+
configuring, navigating, and interacting with the browser. The implementation
|
26
25
|
is still under development and may require further enhancements.
|
27
|
-
|
26
|
+
|
28
27
|
Attributes:
|
29
28
|
driver: The WebDriver instance used to control the browser.
|
30
29
|
port (int): The debugging port used to connect to the browser. Default is 9393.
|
31
30
|
path_driver (str): The path to the ChromeDriver executable.
|
32
|
-
|
31
|
+
|
33
32
|
Methods:
|
34
33
|
__init__(port: int = 9393, close_all_chrome_on_this_port: bool = False):
|
35
|
-
Initializes the Browser object with the specified debugging port and
|
34
|
+
Initializes the Browser object with the specified debugging port and
|
36
35
|
optionally closes all Chrome instances running on the same port.
|
37
36
|
configure_browser() -> None:
|
38
37
|
Configures the browser with debugging options and initializes the WebDriver.
|
39
38
|
start_browser(close_chrome_on_this_port: bool = True, display_message: bool = False):
|
40
|
-
Starts the Chrome browser with the specified debugging port and initializes
|
39
|
+
Starts the Chrome browser with the specified debugging port and initializes
|
41
40
|
the WebDriver.
|
42
41
|
find_ele(value, by=By.XPATH, timeout=12, display_message=True):
|
43
42
|
Finds a single element on the page using the specified locator strategy.
|
@@ -47,29 +46,29 @@ class Browser():
|
|
47
46
|
Closes all Chrome processes forcefully.
|
48
47
|
close_browser(display_message: bool = False):
|
49
48
|
Closes the browser instance and terminates the associated Chrome processes.
|
50
|
-
|
49
|
+
|
51
50
|
pt-br
|
52
51
|
----------
|
53
52
|
Objeto Browser para Automação (Em Desenvolvimento)
|
54
|
-
Esta classe fornece uma interface para automação de interações com o navegador
|
55
|
-
Google Chrome utilizando uma porta de depuração. Inclui métodos para iniciar,
|
56
|
-
configurar, navegar e interagir com o navegador. A implementação ainda está em
|
53
|
+
Esta classe fornece uma interface para automação de interações com o navegador
|
54
|
+
Google Chrome utilizando uma porta de depuração. Inclui métodos para iniciar,
|
55
|
+
configurar, navegar e interagir com o navegador. A implementação ainda está em
|
57
56
|
desenvolvimento e pode requerer melhorias adicionais.
|
58
|
-
|
57
|
+
|
59
58
|
Atributos:
|
60
59
|
driver: A instância do WebDriver usada para controlar o navegador.
|
61
60
|
port (int): A porta de depuração usada para conectar ao navegador. O padrão é 9393.
|
62
61
|
path_driver (str): O caminho para o executável do ChromeDriver.
|
63
|
-
|
62
|
+
|
64
63
|
Métodos:
|
65
64
|
__init__(port: int = 9393, close_all_chrome_on_this_port: bool = False):
|
66
|
-
Inicializa o objeto Browser com a porta de depuração especificada e,
|
67
|
-
opcionalmente, fecha todas as instâncias do Chrome que estão sendo executadas
|
65
|
+
Inicializa o objeto Browser com a porta de depuração especificada e,
|
66
|
+
opcionalmente, fecha todas as instâncias do Chrome que estão sendo executadas
|
68
67
|
na mesma porta.
|
69
68
|
configure_browser() -> None:
|
70
69
|
Configura o navegador com opções de depuração e inicializa o WebDriver.
|
71
70
|
start_browser(close_chrome_on_this_port: bool = True, display_message: bool = False):
|
72
|
-
Inicia o navegador Chrome com a porta de depuração especificada e inicializa
|
71
|
+
Inicia o navegador Chrome com a porta de depuração especificada e inicializa
|
73
72
|
o WebDriver.
|
74
73
|
find_ele(value, by=By.XPATH, timeout=12, display_message=True):
|
75
74
|
Localiza um único elemento na página usando a estratégia de localização especificada.
|
@@ -84,12 +83,13 @@ class Browser():
|
|
84
83
|
driver: None
|
85
84
|
port: int = None
|
86
85
|
path_driver = None
|
87
|
-
|
86
|
+
|
88
87
|
def __init__(self, port: int = 9393, close_all_chrome_on_this_port: bool = False):
|
89
88
|
self.port = port
|
90
89
|
self.path_driver = ChromeDriverManager().install()
|
91
90
|
|
92
|
-
if close_all_chrome_on_this_port:
|
91
|
+
if close_all_chrome_on_this_port:
|
92
|
+
self._close_all_chrome()
|
93
93
|
...
|
94
94
|
|
95
95
|
def configure_browser(self) -> None:
|
@@ -102,33 +102,40 @@ class Browser():
|
|
102
102
|
FileNotFoundError: If the specified path to the ChromeDriver executable does not exist.
|
103
103
|
Exception: For any other errors encountered during the browser configuration process.
|
104
104
|
"""
|
105
|
-
|
105
|
+
|
106
106
|
try:
|
107
107
|
# Use the absolute path from comment
|
108
|
-
|
108
|
+
|
109
109
|
options = Options()
|
110
|
-
options.add_experimental_option(
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
options.add_experimental_option(
|
111
|
+
"debuggerAddress", f"127.0.0.1:{str(self.port)}"
|
112
|
+
)
|
113
|
+
|
114
|
+
# Additional configs
|
114
115
|
options.add_argument("--start-maximized")
|
115
116
|
options.add_argument("--disable-notifications")
|
116
|
-
|
117
|
+
|
117
118
|
# Verifica se o caminho do driver está correto
|
118
119
|
if not os.path.exists(self.path_driver):
|
119
|
-
raise FileNotFoundError(
|
120
|
-
|
120
|
+
raise FileNotFoundError(
|
121
|
+
f"O caminho do driver não foi encontrado: {self.path_driver}"
|
122
|
+
)
|
123
|
+
|
121
124
|
# Create driver with options and chromedriver path
|
122
125
|
self.driver = webdriver.Chrome(
|
123
|
-
#service=self.path_driver,
|
126
|
+
# service=self.path_driver,
|
124
127
|
options=options,
|
125
|
-
keep_alive=True
|
128
|
+
keep_alive=True,
|
126
129
|
)
|
127
130
|
|
128
131
|
except Exception as e:
|
129
|
-
error_print(
|
132
|
+
error_print(
|
133
|
+
f"Erro durante a função: {self.configure_browser.__name__}! Error: {str(e)}."
|
134
|
+
)
|
130
135
|
|
131
|
-
def start_browser(
|
136
|
+
def start_browser(
|
137
|
+
self, close_chrome_on_this_port: bool = True, display_message: bool = False
|
138
|
+
):
|
132
139
|
"""
|
133
140
|
Starts a Chrome browser instance with remote debugging enabled.
|
134
141
|
Args:
|
@@ -143,67 +150,74 @@ class Browser():
|
|
143
150
|
- Configures the browser instance using the `configure_browser` method.
|
144
151
|
- Optionally displays a success message if `display_message` is True.
|
145
152
|
"""
|
146
|
-
|
153
|
+
|
147
154
|
try:
|
148
|
-
if close_chrome_on_this_port:
|
155
|
+
if close_chrome_on_this_port:
|
156
|
+
self.close_browser()
|
149
157
|
|
150
158
|
# Inicia o Chrome com debugging port
|
151
|
-
os.system(
|
159
|
+
os.system(
|
160
|
+
f'start chrome.exe --remote-debugging-port={str(self.port)} --user-data-dir="C:/temp/chrome_profile"'
|
161
|
+
)
|
152
162
|
|
153
163
|
# Aguardar até que o Chrome esteja realmente aberto
|
154
164
|
while True:
|
155
165
|
try:
|
156
166
|
# Tenta conectar ao Chrome na porta de depuração
|
157
|
-
response = requests.get(f
|
167
|
+
response = requests.get(f"http://127.0.0.1:{self.port}/json")
|
158
168
|
if response.status_code == 200:
|
159
169
|
break # O Chrome está aberto
|
160
170
|
except requests.ConnectionError:
|
161
171
|
sleep(1) # Espera um segundo antes de tentar novamente
|
162
|
-
|
172
|
+
|
163
173
|
# Inicializa o Chrome com as opções
|
164
174
|
self.configure_browser()
|
165
|
-
|
166
|
-
if display_message: success_print(f'Browser: Iniciado com sucesso!')
|
167
|
-
|
168
|
-
except Exception as e:
|
169
|
-
error_print(f'Erro ao iniciar navegador: {str(e)}.')
|
170
175
|
|
176
|
+
if display_message:
|
177
|
+
success_print(f"Browser: Iniciado com sucesso!")
|
178
|
+
|
179
|
+
except Exception as e:
|
180
|
+
error_print(f"Erro ao iniciar navegador: {str(e)}.")
|
171
181
|
|
172
|
-
def find_ele(self, value: str, by:By=By.XPATH, timeout=12, display_message=True):
|
182
|
+
def find_ele(self, value: str, by: By = By.XPATH, timeout=12, display_message=True):
|
173
183
|
"""
|
174
184
|
Locate and return a web element on the page using the specified locator strategy.
|
175
185
|
Args:
|
176
186
|
value (str): The locator value to identify the web element.
|
177
|
-
by (selenium.webdriver.common.by.By, optional): The locator strategy to use.
|
187
|
+
by (selenium.webdriver.common.by.By, optional): The locator strategy to use.
|
178
188
|
Defaults to By.XPATH.
|
179
|
-
timeout (int, optional): The maximum time to wait for the element to appear, in seconds.
|
189
|
+
timeout (int, optional): The maximum time to wait for the element to appear, in seconds.
|
180
190
|
Defaults to 12.
|
181
|
-
display_message (bool, optional): Whether to display an error message if the element
|
191
|
+
display_message (bool, optional): Whether to display an error message if the element
|
182
192
|
is not found. Defaults to True.
|
183
193
|
Returns:
|
184
194
|
selenium.webdriver.remote.webelement.WebElement: The located web element if found.
|
185
195
|
None: If the element is not found or an exception occurs.
|
186
196
|
Raises:
|
187
|
-
Exception: Propagates any exception encountered during the element search if
|
197
|
+
Exception: Propagates any exception encountered during the element search if
|
188
198
|
`display_message` is set to False.
|
189
199
|
"""
|
190
|
-
|
200
|
+
|
191
201
|
try:
|
192
202
|
sleep(2)
|
193
203
|
element = WebDriverWait(self.driver, timeout).until(
|
194
204
|
EC.presence_of_element_located((by, value))
|
195
|
-
)
|
196
|
-
|
205
|
+
)
|
206
|
+
return element
|
207
|
+
|
197
208
|
except Exception as e:
|
198
209
|
|
199
210
|
if display_message:
|
200
|
-
error_print(
|
211
|
+
error_print(
|
212
|
+
f"Erro durante a função: {self.find_ele.__name__}! Error: {str(e)}."
|
213
|
+
)
|
214
|
+
return None
|
215
|
+
else:
|
201
216
|
return None
|
202
|
-
else: return None
|
203
217
|
|
204
218
|
# find elements (needs implementation)
|
205
219
|
...
|
206
|
-
|
220
|
+
|
207
221
|
# navigate
|
208
222
|
def get(self, url: str, display_message: bool = False):
|
209
223
|
"""
|
@@ -214,14 +228,14 @@ class Browser():
|
|
214
228
|
Raises:
|
215
229
|
Exception: If an error occurs while navigating to the URL, it logs the error message.
|
216
230
|
"""
|
217
|
-
|
231
|
+
|
218
232
|
try:
|
219
233
|
self.driver.get(url)
|
220
|
-
if display_message:
|
221
|
-
|
222
|
-
except Exception as e:
|
223
|
-
error_print(f'Erro ao navegar para a URL: {url}. Error: {str(e)}.')
|
234
|
+
if display_message:
|
235
|
+
success_print(f"Browser: Navegando para: {url}")
|
224
236
|
|
237
|
+
except Exception as e:
|
238
|
+
error_print(f"Erro ao navegar para a URL: {url}. Error: {str(e)}.")
|
225
239
|
|
226
240
|
def _close_all_browsers(self):
|
227
241
|
"""
|
@@ -233,11 +247,10 @@ class Browser():
|
|
233
247
|
"""
|
234
248
|
|
235
249
|
try:
|
236
|
-
os.system(
|
250
|
+
os.system("taskkill /F /IM chrome.exe >nul 2>&1")
|
237
251
|
except:
|
238
252
|
pass
|
239
253
|
|
240
|
-
|
241
254
|
def close_browser(self, display_message: bool = False):
|
242
255
|
"""
|
243
256
|
Fecha o navegador controlado pelo Selenium e encerra os processos relacionados ao Chrome.
|
@@ -257,46 +270,62 @@ class Browser():
|
|
257
270
|
Observação:
|
258
271
|
Use com cautela, especialmente o encerramento extremo, pois pode afetar outros processos do Chrome em execução.
|
259
272
|
"""
|
260
|
-
|
273
|
+
|
261
274
|
try:
|
262
275
|
# Primeiro tenta fechar todas as janelas via Selenium
|
263
276
|
try:
|
264
277
|
self.driver.close()
|
265
278
|
except:
|
266
279
|
pass
|
267
|
-
|
280
|
+
|
268
281
|
# Depois tenta encerrar a sessão
|
269
282
|
try:
|
270
283
|
self.driver.quit()
|
271
284
|
except:
|
272
285
|
pass
|
273
|
-
|
286
|
+
|
274
287
|
# Aguarda um momento para o processo ser liberado
|
275
288
|
sleep(1)
|
276
|
-
|
289
|
+
|
277
290
|
# Força o fechamento do processo específico do Chrome
|
278
|
-
os.system(
|
279
|
-
|
291
|
+
os.system(
|
292
|
+
f'taskkill /f /im chrome.exe /fi "commandline like *--remote-debugging-port={str(self.port)}*" >nul 2>&1'
|
293
|
+
)
|
294
|
+
|
280
295
|
# Verifica se o processo foi realmente terminado
|
281
|
-
check = os.system(
|
282
|
-
|
296
|
+
check = os.system(
|
297
|
+
f'tasklist /fi "imagename eq chrome.exe" /fi "commandline like *--remote-debugging-port={str(self.port)}*" >nul 2>&1'
|
298
|
+
)
|
299
|
+
|
283
300
|
if check == 0:
|
284
301
|
# Processo ainda existe, tenta método mais agressivo
|
285
|
-
os.system(
|
286
|
-
|
287
|
-
|
302
|
+
os.system(
|
303
|
+
f'taskkill /f /im chrome.exe /fi "commandline like *--remote-debugging-port={str(self.port)}*" /t >nul 2>&1'
|
304
|
+
)
|
305
|
+
if display_message:
|
306
|
+
alert_print(f"Browser: Fechado via força!")
|
307
|
+
|
288
308
|
else:
|
289
|
-
if display_message:
|
290
|
-
|
309
|
+
if display_message:
|
310
|
+
success_print(f"Browser: Fechado com sucesso!")
|
311
|
+
|
291
312
|
except Exception as e:
|
292
|
-
|
293
|
-
|
313
|
+
|
294
314
|
try:
|
295
|
-
if display_message:
|
315
|
+
if display_message:
|
316
|
+
alert_print(
|
317
|
+
f"Erro ao fechar navegador: {str(e)}, Tentando meio mais forte!"
|
318
|
+
)
|
296
319
|
|
297
320
|
# Último recurso - mata todos os processos do Chrome (use com cautela)
|
298
|
-
os.system(
|
299
|
-
|
300
|
-
|
321
|
+
os.system(
|
322
|
+
f'taskkill /f /im chrome.exe /fi "commandline like *--remote-debugging-port={str(self.port)}*" /t >nul 2>&1'
|
323
|
+
)
|
324
|
+
if display_message:
|
325
|
+
alert_print(f"Browser: Fechado via força extrema!")
|
326
|
+
|
301
327
|
except Exception as error_ultimate:
|
302
|
-
if display_message:
|
328
|
+
if display_message:
|
329
|
+
error_print(
|
330
|
+
f"Falha crítica ao tentar fechar o navegador! Error: {str(error_ultimate)}!"
|
331
|
+
)
|