zelium 0.1.0__tar.gz

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.
@@ -0,0 +1,2 @@
1
+ include README.md
2
+ include LICENSE
zelium-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: zelium
3
+ Version: 0.1.0
4
+ Summary: Intelligent abstraction layer over Selenium
5
+ Author-email: Iván <yupivangh@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/yup-Ivan/Zelium
8
+ Project-URL: Repository, https://github.com/yup-Ivan/Zelium
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: selenium>=4.0
12
+
13
+ # ZELIUM
14
+
15
+ **ZELIUM** is a web automation framework based on **Selenium**, written in **Python**, designed to **simplify, standardize, and accelerate** the creation of web automation scripts.
16
+
17
+ It is designed to:
18
+ - Reduce repetitive code
19
+ - Centralize common patterns (waits, scrolls, JS fallbacks…)
20
+ - Provide a clear and expressive API (in Spanish and English)
21
+ - Make maintenance of complex automation scripts easier
22
+
23
+ ---
24
+
25
+ ## 👤 Author
26
+
27
+ - 💻 GitHub: https://github.com/yup-Ivan
28
+
29
+ ---
30
+
31
+ ## 🎯 Main Goals
32
+
33
+ - 🧠 Intelligent abstraction over Selenium
34
+ - 🔁 Reuse of common logic via helpers
35
+ - 🛡️ Robustness against dynamic elements (React, Vue, etc.)
36
+ - 🧩 Clean, readable, and consistent API
37
+ - 🌍 Multilanguage support (aliases in Spanish / English)
38
+
39
+ ---
40
+
41
+ ## 📁 Project Structure
42
+
43
+ ```text
44
+ Zelium/
45
+ ├── __init__.py # Public API of the framework (exports and aliases)
46
+ ├── alarm.py # Handling browser alerts, confirms, and prompts
47
+ ├── config.py # Global initialization and configuration (driver, options…)
48
+ ├── helpers.py # Internal helpers (wait, find, scroll, js_click, etc.)
49
+ ├── js.py # JavaScript utilities (scroll, set_value, remove readonly…)
50
+ ├── tools.py # Reusable helper functions
51
+ └── xpath.py # XPath element actions (click, send_keys, select…)
zelium-0.1.0/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # ZELIUM
2
+
3
+ **ZELIUM** is a web automation framework based on **Selenium**, written in **Python**, designed to **simplify, standardize, and accelerate** the creation of web automation scripts.
4
+
5
+ It is designed to:
6
+ - Reduce repetitive code
7
+ - Centralize common patterns (waits, scrolls, JS fallbacks…)
8
+ - Provide a clear and expressive API (in Spanish and English)
9
+ - Make maintenance of complex automation scripts easier
10
+
11
+ ---
12
+
13
+ ## 👤 Author
14
+
15
+ - 💻 GitHub: https://github.com/yup-Ivan
16
+
17
+ ---
18
+
19
+ ## 🎯 Main Goals
20
+
21
+ - 🧠 Intelligent abstraction over Selenium
22
+ - 🔁 Reuse of common logic via helpers
23
+ - 🛡️ Robustness against dynamic elements (React, Vue, etc.)
24
+ - 🧩 Clean, readable, and consistent API
25
+ - 🌍 Multilanguage support (aliases in Spanish / English)
26
+
27
+ ---
28
+
29
+ ## 📁 Project Structure
30
+
31
+ ```text
32
+ Zelium/
33
+ ├── __init__.py # Public API of the framework (exports and aliases)
34
+ ├── alarm.py # Handling browser alerts, confirms, and prompts
35
+ ├── config.py # Global initialization and configuration (driver, options…)
36
+ ├── helpers.py # Internal helpers (wait, find, scroll, js_click, etc.)
37
+ ├── js.py # JavaScript utilities (scroll, set_value, remove readonly…)
38
+ ├── tools.py # Reusable helper functions
39
+ └── xpath.py # XPath element actions (click, send_keys, select…)
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "zelium"
7
+ version = "0.1.0"
8
+ description = "Intelligent abstraction layer over Selenium"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+
13
+ authors = [
14
+ { name = "Iván", email = "yupivangh@gmail.com" }
15
+ ]
16
+
17
+ dependencies = [
18
+ "selenium>=4.0"
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/yup-Ivan/Zelium"
23
+ Repository = "https://github.com/yup-Ivan/Zelium"
24
+
25
+ [tool.setuptools]
26
+ package-dir = {"" = "src"}
27
+
28
+ [tool.setuptools.packages.find]
29
+ where = ["src"]
zelium-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,55 @@
1
+ # Zelium/__init__.py
2
+ from .js import JS
3
+ from .alarm import Alarm
4
+ from .tools import open
5
+ from .config import start
6
+ from .xpath import (
7
+ exist, get_text, click, send_keys,
8
+ select, force_select_combobox, clear,
9
+ delDisable,
10
+ )
11
+
12
+ __version__ = "0.1.0"
13
+
14
+ # ─────────────────────────────
15
+ # Alias (multi-idioma / semánticos)
16
+ # ─────────────────────────────
17
+ JavaScript = JS
18
+ Alarma = Alarm
19
+
20
+ empezar = start
21
+ abrir = open
22
+
23
+ existe = exist
24
+ obtener_texto = get_text
25
+ pulsar = click
26
+ enviar = send_keys
27
+ seleccionar = select
28
+ forzar_combobox = force_select_combobox
29
+ limpiar = clear
30
+ quitar_disable = delDisable
31
+
32
+ # ─────────────────────────────
33
+ # API
34
+ # ─────────────────────────────
35
+ __all__ = [
36
+ "JS", "JavaScript",
37
+ "Alarm", "Alarma",
38
+ "start", "empezar",
39
+ "open", "abrir",
40
+ "exist", "existe",
41
+ "get_text", "obtener_texto",
42
+ "click", "pulsar",
43
+ "send_keys", "enviar",
44
+ "select", "seleccionar",
45
+ "force_select_combobox", "forzar_combobox",
46
+ "clear", "limpiar",
47
+ "noDisable", "quitar_disable",
48
+ "alarm", "js",
49
+ ]
50
+
51
+ # ─────────────────────────────
52
+ # Instancias
53
+ # ─────────────────────────────
54
+ alarm = Alarm
55
+ js = JS
@@ -0,0 +1,51 @@
1
+ # Zelium/alarm.py
2
+ from selenium.common.exceptions import NoAlertPresentException
3
+ from selenium.webdriver.remote.webdriver import WebDriver
4
+
5
+ class Alarm:
6
+ _driver: WebDriver = None
7
+
8
+ @classmethod
9
+ def set_driver(cls, driver: WebDriver):
10
+ cls._driver = driver
11
+
12
+ @classmethod
13
+ def _get_alert(cls):
14
+ if cls._driver is None:
15
+ raise RuntimeError("Driver no asignado. Usa Zelium.alarm.set_driver(driver)")
16
+ try:
17
+ return cls._driver.switch_to.alert
18
+ except NoAlertPresentException:
19
+ return None
20
+
21
+ @classmethod
22
+ def accept(cls):
23
+ alert = cls._get_alert()
24
+ if alert:
25
+ alert.accept()
26
+ return True
27
+ return False
28
+
29
+ @classmethod
30
+ def deny(cls):
31
+ alert = cls._get_alert()
32
+ if alert:
33
+ alert.dismiss()
34
+ return True
35
+ return False
36
+
37
+ @classmethod
38
+ def delete(cls):
39
+ alert = cls._get_alert()
40
+ if alert:
41
+ text = alert.text
42
+ alert.accept()
43
+ return text
44
+ return None
45
+
46
+ @classmethod
47
+ def text(cls):
48
+ alert = cls._get_alert()
49
+ if alert:
50
+ return alert.text
51
+ return None
@@ -0,0 +1,98 @@
1
+ # Zelium/config.py
2
+ import os
3
+ from seleniumwire import webdriver as sw_webdriver
4
+ from selenium import webdriver as selenium_normal
5
+ from selenium.webdriver.chrome.options import Options
6
+
7
+ from .alarm import Alarm
8
+ from .js import JS
9
+
10
+
11
+ def start(modo="normal", proxy=None, headless=False, usar_seleniumwire=True, perfil=None,):
12
+ """
13
+ Inicia un navegador Chrome con distintas opciones.
14
+
15
+ Args:
16
+ modo (str): "normal", "limpio" o "extension"
17
+ proxy (str | None): proxy en formato host:puerto
18
+ headless (bool): ejecutar Chrome en modo headless
19
+ usar_seleniumwire (bool): usar Selenium Wire (necesario si hay proxy)
20
+ perfil (str | None): ruta a perfil de Chrome (modo extension)
21
+
22
+ Returns:
23
+ webdriver.Chrome: instancia del driver
24
+ """
25
+
26
+ chrome_options = Options()
27
+ chrome_options.add_argument("--start-maximized")
28
+ chrome_options.add_argument("--disable-notifications")
29
+ chrome_options.add_argument("--ignore-certificate-errors")
30
+ chrome_options.add_argument("--disable-infobars")
31
+ chrome_options.add_argument("--log-level=3")
32
+ chrome_options.add_argument("--remote-debugging-port=0")
33
+ chrome_options.add_argument("--disable-extensions")
34
+ chrome_options.add_argument("--blink-settings=imagesEnabled=false")
35
+ chrome_options.add_experimental_option(
36
+ "excludeSwitches", ["enable-logging"]
37
+ )
38
+
39
+ chrome_options.add_argument(
40
+ "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
41
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
42
+ "Chrome/115.0.0.0 Safari/537.36"
43
+ )
44
+
45
+ if headless:
46
+ chrome_options.add_argument("--headless=new")
47
+
48
+ # ─────────────────────────────
49
+ # Modo de ejecución
50
+ # ─────────────────────────────
51
+ if modo == "extension":
52
+ perfil_path = perfil or r"C:\SeleniumProfile"
53
+ os.makedirs(perfil_path, exist_ok=True)
54
+ chrome_options.add_argument(
55
+ f"--user-data-dir={os.path.abspath(perfil_path)}"
56
+ )
57
+
58
+ elif modo == "limpio":
59
+ chrome_options.add_argument("--incognito")
60
+
61
+ # ─────────────────────────────
62
+ # Proxy
63
+ # ─────────────────────────────
64
+ seleniumwire_options = {}
65
+
66
+ if proxy:
67
+ if usar_seleniumwire:
68
+ seleniumwire_options = {
69
+ "proxy": {
70
+ "http": f"http://{proxy}",
71
+ "https": f"http://{proxy}",
72
+ "no_proxy": "localhost,127.0.0.1",
73
+ },
74
+ "verify_ssl": False,
75
+ }
76
+ else:
77
+ chrome_options.add_argument(
78
+ f"--proxy-server=http://{proxy}"
79
+ )
80
+
81
+ # ─────────────────────────────
82
+ # Inicializar driver
83
+ # ─────────────────────────────
84
+ if usar_seleniumwire and proxy:
85
+ driver = sw_webdriver.Chrome(
86
+ options=chrome_options,
87
+ seleniumwire_options=seleniumwire_options,
88
+ )
89
+ else:
90
+ driver = selenium_normal.Chrome(options=chrome_options)
91
+
92
+ # ─────────────────────────────
93
+ # Inyectar driver en módulos
94
+ # ─────────────────────────────
95
+ Alarm.set_driver(driver)
96
+ JS.set_driver(driver)
97
+
98
+ return driver
@@ -0,0 +1,26 @@
1
+ # Zelium/helpers.py
2
+ from selenium.webdriver.common.by import By
3
+ from selenium.webdriver.support.ui import WebDriverWait
4
+ from selenium.webdriver.support import expected_conditions as EC
5
+
6
+
7
+ def wait(driver, condition, timeout=5):
8
+ return WebDriverWait(driver, timeout).until(condition)
9
+
10
+
11
+ def find(xpath, driver, timeout=5, visible=False):
12
+ condition = (
13
+ EC.visibility_of_element_located
14
+ if visible else EC.presence_of_element_located
15
+ )
16
+ return wait(driver, condition((By.XPATH, xpath)), timeout)
17
+
18
+
19
+ def scroll(elem, driver):
20
+ driver.execute_script(
21
+ "arguments[0].scrollIntoView({block:'center'});", elem
22
+ )
23
+
24
+
25
+ def js_click(elem, driver):
26
+ driver.execute_script("arguments[0].click();", elem)
@@ -0,0 +1,115 @@
1
+ # Zelium/js.py
2
+ from selenium.common.exceptions import JavascriptException, NoSuchElementException
3
+ from selenium.webdriver.remote.webdriver import WebDriver
4
+ from selenium.webdriver.common.by import By
5
+ from selenium.webdriver.support.ui import WebDriverWait
6
+ from selenium.webdriver.support import expected_conditions as EC
7
+ from selenium.common.exceptions import JavascriptException, TimeoutException
8
+
9
+ class JS:
10
+ _driver: WebDriver = None
11
+
12
+ @classmethod
13
+ def set_driver(cls, driver: WebDriver):
14
+ cls._driver = driver
15
+
16
+ @classmethod
17
+ def execute(cls, script: str, *args):
18
+ if cls._driver is None:
19
+ raise RuntimeError("Driver no asignado. Usa JS.set_driver(driver)")
20
+ try:
21
+ return cls._driver.execute_script(script, *args)
22
+ except JavascriptException as e:
23
+ print(f"[Error JS] {e}")
24
+ return None
25
+
26
+ # ─────────────────────────────
27
+ # Sub funciones predeterminadas
28
+ # ─────────────────────────────
29
+ @classmethod
30
+ def quitar_readonly(cls, xpath: str):
31
+ if cls._driver is None:
32
+ raise RuntimeError("Driver no asignado. Usa JS.set_driver(driver)")
33
+ try:
34
+ elemento = cls._driver.find_element(By.XPATH, xpath)
35
+ cls._driver.execute_script("arguments[0].removeAttribute('readonly')", elemento)
36
+ except NoSuchElementException:
37
+ print(f"[Advertencia] No se encontró el elemento con XPath: {xpath}")
38
+ except JavascriptException as e:
39
+ print(f"[Error] No se pudo eliminar el atributo 'readonly': {e}")
40
+
41
+ @classmethod
42
+ def set_value(cls, xpath: str, value):
43
+ if cls._driver is None:
44
+ raise RuntimeError("Driver no asignado. Usa JS.set_driver(driver)")
45
+ try:
46
+ elemento = cls._driver.find_element(By.XPATH, xpath)
47
+ cls._driver.execute_script("arguments[0].value = arguments[1];", elemento, value)
48
+ except NoSuchElementException:
49
+ print(f"[Advertencia] No se encontró el elemento con XPath: {xpath}")
50
+ except JavascriptException as e:
51
+ print(f"[Error] No se pudo establecer el valor: {e}")
52
+
53
+ @classmethod
54
+ def establecer_fecha(cls, xpath: str, valor: str):
55
+ if cls._driver is None:
56
+ raise RuntimeError("Driver no asignado. Usa JS.set_driver(driver)")
57
+ try:
58
+ elemento = cls._driver.find_element(By.XPATH, xpath)
59
+ cls._driver.execute_script("arguments[0].removeAttribute('readonly')", elemento)
60
+ cls._driver.execute_script("arguments[0].value = arguments[1];", elemento, valor)
61
+ cls._driver.execute_script(
62
+ "arguments[0].dispatchEvent(new Event('change', { bubbles: true }));", elemento
63
+ )
64
+ except NoSuchElementException:
65
+ print(f"[Advertencia] No se encontró el elemento con XPath: {xpath}")
66
+ except JavascriptException as e:
67
+ print(f"[Error] No se pudo establecer la fecha: {e}")
68
+
69
+ @classmethod
70
+ def agregar_clase_valid(cls, xpath=None, xpaths=None, timeout=5):
71
+ if cls._driver is None:
72
+ raise RuntimeError("Driver no asignado. Usa JS.set_driver(driver)")
73
+
74
+ if not xpaths and not xpath:
75
+ print("[Error] agregar_clase_valid: No se proporcionó ni 'xpath' ni 'xpaths'.")
76
+ return 0
77
+
78
+ if xpaths is None:
79
+ xpaths = [xpath]
80
+
81
+ if not isinstance(xpaths, (list, tuple)):
82
+ print(f"[Error] agregar_clase_valid: 'xpaths' no es iterable ({type(xpaths)})")
83
+ return 0
84
+
85
+ modificados = 0
86
+ js = "if (arguments[0]) { arguments[0].classList.add('valid'); return true; } return false;"
87
+
88
+ for xp in xpaths:
89
+ try:
90
+ elemento = WebDriverWait(cls._driver, timeout).until(
91
+ EC.presence_of_element_located((By.XPATH, xp))
92
+ )
93
+ result = cls._driver.execute_script(js, elemento)
94
+ if result:
95
+ modificados += 1
96
+ except TimeoutException:
97
+ print(f"[Advertencia] No se encontró el elemento con XPath (timeout {timeout}s): {xp}")
98
+ except JavascriptException as e:
99
+ print(f"[Error JS en {xp}] {e}")
100
+ except Exception as e:
101
+ print(f"[Error inesperado en {xp}] {type(e).__name__}: {e}")
102
+
103
+ return modificados
104
+
105
+ @classmethod
106
+ def scroll(cls, valor):
107
+ if cls._driver is None:
108
+ raise RuntimeError("Driver no asignado. Usa JS.set_driver(driver)")
109
+ try:
110
+ cls._driver.execute_script(f"window.scrollBy(0, {valor});")
111
+
112
+ except Exception as e:
113
+ print(e)
114
+ except JavascriptException as e:
115
+ print(f"[Error JS] No se pudo hacer scroll: {e}")
@@ -0,0 +1,10 @@
1
+ # Zelium/tools.py
2
+ from selenium.common.exceptions import WebDriverException
3
+
4
+ def open(url, driver):
5
+ try:
6
+ driver.get(url)
7
+ except WebDriverException as e:
8
+ print(f"[WebDriverError] No se pudo abrir {url}: {e}")
9
+ except Exception as e:
10
+ print(f"[Error inesperado] No se pudo abrir {url}: {type(e).__name__}: {e}")
@@ -0,0 +1,149 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support.ui import Select
3
+ from selenium.webdriver.support import expected_conditions as EC
4
+ from selenium.common.exceptions import (
5
+ JavascriptException,
6
+ TimeoutException,
7
+ ElementNotInteractableException,
8
+ )
9
+ from .helpers import wait, find, scroll, js_click
10
+ import time
11
+
12
+
13
+ def exist(xpath, driver, timeout=5):
14
+ try:
15
+ find(xpath, driver, timeout)
16
+ return True
17
+ except TimeoutException:
18
+ return False
19
+
20
+
21
+ def get_text(xpath, driver, timeout=5):
22
+ try:
23
+ elem = find(xpath, driver, timeout)
24
+ return elem.text
25
+ except TimeoutException:
26
+ return None
27
+
28
+
29
+ def click(xpath, driver, timeout=5):
30
+ try:
31
+ elem = wait(
32
+ driver,
33
+ EC.element_to_be_clickable((By.XPATH, xpath)),
34
+ timeout,
35
+ )
36
+ scroll(elem, driver)
37
+ elem.click()
38
+ return True
39
+
40
+ except (TimeoutException, ElementNotInteractableException):
41
+ try:
42
+ elem = find(xpath, driver, timeout)
43
+ scroll(elem, driver)
44
+ js_click(elem, driver)
45
+ return True
46
+ except Exception:
47
+ return False
48
+
49
+
50
+ def send_keys(xpath, value, driver, timeout=5):
51
+ if value is None:
52
+ return False
53
+
54
+ try:
55
+ elem = find(xpath, driver, timeout, visible=True)
56
+ scroll(elem, driver)
57
+ elem.clear()
58
+ elem.send_keys(value)
59
+ return True
60
+
61
+ except (TimeoutException, ElementNotInteractableException):
62
+ try:
63
+ elem = find(xpath, driver, timeout)
64
+ driver.execute_script(
65
+ """
66
+ arguments[0].value = arguments[1];
67
+ arguments[0].dispatchEvent(new Event('input', {bubbles:true}));
68
+ arguments[0].dispatchEvent(new Event('change', {bubbles:true}));
69
+ """,
70
+ elem,
71
+ value,
72
+ )
73
+ return True
74
+ except Exception:
75
+ return False
76
+
77
+
78
+ def select(xpath, buscar, driver, attr="value", timeout=5):
79
+ try:
80
+ elem = find(xpath, driver, timeout)
81
+ scroll(elem, driver)
82
+
83
+ sel = Select(elem)
84
+ buscar = str(buscar)
85
+
86
+ if attr == "value":
87
+ sel.select_by_value(buscar)
88
+ elif attr == "text":
89
+ sel.select_by_visible_text(buscar)
90
+ else:
91
+ for option in sel.options:
92
+ if option.get_attribute(attr) == buscar:
93
+ option.click()
94
+ break
95
+ else:
96
+ return False
97
+
98
+ return True
99
+
100
+ except Exception:
101
+ return False
102
+
103
+
104
+ def force_select_combobox(input_xpath, option_text, driver, timeout=5):
105
+ try:
106
+ input_elem = find(input_xpath, driver, timeout)
107
+ scroll(input_elem, driver)
108
+ input_elem.click()
109
+
110
+ option_xpath = (
111
+ f"//li[@role='option' and normalize-space(text())='{option_text}']"
112
+ )
113
+ option_elem = find(option_xpath, driver, timeout)
114
+
115
+ scroll(option_elem, driver)
116
+ js_click(option_elem, driver)
117
+
118
+ return True
119
+
120
+ except Exception:
121
+ return False
122
+
123
+
124
+ def clear(xpath, driver, timeout=5):
125
+ try:
126
+ elem = find(xpath, driver, timeout)
127
+ elem.clear()
128
+ return True
129
+ except Exception:
130
+ return False
131
+
132
+
133
+ def delDisable(xpath, driver, timeout=5):
134
+ try:
135
+ elem = find(xpath, driver, timeout)
136
+ driver.execute_script(
137
+ """
138
+ arguments[0].removeAttribute('readonly');
139
+ arguments[0].removeAttribute('disabled');
140
+ try { arguments[0].readOnly = false; } catch(e) {}
141
+ """,
142
+ elem,
143
+ )
144
+ time.sleep(0.3)
145
+ elem.click()
146
+ return True
147
+
148
+ except (TimeoutException, JavascriptException):
149
+ return False
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: zelium
3
+ Version: 0.1.0
4
+ Summary: Intelligent abstraction layer over Selenium
5
+ Author-email: Iván <yupivangh@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/yup-Ivan/Zelium
8
+ Project-URL: Repository, https://github.com/yup-Ivan/Zelium
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: selenium>=4.0
12
+
13
+ # ZELIUM
14
+
15
+ **ZELIUM** is a web automation framework based on **Selenium**, written in **Python**, designed to **simplify, standardize, and accelerate** the creation of web automation scripts.
16
+
17
+ It is designed to:
18
+ - Reduce repetitive code
19
+ - Centralize common patterns (waits, scrolls, JS fallbacks…)
20
+ - Provide a clear and expressive API (in Spanish and English)
21
+ - Make maintenance of complex automation scripts easier
22
+
23
+ ---
24
+
25
+ ## 👤 Author
26
+
27
+ - 💻 GitHub: https://github.com/yup-Ivan
28
+
29
+ ---
30
+
31
+ ## 🎯 Main Goals
32
+
33
+ - 🧠 Intelligent abstraction over Selenium
34
+ - 🔁 Reuse of common logic via helpers
35
+ - 🛡️ Robustness against dynamic elements (React, Vue, etc.)
36
+ - 🧩 Clean, readable, and consistent API
37
+ - 🌍 Multilanguage support (aliases in Spanish / English)
38
+
39
+ ---
40
+
41
+ ## 📁 Project Structure
42
+
43
+ ```text
44
+ Zelium/
45
+ ├── __init__.py # Public API of the framework (exports and aliases)
46
+ ├── alarm.py # Handling browser alerts, confirms, and prompts
47
+ ├── config.py # Global initialization and configuration (driver, options…)
48
+ ├── helpers.py # Internal helpers (wait, find, scroll, js_click, etc.)
49
+ ├── js.py # JavaScript utilities (scroll, set_value, remove readonly…)
50
+ ├── tools.py # Reusable helper functions
51
+ └── xpath.py # XPath element actions (click, send_keys, select…)
@@ -0,0 +1,16 @@
1
+ MANIFEST.in
2
+ README.md
3
+ pyproject.toml
4
+ src/zelium/__init__.py
5
+ src/zelium/alarm.py
6
+ src/zelium/config.py
7
+ src/zelium/helpers.py
8
+ src/zelium/js.py
9
+ src/zelium/tools.py
10
+ src/zelium/xpath.py
11
+ src/zelium.egg-info/PKG-INFO
12
+ src/zelium.egg-info/SOURCES.txt
13
+ src/zelium.egg-info/dependency_links.txt
14
+ src/zelium.egg-info/requires.txt
15
+ src/zelium.egg-info/top_level.txt
16
+ tests/test.py
@@ -0,0 +1 @@
1
+ selenium>=4.0
@@ -0,0 +1 @@
1
+ zelium
@@ -0,0 +1,21 @@
1
+ import Zelium
2
+ import time
3
+
4
+ driver = Zelium.start()
5
+
6
+ Zelium.open("http://127.0.0.1:5000", driver)
7
+ time.sleep(2)
8
+
9
+ Zelium.alarm.accept()
10
+ time.sleep(2)
11
+
12
+ Zelium.js.quitar_readonly("//input[@id='fecha']")
13
+ time.sleep(2)
14
+
15
+ Zelium.js.set_value("//input[@id='nombre']", "Iván")
16
+
17
+ Zelium.js.scroll(300)
18
+
19
+ time.sleep(5)
20
+
21
+ driver.quit()