robo_appian 0.0.18__py3-none-any.whl → 0.0.20__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 +43 -21
- robo_appian/components/InputUtils.py +59 -64
- robo_appian/components/LabelUtils.py +25 -5
- 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/ComponentUtils.py +73 -24
- {robo_appian-0.0.18.dist-info → robo_appian-0.0.20.dist-info}/METADATA +1 -1
- robo_appian-0.0.20.dist-info/RECORD +22 -0
- robo_appian-0.0.18.dist-info/RECORD +0 -22
- {robo_appian-0.0.18.dist-info → robo_appian-0.0.20.dist-info}/LICENSE +0 -0
- {robo_appian-0.0.18.dist-info → robo_appian-0.0.20.dist-info}/WHEEL +0 -0
|
@@ -2,6 +2,7 @@ from selenium.webdriver.common.by import By
|
|
|
2
2
|
from selenium.webdriver.support import expected_conditions as EC
|
|
3
3
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
4
4
|
from selenium.webdriver.remote.webelement import WebElement
|
|
5
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class ButtonUtils:
|
|
@@ -36,32 +37,18 @@ class ButtonUtils:
|
|
|
36
37
|
"""
|
|
37
38
|
xpath = f".//button[./span[contains(translate(normalize-space(.), '\u00a0', ' '), '{label}')]]"
|
|
38
39
|
try:
|
|
39
|
-
component =
|
|
40
|
+
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
40
41
|
except Exception as e:
|
|
41
|
-
raise
|
|
42
|
+
raise Exception(f"Button with label '{label}' not found or not clickable.") from e
|
|
42
43
|
return component
|
|
43
44
|
|
|
44
45
|
@staticmethod
|
|
45
|
-
def
|
|
46
|
-
"""
|
|
47
|
-
Finds a button by its label.
|
|
48
|
-
|
|
49
|
-
Parameters:
|
|
50
|
-
wait: Selenium WebDriverWait instance.
|
|
51
|
-
label: The label of the button to find.
|
|
52
|
-
label: The label of the button to find.
|
|
53
|
-
|
|
54
|
-
Returns:
|
|
55
|
-
WebElement representing the button.
|
|
56
|
-
|
|
57
|
-
Example:
|
|
58
|
-
component = ButtonUtils._findByLabelText(wait, "Submit")
|
|
59
|
-
"""
|
|
46
|
+
def __findByLabelText(wait: WebDriverWait, label: str):
|
|
60
47
|
xpath = f".//button[./span[normalize-space(.)='{label}']]"
|
|
61
48
|
try:
|
|
62
|
-
component =
|
|
49
|
+
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
63
50
|
except Exception as e:
|
|
64
|
-
raise
|
|
51
|
+
raise Exception(f"Button with label '{label}' not found.") from e
|
|
65
52
|
return component
|
|
66
53
|
|
|
67
54
|
@staticmethod
|
|
@@ -87,7 +74,7 @@ class ButtonUtils:
|
|
|
87
74
|
Example:
|
|
88
75
|
ButtonUtils.clickByLabelText(wait, "Button Label")
|
|
89
76
|
"""
|
|
90
|
-
component = ButtonUtils.
|
|
77
|
+
component = ButtonUtils.__findByLabelText(wait, label)
|
|
91
78
|
ButtonUtils.__click(wait, component)
|
|
92
79
|
|
|
93
80
|
@staticmethod
|
|
@@ -106,6 +93,41 @@ class ButtonUtils:
|
|
|
106
93
|
try:
|
|
107
94
|
component = wait.until(EC.element_to_be_clickable((By.ID, id)))
|
|
108
95
|
except Exception as e:
|
|
109
|
-
raise
|
|
96
|
+
raise Exception(f"Input button with id '{id}' not found or not clickable.") from e
|
|
110
97
|
|
|
111
98
|
ButtonUtils.__click(wait, component)
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
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}')]]"
|
|
112
|
+
try:
|
|
113
|
+
ComponentUtils.findComponentByXPath(wait, xpath)
|
|
114
|
+
except Exception:
|
|
115
|
+
return False
|
|
116
|
+
return True
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def isButtonExistsByPartialLabelTextAfterLoad(wait: WebDriverWait, label: str):
|
|
120
|
+
try:
|
|
121
|
+
ButtonUtils._findByPartialLabelText(wait, label)
|
|
122
|
+
except Exception:
|
|
123
|
+
return False
|
|
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,4 @@
|
|
|
1
1
|
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
2
|
-
from selenium.webdriver.common.by import By
|
|
3
2
|
from selenium.webdriver.support import expected_conditions as EC
|
|
4
3
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
5
4
|
from selenium.webdriver.remote.webelement import WebElement
|
|
@@ -19,70 +18,53 @@ class InputUtils:
|
|
|
19
18
|
"""
|
|
20
19
|
|
|
21
20
|
@staticmethod
|
|
22
|
-
def
|
|
21
|
+
def __findComponentByPartialLabel(wait: WebDriverWait, label: str):
|
|
23
22
|
"""
|
|
24
|
-
Finds input
|
|
23
|
+
Finds an input component by its label text, allowing for partial matches.
|
|
25
24
|
|
|
26
25
|
Parameters:
|
|
27
26
|
wait: Selenium WebDriverWait instance.
|
|
28
|
-
|
|
27
|
+
label: The visible text label of the input component, allowing for partial matches.
|
|
29
28
|
|
|
30
29
|
Returns:
|
|
31
|
-
A
|
|
30
|
+
A Selenium WebElement representing the input component.
|
|
32
31
|
|
|
33
32
|
Example:
|
|
34
|
-
InputUtils.
|
|
33
|
+
InputUtils.__findInputComponentByPartialLabel(wait, "User")
|
|
35
34
|
"""
|
|
36
|
-
label_components = ComponentUtils.findComponentsByXPath(wait, xpath)
|
|
37
|
-
input_components = []
|
|
38
|
-
for label_component in label_components:
|
|
39
|
-
attribute: str = "for"
|
|
40
|
-
component_id = label_component.get_attribute(attribute) # type: ignore[reportUnknownMemberType]
|
|
41
|
-
if component_id:
|
|
42
|
-
try:
|
|
43
|
-
component = wait.until(EC.element_to_be_clickable((By.ID, component_id)))
|
|
44
|
-
input_components.append(component)
|
|
45
|
-
except Exception as e:
|
|
46
|
-
raise Exception(f"Could not find clickable input component with id '{component_id}': {e}")
|
|
47
|
-
else:
|
|
48
|
-
raise ValueError(f"Input component with label '{label_component.text}' does not have 'for' attribute.")
|
|
49
|
-
return input_components
|
|
50
|
-
|
|
51
|
-
@staticmethod
|
|
52
|
-
def __findInputComponentsByPartialLabel(wait: WebDriverWait, label: str):
|
|
53
|
-
"""Finds input components by their label text, allowing for partial matches.
|
|
54
35
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
label: The visible text label of the input component, allowing for partial matches.
|
|
36
|
+
xpath = f'.//div/label[contains(normalize-space(.), "{label}")]'
|
|
37
|
+
label_component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
58
38
|
|
|
59
|
-
|
|
60
|
-
|
|
39
|
+
input_id = label_component.get_attribute("for")
|
|
40
|
+
if input_id is None:
|
|
41
|
+
raise ValueError(f"Label component with text '{label}' does not have a 'for' attribute.")
|
|
61
42
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"""
|
|
65
|
-
xpath = f'.//div/label[contains(normalize-space(.), "{label}")]'
|
|
66
|
-
components = InputUtils.__findInputComponentsByXpath(wait, xpath)
|
|
67
|
-
return components
|
|
43
|
+
component = ComponentUtils.findComponentById(wait, input_id)
|
|
44
|
+
return component
|
|
68
45
|
|
|
69
46
|
@staticmethod
|
|
70
|
-
def
|
|
71
|
-
"""Finds
|
|
72
|
-
|
|
47
|
+
def __findComponentByLabel(wait: WebDriverWait, label: str):
|
|
48
|
+
"""Finds a component by its label text.
|
|
73
49
|
Parameters:
|
|
74
50
|
wait: Selenium WebDriverWait instance.
|
|
75
51
|
label: The visible text label of the input component.
|
|
76
52
|
|
|
77
53
|
Returns:
|
|
78
|
-
A
|
|
54
|
+
A Selenium WebElement representing the input component.
|
|
79
55
|
|
|
80
56
|
Example:
|
|
81
|
-
InputUtils.
|
|
57
|
+
InputUtils.__findComponentByLabel(wait, "Username")
|
|
82
58
|
"""
|
|
59
|
+
|
|
83
60
|
xpath = f'.//div/label[normalize-space(.)="{label}"]'
|
|
84
|
-
|
|
85
|
-
|
|
61
|
+
label_component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
62
|
+
input_id = label_component.get_attribute("for")
|
|
63
|
+
if input_id is None:
|
|
64
|
+
raise ValueError(f"Label component with text '{label}' does not have a 'for' attribute.")
|
|
65
|
+
|
|
66
|
+
component = ComponentUtils.findComponentById(wait, input_id)
|
|
67
|
+
return component
|
|
86
68
|
|
|
87
69
|
@staticmethod
|
|
88
70
|
def _setValueByComponent(wait: WebDriverWait, component: WebElement, value: str):
|
|
@@ -102,26 +84,20 @@ class InputUtils:
|
|
|
102
84
|
return component
|
|
103
85
|
|
|
104
86
|
@staticmethod
|
|
105
|
-
def
|
|
87
|
+
def setValueByPartialLabelText(wait: WebDriverWait, label: str, value: str):
|
|
106
88
|
"""
|
|
107
|
-
Sets a value in an input component identified by its label text.
|
|
89
|
+
Sets a value in an input component identified by its partial label text.
|
|
90
|
+
|
|
108
91
|
Parameters:
|
|
109
92
|
wait: Selenium WebDriverWait instance.
|
|
110
|
-
label: The visible text label of the input component.
|
|
93
|
+
label: The visible text label of the input component (partial match).
|
|
111
94
|
value: The value to set in the input field.
|
|
95
|
+
|
|
112
96
|
Returns:
|
|
113
97
|
None
|
|
114
|
-
Example:
|
|
115
|
-
InputUtils.setValueByLabelText(wait, "Username", "test_user")
|
|
116
98
|
"""
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
InputUtils._setValueByComponent(wait, component, value)
|
|
120
|
-
|
|
121
|
-
@staticmethod
|
|
122
|
-
def setValueByPartialLabelText(wait: WebDriverWait, label: str, value: str):
|
|
123
|
-
input_components = InputUtils.__findInputComponentsByPartialLabel(wait, label)
|
|
124
|
-
InputUtils.__setValueByComponents(wait, input_components, value)
|
|
99
|
+
component = InputUtils.__findComponentByPartialLabel(wait, label)
|
|
100
|
+
InputUtils._setValueByComponent(wait, component, value)
|
|
125
101
|
|
|
126
102
|
@staticmethod
|
|
127
103
|
def setValueByLabelText(wait: WebDriverWait, label: str, value: str):
|
|
@@ -139,17 +115,17 @@ class InputUtils:
|
|
|
139
115
|
Example:
|
|
140
116
|
InputUtils.setValueByLabelText(wait, "Username", "test_user")
|
|
141
117
|
"""
|
|
142
|
-
|
|
143
|
-
InputUtils.
|
|
118
|
+
component = InputUtils.__findComponentByLabel(wait, label)
|
|
119
|
+
InputUtils._setValueByComponent(wait, component, value)
|
|
144
120
|
|
|
145
121
|
@staticmethod
|
|
146
|
-
def setValueById(wait: WebDriverWait,
|
|
122
|
+
def setValueById(wait: WebDriverWait, id: str, value: str):
|
|
147
123
|
"""
|
|
148
124
|
Sets a value in an input component identified by its ID.
|
|
149
125
|
|
|
150
126
|
Parameters:
|
|
151
127
|
wait: Selenium WebDriverWait instance.
|
|
152
|
-
|
|
128
|
+
id: The ID of the input component.
|
|
153
129
|
value: The value to set in the input field.
|
|
154
130
|
|
|
155
131
|
Returns:
|
|
@@ -158,9 +134,28 @@ class InputUtils:
|
|
|
158
134
|
Example:
|
|
159
135
|
InputUtils.setValueById(wait, "inputComponentId", "test_value")
|
|
160
136
|
"""
|
|
161
|
-
try:
|
|
162
|
-
|
|
163
|
-
except Exception as e:
|
|
164
|
-
|
|
137
|
+
# try:
|
|
138
|
+
# component = wait.until(EC.element_to_be_clickable((By.ID, component_id)))
|
|
139
|
+
# except Exception as e:
|
|
140
|
+
# raise Exception(f"Timeout or error finding input component with id '{component_id}': {e}")
|
|
141
|
+
component = ComponentUtils.findComponentById(wait, id)
|
|
142
|
+
InputUtils._setValueByComponent(wait, component, value)
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def setValueByPlaceholderText(wait: WebDriverWait, text: str, value: str):
|
|
146
|
+
"""Sets a value in an input component identified by its placeholder text.
|
|
147
|
+
|
|
148
|
+
Parameters:
|
|
149
|
+
wait: Selenium WebDriverWait instance.
|
|
150
|
+
text: The placeholder text of the input component.
|
|
151
|
+
value: The value to set in the input field.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
None
|
|
155
|
+
|
|
156
|
+
Example:
|
|
157
|
+
InputUtils.setValueByPlaceholderText(wait, "Enter your name", "John Doe")
|
|
158
|
+
"""
|
|
159
|
+
xpath = f'.//input[@placeholder="{text}"]'
|
|
160
|
+
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
165
161
|
InputUtils._setValueByComponent(wait, component, value)
|
|
166
|
-
return component
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from selenium.webdriver.common.by import By
|
|
2
1
|
from selenium.webdriver.support import expected_conditions as EC
|
|
3
2
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
3
|
+
from selenium.webdriver.common.by import By
|
|
4
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class LabelUtils:
|
|
@@ -24,11 +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
|
-
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
30
|
+
# component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
31
|
+
component = ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
30
32
|
except Exception as e:
|
|
31
|
-
raise
|
|
33
|
+
raise Exception(f"Label with text '{label}' not found.") from e
|
|
32
34
|
|
|
33
35
|
return component
|
|
34
36
|
|
|
@@ -47,9 +49,27 @@ class LabelUtils:
|
|
|
47
49
|
component.click()
|
|
48
50
|
|
|
49
51
|
@staticmethod
|
|
50
|
-
def
|
|
52
|
+
def isLabelExists(wait: WebDriverWait, label: str):
|
|
51
53
|
try:
|
|
52
54
|
LabelUtils.__findByLabelText(wait, label)
|
|
53
55
|
except Exception:
|
|
54
56
|
return False
|
|
55
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
|
|
@@ -58,36 +58,38 @@ class ComponentUtils:
|
|
|
58
58
|
return component
|
|
59
59
|
|
|
60
60
|
@staticmethod
|
|
61
|
-
def
|
|
62
|
-
|
|
61
|
+
def findComponentById(wait: WebDriverWait, id: str):
|
|
62
|
+
try:
|
|
63
|
+
component = wait.until(EC.presence_of_element_located((By.ID, id)))
|
|
64
|
+
except Exception:
|
|
65
|
+
raise Exception(f"Component with ID '{id}' not found.")
|
|
66
|
+
return component
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
xpath = "//button[@id='submit']"
|
|
74
|
-
ComponentUtils.findComponentUsingXpathAndClick(wait, xpath)
|
|
76
|
+
@staticmethod
|
|
77
|
+
def findVisibleComponentByXpath(wait: WebDriverWait, xpath: str):
|
|
75
78
|
"""
|
|
76
|
-
component
|
|
77
|
-
component.click()
|
|
79
|
+
Finds a component using the given XPath in the current WebDriver instance.
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
:param wait: WebDriverWait instance to wait for elements
|
|
82
|
+
:param xpath: XPath string to locate the component
|
|
83
|
+
:return: WebElement if found, raises NoSuchElementException otherwise
|
|
82
84
|
|
|
83
|
-
:param wait: WebDriverWait instance to wait for elements
|
|
84
|
-
:param xpath: XPath string to locate the component
|
|
85
|
-
:return: WebElement if found, raises NoSuchElementException otherwise
|
|
86
85
|
Example usage:
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
component = ComponentUtils.findVisibleComponentByXpath(wait, "//button[@id='submit']")
|
|
87
|
+
component.click()
|
|
89
88
|
"""
|
|
90
|
-
|
|
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.")
|
|
91
93
|
return component
|
|
92
94
|
|
|
93
95
|
@staticmethod
|
|
@@ -95,7 +97,7 @@ class ComponentUtils:
|
|
|
95
97
|
"""Checks if a component with the given XPath exists in the current WebDriver instance."""
|
|
96
98
|
status = False
|
|
97
99
|
try:
|
|
98
|
-
ComponentUtils.
|
|
100
|
+
ComponentUtils.findVisibleComponentByXpath(wait, xpath)
|
|
99
101
|
status = True
|
|
100
102
|
except NoSuchElementException:
|
|
101
103
|
pass
|
|
@@ -190,3 +192,50 @@ class ComponentUtils:
|
|
|
190
192
|
return valid_components
|
|
191
193
|
|
|
192
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.")
|
|
@@ -0,0 +1,22 @@
|
|
|
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/ComponentUtils.py,sha256=qm_55lVSuyu6o5NkqD4N8fSzAxVBxLIlMzzOVomxZiA,8940
|
|
18
|
+
robo_appian/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
robo_appian-0.0.20.dist-info/LICENSE,sha256=g-xR4dRa9_4iFkMoJmED-wE-J5hoxbk3105Knhfpjm0,1068
|
|
20
|
+
robo_appian-0.0.20.dist-info/METADATA,sha256=8lqgIdQ88C-EvlwwfUXVG2KivdrLIPlwllt4qoAJicQ,2261
|
|
21
|
+
robo_appian-0.0.20.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
22
|
+
robo_appian-0.0.20.dist-info/RECORD,,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
robo_appian/__init__.py,sha256=6u9n2W7P1IKSSr5IPGsg7LhVR1o1uYv424mXDjJLgb0,720
|
|
2
|
-
robo_appian/components/ButtonUtils.py,sha256=qFe84Pv3J64X2oqBvbOEnyZPudcCOK_Rrz-PAEAahM4,3874
|
|
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=LNPNX2TYubPS7sgOx329JPixTrbtZZ7XhhpUolC9XYw,6514
|
|
6
|
-
robo_appian/components/LabelUtils.py,sha256=Fue3BDpqvHKGK_vBOtMld3Lai3ZQ2wzZPeQJESrjUF8,1860
|
|
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=sHHT-mcdhZs9hHIAVD3KkrgLFXn4gIo58NsHHhI156w,7088
|
|
18
|
-
robo_appian/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
robo_appian-0.0.18.dist-info/LICENSE,sha256=g-xR4dRa9_4iFkMoJmED-wE-J5hoxbk3105Knhfpjm0,1068
|
|
20
|
-
robo_appian-0.0.18.dist-info/METADATA,sha256=kbjqustBLua2sfLOP3uhL7awiy4Ykl6Y4nmnnY7ZpcA,2261
|
|
21
|
-
robo_appian-0.0.18.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
22
|
-
robo_appian-0.0.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|