robo_appian 0.0.19__py3-none-any.whl → 0.0.21__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.
Potentially problematic release.
This version of robo_appian might be problematic. Click here for more details.
- robo_appian/components/ButtonUtils.py +26 -7
- robo_appian/components/LabelUtils.py +22 -3
- robo_appian/components/LinkUtils.py +4 -2
- robo_appian/components/SearchDropdownUtils.py +5 -5
- robo_appian/components/SearchInputUtils.py +1 -1
- robo_appian/components/TableUtils.py +28 -26
- robo_appian/controllers/ComponentDriver.py +1 -1
- robo_appian/utils/BrowserUtils.py +52 -0
- robo_appian/utils/ComponentUtils.py +70 -20
- {robo_appian-0.0.19.dist-info → robo_appian-0.0.21.dist-info}/METADATA +4 -2
- robo_appian-0.0.21.dist-info/RECORD +23 -0
- {robo_appian-0.0.19.dist-info → robo_appian-0.0.21.dist-info}/WHEEL +1 -1
- robo_appian-0.0.19.dist-info/RECORD +0 -22
- {robo_appian-0.0.19.dist-info → robo_appian-0.0.21.dist-info/licenses}/LICENSE +0 -0
|
@@ -39,7 +39,7 @@ class ButtonUtils:
|
|
|
39
39
|
try:
|
|
40
40
|
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
41
41
|
except Exception as e:
|
|
42
|
-
raise
|
|
42
|
+
raise Exception(f"Button with label '{label}' not found or not clickable.") from e
|
|
43
43
|
return component
|
|
44
44
|
|
|
45
45
|
@staticmethod
|
|
@@ -48,7 +48,7 @@ class ButtonUtils:
|
|
|
48
48
|
try:
|
|
49
49
|
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
50
50
|
except Exception as e:
|
|
51
|
-
raise
|
|
51
|
+
raise Exception(f"Button with label '{label}' not found.") from e
|
|
52
52
|
return component
|
|
53
53
|
|
|
54
54
|
@staticmethod
|
|
@@ -93,22 +93,41 @@ class ButtonUtils:
|
|
|
93
93
|
try:
|
|
94
94
|
component = wait.until(EC.element_to_be_clickable((By.ID, id)))
|
|
95
95
|
except Exception as e:
|
|
96
|
-
raise
|
|
96
|
+
raise Exception(f"Input button with id '{id}' not found or not clickable.") from e
|
|
97
97
|
|
|
98
98
|
ButtonUtils.__click(wait, component)
|
|
99
99
|
|
|
100
100
|
@staticmethod
|
|
101
|
-
def
|
|
101
|
+
def isButtonExistsByLabelText(wait: WebDriverWait, label: str):
|
|
102
|
+
xpath = f".//button[./span[normalize-space(.)='{label}']]"
|
|
103
|
+
try:
|
|
104
|
+
ComponentUtils.findComponentByXPath(wait, xpath)
|
|
105
|
+
except Exception:
|
|
106
|
+
return False
|
|
107
|
+
return True
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def isButtonExistsByPartialLabelText(wait: WebDriverWait, label: str):
|
|
111
|
+
xpath = f".//button[./span[contains(translate(normalize-space(.), '\u00a0', ' '), '{label}')]]"
|
|
102
112
|
try:
|
|
103
|
-
|
|
113
|
+
ComponentUtils.findComponentByXPath(wait, xpath)
|
|
104
114
|
except Exception:
|
|
105
115
|
return False
|
|
106
116
|
return True
|
|
107
117
|
|
|
108
118
|
@staticmethod
|
|
109
|
-
def
|
|
119
|
+
def isButtonExistsByPartialLabelTextAfterLoad(wait: WebDriverWait, label: str):
|
|
110
120
|
try:
|
|
111
|
-
ButtonUtils.
|
|
121
|
+
ButtonUtils._findByPartialLabelText(wait, label)
|
|
112
122
|
except Exception:
|
|
113
123
|
return False
|
|
114
124
|
return True
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def waitForButtonToBeVisibleByPartialLabelText(wait: WebDriverWait, label: str):
|
|
128
|
+
xpath = f".//button[./span[contains(translate(normalize-space(.), '\u00a0', ' '), '{label}')]]"
|
|
129
|
+
try:
|
|
130
|
+
component = ComponentUtils.waitForComponentToBeVisibleByXpath(wait, xpath)
|
|
131
|
+
except Exception as e:
|
|
132
|
+
raise Exception(f"Button with partial label '{label}' not visible.") from e
|
|
133
|
+
return component
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from selenium.webdriver.support import expected_conditions as EC
|
|
2
2
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
3
|
+
from selenium.webdriver.common.by import By
|
|
3
4
|
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
4
5
|
|
|
5
6
|
|
|
@@ -24,12 +25,12 @@ class LabelUtils:
|
|
|
24
25
|
Example:
|
|
25
26
|
component = LabelUtils._findByLabelText(wait, "Submit")
|
|
26
27
|
"""
|
|
27
|
-
xpath = f
|
|
28
|
+
xpath = f'.//*[normalize-space(.)="{label}"]'
|
|
28
29
|
try:
|
|
29
30
|
# component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
30
31
|
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
31
32
|
except Exception as e:
|
|
32
|
-
raise
|
|
33
|
+
raise Exception(f"Label with text '{label}' not found.") from e
|
|
33
34
|
|
|
34
35
|
return component
|
|
35
36
|
|
|
@@ -48,9 +49,27 @@ class LabelUtils:
|
|
|
48
49
|
component.click()
|
|
49
50
|
|
|
50
51
|
@staticmethod
|
|
51
|
-
def
|
|
52
|
+
def isLabelExists(wait: WebDriverWait, label: str):
|
|
52
53
|
try:
|
|
53
54
|
LabelUtils.__findByLabelText(wait, label)
|
|
54
55
|
except Exception:
|
|
55
56
|
return False
|
|
56
57
|
return True
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def isLabelExistsAfterLoad(wait: WebDriverWait, label: str):
|
|
61
|
+
try:
|
|
62
|
+
xpath = f'.//*[normalize-space(.)="{label}"]'
|
|
63
|
+
wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
64
|
+
wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
65
|
+
except Exception:
|
|
66
|
+
return False
|
|
67
|
+
return True
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def waitForLabelToBeVisible(wait: WebDriverWait, label: str):
|
|
71
|
+
try:
|
|
72
|
+
xpath = f'.//*[normalize-space(.)="{label}"]'
|
|
73
|
+
wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
74
|
+
except Exception as e:
|
|
75
|
+
raise Exception(f"Label with text '{label}' not found.") from e
|
|
@@ -19,9 +19,10 @@ class LinkUtils:
|
|
|
19
19
|
|
|
20
20
|
@staticmethod
|
|
21
21
|
def find(wait: WebDriverWait, label: str):
|
|
22
|
-
xpath = f'.//a[normalize-space(.)="{label}"]'
|
|
22
|
+
# xpath = f'.//a[normalize-space(.)="{label}"]'
|
|
23
|
+
xpath = f'.//a[normalize-space(.)="{label}" and not(ancestor::*[@aria-hidden="true"])]'
|
|
23
24
|
try:
|
|
24
|
-
component = wait.until(EC.
|
|
25
|
+
component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
25
26
|
except Exception as e:
|
|
26
27
|
raise Exception(f"Could not find clickable link with label '{label}': {e}")
|
|
27
28
|
return component
|
|
@@ -40,5 +41,6 @@ class LinkUtils:
|
|
|
40
41
|
"""
|
|
41
42
|
|
|
42
43
|
component = LinkUtils.find(wait, label)
|
|
44
|
+
wait.until(EC.element_to_be_clickable(component))
|
|
43
45
|
component.click()
|
|
44
46
|
return component
|
|
@@ -24,7 +24,7 @@ class SearchDropdownUtils:
|
|
|
24
24
|
wait.until(EC.presence_of_element_located((By.ID, input_component_id)))
|
|
25
25
|
input_component = wait.until(EC.element_to_be_clickable((By.ID, input_component_id)))
|
|
26
26
|
except Exception as e:
|
|
27
|
-
raise
|
|
27
|
+
raise Exception(f"Failed to locate or click input component with ID '{input_component_id}': {e}")
|
|
28
28
|
InputUtils._setValueByComponent(wait, input_component, value)
|
|
29
29
|
|
|
30
30
|
dropdown_option_id = str(component_id) + "_list"
|
|
@@ -33,7 +33,7 @@ class SearchDropdownUtils:
|
|
|
33
33
|
try:
|
|
34
34
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
35
35
|
except Exception as e:
|
|
36
|
-
raise
|
|
36
|
+
raise Exception(f"Failed to locate or click dropdown option with XPath '{xpath}': {e}")
|
|
37
37
|
component.click()
|
|
38
38
|
|
|
39
39
|
@staticmethod
|
|
@@ -42,7 +42,7 @@ class SearchDropdownUtils:
|
|
|
42
42
|
try:
|
|
43
43
|
combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
44
44
|
except Exception as e:
|
|
45
|
-
raise
|
|
45
|
+
raise Exception(f"Failed to locate or click dropdown component with XPath '{xpath}': {e}")
|
|
46
46
|
|
|
47
47
|
SearchDropdownUtils._selectSearchDropdownValueByComboboxComponent(wait, combobox, value)
|
|
48
48
|
|
|
@@ -54,7 +54,7 @@ class SearchDropdownUtils:
|
|
|
54
54
|
try:
|
|
55
55
|
combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
56
56
|
except Exception as e:
|
|
57
|
-
raise
|
|
57
|
+
raise Exception(f"Failed to locate or click dropdown component with XPath '{xpath}': {e}")
|
|
58
58
|
SearchDropdownUtils._selectSearchDropdownValueByComboboxComponent(wait, combobox, value)
|
|
59
59
|
|
|
60
60
|
@staticmethod
|
|
@@ -63,7 +63,7 @@ class SearchDropdownUtils:
|
|
|
63
63
|
if id is not None:
|
|
64
64
|
component_id = id.rsplit("_value", 1)[0]
|
|
65
65
|
else:
|
|
66
|
-
raise
|
|
66
|
+
raise Exception("Combobox element does not have an 'id' attribute.")
|
|
67
67
|
|
|
68
68
|
wait.until(EC.element_to_be_clickable(combobox))
|
|
69
69
|
combobox.click()
|
|
@@ -33,7 +33,7 @@ class SearchInputUtils:
|
|
|
33
33
|
drop_down_item = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
34
34
|
drop_down_item = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
35
35
|
except Exception as e:
|
|
36
|
-
raise
|
|
36
|
+
raise Exception(
|
|
37
37
|
f"Dropdown item with value '{value}' not found for component '{search_input_component.text}'."
|
|
38
38
|
) from e
|
|
39
39
|
drop_down_item.click()
|
|
@@ -21,30 +21,6 @@ class TableUtils:
|
|
|
21
21
|
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
@staticmethod
|
|
25
|
-
def findTableByColumnName(wait: WebDriverWait, columnName: str):
|
|
26
|
-
"""
|
|
27
|
-
Finds a table component by its column name.
|
|
28
|
-
|
|
29
|
-
:param wait: Selenium WebDriverWait instance.
|
|
30
|
-
:param columnName: The name of the column to search for.
|
|
31
|
-
:return: WebElement representing the table.
|
|
32
|
-
Example:
|
|
33
|
-
component = TableUtils.findTableByColumnName(wait, "Status")
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]'
|
|
37
|
-
try:
|
|
38
|
-
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
39
|
-
except Exception as e:
|
|
40
|
-
raise Exception(f"Could not find table with column name '{columnName}': {e}")
|
|
41
|
-
|
|
42
|
-
try:
|
|
43
|
-
component = wait.until(EC.element_to_be_clickable(component))
|
|
44
|
-
except Exception as e:
|
|
45
|
-
raise Exception(f"Table found by column name '{columnName}' is not clickable: {e}")
|
|
46
|
-
return component
|
|
47
|
-
|
|
48
24
|
@staticmethod
|
|
49
25
|
def rowCount(tableObject):
|
|
50
26
|
"""
|
|
@@ -98,7 +74,8 @@ class TableUtils:
|
|
|
98
74
|
|
|
99
75
|
@staticmethod
|
|
100
76
|
def __findRowByColumnNameAndRowNumber(wait, rowNumber, columnName):
|
|
101
|
-
xpath = f'.//table[./thead/tr/th/div[normalize-space(.)="{columnName}"] ]/tbody/tr[@data-dnd-name="row {rowNumber + 1}"]'
|
|
77
|
+
# xpath = f'.//table[./thead/tr/th/div[normalize-space(.)="{columnName}"] ]/tbody/tr[@data-dnd-name="row {rowNumber + 1}"]'
|
|
78
|
+
xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]/tbody/tr[@data-dnd-name="row {rowNumber + 1}" and not(ancestor::*[@aria-hidden="true"])]'
|
|
102
79
|
row = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
103
80
|
return row
|
|
104
81
|
|
|
@@ -134,7 +111,8 @@ class TableUtils:
|
|
|
134
111
|
|
|
135
112
|
@staticmethod
|
|
136
113
|
def findComponentByColumnNameAndRowNumber(wait, rowNumber, columnName):
|
|
137
|
-
xpath = f'.//table/thead/tr/th[./div[normalize-space(.)="{columnName}"]]'
|
|
114
|
+
# xpath = f'.//table/thead/tr/th[./div[normalize-space(.)="{columnName}"]]'
|
|
115
|
+
xpath = f'.//table/thead/tr/th[@abbr="{columnName}" and not(ancestor::*[@aria-hidden="true"]) ]'
|
|
138
116
|
column = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
139
117
|
id = column.get_attribute("id")
|
|
140
118
|
parts = id.rsplit("_", 1)
|
|
@@ -145,3 +123,27 @@ class TableUtils:
|
|
|
145
123
|
component = ComponentUtils.findChildComponentByXpath(wait, tableRow, xpath)
|
|
146
124
|
component = wait.until(EC.element_to_be_clickable(component))
|
|
147
125
|
return component
|
|
126
|
+
|
|
127
|
+
@staticmethod
|
|
128
|
+
def findTableByColumnName(wait: WebDriverWait, columnName: str):
|
|
129
|
+
"""
|
|
130
|
+
Finds a table component by its column name.
|
|
131
|
+
|
|
132
|
+
:param wait: Selenium WebDriverWait instance.
|
|
133
|
+
:param columnName: The name of the column to search for.
|
|
134
|
+
:return: WebElement representing the table.
|
|
135
|
+
Example:
|
|
136
|
+
component = TableUtils.findTableByColumnName(wait, "Status")
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]'
|
|
140
|
+
try:
|
|
141
|
+
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
142
|
+
except Exception as e:
|
|
143
|
+
raise Exception(f"Could not find table with column name '{columnName}': {e}")
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
component = wait.until(EC.element_to_be_clickable(component))
|
|
147
|
+
except Exception as e:
|
|
148
|
+
raise Exception(f"Table found by column name '{columnName}' is not clickable: {e}")
|
|
149
|
+
return component
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BrowserUtils:
|
|
5
|
+
@staticmethod
|
|
6
|
+
def switch_to_Tab(wait: WebDriverWait, tab_number):
|
|
7
|
+
"""
|
|
8
|
+
Switches to the specified browser tab.
|
|
9
|
+
|
|
10
|
+
:param wait: WebDriverWait instance
|
|
11
|
+
:param tab_number: The index of the tab to switch to
|
|
12
|
+
:return: None
|
|
13
|
+
Example usage:
|
|
14
|
+
BrowserUtils.switch_to_Tab(wait, 1)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# Switch to the specified browser tab
|
|
18
|
+
handler = wait._driver.window_handles[tab_number]
|
|
19
|
+
wait._driver.switch_to.window(handler)
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def switch_to_next_tab(wait: WebDriverWait):
|
|
23
|
+
"""
|
|
24
|
+
Switches to the next browser tab.
|
|
25
|
+
|
|
26
|
+
:param wait: WebDriverWait instance
|
|
27
|
+
:return: None
|
|
28
|
+
Example usage:
|
|
29
|
+
BrowserUtils.switch_to_next_tab(wait)
|
|
30
|
+
"""
|
|
31
|
+
current_tab_index = wait._driver.window_handles.index(
|
|
32
|
+
wait._driver.current_window_handle
|
|
33
|
+
)
|
|
34
|
+
next_tab_index = (current_tab_index + 1) % len(wait._driver.window_handles)
|
|
35
|
+
BrowserUtils.switch_to_Tab(wait, next_tab_index)
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def close_current_tab_and_switch_back(wait: WebDriverWait):
|
|
39
|
+
"""
|
|
40
|
+
Closes the current browser tab and switches back to the original tab.
|
|
41
|
+
|
|
42
|
+
:param wait: WebDriverWait instance
|
|
43
|
+
:return: None
|
|
44
|
+
Example usage:
|
|
45
|
+
BrowserUtils.close_current_tab_and_switch_back(wait)
|
|
46
|
+
"""
|
|
47
|
+
current_tab_index = wait._driver.window_handles.index(
|
|
48
|
+
wait._driver.current_window_handle
|
|
49
|
+
)
|
|
50
|
+
wait._driver.close()
|
|
51
|
+
original_tab_index = (current_tab_index - 1) % len(wait._driver.window_handles)
|
|
52
|
+
BrowserUtils.switch_to_Tab(wait, original_tab_index)
|
|
@@ -57,25 +57,6 @@ class ComponentUtils:
|
|
|
57
57
|
raise Exception(f"Child component with XPath '{xpath}' not found within the given parent component.")
|
|
58
58
|
return component
|
|
59
59
|
|
|
60
|
-
@staticmethod
|
|
61
|
-
def findComponentUsingXpathAndClick(wait: WebDriverWait, xpath: str):
|
|
62
|
-
"""Finds a component using the given XPath and clicks it.
|
|
63
|
-
|
|
64
|
-
:param wait: WebDriverWait instance to wait for elements
|
|
65
|
-
:param xpath: XPath string to locate the component
|
|
66
|
-
:return: None
|
|
67
|
-
Example usage:
|
|
68
|
-
from selenium.webdriver.support.ui import WebDriverWait
|
|
69
|
-
from selenium import webdriver
|
|
70
|
-
|
|
71
|
-
driver = webdriver.Chrome()
|
|
72
|
-
wait = WebDriverWait(driver, 10)
|
|
73
|
-
xpath = "//button[@id='submit']"
|
|
74
|
-
ComponentUtils.findComponentUsingXpathAndClick(wait, xpath)
|
|
75
|
-
"""
|
|
76
|
-
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
77
|
-
component.click()
|
|
78
|
-
|
|
79
60
|
@staticmethod
|
|
80
61
|
def findComponentById(wait: WebDriverWait, id: str):
|
|
81
62
|
try:
|
|
@@ -84,6 +65,14 @@ class ComponentUtils:
|
|
|
84
65
|
raise Exception(f"Component with ID '{id}' not found.")
|
|
85
66
|
return component
|
|
86
67
|
|
|
68
|
+
@staticmethod
|
|
69
|
+
def waitForComponentToBeVisibleByXpath(wait: WebDriverWait, xpath: str):
|
|
70
|
+
try:
|
|
71
|
+
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
72
|
+
except Exception:
|
|
73
|
+
raise Exception(f"Component with XPath '{xpath}' not visible.")
|
|
74
|
+
return component
|
|
75
|
+
|
|
87
76
|
@staticmethod
|
|
88
77
|
def findVisibleComponentByXpath(wait: WebDriverWait, xpath: str):
|
|
89
78
|
"""
|
|
@@ -97,7 +86,10 @@ class ComponentUtils:
|
|
|
97
86
|
component = ComponentUtils.findVisibleComponentByXpath(wait, "//button[@id='submit']")
|
|
98
87
|
component.click()
|
|
99
88
|
"""
|
|
100
|
-
|
|
89
|
+
try:
|
|
90
|
+
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
91
|
+
except Exception:
|
|
92
|
+
raise Exception(f"Component with XPath '{xpath}' not visible.")
|
|
101
93
|
return component
|
|
102
94
|
|
|
103
95
|
@staticmethod
|
|
@@ -200,3 +192,61 @@ class ComponentUtils:
|
|
|
200
192
|
return valid_components
|
|
201
193
|
|
|
202
194
|
raise Exception(f"No valid components found for XPath: {xpath}")
|
|
195
|
+
|
|
196
|
+
@staticmethod
|
|
197
|
+
def findComponentByXPath(wait: WebDriverWait, xpath: str):
|
|
198
|
+
# component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
199
|
+
component = wait._driver.find_element(By.XPATH, xpath)
|
|
200
|
+
return component
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def findComponentUsingXpathAndClick(wait: WebDriverWait, xpath: str):
|
|
204
|
+
"""Finds a component using the given XPath and clicks it.
|
|
205
|
+
|
|
206
|
+
:param wait: WebDriverWait instance to wait for elements
|
|
207
|
+
:param xpath: XPath string to locate the component
|
|
208
|
+
:return: None
|
|
209
|
+
Example usage:
|
|
210
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
211
|
+
from selenium import webdriver
|
|
212
|
+
|
|
213
|
+
driver = webdriver.Chrome()
|
|
214
|
+
wait = WebDriverWait(driver, 10)
|
|
215
|
+
xpath = "//button[@id='submit']"
|
|
216
|
+
ComponentUtils.findComponentUsingXpathAndClick(wait, xpath)
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
220
|
+
ComponentUtils.click(wait, component)
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def click(wait: WebDriverWait, component: WebElement):
|
|
224
|
+
"""
|
|
225
|
+
Clicks the given component after waiting for it to be clickable.
|
|
226
|
+
|
|
227
|
+
:param wait: WebDriverWait instance to wait for elements
|
|
228
|
+
:param component: WebElement representing the component to click
|
|
229
|
+
:return: None
|
|
230
|
+
Example usage:
|
|
231
|
+
ComponentUtils.click(wait, component)
|
|
232
|
+
"""
|
|
233
|
+
wait.until(EC.element_to_be_clickable(component))
|
|
234
|
+
component.click()
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def waitForComponentToBeInVisible(wait: WebDriverWait, component: WebElement):
|
|
238
|
+
try:
|
|
239
|
+
wait.until(EC.staleness_of(component))
|
|
240
|
+
except Exception:
|
|
241
|
+
raise Exception("Component did not become invisible (stale) within the timeout period.")
|
|
242
|
+
|
|
243
|
+
@staticmethod
|
|
244
|
+
def isComponentPresentByXpath(wait: WebDriverWait, xpath: str):
|
|
245
|
+
status = False
|
|
246
|
+
try:
|
|
247
|
+
wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
248
|
+
status = True
|
|
249
|
+
except NoSuchElementException:
|
|
250
|
+
pass
|
|
251
|
+
|
|
252
|
+
return status
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: robo_appian
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.21
|
|
4
4
|
Summary: Automate your Appian code testing with Python. Boost quality, save time.
|
|
5
|
+
License-File: LICENSE
|
|
5
6
|
Author: Dinil Mithra
|
|
6
7
|
Author-email: dinilmithra@mailme@gmail.com
|
|
7
8
|
Requires-Python: >=3.12,<4.0
|
|
@@ -9,6 +10,7 @@ Classifier: Operating System :: OS Independent
|
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
14
|
Requires-Dist: numpy
|
|
13
15
|
Requires-Dist: requests (>=2.25.1,<3.0.0)
|
|
14
16
|
Requires-Dist: selenium (>=4.34.0)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
robo_appian/__init__.py,sha256=6u9n2W7P1IKSSr5IPGsg7LhVR1o1uYv424mXDjJLgb0,720
|
|
2
|
+
robo_appian/components/ButtonUtils.py,sha256=JjI81SsSqBGkX4A8c2EiQDfC1L3fkxp2s1Lzr51rUpI,4858
|
|
3
|
+
robo_appian/components/DateUtils.py,sha256=3iptq3IDCy4IwefEyPtvEQ1nUFI1OVpTF3dAnViHIoM,3258
|
|
4
|
+
robo_appian/components/DropdownUtils.py,sha256=X_ucR4uCiU3fnsMXGnJC9PTfwbfW3w3ulzyuURh1Vlw,11149
|
|
5
|
+
robo_appian/components/InputUtils.py,sha256=78O7G8mNjEBVdrZUjlL9PMvDzTZ9uHEm0rDB5MsuYRQ,6050
|
|
6
|
+
robo_appian/components/LabelUtils.py,sha256=1BDbgIVzxQJv5JkWWcmkd5QGrAjQvtUSZVc49gzyT0c,2711
|
|
7
|
+
robo_appian/components/LinkUtils.py,sha256=32_0mW-j624Be9xlFZAkZsLjJ2OaORfp-ePSRyFwTfs,1549
|
|
8
|
+
robo_appian/components/SearchDropdownUtils.py,sha256=sX9b__Rir7feH1SkCd53EeLJXO7OTLkeA1FMbZU_CNs,4504
|
|
9
|
+
robo_appian/components/SearchInputUtils.py,sha256=2mg1QkEZGVJ-rLTvB0pMNSKvNhiqOU9QrUH0CNr4la4,3260
|
|
10
|
+
robo_appian/components/TabUtils.py,sha256=k-HkIK8ca-KnHXSDTXDV4190jT5P84tZ3frWSCndn5I,2257
|
|
11
|
+
robo_appian/components/TableUtils.py,sha256=_NBytGtP0EzBkjzrffpQ-pm3PoRPUykUvEwTcXu0xPk,6322
|
|
12
|
+
robo_appian/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
robo_appian/controllers/ComponentDriver.py,sha256=4zKn6Jy71cFsGWqOh7EgQ6NYfRIVvi5l5Pn31tLLM9s,4350
|
|
14
|
+
robo_appian/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
robo_appian/exceptions/MyCustomError.py,sha256=DVAkytXNNQNjqyTyCjk6FFd6fr3AsBe57Y19erDSqVs,222
|
|
16
|
+
robo_appian/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
robo_appian/utils/BrowserUtils.py,sha256=Lp0yeHjqstdyA5POqFv4TxGY1TKixApMT6G_nnWadXs,1747
|
|
18
|
+
robo_appian/utils/ComponentUtils.py,sha256=NEzv7IqxaePtIIsziuD9pdrqji9Zo2REQsE5zn2ME5w,9254
|
|
19
|
+
robo_appian/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
robo_appian-0.0.21.dist-info/METADATA,sha256=qs0_pVCEf2YFzHhQHgDuaAFP6IvCpIloaK9GJhwiC3I,2334
|
|
21
|
+
robo_appian-0.0.21.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
22
|
+
robo_appian-0.0.21.dist-info/licenses/LICENSE,sha256=g-xR4dRa9_4iFkMoJmED-wE-J5hoxbk3105Knhfpjm0,1068
|
|
23
|
+
robo_appian-0.0.21.dist-info/RECORD,,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
robo_appian/__init__.py,sha256=6u9n2W7P1IKSSr5IPGsg7LhVR1o1uYv424mXDjJLgb0,720
|
|
2
|
-
robo_appian/components/ButtonUtils.py,sha256=4zF7lDvn1DMIX3nI7Nl9glC1NYfFpvVj43a8N215Bx4,3990
|
|
3
|
-
robo_appian/components/DateUtils.py,sha256=3iptq3IDCy4IwefEyPtvEQ1nUFI1OVpTF3dAnViHIoM,3258
|
|
4
|
-
robo_appian/components/DropdownUtils.py,sha256=X_ucR4uCiU3fnsMXGnJC9PTfwbfW3w3ulzyuURh1Vlw,11149
|
|
5
|
-
robo_appian/components/InputUtils.py,sha256=78O7G8mNjEBVdrZUjlL9PMvDzTZ9uHEm0rDB5MsuYRQ,6050
|
|
6
|
-
robo_appian/components/LabelUtils.py,sha256=d0IUm330RokFRny3CdRGNOzGtDHYqZT0WzVS1TgSscI,1958
|
|
7
|
-
robo_appian/components/LinkUtils.py,sha256=_m9dpHW9mUJFMcLp95K2s-YDYAvG-RlPF6giw3dmYcE,1389
|
|
8
|
-
robo_appian/components/SearchDropdownUtils.py,sha256=rjsC3kd8Z-eHAAzF4OBJVchStRV5pCB2dtpVEL6cdCQ,4519
|
|
9
|
-
robo_appian/components/SearchInputUtils.py,sha256=7sI8D6MXDzBPwbkIQodtxvXD2aA-8HiqvDCEJUlekZo,3263
|
|
10
|
-
robo_appian/components/TabUtils.py,sha256=k-HkIK8ca-KnHXSDTXDV4190jT5P84tZ3frWSCndn5I,2257
|
|
11
|
-
robo_appian/components/TableUtils.py,sha256=SmtB4jq0XGZc0smMTe1HRvcCurQTXz3CytswbogfwTY,6059
|
|
12
|
-
robo_appian/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
robo_appian/controllers/ComponentDriver.py,sha256=jNaQrbKCFFyahpLKmipsA0v3p3bpjy9dMgW36IdE-Fw,4353
|
|
14
|
-
robo_appian/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
robo_appian/exceptions/MyCustomError.py,sha256=DVAkytXNNQNjqyTyCjk6FFd6fr3AsBe57Y19erDSqVs,222
|
|
16
|
-
robo_appian/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
robo_appian/utils/ComponentUtils.py,sha256=AR9Z_RYH939KZv4yX2cpilIaZ83-DVXWCYUcuke81iE,7424
|
|
18
|
-
robo_appian/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
robo_appian-0.0.19.dist-info/LICENSE,sha256=g-xR4dRa9_4iFkMoJmED-wE-J5hoxbk3105Knhfpjm0,1068
|
|
20
|
-
robo_appian-0.0.19.dist-info/METADATA,sha256=RW32QbdJS10nDZOjv74t8j_E0VeQe-Cn7pHjjUxSXSU,2261
|
|
21
|
-
robo_appian-0.0.19.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
22
|
-
robo_appian-0.0.19.dist-info/RECORD,,
|
|
File without changes
|