robo-appian 0.0.1__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.
Files changed (27) hide show
  1. robo_appian-0.0.1/LICENSE +21 -0
  2. robo_appian-0.0.1/PKG-INFO +26 -0
  3. robo_appian-0.0.1/README.md +2 -0
  4. robo_appian-0.0.1/pyproject.toml +16 -0
  5. robo_appian-0.0.1/robo_appian/__init__.py +11 -0
  6. robo_appian-0.0.1/robo_appian/utils/__init__.py +0 -0
  7. robo_appian-0.0.1/robo_appian/utils/components/ButtonUtils.py +21 -0
  8. robo_appian-0.0.1/robo_appian/utils/components/ComponentUtils.py +178 -0
  9. robo_appian-0.0.1/robo_appian/utils/components/DateUtils.py +39 -0
  10. robo_appian-0.0.1/robo_appian/utils/components/DropdownUtils.py +50 -0
  11. robo_appian-0.0.1/robo_appian/utils/components/InputUtils.py +49 -0
  12. robo_appian-0.0.1/robo_appian/utils/components/LabelUtils.py +11 -0
  13. robo_appian-0.0.1/robo_appian/utils/components/LinkUtils.py +13 -0
  14. robo_appian-0.0.1/robo_appian/utils/components/TabUtils.py +18 -0
  15. robo_appian-0.0.1/robo_appian/utils/components/TableUtils.py +66 -0
  16. robo_appian-0.0.1/robo_appian/utils/components/__init__.py +0 -0
  17. robo_appian-0.0.1/robo_appian/utils/controllers/ComponentDriver.py +72 -0
  18. robo_appian-0.0.1/robo_appian/utils/controllers/__init__.py +0 -0
  19. robo_appian-0.0.1/robo_appian/utils/exceptions/MyCustomError.py +6 -0
  20. robo_appian-0.0.1/robo_appian/utils/exceptions/__init__.py +0 -0
  21. robo_appian-0.0.1/robo_appian.egg-info/PKG-INFO +26 -0
  22. robo_appian-0.0.1/robo_appian.egg-info/SOURCES.txt +25 -0
  23. robo_appian-0.0.1/robo_appian.egg-info/dependency_links.txt +1 -0
  24. robo_appian-0.0.1/robo_appian.egg-info/requires.txt +1 -0
  25. robo_appian-0.0.1/robo_appian.egg-info/top_level.txt +1 -0
  26. robo_appian-0.0.1/setup.cfg +4 -0
  27. robo_appian-0.0.1/setup.py +22 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 dinilmithra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: robo_appian
3
+ Version: 0.0.1
4
+ Summary: Automate your Appin code testing with Python. Boost quality, save time.
5
+ Home-page: https://github.com/dinilmithra/robo_appian.git
6
+ Author: Dinil Mithra
7
+ Author-email: dinilmithra@mailme@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: selenium>=4.34.0
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: requires-dist
22
+ Dynamic: requires-python
23
+ Dynamic: summary
24
+
25
+ # Robo Test suite for Appian framework
26
+ Robo Test suite for Appian framework
@@ -0,0 +1,2 @@
1
+ # Robo Test suite for Appian framework
2
+ Robo Test suite for Appian framework
@@ -0,0 +1,16 @@
1
+ [tool.poetry]
2
+ name = "robo_appian"
3
+ version = "0.0.1"
4
+ description = "Automate your Appin code testing with Python. Boost quality, save time."
5
+ authors = ["Dinil Mithra <dinilmithra@mailme@gmail.com>"]
6
+ readme = "README.md"
7
+
8
+ [tool.poetry.dependencies]
9
+ python = ">=3.8,<4.0"
10
+ requests = "^2.25.1"
11
+ numpy = "*"
12
+ selenium = ">=4.34.0"
13
+
14
+ [build-system]
15
+ requires = ["setuptools>=61.0"]
16
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,11 @@
1
+ from robo_appian.utils.components.ButtonUtils import ButtonUtils
2
+ from robo_appian.utils.components.ComponentUtils import ComponentUtils
3
+ from robo_appian.utils.components.DateUtils import DateUtils
4
+ from robo_appian.utils.components.DropdownUtils import DropdownUtils
5
+ from robo_appian.utils.components.InputUtils import InputUtils
6
+ from robo_appian.utils.components.LabelUtils import LabelUtils
7
+ from robo_appian.utils.components.LinkUtils import LinkUtils
8
+ from robo_appian.utils.components.TableUtils import TableUtils
9
+ from robo_appian.utils.components.TabUtils import TabUtils
10
+
11
+ __version__ = "0.1.0"
File without changes
@@ -0,0 +1,21 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+
5
+ class ButtonUtils():
6
+
7
+ @staticmethod
8
+ def find(wait, label):
9
+ xpath = f".//button[./span[contains(translate(normalize-space(.), '\u00A0', ' '), '{label}')]]"
10
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
11
+ return component
12
+
13
+ @staticmethod
14
+ def click(wait, label):
15
+ component = ButtonUtils.find(wait, label)
16
+ component.click()
17
+
18
+ @staticmethod
19
+ def clickInputButtonById(wait, id):
20
+ component = wait.until(EC.element_to_be_clickable((By.ID, id)))
21
+ component.click()
@@ -0,0 +1,178 @@
1
+ from selenium.common.exceptions import NoSuchElementException
2
+ from selenium.webdriver import ActionChains
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
+
7
+
8
+ class ComponentUtils():
9
+
10
+ @staticmethod
11
+ def today():
12
+ from datetime import date
13
+ today = date.today()
14
+ yesterday_formatted = today.strftime("%m/%d/%Y")
15
+ return yesterday_formatted
16
+
17
+ @staticmethod
18
+ def yesterday():
19
+ from datetime import date, timedelta
20
+ yesterday = date.today() - timedelta(days=1)
21
+ yesterday_formatted = yesterday.strftime("%m/%d/%Y")
22
+ return yesterday_formatted
23
+
24
+ @staticmethod
25
+ def find_dropdown_id(wait, dropdown_label):
26
+ label_class_name = "FieldLayout---field_label"
27
+ xpath = f'.//div/span[normalize-space(text())="{dropdown_label}" and @class="{label_class_name}"]'
28
+ span_element = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
29
+ span_element_id = span_element.get_attribute('id')
30
+ return span_element_id
31
+
32
+ @staticmethod
33
+ def find_input_id(wait, label_text):
34
+ label_class_name = "FieldLayout---field_label"
35
+ xpath = f'.//div/div/label[@class="{label_class_name}" and contains(normalize-space(text()), "{label_text}")]'
36
+ label_element = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
37
+ input_element_id = label_element.get_attribute('for')
38
+ return input_element_id
39
+
40
+ @staticmethod
41
+ def set_input_value(wait, label_text, value):
42
+ input_element_id = ComponentUtils.find_input_id(wait, label_text)
43
+ input_element = ComponentUtils.set_input_value_using_id(wait, input_element_id, value)
44
+ return input_element
45
+
46
+ @staticmethod
47
+ def set_input_value_using_id(wait, input_element_id, value):
48
+ input_element = wait.until(EC.presence_of_element_located((By.ID, input_element_id)))
49
+ input_element = wait.until(EC.element_to_be_clickable((By.ID, input_element_id)))
50
+ input_element.clear()
51
+ input_element.send_keys(value)
52
+ input_element.send_keys(Keys.RETURN)
53
+ return input_element
54
+
55
+ @staticmethod
56
+ def select_search_dropdown_value(wait, label, value):
57
+ span_element_id = ComponentUtils.find_dropdown_id(wait, label)
58
+ xpath = f'.//div[@id="{span_element_id}_value"]'
59
+ combobox = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
60
+ disabled = combobox.get_attribute("aria-disabled")
61
+ if disabled == "true":
62
+ return
63
+ aria_controls = combobox.get_attribute("aria-controls")
64
+ combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
65
+ combobox.click()
66
+
67
+ input_element_id = span_element_id + "_searchInput"
68
+ ComponentUtils.set_input_value_using_id(wait, input_element_id, value)
69
+
70
+ xpath = f'.//ul[@id="{aria_controls}"]/li[./div[normalize-space(text())="{value}"]]'
71
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
72
+ component.click()
73
+
74
+ @staticmethod
75
+ def selectDropdownValue(wait, combobox, value):
76
+
77
+ aria_controls = combobox.get_attribute("aria-controls")
78
+ combobox.click()
79
+
80
+ xpath = f'.//div/ul[@id="{aria_controls}"]/li[./div[normalize-space(text())="{value}"]]'
81
+ component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
82
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
83
+ component.click()
84
+
85
+ @staticmethod
86
+ def select_dropdown_value(wait, label, value):
87
+ span_element_id = ComponentUtils.find_dropdown_id(wait, label)
88
+
89
+ xpath = f'.//div[@id="{span_element_id}_value"]'
90
+ combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
91
+ disabled = combobox.get_attribute("aria-disabled")
92
+ if disabled == "true":
93
+ return
94
+
95
+ combobox = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
96
+ ComponentUtils.selectDropdownValue(wait, combobox, value)
97
+
98
+ @staticmethod
99
+ def findButton(wait, button_text):
100
+ xpath = f'.//button[.//span/span[contains(normalize-space(text()), "{button_text}")]]'
101
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
102
+ return component
103
+
104
+ @staticmethod
105
+ def click_button(wait, button_text):
106
+ component = ComponentUtils.findButton(wait, button_text)
107
+ component.click()
108
+
109
+ @staticmethod
110
+ def select_tab(wait, tab_label_text):
111
+ xpath = f'.//div[@role="presentation"]/div/div/p[./span[normalize-space(text())="{tab_label_text}"]]'
112
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
113
+ component.click()
114
+
115
+ @staticmethod
116
+ def findSuccessMessage(wait, message):
117
+ xpath = f'.//div/div/p/span/strong[normalize-space(text())="{message}"]'
118
+ component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
119
+ return component
120
+
121
+ @staticmethod
122
+ def findComponentUsingXpathAndClick(wait, xpath):
123
+ component = ComponentUtils.findComponentUsingXpath(wait, xpath)
124
+ component.click()
125
+
126
+ @staticmethod
127
+ def findComponentUsingXpath(wait, xpath):
128
+ component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
129
+ return component
130
+
131
+ @staticmethod
132
+ def checkComponentExistsByXpath(wait, xpath):
133
+ status = False
134
+ try:
135
+ component = ComponentUtils.findComponentUsingXpath(wait, xpath)
136
+ status = True
137
+ except NoSuchElementException:
138
+ pass
139
+
140
+ return status
141
+
142
+ @staticmethod
143
+ def checkComponentExistsById(driver, id):
144
+ status = False
145
+ try:
146
+ component = driver.find_element(By.ID, id)
147
+ status = True
148
+ except NoSuchElementException:
149
+ pass
150
+
151
+ return status
152
+
153
+ @staticmethod
154
+ def findCount(wait, xpath):
155
+
156
+ length = 0
157
+
158
+ try:
159
+ component = wait.until(EC.presence_of_all_elements_located((By.XPATH, xpath)))
160
+ length = len(component)
161
+ except NoSuchElementException:
162
+ pass
163
+
164
+ return length
165
+
166
+ @staticmethod
167
+ def findComponent(wait, label):
168
+ xpath = f".//div/label[text()='{label}']"
169
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
170
+ component_id = component.get_attribute("for")
171
+
172
+ component = wait.until(EC.element_to_be_clickable((By.ID, component_id)))
173
+ return component
174
+
175
+ @staticmethod
176
+ def tab(driver):
177
+ actions = ActionChains(driver)
178
+ actions.send_keys(Keys.TAB).perform()
@@ -0,0 +1,39 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+ from robo_appian.utils.components.InputUtils import InputUtils
5
+
6
+
7
+ class DateUtils():
8
+
9
+ @staticmethod
10
+ def findComponent(wait, label):
11
+ xpath = f".//div/label[text()='{label}']"
12
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
13
+ component_id = component.get_attribute("for")
14
+
15
+ component = wait.until(EC.element_to_be_clickable((By.ID, component_id)))
16
+ return component
17
+
18
+ @staticmethod
19
+ def setDateValue(wait, label, value):
20
+ component = DateUtils.findComponent(wait, label)
21
+ InputUtils.setValueUsingComponent(component, value)
22
+ return component
23
+
24
+ @staticmethod
25
+ def setDateValueAndSubmit(wait, label, value):
26
+ # component=DateUtils.setDateValue(wait, label, value)
27
+ # component.send_keys(Keys.RETURN)
28
+
29
+ component = DateUtils.findComponent(wait, label)
30
+ InputUtils.setValueAndSubmitUsingComponent(component, value)
31
+
32
+ return component
33
+
34
+ @staticmethod
35
+ def click(wait, label):
36
+ component = DateUtils.findComponent(wait, label)
37
+ component.click()
38
+
39
+ return component
@@ -0,0 +1,50 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+ from robo_appian.utils.components.InputUtils import InputUtils
5
+
6
+
7
+ class DropdownUtils():
8
+
9
+ @staticmethod
10
+ def findDropdownEnabled(wait, dropdown_label):
11
+ xpath = f'.//div[./div/span[normalize-space(text())="{dropdown_label}"]]/div/div/div/div[@role="combobox" and @tabindex="0"]'
12
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
13
+ return component
14
+
15
+ @staticmethod
16
+ def selectValueUsingComponent(wait, combobox, value):
17
+ component = combobox.find_element(By.XPATH, "./div/div")
18
+ aria_controls = component.get_attribute("aria-controls")
19
+ component.click()
20
+
21
+ xpath = f'.//div/ul[@id="{aria_controls}"]/li[./div[normalize-space(text())="{value}"]]'
22
+ # component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
23
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
24
+ component.click()
25
+
26
+ @staticmethod
27
+ def selectDropdownValue(wait, label, value):
28
+ combobox = DropdownUtils.findDropdownEnabled(wait, label)
29
+ aria_controls = combobox.get_attribute("aria-controls")
30
+ combobox.click()
31
+
32
+ xpath = f'.//div/ul[@id="{aria_controls}"]/li[./div[normalize-space(text())="{value}"]]'
33
+ component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
34
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
35
+ component.click()
36
+
37
+ @staticmethod
38
+ def selectSearchDropdownValue(wait, dropdown_label, value):
39
+ component = DropdownUtils.findDropdownEnabled(wait, dropdown_label)
40
+ component_id = component.get_attribute("aria-labelledby")
41
+ aria_controls = component.get_attribute("aria-controls")
42
+ component.click()
43
+
44
+ input_component_id = component_id + "_searchInput"
45
+ input_component = wait.until(EC.element_to_be_clickable((By.ID, input_component_id)))
46
+ InputUtils.setValueUsingComponent(input_component, value)
47
+
48
+ xpath = f'.//ul[@id="{aria_controls}"]/li[./div[normalize-space(text())="{value}"]][1]'
49
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
50
+ component.click()
@@ -0,0 +1,49 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.common.keys import Keys
3
+ from selenium.webdriver.support import expected_conditions as EC
4
+
5
+
6
+ class InputUtils():
7
+
8
+ @staticmethod
9
+ def findComponent(wait, label):
10
+ xpath = f".//div/label[text()='{label}']"
11
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
12
+ component_id = component.get_attribute("for")
13
+ component = wait.until(EC.element_to_be_clickable((By.ID, component_id)))
14
+ return component
15
+
16
+ @staticmethod
17
+ def setValueUsingComponent(component, value):
18
+ component.clear()
19
+ component.send_keys(value)
20
+ return component
21
+
22
+ @staticmethod
23
+ def setValueAndSubmitUsingComponent(component, value):
24
+ component = InputUtils.setValueUsingComponent(component, value)
25
+ component.send_keys(Keys.ENTER)
26
+ return component
27
+
28
+ @staticmethod
29
+ def setInputValue(wait, label, value):
30
+ component = InputUtils.findComponent(wait, label)
31
+ InputUtils.setValueUsingComponent(component, value)
32
+ return component
33
+
34
+ @staticmethod
35
+ def setValueAndSubmit(wait, label, value):
36
+ component = InputUtils.findComponent(wait, label)
37
+ component = InputUtils.setValueAndSubmitUsingComponent(component, value)
38
+ return component
39
+
40
+ @staticmethod
41
+ def setSearchInputValue(wait, label, value):
42
+ xpath = f".//div[./div/span[text()='{label}']]/div/div/div/input[@role='combobox']"
43
+ search_input_component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
44
+ aria_controls = search_input_component.get_attribute("aria-controls")
45
+ InputUtils.setValueUsingComponent(search_input_component, value)
46
+
47
+ xpath = f".//ul[@id='{aria_controls}' and @role='listbox' ]/li[@role='option']/div/div/div/div/div/div/p[text()='{value}'][1]"
48
+ drop_down_item = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
49
+ drop_down_item.click()
@@ -0,0 +1,11 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+
5
+ class LabelUtils():
6
+
7
+ @staticmethod
8
+ def find(wait, label):
9
+ xpath = f".//*[text()='{label}']"
10
+ component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
11
+ return component
@@ -0,0 +1,13 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+
5
+ class LinkUtils():
6
+
7
+ @staticmethod
8
+ def click(wait, label):
9
+ xpath = f'.//p/span[text()="{label}"]'
10
+ # component = wait.until(EC.presence_of_element_located((By.XPATH, xpath)) )
11
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
12
+ component.click()
13
+ return component
@@ -0,0 +1,18 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+
5
+ class TabUtils():
6
+
7
+ @staticmethod
8
+ def find_selected_tab(wait, label):
9
+ xpath = f".//div[./div[./div/div/div/div/div/p/strong[normalize-space(text())='{label}']]/span[text()='Selected Tab.']]/div[@role='link']"
10
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
11
+ return component
12
+
13
+ @staticmethod
14
+ def select_tab(wait, label):
15
+ xpath = f".//div[@role='link']/div/div/div/div/div[./p/span[text()='{label}']]"
16
+ # xpath=f".//div[./div[./div/div/div/div/div/p/strong[normalize-space(text())='{label}']]/span[text()='Selected Tab.']]/div[@role='link']"
17
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
18
+ component.click()
@@ -0,0 +1,66 @@
1
+ from selenium.webdriver.common.by import By
2
+ from selenium.webdriver.support import expected_conditions as EC
3
+
4
+
5
+ class TableUtils():
6
+
7
+ @staticmethod
8
+ def findTableUsingColumnName(wait, columnName):
9
+ # xpath = f".//table[./thead/tr/th[@abbr='{columnName}']]"
10
+ xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]'
11
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
12
+ return component
13
+
14
+ @staticmethod
15
+ def clickOnLinkUsingHoverText(wait, columnName, rowNumber, hoverText):
16
+ xpath = f".//table[./thead/tr/th[@abbr='{columnName}']]/tbody/tr[@data-dnd-name='row {rowNumber + 1}']/td[not (@data-empty-grid-message)]/div/p/a[./span[text()='{hoverText}']]"
17
+ # xpath=f".//table[./thead/tr/th/div[text()='{columnName}']][1]/tbody/tr[@data-dnd-name='row {rowNumber}']/td/div/p/a[./span[text()='{hoverText}']]"
18
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
19
+ component.click()
20
+
21
+ @staticmethod
22
+ def clickOnButtonUsingHoverText(wait, columnName, rowNumber, hoverText):
23
+ xpath = f".//table[./thead/tr/th[@abbr='{columnName}']]/tbody/tr[@data-dnd-name='row {rowNumber}']/td[not (@data-empty-grid-message)]"
24
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
25
+ component.click()
26
+
27
+ xpath = f".//table[./thead/tr/th[@abbr='{columnName}']]/tbody/tr[@data-dnd-name='row {rowNumber}']/td[not (@data-empty-grid-message)]/div/div/button[./span[text()='{hoverText}']]"
28
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
29
+ component.click()
30
+
31
+ @staticmethod
32
+ def rowCount(tableObject):
33
+ xpath = "./tbody/tr[./td[not (@data-empty-grid-message)]]"
34
+ rows = tableObject.find_elements(By.XPATH, xpath)
35
+ return len(rows)
36
+
37
+ @staticmethod
38
+ def findColumNumberUsingColumnName(tableObject, columnName):
39
+
40
+ xpath = f'./thead/tr/th[@scope="col" and @abbr="{columnName}"]'
41
+ component = tableObject.find_element(By.XPATH, xpath)
42
+ class_string = component.get_attribute("class")
43
+ partial_string = "headCell_"
44
+ words = class_string.split()
45
+ selected_word = None
46
+
47
+ for word in words:
48
+ if partial_string in word:
49
+ selected_word = word
50
+
51
+ data = selected_word.split("_")
52
+ return int(data[1])
53
+
54
+ @staticmethod
55
+ def find_component_from_tabele_cell(wait, rowNumber, columnName):
56
+
57
+ tableObject = TableUtils.findTableUsingColumnName(wait, columnName)
58
+ columnNumber = TableUtils.findColumNumberUsingColumnName(tableObject, columnName)
59
+ # xpath=f'./tbody/tr[@data-dnd-name="row {rowNumber+1}"]/td[not (@data-empty-grid-message)][{columnNumber}]'
60
+ # component = tableObject.find_elements(By.XPATH, xpath)
61
+ rowNumber = rowNumber + 1
62
+ columnNumber = columnNumber + 1
63
+ xpath = f'.//table[./thead/tr/th[@abbr="{columnName}"]]/tbody/tr[@data-dnd-name="row {rowNumber}"]/td[not (@data-empty-grid-message)][{columnNumber}]/*'
64
+ component = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
65
+ # childComponent=component.find_element(By.xpath("./*"))
66
+ return component
@@ -0,0 +1,72 @@
1
+ from robo_appian.utils.components.ComponentUtils import ComponentUtils
2
+ from robo_appian.utils.components.DateUtils import DateUtils
3
+ from robo_appian.utils.components.DropdownUtils import DropdownUtils
4
+ from robo_appian.utils.components.InputUtils import InputUtils
5
+ from robo_appian.utils.components.LabelUtils import LabelUtils
6
+ from robo_appian.utils.components.LinkUtils import LinkUtils
7
+ from robo_appian.utils.components.TabUtils import TabUtils
8
+
9
+
10
+ class ComponentDriver():
11
+
12
+ @staticmethod
13
+ def execute(wait, type, action, label, value):
14
+
15
+ match type:
16
+
17
+ case "Date":
18
+ match action:
19
+ case "Set Value":
20
+ DateUtils.setDateValue(wait, label, value)
21
+ case _:
22
+ raise ValueError(f"Unsupported action for {type}: {action}")
23
+ case "Input Text":
24
+ match action:
25
+ case "Set Value":
26
+ InputUtils.setInputValue(wait, label, value)
27
+ case _:
28
+ raise ValueError(f"Unsupported action for {type}: {action}")
29
+ case "Search Input Text":
30
+ match action:
31
+ case "Select":
32
+ InputUtils.setSearchInputValue(wait, label, value)
33
+ case _:
34
+ raise ValueError(f"Unsupported action for {type}: {action}")
35
+ case "Label":
36
+ match action:
37
+ case "Find":
38
+ LabelUtils.find(wait, label)
39
+ case _:
40
+ raise ValueError(f"Unsupported action for {type}: {action}")
41
+ case "Link":
42
+ match action:
43
+ case "Click":
44
+ LinkUtils.click(wait, label)
45
+ case _:
46
+ raise ValueError(f"Unsupported action for {type}: {action}")
47
+ case "Drop Down":
48
+ match action:
49
+ case "Select":
50
+ DropdownUtils.selectDropdownValue(wait, label, value)
51
+ case _:
52
+ raise ValueError(f"Unsupported action for {type}: {action}")
53
+ case "Search Drop Down":
54
+ match action:
55
+ case "Select":
56
+ DropdownUtils.selectSearchDropdownValue(wait, label, value)
57
+ case _:
58
+ raise ValueError(f"Unsupported action for {type}: {action}")
59
+ case "Button":
60
+ match action:
61
+ case "Click":
62
+ ComponentUtils.click_button(wait, label)
63
+ case _:
64
+ raise ValueError(f"Unsupported action for {type}: {action}")
65
+ case "Tab":
66
+ match action:
67
+ case "Find":
68
+ TabUtils.find_selected_tab(wait, label)
69
+ case _:
70
+ raise ValueError(f"Unsupported action for {type}: {action}")
71
+ case _:
72
+ raise ValueError(f"Unsupported component type: {type}")
@@ -0,0 +1,6 @@
1
+ class MyCustomError(Exception):
2
+ """A custom exception for specific error conditions."""
3
+
4
+ def __init__(self, message="This is a custom error!"):
5
+ self.message = message
6
+ super().__init__(self.message)
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: robo_appian
3
+ Version: 0.0.1
4
+ Summary: Automate your Appin code testing with Python. Boost quality, save time.
5
+ Home-page: https://github.com/dinilmithra/robo_appian.git
6
+ Author: Dinil Mithra
7
+ Author-email: dinilmithra@mailme@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: selenium>=4.34.0
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: requires-dist
22
+ Dynamic: requires-python
23
+ Dynamic: summary
24
+
25
+ # Robo Test suite for Appian framework
26
+ Robo Test suite for Appian framework
@@ -0,0 +1,25 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ robo_appian/__init__.py
6
+ robo_appian.egg-info/PKG-INFO
7
+ robo_appian.egg-info/SOURCES.txt
8
+ robo_appian.egg-info/dependency_links.txt
9
+ robo_appian.egg-info/requires.txt
10
+ robo_appian.egg-info/top_level.txt
11
+ robo_appian/utils/__init__.py
12
+ robo_appian/utils/components/ButtonUtils.py
13
+ robo_appian/utils/components/ComponentUtils.py
14
+ robo_appian/utils/components/DateUtils.py
15
+ robo_appian/utils/components/DropdownUtils.py
16
+ robo_appian/utils/components/InputUtils.py
17
+ robo_appian/utils/components/LabelUtils.py
18
+ robo_appian/utils/components/LinkUtils.py
19
+ robo_appian/utils/components/TabUtils.py
20
+ robo_appian/utils/components/TableUtils.py
21
+ robo_appian/utils/components/__init__.py
22
+ robo_appian/utils/controllers/ComponentDriver.py
23
+ robo_appian/utils/controllers/__init__.py
24
+ robo_appian/utils/exceptions/MyCustomError.py
25
+ robo_appian/utils/exceptions/__init__.py
@@ -0,0 +1 @@
1
+ selenium>=4.34.0
@@ -0,0 +1 @@
1
+ robo_appian
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='robo_appian',
5
+ version='0.0.1',
6
+ packages=find_packages(),
7
+ install_requires=[
8
+ 'selenium>=4.34.0'
9
+ ],
10
+ author='Dinil Mithra',
11
+ author_email='dinilmithra@mailme@gmail.com',
12
+ description='Automate your Appin code testing with Python. Boost quality, save time.',
13
+ long_description=open('README.md').read(),
14
+ long_description_content_type='text/markdown',
15
+ url='https://github.com/dinilmithra/robo_appian.git',
16
+ classifiers=[
17
+ 'Programming Language :: Python :: 3',
18
+ # 'License :: MIT License',
19
+ 'Operating System :: OS Independent',
20
+ ],
21
+ python_requires='>=3.12',
22
+ )