robo_appian 0.0.4__tar.gz → 0.0.6__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.
Potentially problematic release.
This version of robo_appian might be problematic. Click here for more details.
- {robo_appian-0.0.4/robo_appian.egg-info → robo_appian-0.0.6}/PKG-INFO +13 -36
- {robo_appian-0.0.4 → robo_appian-0.0.6}/pyproject.toml +1 -3
- robo_appian-0.0.6/robo_appian/__init__.py +23 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/components/ButtonUtils.py +2 -3
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/components/DateUtils.py +3 -3
- robo_appian-0.0.6/robo_appian/components/DropdownUtils.py +136 -0
- robo_appian-0.0.6/robo_appian/components/InputUtils.py +107 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/components/LabelUtils.py +1 -1
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/components/LinkUtils.py +1 -1
- robo_appian-0.0.6/robo_appian/components/SearchInputUtils.py +64 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/components/TabUtils.py +2 -2
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/components/TableUtils.py +8 -1
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/controllers/ComponentDriver.py +18 -13
- {robo_appian-0.0.4/robo_appian_source_backup/utils/components → robo_appian-0.0.6/robo_appian/utils}/ComponentUtils.py +37 -100
- robo_appian-0.0.4/MANIFEST.in +0 -7
- robo_appian-0.0.4/PKG-INFO +0 -163
- robo_appian-0.0.4/robo_appian/__init__.py +0 -23
- robo_appian-0.0.4/robo_appian/utils/__init__.py +0 -1
- robo_appian-0.0.4/robo_appian/utils/components/__init__.py +0 -1
- robo_appian-0.0.4/robo_appian/utils/controllers/__init__.py +0 -1
- robo_appian-0.0.4/robo_appian/utils/exceptions/__init__.py +0 -1
- robo_appian-0.0.4/robo_appian.egg-info/SOURCES.txt +0 -31
- robo_appian-0.0.4/robo_appian.egg-info/dependency_links.txt +0 -1
- robo_appian-0.0.4/robo_appian.egg-info/requires.txt +0 -3
- robo_appian-0.0.4/robo_appian.egg-info/top_level.txt +0 -2
- robo_appian-0.0.4/robo_appian_source_backup/__init__.py +0 -23
- robo_appian-0.0.4/robo_appian_source_backup/utils/components/DropdownUtils.py +0 -141
- robo_appian-0.0.4/robo_appian_source_backup/utils/components/InputUtils.py +0 -193
- robo_appian-0.0.4/setup.cfg +0 -4
- robo_appian-0.0.4/setup.py +0 -66
- {robo_appian-0.0.4 → robo_appian-0.0.6}/LICENSE +0 -0
- {robo_appian-0.0.4 → robo_appian-0.0.6}/README.md +0 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian/components}/__init__.py +0 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils/components → robo_appian-0.0.6/robo_appian/controllers}/__init__.py +0 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils → robo_appian-0.0.6/robo_appian}/exceptions/MyCustomError.py +0 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils/controllers → robo_appian-0.0.6/robo_appian/exceptions}/__init__.py +0 -0
- {robo_appian-0.0.4/robo_appian_source_backup/utils/exceptions → robo_appian-0.0.6/robo_appian/utils}/__init__.py +0 -0
|
@@ -1,43 +1,20 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: robo_appian
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary:
|
|
5
|
-
|
|
6
|
-
Author:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Project-URL: Source, https://github.com/yourusername/robo_appian
|
|
10
|
-
Project-URL: Documentation, https://robo-appian.readthedocs.io/
|
|
11
|
-
Keywords: selenium,automation,testing,appian,ui
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: Topic :: Software Development :: Testing
|
|
15
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
|
16
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
3
|
+
Version: 0.0.6
|
|
4
|
+
Summary: Automate your Appian code testing with Python. Boost quality, save time.
|
|
5
|
+
Author: Dinil Mithra
|
|
6
|
+
Author-email: dinilmithra@mailme@gmail.com
|
|
7
|
+
Requires-Python: >=3.12,<4.0
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
17
9
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
22
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
-
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Requires-Dist: numpy
|
|
13
|
+
Requires-Dist: requests (>=2.25.1,<3.0.0)
|
|
14
|
+
Requires-Dist: selenium (>=4.34.0)
|
|
15
|
+
Project-URL: Homepage, https://github.com/dinilmithra/robo_appian
|
|
16
|
+
Project-URL: Repository, https://github.com/dinilmithra/robo_appian.git
|
|
24
17
|
Description-Content-Type: text/markdown
|
|
25
|
-
License-File: LICENSE
|
|
26
|
-
Requires-Dist: selenium>=4.34.0
|
|
27
|
-
Requires-Dist: requests>=2.25.0
|
|
28
|
-
Requires-Dist: numpy>=1.21.0
|
|
29
|
-
Dynamic: author
|
|
30
|
-
Dynamic: author-email
|
|
31
|
-
Dynamic: classifier
|
|
32
|
-
Dynamic: description
|
|
33
|
-
Dynamic: description-content-type
|
|
34
|
-
Dynamic: home-page
|
|
35
|
-
Dynamic: keywords
|
|
36
|
-
Dynamic: license-file
|
|
37
|
-
Dynamic: project-url
|
|
38
|
-
Dynamic: requires-dist
|
|
39
|
-
Dynamic: requires-python
|
|
40
|
-
Dynamic: summary
|
|
41
18
|
|
|
42
19
|
# Robo Appian
|
|
43
20
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
|
-
include = ["*.pyc"]
|
|
3
2
|
name = "robo_appian"
|
|
4
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.6"
|
|
5
4
|
description = "Automate your Appian code testing with Python. Boost quality, save time."
|
|
6
5
|
authors = ["Dinil Mithra <dinilmithra@mailme@gmail.com>"]
|
|
7
6
|
readme = "README.md"
|
|
@@ -17,7 +16,6 @@ python = "^3.12"
|
|
|
17
16
|
requests = "^2.25.1"
|
|
18
17
|
numpy = "*"
|
|
19
18
|
selenium = ">=4.34.0"
|
|
20
|
-
pyarmor = ">=8.0.0"
|
|
21
19
|
|
|
22
20
|
[tool.poetry.group.dev.dependencies]
|
|
23
21
|
mkdocs = "^1.5.0"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from robo_appian.components.ButtonUtils import ButtonUtils
|
|
2
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
3
|
+
from robo_appian.components.DateUtils import DateUtils
|
|
4
|
+
from robo_appian.components.DropdownUtils import DropdownUtils
|
|
5
|
+
from robo_appian.components.InputUtils import InputUtils
|
|
6
|
+
from robo_appian.components.LabelUtils import LabelUtils
|
|
7
|
+
from robo_appian.components.LinkUtils import LinkUtils
|
|
8
|
+
from robo_appian.components.TableUtils import TableUtils
|
|
9
|
+
from robo_appian.components.TabUtils import TabUtils
|
|
10
|
+
|
|
11
|
+
__version__ = "0.0.2"
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ButtonUtils",
|
|
15
|
+
"ComponentUtils",
|
|
16
|
+
"DateUtils",
|
|
17
|
+
"DropdownUtils",
|
|
18
|
+
"InputUtils",
|
|
19
|
+
"LabelUtils",
|
|
20
|
+
"LinkUtils",
|
|
21
|
+
"TableUtils",
|
|
22
|
+
"TabUtils"
|
|
23
|
+
]
|
|
@@ -10,7 +10,7 @@ class ButtonUtils:
|
|
|
10
10
|
Usage Example:
|
|
11
11
|
|
|
12
12
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
13
|
-
from robo_appian.
|
|
13
|
+
from robo_appian.components.ButtonUtils import ButtonUtils
|
|
14
14
|
|
|
15
15
|
wait = WebDriverWait(driver, 10)
|
|
16
16
|
ButtonUtils.click(wait, "Login")
|
|
@@ -68,5 +68,4 @@ class ButtonUtils:
|
|
|
68
68
|
|
|
69
69
|
"""
|
|
70
70
|
component = wait.until(EC.element_to_be_clickable((By.ID, id)))
|
|
71
|
-
component.click()
|
|
72
|
-
component.click()
|
|
71
|
+
component.click()
|
|
@@ -4,7 +4,7 @@ from selenium.webdriver.support.ui import WebDriverWait
|
|
|
4
4
|
from selenium.webdriver.remote.webdriver import WebDriver
|
|
5
5
|
from selenium.webdriver.remote.webelement import WebElement
|
|
6
6
|
|
|
7
|
-
from robo_appian.
|
|
7
|
+
from robo_appian.components.InputUtils import InputUtils
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class DateUtils:
|
|
@@ -14,7 +14,7 @@ class DateUtils:
|
|
|
14
14
|
Usage Example:
|
|
15
15
|
|
|
16
16
|
# Set a date value
|
|
17
|
-
from robo_appian.
|
|
17
|
+
from robo_appian.components.DateUtils import DateUtils
|
|
18
18
|
DateUtils.setDateValue(wait, "Start Date", "01/01/2024")
|
|
19
19
|
|
|
20
20
|
"""
|
|
@@ -75,7 +75,7 @@ class DateUtils:
|
|
|
75
75
|
# component = wait.until(EC.element_to_be_clickable((By.XPATH, f".//div/label[text()='{label}']/following-sibling::input")))
|
|
76
76
|
|
|
77
77
|
component = DateUtils.findComponent(wait, label)
|
|
78
|
-
InputUtils.
|
|
78
|
+
InputUtils._setComponentValue(component, value)
|
|
79
79
|
return component
|
|
80
80
|
|
|
81
81
|
@staticmethod
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import stat
|
|
2
|
+
from turtle import st
|
|
3
|
+
from selenium.webdriver.common.by import By
|
|
4
|
+
from selenium.webdriver.support import expected_conditions as EC
|
|
5
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
6
|
+
from selenium.webdriver.remote.webdriver import WebDriver
|
|
7
|
+
from selenium.webdriver.remote.webelement import WebElement
|
|
8
|
+
|
|
9
|
+
from robo_appian.components.InputUtils import InputUtils
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DropdownUtils:
|
|
13
|
+
"""
|
|
14
|
+
Utility class for interacting with dropdown components in Appian UI.
|
|
15
|
+
|
|
16
|
+
Usage Example:
|
|
17
|
+
|
|
18
|
+
# Select a value from a dropdown
|
|
19
|
+
from robo_appian.components.DropdownUtils import DropdownUtils
|
|
20
|
+
DropdownUtils.selectDropdownValueByLabelText(wait, "Status", "Approved")
|
|
21
|
+
|
|
22
|
+
# Select a value from a search dropdown
|
|
23
|
+
from robo_appian.components.DropdownUtils import DropdownUtils
|
|
24
|
+
DropdownUtils.selectSearchDropdownValueByLabelText(wait, "Category", "Finance")
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def __findDropdownComponentsByXpath(wait: WebDriverWait, xpath: str):
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
# Wait for at least one element to be present
|
|
32
|
+
wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
33
|
+
|
|
34
|
+
# Find all matching elements
|
|
35
|
+
driver = wait._driver
|
|
36
|
+
components = driver.find_elements(By.XPATH, xpath)
|
|
37
|
+
|
|
38
|
+
# Filter for clickable and displayed components
|
|
39
|
+
valid_components = []
|
|
40
|
+
for component in components:
|
|
41
|
+
try:
|
|
42
|
+
if component.is_displayed() and component.is_enabled():
|
|
43
|
+
valid_components.append(component)
|
|
44
|
+
except Exception:
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
if not valid_components:
|
|
48
|
+
raise Exception(
|
|
49
|
+
f'No valid dropdown components with xpath "{xpath}" found.'
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Return single component if only one found, list if multiple
|
|
53
|
+
return valid_components
|
|
54
|
+
|
|
55
|
+
except Exception as e:
|
|
56
|
+
raise Exception(
|
|
57
|
+
f'Dropdown component with xpath "{xpath}" not found: {str(e)}'
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def selectDropdownValueByComponent(wait, combobox, value):
|
|
62
|
+
dropdown_id = combobox.get_attribute("aria-controls") # type: ignore[reportUnknownMemberType]
|
|
63
|
+
combobox.click()
|
|
64
|
+
|
|
65
|
+
option_xpath = f'.//div/ul[@id="{dropdown_id}"]/li[./div[normalize-space(text())="{value}"]]'
|
|
66
|
+
component = wait.until(EC.presence_of_element_located((By.XPATH, option_xpath)))
|
|
67
|
+
component = wait.until(EC.element_to_be_clickable((By.XPATH, option_xpath)))
|
|
68
|
+
component.click()
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def __selectDropdownValueByXpath(wait, xpath, value):
|
|
72
|
+
components = DropdownUtils.__findDropdownComponentsByXpath(wait, xpath)
|
|
73
|
+
for combobox in components:
|
|
74
|
+
if combobox.is_displayed() and combobox.is_enabled():
|
|
75
|
+
DropdownUtils.selectDropdownValueByComponent(wait, combobox, value)
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def selectDropdownValueByLabelText(
|
|
79
|
+
wait: WebDriverWait, dropdown_label: str, value: str
|
|
80
|
+
):
|
|
81
|
+
|
|
82
|
+
xpath = f'.//div[./div/span[normalize-space(text())="{dropdown_label}"]]/div/div/div/div[@role="combobox" and @tabindex="0"]'
|
|
83
|
+
DropdownUtils.__selectDropdownValueByXpath(wait, xpath, value)
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def selectDropdownValueByPartialLabelText(
|
|
87
|
+
wait: WebDriverWait, dropdown_label: str, value: str
|
|
88
|
+
):
|
|
89
|
+
|
|
90
|
+
xpath = f'.//div[./div/span[contains(normalize-space(text()), "{dropdown_label}")]]/div/div/div/div[@role="combobox" and @tabindex="0"]'
|
|
91
|
+
DropdownUtils.__selectDropdownValueByXpath(wait, xpath, value)
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def __selectSearchDropdownValueByXpath(wait, xpath, value):
|
|
95
|
+
|
|
96
|
+
components = DropdownUtils.__findDropdownComponentsByXpath(wait, xpath)
|
|
97
|
+
|
|
98
|
+
for component in components:
|
|
99
|
+
if component.is_displayed() and component.is_enabled():
|
|
100
|
+
component_id = component.get_attribute("aria-labelledby") # type: ignore[reportUnknownMemberType]
|
|
101
|
+
dropdown_id = component.get_attribute("aria-controls") # type: ignore[reportUnknownMemberType]
|
|
102
|
+
component.click()
|
|
103
|
+
|
|
104
|
+
input_component_id = str(component_id) + "_searchInput"
|
|
105
|
+
input_component = wait.until(
|
|
106
|
+
EC.element_to_be_clickable((By.ID, input_component_id))
|
|
107
|
+
)
|
|
108
|
+
InputUtils._setComponentValue(input_component, value)
|
|
109
|
+
|
|
110
|
+
xpath = f'.//ul[@id="{dropdown_id}"]/li[./div[normalize-space(text())="{value}"]][1]'
|
|
111
|
+
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
112
|
+
component.click()
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def selectSearchDropdownValueByLabelText(
|
|
116
|
+
wait: WebDriverWait, dropdown_label: str, value: str
|
|
117
|
+
):
|
|
118
|
+
xpath = f'.//div[./div/span[normalize-space(text())="{dropdown_label}"]]/div/div/div/div[@role="combobox" and @tabindex="0"]'
|
|
119
|
+
DropdownUtils.__selectSearchDropdownValueByXpath(wait, xpath, value)
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def selectSearchDropdownValueByPartialLabelText(
|
|
123
|
+
wait: WebDriverWait, dropdown_label: str, value: str
|
|
124
|
+
):
|
|
125
|
+
|
|
126
|
+
xpath = f'.//div[./div/span[contains(normalize-space(text()), "{dropdown_label}")]]/div/div/div/div[@role="combobox" and @tabindex="0"]'
|
|
127
|
+
DropdownUtils.__selectSearchDropdownValueByXpath(wait, xpath, value)
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def selectValueByDropdownWrapperComponent(
|
|
131
|
+
wait: WebDriverWait, component: WebElement, value: str
|
|
132
|
+
):
|
|
133
|
+
xpath = f'./div/div[@role="combobox" and @tabindex="0"]'
|
|
134
|
+
combobox = component.find_element(By.XPATH, xpath)
|
|
135
|
+
DropdownUtils.selectDropdownValueByComponent(wait, combobox, value)
|
|
136
|
+
return combobox
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from numpy import size
|
|
2
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
3
|
+
from selenium.webdriver.common.by import By
|
|
4
|
+
from selenium.webdriver.common.keys import Keys
|
|
5
|
+
from selenium.webdriver.support import expected_conditions as EC
|
|
6
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
7
|
+
from selenium.webdriver.remote.webelement import WebElement
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InputUtils:
|
|
12
|
+
"""
|
|
13
|
+
Utility class for interacting with input components in Appian UI.
|
|
14
|
+
|
|
15
|
+
Usage Example:
|
|
16
|
+
|
|
17
|
+
# Set a value in an input field
|
|
18
|
+
from robo_appian.components.InputUtils import InputUtils
|
|
19
|
+
InputUtils.setValueByLabelText(wait, "Username", "test_user")
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def setValueAndSubmitUsingComponent(component: WebElement, value: str):
|
|
25
|
+
"""
|
|
26
|
+
Sets a value in an input component and submits it using the provided component element.
|
|
27
|
+
|
|
28
|
+
Parameters:
|
|
29
|
+
component: The Selenium WebElement for the input component.
|
|
30
|
+
value: The value to set in the input field.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
The Selenium WebElement for the input component after setting the value and submitting.
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
InputUtils.setValueAndSubmitUsingComponent(component, "test_user")
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
# This method assumes that the component is already found and passed as an argument.
|
|
40
|
+
|
|
41
|
+
if not component.is_displayed():
|
|
42
|
+
raise Exception(
|
|
43
|
+
f"Component with label '{component.text}' is not displayed."
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
component = InputUtils._setComponentValue(component, value)
|
|
47
|
+
component.send_keys(Keys.ENTER)
|
|
48
|
+
return component
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def __findInputComponentsByLabelPath(wait: WebDriverWait, xpath: str):
|
|
52
|
+
label_components = ComponentUtils.findComponentsByXPath(wait, xpath)
|
|
53
|
+
input_components = []
|
|
54
|
+
for label_component in label_components:
|
|
55
|
+
attribute: str = "for"
|
|
56
|
+
component_id = label_component.get_attribute(attribute) # type: ignore[reportUnknownMemberType]
|
|
57
|
+
if component_id:
|
|
58
|
+
component = wait.until(
|
|
59
|
+
EC.element_to_be_clickable((By.ID, component_id))
|
|
60
|
+
)
|
|
61
|
+
input_components.append(component)
|
|
62
|
+
return input_components
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def __findInputComponentsByPartialLabel(wait: WebDriverWait, label: str):
|
|
66
|
+
xpath = f'.//div/label[contains(normalize-space(text()), "{label}")]'
|
|
67
|
+
components = InputUtils.__findInputComponentsByLabelPath(wait, xpath)
|
|
68
|
+
return components
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def __findInputComponentsByLabel(wait: WebDriverWait, label: str):
|
|
72
|
+
xpath = f'.//div/label[normalize-space(text())="{label}"]'
|
|
73
|
+
components = InputUtils.__findInputComponentsByLabelPath(wait, xpath)
|
|
74
|
+
return components
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def _setComponentValue(component: WebElement, value: str):
|
|
78
|
+
component.clear()
|
|
79
|
+
component.send_keys(value)
|
|
80
|
+
return component
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def __setValueByComponents(wait: WebDriverWait, input_components, value: str):
|
|
84
|
+
"""
|
|
85
|
+
Sets a value in an input component identified by its label text.
|
|
86
|
+
Parameters:
|
|
87
|
+
wait: Selenium WebDriverWait instance.
|
|
88
|
+
label: The visible text label of the input component.
|
|
89
|
+
value: The value to set in the input field.
|
|
90
|
+
Returns:
|
|
91
|
+
None
|
|
92
|
+
Example:
|
|
93
|
+
InputUtils.setValueByLabelText(wait, "Username", "test_user")
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
for component in input_components:
|
|
97
|
+
InputUtils._setComponentValue(component, value)
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def setValueByPartialLabelText(wait: WebDriverWait, label: str, value: str):
|
|
101
|
+
input_components = InputUtils.__findInputComponentsByPartialLabel(wait, label)
|
|
102
|
+
InputUtils.__setValueByComponents(wait, input_components, value)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def setValueByLabelText(wait: WebDriverWait, label: str, value: str):
|
|
106
|
+
input_components = InputUtils.__findInputComponentsByLabel(wait, label)
|
|
107
|
+
InputUtils.__setValueByComponents(wait, input_components, value)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
2
|
+
from selenium.webdriver.common.by import By
|
|
3
|
+
from selenium.webdriver.support import expected_conditions as EC
|
|
4
|
+
from robo_appian.components.InputUtils import InputUtils
|
|
5
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SearchInputUtils:
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def __findSearchInputComponentsByLabelPathAndSelectValue(
|
|
12
|
+
wait: WebDriverWait, xpath: str, value: str
|
|
13
|
+
):
|
|
14
|
+
search_input_components = ComponentUtils.findComponentsByXPath(wait, xpath)
|
|
15
|
+
input_components = []
|
|
16
|
+
for search_input_component in search_input_components:
|
|
17
|
+
attribute: str = "aria-controls"
|
|
18
|
+
dropdown_list_id = search_input_component.get_attribute(attribute)
|
|
19
|
+
if dropdown_list_id:
|
|
20
|
+
InputUtils._setComponentValue(search_input_component, value)
|
|
21
|
+
xpath = f".//ul[@id='{dropdown_list_id}' and @role='listbox' ]/li[@role='option']/div/div/div/div/div/div/p[text()='{value}'][1]"
|
|
22
|
+
drop_down_item = wait.until(
|
|
23
|
+
EC.element_to_be_clickable((By.XPATH, xpath))
|
|
24
|
+
)
|
|
25
|
+
drop_down_item.click()
|
|
26
|
+
else:
|
|
27
|
+
raise ValueError(
|
|
28
|
+
f"Search input component with label '{search_input_component.text}' does not have 'aria-controls' attribute."
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return input_components
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def __selectSearchInputComponentsByPartialLabelText(
|
|
35
|
+
wait: WebDriverWait, label: str, value: str
|
|
36
|
+
):
|
|
37
|
+
xpath = f".//div[./div/span[contains(normalize-space(text())='{label}']]/div/div/div/input[@role='combobox']"
|
|
38
|
+
SearchInputUtils.__findSearchInputComponentsByLabelPathAndSelectValue(
|
|
39
|
+
wait, xpath, value
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def __selectSearchInputComponentsByLabelText(
|
|
44
|
+
wait: WebDriverWait, label: str, value: str
|
|
45
|
+
):
|
|
46
|
+
xpath = (
|
|
47
|
+
f".//div[./div/span[text()='{label}']]/div/div/div/input[@role='combobox']"
|
|
48
|
+
)
|
|
49
|
+
SearchInputUtils.__findSearchInputComponentsByLabelPathAndSelectValue(
|
|
50
|
+
wait, xpath, value
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def selectSearchDropdownByLabelText(wait: WebDriverWait, label: str, value: str):
|
|
55
|
+
|
|
56
|
+
SearchInputUtils.__selectSearchInputComponentsByLabelText(wait, label, value)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def selectSearchDropdownByPartialLabelText(
|
|
60
|
+
wait: WebDriverWait, label: str, value: str
|
|
61
|
+
):
|
|
62
|
+
SearchInputUtils.__selectSearchInputComponentsByPartialLabelText(
|
|
63
|
+
wait, label, value
|
|
64
|
+
)
|
|
@@ -9,11 +9,11 @@ class TabUtils:
|
|
|
9
9
|
Usage Example:
|
|
10
10
|
|
|
11
11
|
# Select a tab by its label
|
|
12
|
-
from robo_appian.
|
|
12
|
+
from robo_appian.components.TabUtils import TabUtils
|
|
13
13
|
TabUtils.select_tab(wait, "Settings")
|
|
14
14
|
|
|
15
15
|
# Find the currently selected tab by its label
|
|
16
|
-
from robo_appian.
|
|
16
|
+
from robo_appian.components.TabUtils import TabUtils
|
|
17
17
|
selected_tab = TabUtils.find_selected_tab(wait, "Settings")
|
|
18
18
|
"""
|
|
19
19
|
|
|
@@ -11,7 +11,7 @@ class TableUtils:
|
|
|
11
11
|
Usage Example:
|
|
12
12
|
|
|
13
13
|
# Find a table using a column name
|
|
14
|
-
from robo_appian.
|
|
14
|
+
from robo_appian.components.TableUtils import TableUtils
|
|
15
15
|
table = TableUtils.findTableUsingColumnName(wait, "Status")
|
|
16
16
|
|
|
17
17
|
"""
|
|
@@ -140,6 +140,10 @@ class TableUtils:
|
|
|
140
140
|
|
|
141
141
|
xpath = f'./thead/tr/th[@scope="col" and @abbr="{columnName}"]'
|
|
142
142
|
component = tableObject.find_element(By.XPATH, xpath)
|
|
143
|
+
|
|
144
|
+
if component is None:
|
|
145
|
+
raise ValueError(f"Could not find a column with abbr '{columnName}' in the table header.")
|
|
146
|
+
|
|
143
147
|
class_string = component.get_attribute("class")
|
|
144
148
|
partial_string = "headCell_"
|
|
145
149
|
words = class_string.split()
|
|
@@ -149,6 +153,9 @@ class TableUtils:
|
|
|
149
153
|
if partial_string in word:
|
|
150
154
|
selected_word = word
|
|
151
155
|
|
|
156
|
+
if selected_word is None:
|
|
157
|
+
raise ValueError(f"Could not find a class containing '{partial_string}' in the column header for '{columnName}'.")
|
|
158
|
+
|
|
152
159
|
data = selected_word.split("_")
|
|
153
160
|
return int(data[1])
|
|
154
161
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
from robo_appian.
|
|
2
|
-
from
|
|
3
|
-
from robo_appian.utils.
|
|
4
|
-
from robo_appian.
|
|
5
|
-
from robo_appian.
|
|
6
|
-
from robo_appian.
|
|
7
|
-
from robo_appian.
|
|
1
|
+
from robo_appian.components.ButtonUtils import ButtonUtils
|
|
2
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
3
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
4
|
+
from robo_appian.components.DateUtils import DateUtils
|
|
5
|
+
from robo_appian.components.DropdownUtils import DropdownUtils
|
|
6
|
+
from robo_appian.components.InputUtils import InputUtils
|
|
7
|
+
from robo_appian.components.LabelUtils import LabelUtils
|
|
8
|
+
from robo_appian.components.LinkUtils import LinkUtils
|
|
9
|
+
from robo_appian.components.TabUtils import TabUtils
|
|
10
|
+
from robo_appian.components.SearchInputUtils import SearchInputUtils
|
|
8
11
|
|
|
9
12
|
|
|
10
13
|
class ComponentDriver:
|
|
@@ -17,7 +20,7 @@ class ComponentDriver:
|
|
|
17
20
|
"""
|
|
18
21
|
|
|
19
22
|
@staticmethod
|
|
20
|
-
def execute(wait
|
|
23
|
+
def execute(wait: WebDriverWait, type, action, label, value):
|
|
21
24
|
"""
|
|
22
25
|
Executes an action on a specified component type.
|
|
23
26
|
Parameters:
|
|
@@ -42,13 +45,15 @@ class ComponentDriver:
|
|
|
42
45
|
case "Input Text":
|
|
43
46
|
match action:
|
|
44
47
|
case "Set Value":
|
|
45
|
-
InputUtils.
|
|
48
|
+
InputUtils.setValueByLabelText(wait, label, value)
|
|
46
49
|
case _:
|
|
47
50
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
48
51
|
case "Search Input Text":
|
|
49
52
|
match action:
|
|
50
53
|
case "Select":
|
|
51
|
-
|
|
54
|
+
SearchInputUtils.selectSearchDropdownByLabelText(
|
|
55
|
+
wait, label, value
|
|
56
|
+
)
|
|
52
57
|
case _:
|
|
53
58
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
54
59
|
case "Label":
|
|
@@ -66,19 +71,19 @@ class ComponentDriver:
|
|
|
66
71
|
case "Drop Down":
|
|
67
72
|
match action:
|
|
68
73
|
case "Select":
|
|
69
|
-
DropdownUtils.
|
|
74
|
+
DropdownUtils.selectDropdownValueByLabelText(wait, label, value)
|
|
70
75
|
case _:
|
|
71
76
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
72
77
|
case "Search Drop Down":
|
|
73
78
|
match action:
|
|
74
79
|
case "Select":
|
|
75
|
-
DropdownUtils.
|
|
80
|
+
DropdownUtils.selectSearchDropdownValueByLabelText(wait, label, value)
|
|
76
81
|
case _:
|
|
77
82
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
78
83
|
case "Button":
|
|
79
84
|
match action:
|
|
80
85
|
case "Click":
|
|
81
|
-
|
|
86
|
+
ButtonUtils.click(wait, label)
|
|
82
87
|
case _:
|
|
83
88
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
84
89
|
case "Tab":
|