robo_appian 0.0.14__py3-none-any.whl → 0.0.16__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 +7 -7
- robo_appian/components/DropdownUtils.py +5 -5
- robo_appian/components/InputUtils.py +3 -3
- robo_appian/components/LabelUtils.py +15 -6
- robo_appian/components/LinkUtils.py +1 -1
- robo_appian/components/SearchDropdownUtils.py +31 -15
- robo_appian/components/SearchInputUtils.py +3 -2
- robo_appian/components/TabUtils.py +25 -33
- robo_appian/components/TableUtils.py +36 -11
- robo_appian/controllers/ComponentDriver.py +2 -2
- robo_appian/utils/ComponentUtils.py +7 -3
- {robo_appian-0.0.14.dist-info → robo_appian-0.0.16.dist-info}/METADATA +1 -1
- robo_appian-0.0.16.dist-info/RECORD +22 -0
- robo_appian-0.0.14.dist-info/RECORD +0 -22
- {robo_appian-0.0.14.dist-info → robo_appian-0.0.16.dist-info}/LICENSE +0 -0
- {robo_appian-0.0.14.dist-info → robo_appian-0.0.16.dist-info}/WHEEL +0 -0
|
@@ -13,7 +13,7 @@ class ButtonUtils:
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
@staticmethod
|
|
16
|
-
def
|
|
16
|
+
def _findByPartialLabelText(wait: WebDriverWait, label: str):
|
|
17
17
|
"""
|
|
18
18
|
Finds a button by its label.
|
|
19
19
|
|
|
@@ -26,7 +26,7 @@ class ButtonUtils:
|
|
|
26
26
|
WebElement representing the button.
|
|
27
27
|
|
|
28
28
|
Example:
|
|
29
|
-
component = ButtonUtils.
|
|
29
|
+
component = ButtonUtils._findByPartialLabelText(wait, "Submit")
|
|
30
30
|
"""
|
|
31
31
|
xpath = f".//button[./span[contains(translate(normalize-space(.), '\u00a0', ' '), '{label}')]]"
|
|
32
32
|
try:
|
|
@@ -36,7 +36,7 @@ class ButtonUtils:
|
|
|
36
36
|
return component
|
|
37
37
|
|
|
38
38
|
@staticmethod
|
|
39
|
-
def
|
|
39
|
+
def _findByLabelText(wait: WebDriverWait, label: str):
|
|
40
40
|
"""
|
|
41
41
|
Finds a button by its label.
|
|
42
42
|
|
|
@@ -49,9 +49,9 @@ class ButtonUtils:
|
|
|
49
49
|
WebElement representing the button.
|
|
50
50
|
|
|
51
51
|
Example:
|
|
52
|
-
component = ButtonUtils.
|
|
52
|
+
component = ButtonUtils._findByLabelText(wait, "Submit")
|
|
53
53
|
"""
|
|
54
|
-
xpath = f".//button[./span[normalize-space(
|
|
54
|
+
xpath = f".//button[./span[normalize-space(.)='{label}']]"
|
|
55
55
|
try:
|
|
56
56
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
57
57
|
except Exception as e:
|
|
@@ -68,7 +68,7 @@ class ButtonUtils:
|
|
|
68
68
|
Example:
|
|
69
69
|
ButtonUtils.clickByPartialLabelText(wait, "Button Label")
|
|
70
70
|
"""
|
|
71
|
-
component = ButtonUtils.
|
|
71
|
+
component = ButtonUtils._findByPartialLabelText(wait, label)
|
|
72
72
|
component.click()
|
|
73
73
|
|
|
74
74
|
@staticmethod
|
|
@@ -81,7 +81,7 @@ class ButtonUtils:
|
|
|
81
81
|
Example:
|
|
82
82
|
ButtonUtils.clickByLabelText(wait, "Button Label")
|
|
83
83
|
"""
|
|
84
|
-
component = ButtonUtils.
|
|
84
|
+
component = ButtonUtils._findByLabelText(wait, label)
|
|
85
85
|
component.click()
|
|
86
86
|
|
|
87
87
|
@staticmethod
|
|
@@ -25,7 +25,7 @@ class DropdownUtils:
|
|
|
25
25
|
Example:
|
|
26
26
|
component = DropdownUtils.__findComboboxByPartialLabelText(wait, "Dropdown Label")
|
|
27
27
|
"""
|
|
28
|
-
xpath = f'.//div[./div/span[contains(normalize-space(
|
|
28
|
+
xpath = f'.//div[./div/span[contains(normalize-space(.), "{label}")]]/div/div/div/div[@role="combobox" and not(@aria-disabled="true")]' # noqa: E501
|
|
29
29
|
try:
|
|
30
30
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
31
31
|
except Exception as e:
|
|
@@ -44,7 +44,7 @@ class DropdownUtils:
|
|
|
44
44
|
Example:
|
|
45
45
|
component = DropdownUtils.__findComboboxByLabelText(wait, "Dropdown Label")
|
|
46
46
|
"""
|
|
47
|
-
xpath = f'.//div[./div/span[normalize-space(
|
|
47
|
+
xpath = f'.//div[./div/span[normalize-space(.)="{label}"]]/div/div/div/div[@role="combobox" and not(@aria-disabled="true")]' # noqa: E501
|
|
48
48
|
try:
|
|
49
49
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
50
50
|
except Exception as e:
|
|
@@ -96,7 +96,7 @@ class DropdownUtils:
|
|
|
96
96
|
print("The value does not exist in the dropdown.")
|
|
97
97
|
"""
|
|
98
98
|
|
|
99
|
-
xpath = f'.//div/ul[@id="{dropdown_option_id}"]/li[./div[normalize-space(
|
|
99
|
+
xpath = f'.//div/ul[@id="{dropdown_option_id}"]/li[./div[normalize-space(.)="{value}"]]'
|
|
100
100
|
try:
|
|
101
101
|
wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
102
102
|
return True
|
|
@@ -116,7 +116,7 @@ class DropdownUtils:
|
|
|
116
116
|
Example:
|
|
117
117
|
DropdownUtils.selectDropdownValueByDropdownOptionId(wait, "dropdown_option_id", "Option Value")
|
|
118
118
|
"""
|
|
119
|
-
option_xpath = f'.//div/ul[@id="{dropdown_option_id}"]/li[./div[normalize-space(
|
|
119
|
+
option_xpath = f'.//div/ul[@id="{dropdown_option_id}"]/li[./div[normalize-space(.)="{value}"]]'
|
|
120
120
|
try:
|
|
121
121
|
try:
|
|
122
122
|
component = wait.until(EC.presence_of_element_located((By.XPATH, option_xpath)))
|
|
@@ -172,7 +172,7 @@ class DropdownUtils:
|
|
|
172
172
|
else:
|
|
173
173
|
print("The dropdown is editable.")
|
|
174
174
|
"""
|
|
175
|
-
xpath = f'.//div[./div/span[normalize-space(
|
|
175
|
+
xpath = f'.//div[./div/span[normalize-space(.)="{label}"]]/div/div/p[text()]'
|
|
176
176
|
try:
|
|
177
177
|
wait._driver.find_element(By.XPATH, xpath)
|
|
178
178
|
return True
|
|
@@ -31,7 +31,7 @@ class InputUtils:
|
|
|
31
31
|
A list of Selenium WebElement representing the input components.
|
|
32
32
|
|
|
33
33
|
Example:
|
|
34
|
-
InputUtils.__findInputComponentsByXpath(wait, './/div/label[normalize-space(
|
|
34
|
+
InputUtils.__findInputComponentsByXpath(wait, './/div/label[normalize-space(.)="Username"]')
|
|
35
35
|
"""
|
|
36
36
|
label_components = ComponentUtils.findComponentsByXPath(wait, xpath)
|
|
37
37
|
input_components = []
|
|
@@ -62,7 +62,7 @@ class InputUtils:
|
|
|
62
62
|
Example:
|
|
63
63
|
InputUtils.__findInputComponentsByPartialLabel(wait, "Username")
|
|
64
64
|
"""
|
|
65
|
-
xpath = f'.//div/label[contains(normalize-space(
|
|
65
|
+
xpath = f'.//div/label[contains(normalize-space(.), "{label}")]'
|
|
66
66
|
components = InputUtils.__findInputComponentsByXpath(wait, xpath)
|
|
67
67
|
return components
|
|
68
68
|
|
|
@@ -80,7 +80,7 @@ class InputUtils:
|
|
|
80
80
|
Example:
|
|
81
81
|
InputUtils.__findComponentsByLabel(wait, "Username")
|
|
82
82
|
"""
|
|
83
|
-
xpath = f'.//div/label[normalize-space(
|
|
83
|
+
xpath = f'.//div/label[normalize-space(.)="{label}"]'
|
|
84
84
|
components = InputUtils.__findInputComponentsByXpath(wait, xpath)
|
|
85
85
|
return components
|
|
86
86
|
|
|
@@ -8,13 +8,13 @@ class LabelUtils:
|
|
|
8
8
|
Utility class for interacting with label components in Appian UI.
|
|
9
9
|
Usage Example:
|
|
10
10
|
# Find a label by its text
|
|
11
|
-
component = LabelUtils.
|
|
11
|
+
component = LabelUtils._findByLabelText(wait, "Submit")
|
|
12
12
|
# Click a label by its text
|
|
13
13
|
LabelUtils.clickByLabelText(wait, "Submit")
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
@staticmethod
|
|
17
|
-
def
|
|
17
|
+
def __findByLabelText(wait: WebDriverWait, label: str):
|
|
18
18
|
"""
|
|
19
19
|
Finds a label element by its text.
|
|
20
20
|
|
|
@@ -22,11 +22,11 @@ class LabelUtils:
|
|
|
22
22
|
:param label: The text of the label to find.
|
|
23
23
|
:return: WebElement representing the label.
|
|
24
24
|
Example:
|
|
25
|
-
component = LabelUtils.
|
|
25
|
+
component = LabelUtils._findByLabelText(wait, "Submit")
|
|
26
26
|
"""
|
|
27
|
-
xpath = f".//*[normalize-space(
|
|
27
|
+
xpath = f".//*[normalize-space(.)='{label}']"
|
|
28
28
|
try:
|
|
29
|
-
component = wait.until(EC.
|
|
29
|
+
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
30
30
|
except Exception as e:
|
|
31
31
|
raise RuntimeError(f"Label with text '{label}' not found.") from e
|
|
32
32
|
|
|
@@ -42,5 +42,14 @@ class LabelUtils:
|
|
|
42
42
|
Example:
|
|
43
43
|
LabelUtils.clickByLabelText(wait, "Submit")
|
|
44
44
|
"""
|
|
45
|
-
component = LabelUtils.
|
|
45
|
+
component = LabelUtils.__findByLabelText(wait, label)
|
|
46
|
+
wait.until(EC.element_to_be_clickable(component))
|
|
46
47
|
component.click()
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def checkLabelExists(wait: WebDriverWait, label: str):
|
|
51
|
+
try:
|
|
52
|
+
LabelUtils.__findByLabelText(wait, label)
|
|
53
|
+
except Exception:
|
|
54
|
+
return False
|
|
55
|
+
return True
|
|
@@ -19,7 +19,7 @@ class LinkUtils:
|
|
|
19
19
|
|
|
20
20
|
@staticmethod
|
|
21
21
|
def find(wait: WebDriverWait, label: str):
|
|
22
|
-
xpath = f'.//a[normalize-space(
|
|
22
|
+
xpath = f'.//a[normalize-space(.)="{label}"]'
|
|
23
23
|
try:
|
|
24
24
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
25
25
|
except TimeoutError as e:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
2
2
|
from selenium.webdriver.support import expected_conditions as EC
|
|
3
3
|
from selenium.webdriver.common.by import By
|
|
4
|
+
from selenium.webdriver.remote.webelement import WebElement
|
|
4
5
|
from robo_appian.components.InputUtils import InputUtils
|
|
5
6
|
|
|
6
7
|
|
|
@@ -14,15 +15,21 @@ class SearchDropdownUtils:
|
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
17
|
@staticmethod
|
|
17
|
-
def
|
|
18
|
-
|
|
18
|
+
def __selectSearchDropdownValueByDropdownId(wait, component_id, value):
|
|
19
|
+
if not component_id:
|
|
20
|
+
raise ValueError("Invalid component_id provided.")
|
|
21
|
+
|
|
19
22
|
try:
|
|
23
|
+
input_component_id = str(component_id) + "_searchInput"
|
|
24
|
+
wait.until(EC.presence_of_element_located((By.ID, input_component_id)))
|
|
20
25
|
input_component = wait.until(EC.element_to_be_clickable((By.ID, input_component_id)))
|
|
21
26
|
except Exception as e:
|
|
22
27
|
raise RuntimeError(f"Failed to locate or click input component with ID '{input_component_id}': {e}")
|
|
23
28
|
InputUtils._setValueByComponent(input_component, value)
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
dropdown_option_id = str(component_id) + "_list"
|
|
31
|
+
|
|
32
|
+
xpath = f'.//ul[@id="{dropdown_option_id}"]/li[./div[normalize-space(.)="{value}"]][1]'
|
|
26
33
|
try:
|
|
27
34
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
28
35
|
except Exception as e:
|
|
@@ -31,28 +38,37 @@ class SearchDropdownUtils:
|
|
|
31
38
|
|
|
32
39
|
@staticmethod
|
|
33
40
|
def __selectSearchDropdownValueByPartialLabelText(wait: WebDriverWait, label: str, value: str):
|
|
34
|
-
xpath = f'.//div[./div/span[contains(normalize-space(
|
|
41
|
+
xpath = f'.//div[./div/span[contains(normalize-space(.), "{label}")]]/div/div/div/div[@role="combobox" and not(@aria-disabled="true")]'
|
|
35
42
|
try:
|
|
36
|
-
|
|
43
|
+
combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
37
44
|
except Exception as e:
|
|
38
45
|
raise RuntimeError(f"Failed to locate or click dropdown component with XPath '{xpath}': {e}")
|
|
39
|
-
component_id = component.get_attribute("aria-labelledby")
|
|
40
|
-
dropdown_id = component.get_attribute("aria-controls")
|
|
41
|
-
component.click()
|
|
42
46
|
|
|
43
|
-
SearchDropdownUtils.
|
|
47
|
+
SearchDropdownUtils._selectSearchDropdownValueByComboboxComponent(wait, combobox, value)
|
|
44
48
|
|
|
45
49
|
@staticmethod
|
|
46
50
|
def __selectSearchDropdownValueByLabelText(wait: WebDriverWait, label: str, value: str):
|
|
47
|
-
xpath =
|
|
51
|
+
xpath = (
|
|
52
|
+
f'.//div[./div/span[normalize-space(.)="{label}"]]/div/div/div/div[@role="combobox" and not(@aria-disabled="true")]'
|
|
53
|
+
)
|
|
48
54
|
try:
|
|
49
|
-
|
|
55
|
+
combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
50
56
|
except Exception as e:
|
|
51
57
|
raise RuntimeError(f"Failed to locate or click dropdown component with XPath '{xpath}': {e}")
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
SearchDropdownUtils._selectSearchDropdownValueByComboboxComponent(wait, combobox, value)
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def _selectSearchDropdownValueByComboboxComponent(wait: WebDriverWait, combobox: WebElement, value: str):
|
|
62
|
+
id = combobox.get_attribute("id")
|
|
63
|
+
if id is not None:
|
|
64
|
+
component_id = id.rsplit("_value", 1)[0]
|
|
65
|
+
else:
|
|
66
|
+
raise RuntimeError("Combobox element does not have an 'id' attribute.")
|
|
67
|
+
|
|
68
|
+
wait.until(EC.element_to_be_clickable(combobox))
|
|
69
|
+
combobox.click()
|
|
70
|
+
|
|
71
|
+
SearchDropdownUtils.__selectSearchDropdownValueByDropdownId(wait, component_id, value)
|
|
56
72
|
|
|
57
73
|
@staticmethod
|
|
58
74
|
def selectSearchDropdownValueByLabelText(wait: WebDriverWait, dropdown_label: str, value: str):
|
|
@@ -28,8 +28,9 @@ class SearchInputUtils:
|
|
|
28
28
|
dropdown_list_id = search_input_component.get_attribute(attribute)
|
|
29
29
|
if dropdown_list_id:
|
|
30
30
|
InputUtils._setValueByComponent(search_input_component, value)
|
|
31
|
-
xpath = f
|
|
31
|
+
xpath = f'.//ul[@id="{dropdown_list_id}" and @role="listbox" ]/li[@role="option" and @tabindex="-1" and ./div/div/div/div/div/div/p[normalize-space(.)="{value}"][1]]'
|
|
32
32
|
try:
|
|
33
|
+
drop_down_item = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
33
34
|
drop_down_item = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
34
35
|
except TimeoutError as e:
|
|
35
36
|
raise TimeoutError(
|
|
@@ -49,7 +50,7 @@ class SearchInputUtils:
|
|
|
49
50
|
|
|
50
51
|
@staticmethod
|
|
51
52
|
def __selectSearchInputComponentsByPartialLabelText(wait: WebDriverWait, label: str, value: str):
|
|
52
|
-
xpath = f".//div[./div/span[contains(normalize-space(
|
|
53
|
+
xpath = f".//div[./div/span[contains(normalize-space(.)='{label}']]/div/div/div/input[@role='combobox']"
|
|
53
54
|
SearchInputUtils.__findSearchInputComponentsByLabelPathAndSelectValue(wait, xpath, value)
|
|
54
55
|
|
|
55
56
|
@staticmethod
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from selenium.webdriver.common.by import By
|
|
2
2
|
from selenium.webdriver.support import expected_conditions as EC
|
|
3
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class TabUtils:
|
|
@@ -17,47 +18,38 @@ class TabUtils:
|
|
|
17
18
|
selected_tab = TabUtils.findSelectedTabByLabelText(wait, "Tab Label")
|
|
18
19
|
|
|
19
20
|
# Select an inactive tab by its label
|
|
20
|
-
TabUtils.
|
|
21
|
+
TabUtils.selectTabByLabelText(wait, "Inactive Tab Label")
|
|
21
22
|
|
|
22
23
|
driver.quit()
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
@staticmethod
|
|
26
|
-
def
|
|
27
|
-
"""
|
|
28
|
-
Finds the currently selected tab by its label.
|
|
29
|
-
|
|
30
|
-
:param wait: Selenium WebDriverWait instance.
|
|
31
|
-
:param label: The label of the tab to find.
|
|
32
|
-
:return: WebElement representing the selected tab.
|
|
33
|
-
Example:
|
|
34
|
-
component = TabUtils.findSelectedTabByLabelText(wait, "Tab Label")
|
|
35
|
-
"""
|
|
36
|
-
xpath = f".//div[./div[./div/div/div/div/div/p/strong[normalize-space(text())='{label}']]/span[text()='Selected Tab.']]/div[@role='link']"
|
|
27
|
+
def findTabByLabelText(wait, label):
|
|
28
|
+
xpath = f'//div/div[@role="link" ]/div/div/div/div/div/p[normalize-space(.)="{label}"]'
|
|
37
29
|
try:
|
|
38
|
-
component = wait.until(EC.
|
|
39
|
-
except
|
|
40
|
-
raise
|
|
41
|
-
except Exception as e:
|
|
42
|
-
raise RuntimeError(f"Could not find selected tab with label '{label}': {e}")
|
|
30
|
+
component = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
31
|
+
except Exception:
|
|
32
|
+
raise Exception(f"Tab with label '{label}' not found.")
|
|
43
33
|
return component
|
|
44
34
|
|
|
45
35
|
@staticmethod
|
|
46
|
-
def
|
|
47
|
-
|
|
48
|
-
Selects an inactive tab by its label.
|
|
49
|
-
|
|
50
|
-
:param wait: Selenium WebDriverWait instance.
|
|
51
|
-
:param label: The label of the tab to select.
|
|
52
|
-
:return: None
|
|
53
|
-
Example:
|
|
54
|
-
TabUtils.selectInactiveTabByLabelText(wait, "Tab Label")
|
|
55
|
-
"""
|
|
56
|
-
xpath = f".//div[@role='link']/div/div/div/div/div[./p/span[text()='{label}']]"
|
|
36
|
+
def selectTabByLabelText(wait, label):
|
|
37
|
+
component = TabUtils.findTabByLabelText(wait, label)
|
|
57
38
|
try:
|
|
58
|
-
component = wait.until(EC.element_to_be_clickable(
|
|
59
|
-
except
|
|
60
|
-
raise
|
|
61
|
-
except Exception as e:
|
|
62
|
-
raise RuntimeError(f"Could not find tab with label '{label}': {e}")
|
|
39
|
+
component = wait.until(EC.element_to_be_clickable(component))
|
|
40
|
+
except Exception:
|
|
41
|
+
raise Exception(f"Tab with label '{label}' is not clickable.")
|
|
63
42
|
component.click()
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def checkTabSelectedByLabelText(wait, label):
|
|
46
|
+
component = TabUtils.findTabByLabelText(wait, label)
|
|
47
|
+
|
|
48
|
+
select_text = "Selected Tab."
|
|
49
|
+
xpath = f'./span[normalize-space(.)="{select_text}"]'
|
|
50
|
+
try:
|
|
51
|
+
component = ComponentUtils.findChildComponentByXpath(wait, component, xpath)
|
|
52
|
+
except Exception:
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
return True
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
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
|
+
from robo_appian.utils.ComponentUtils import ComponentUtils
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class TableUtils:
|
|
@@ -34,11 +35,14 @@ class TableUtils:
|
|
|
34
35
|
|
|
35
36
|
xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]'
|
|
36
37
|
try:
|
|
37
|
-
component = wait.until(EC.
|
|
38
|
-
except
|
|
39
|
-
raise
|
|
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))
|
|
40
44
|
except Exception as e:
|
|
41
|
-
raise
|
|
45
|
+
raise Exception(f"Table found by column name '{columnName}' is not clickable: {e}")
|
|
42
46
|
return component
|
|
43
47
|
|
|
44
48
|
@staticmethod
|
|
@@ -56,7 +60,7 @@ class TableUtils:
|
|
|
56
60
|
try:
|
|
57
61
|
rows = tableObject.find_elements(By.XPATH, xpath)
|
|
58
62
|
except Exception as e:
|
|
59
|
-
raise
|
|
63
|
+
raise Exception(f"Could not count rows in table: {e}")
|
|
60
64
|
return len(rows)
|
|
61
65
|
|
|
62
66
|
@staticmethod
|
|
@@ -92,6 +96,12 @@ class TableUtils:
|
|
|
92
96
|
data = selected_word.split("_")
|
|
93
97
|
return int(data[1])
|
|
94
98
|
|
|
99
|
+
@staticmethod
|
|
100
|
+
def __findRowByColumnNameAndRowNumber(wait, rowNumber, columnName):
|
|
101
|
+
xpath = f'.//table[./thead/tr/th/div[normalize-space(.)="{columnName}"] ]/tbody/tr[@data-dnd-name="row {rowNumber + 1}"]'
|
|
102
|
+
row = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
|
|
103
|
+
return row
|
|
104
|
+
|
|
95
105
|
@staticmethod
|
|
96
106
|
def findComponentFromTableCell(wait, rowNumber, columnName):
|
|
97
107
|
"""
|
|
@@ -107,16 +117,31 @@ class TableUtils:
|
|
|
107
117
|
|
|
108
118
|
tableObject = TableUtils.findTableByColumnName(wait, columnName)
|
|
109
119
|
columnNumber = TableUtils.__findColumNumberByColumnName(tableObject, columnName)
|
|
110
|
-
# xpath=f'./tbody/tr[@data-dnd-name="row {rowNumber+1}"]/td[not (@data-empty-grid-message)][{columnNumber}]'
|
|
111
|
-
# component = tableObject.find_elements(By.XPATH, xpath)
|
|
112
120
|
rowNumber = rowNumber + 1
|
|
113
121
|
columnNumber = columnNumber + 1
|
|
114
122
|
xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]/tbody/tr[@data-dnd-name="row {rowNumber}"]/td[not (@data-empty-grid-message)][{columnNumber}]/*'
|
|
115
123
|
try:
|
|
116
124
|
component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
|
|
117
|
-
except TimeoutError as e:
|
|
118
|
-
raise TimeoutError(f"Could not find component in cell at row {rowNumber}, column '{columnName}': {e}")
|
|
119
125
|
except Exception as e:
|
|
120
|
-
raise
|
|
121
|
-
|
|
126
|
+
raise Exception(f"Could not find component in cell at row {rowNumber}, column '{columnName}': {e}")
|
|
127
|
+
return component
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def selectRowFromTableByColumnNameAndRowNumber(wait, rowNumber, columnName):
|
|
131
|
+
row = TableUtils.__findRowByColumnNameAndRowNumber(wait, rowNumber, columnName)
|
|
132
|
+
row = wait.until(EC.element_to_be_clickable(row))
|
|
133
|
+
row.click()
|
|
134
|
+
|
|
135
|
+
@staticmethod
|
|
136
|
+
def findComponentByColumnNameAndRowNumber(wait, rowNumber, columnName):
|
|
137
|
+
xpath = f'.//table/thead/tr/th[./div[normalize-space(.)="{columnName}"]]'
|
|
138
|
+
column = wait.until(EC.visibility_of_element_located((By.XPATH, xpath)))
|
|
139
|
+
id = column.get_attribute("id")
|
|
140
|
+
parts = id.rsplit("_", 1)
|
|
141
|
+
columnNumber = int(parts[-1])
|
|
142
|
+
|
|
143
|
+
tableRow = TableUtils.__findRowByColumnNameAndRowNumber(wait, rowNumber, columnName)
|
|
144
|
+
xpath = f"./td[{columnNumber + 1}]/*"
|
|
145
|
+
component = ComponentUtils.findChildComponentByXpath(wait, tableRow, xpath)
|
|
146
|
+
component = wait.until(EC.element_to_be_clickable(component))
|
|
122
147
|
return component
|
|
@@ -56,7 +56,7 @@ class ComponentDriver:
|
|
|
56
56
|
case "Label":
|
|
57
57
|
match action:
|
|
58
58
|
case "Find":
|
|
59
|
-
LabelUtils.
|
|
59
|
+
LabelUtils.checkLabelExists(wait, label)
|
|
60
60
|
case _:
|
|
61
61
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
62
62
|
case "Link":
|
|
@@ -86,7 +86,7 @@ class ComponentDriver:
|
|
|
86
86
|
case "Tab":
|
|
87
87
|
match action:
|
|
88
88
|
case "Find":
|
|
89
|
-
TabUtils.
|
|
89
|
+
TabUtils.selectTabByLabelText(wait, label)
|
|
90
90
|
case _:
|
|
91
91
|
raise ValueError(f"Unsupported action for {type}: {action}")
|
|
92
92
|
case _:
|
|
@@ -34,7 +34,7 @@ class ComponentUtils:
|
|
|
34
34
|
return yesterday_formatted
|
|
35
35
|
|
|
36
36
|
@staticmethod
|
|
37
|
-
def
|
|
37
|
+
def findChildComponentByXpath(wait: WebDriverWait, component: WebElement, xpath: str):
|
|
38
38
|
"""Finds a child component using the given XPath within a parent component.
|
|
39
39
|
|
|
40
40
|
:param wait: WebDriverWait instance to wait for elements
|
|
@@ -49,9 +49,13 @@ class ComponentUtils:
|
|
|
49
49
|
wait = WebDriverWait(driver, 10)
|
|
50
50
|
parent_component = driver.find_element(By.ID, "parent")
|
|
51
51
|
xpath = ".//button[@class='child']"
|
|
52
|
-
child_component = ComponentUtils.
|
|
52
|
+
child_component = ComponentUtils.findChildComponentByXpath(wait, parent_component, xpath)
|
|
53
53
|
"""
|
|
54
|
-
|
|
54
|
+
try:
|
|
55
|
+
component = component.find_element(By.XPATH, xpath)
|
|
56
|
+
except Exception:
|
|
57
|
+
raise Exception(f"Child component with XPath '{xpath}' not found within the given parent component.")
|
|
58
|
+
return component
|
|
55
59
|
|
|
56
60
|
@staticmethod
|
|
57
61
|
def findComponentUsingXpathAndClick(wait: WebDriverWait, xpath: str):
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
robo_appian/__init__.py,sha256=6u9n2W7P1IKSSr5IPGsg7LhVR1o1uYv424mXDjJLgb0,720
|
|
2
|
+
robo_appian/components/ButtonUtils.py,sha256=_FUote6eBekTAq7KsFJvE301ZRbmnjYr_-56I-JDRVg,3593
|
|
3
|
+
robo_appian/components/DateUtils.py,sha256=9scKYCyJavVyHzoHVfe1cdW2rEp4NAXsP5Zs_CV3fwk,3252
|
|
4
|
+
robo_appian/components/DropdownUtils.py,sha256=X_ucR4uCiU3fnsMXGnJC9PTfwbfW3w3ulzyuURh1Vlw,11149
|
|
5
|
+
robo_appian/components/InputUtils.py,sha256=21MsMuGHwUtpTmZdwUxVrpePMr2Kdy7aOZ6kqPV4lQ4,6423
|
|
6
|
+
robo_appian/components/LabelUtils.py,sha256=Fue3BDpqvHKGK_vBOtMld3Lai3ZQ2wzZPeQJESrjUF8,1860
|
|
7
|
+
robo_appian/components/LinkUtils.py,sha256=PS3U_o8BpTu5gFLHKPTGcUrs0Qo2H8qHNueKuXTC_y4,1514
|
|
8
|
+
robo_appian/components/SearchDropdownUtils.py,sha256=tCNsggjX-LPcADRizwLFjEE5Xxg5mT5Y8qN4wT9sU1s,4492
|
|
9
|
+
robo_appian/components/SearchInputUtils.py,sha256=bBKXDWT2O4ZKoUz-YbLjnOhy56Af2OR9g707buQ7Y2w,3487
|
|
10
|
+
robo_appian/components/TabUtils.py,sha256=uW90mZxO1OaU79NKarC62dVyBsKPjbCkjyh004TH2fo,1923
|
|
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=SuMpMBpHpErA9dpYLavfXQ50bSl24lLnWd1p61KzOeU,7063
|
|
18
|
+
robo_appian/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
robo_appian-0.0.16.dist-info/LICENSE,sha256=g-xR4dRa9_4iFkMoJmED-wE-J5hoxbk3105Knhfpjm0,1068
|
|
20
|
+
robo_appian-0.0.16.dist-info/METADATA,sha256=9GwUS8cObRQP2wCxbE0PNuU5f9VTMwr3eJ9w-vS7IZI,2261
|
|
21
|
+
robo_appian-0.0.16.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
22
|
+
robo_appian-0.0.16.dist-info/RECORD,,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
robo_appian/__init__.py,sha256=6u9n2W7P1IKSSr5IPGsg7LhVR1o1uYv424mXDjJLgb0,720
|
|
2
|
-
robo_appian/components/ButtonUtils.py,sha256=G4IMtzYfj-Rq_taX8qZ8U3gLbz7ajsxZvg9n8l2235o,3597
|
|
3
|
-
robo_appian/components/DateUtils.py,sha256=9scKYCyJavVyHzoHVfe1cdW2rEp4NAXsP5Zs_CV3fwk,3252
|
|
4
|
-
robo_appian/components/DropdownUtils.py,sha256=OscvU2mAC-ZhTQxB6j4amac4nByGpeu57ak7OLKdyY8,11174
|
|
5
|
-
robo_appian/components/InputUtils.py,sha256=6BqkAhKyUUcn9cTHbP97DuPaVU17kGAftstl310RMaE,6438
|
|
6
|
-
robo_appian/components/LabelUtils.py,sha256=luT_bY720GJF95sA1fWgu8FB0XiupK3fTNG9jmghQ60,1583
|
|
7
|
-
robo_appian/components/LinkUtils.py,sha256=AfJma3ahznMGm771ukAES3qSCBBug6lO5LxzN8PPf6w,1519
|
|
8
|
-
robo_appian/components/SearchDropdownUtils.py,sha256=sSe-GnbLL-Va8RvX_bTkcTSd9uPMfcmROlmRa8BEp1U,4042
|
|
9
|
-
robo_appian/components/SearchInputUtils.py,sha256=FcRazZ_3J-_XvXOwZhV4TVr-t65kWFG2-RjVH8rlkgo,3356
|
|
10
|
-
robo_appian/components/TabUtils.py,sha256=Pq-g61uPbhyfSgC8mt9PBBcdDDnmCcRziltfHGA52qw,2463
|
|
11
|
-
robo_appian/components/TableUtils.py,sha256=do9FvJIjV0hX2pafrIv5A9-NYxwyMZC-Z4k2Wo1yWs4,5039
|
|
12
|
-
robo_appian/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
robo_appian/controllers/ComponentDriver.py,sha256=0GzEXsncWg4oPHGmG48wKeGlrEHxkSX-Ml_NsLIcrvQ,4358
|
|
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=1tpHMxfZlqlhBbBpoNUP8T-Us1cBeyO80clAalz-U-s,6862
|
|
18
|
-
robo_appian/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
robo_appian-0.0.14.dist-info/LICENSE,sha256=g-xR4dRa9_4iFkMoJmED-wE-J5hoxbk3105Knhfpjm0,1068
|
|
20
|
-
robo_appian-0.0.14.dist-info/METADATA,sha256=plmMDkRAUHrkPjsjGunbVAZWN4E2dO682h0lIuCutN8,2261
|
|
21
|
-
robo_appian-0.0.14.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
22
|
-
robo_appian-0.0.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|