movoid-robotframework-selenium 1.0.0__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.
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.1
2
+ Name: movoid_robotframework_selenium
3
+ Version: 1.0.0
4
+ Home-page:
5
+ Author: movoid
6
+ Author-email: bobrobotsun@163.com
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: selenium
9
+ Requires-Dist: movoid_function
10
+ Requires-Dist: movoid_robotframework
11
+ Requires-Dist: robotframework_selenium2library
12
+ Requires-Dist: opencv-python
13
+
14
+ This is a simple program for developer to
@@ -0,0 +1 @@
1
+ This is a simple program for developer to
@@ -0,0 +1,13 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ # File : RobotFrameworkSelenium
5
+ # Author : Sun YiFan-Movoid
6
+ # Time : 2024/2/20 12:33
7
+ # Description :
8
+ """
9
+ from .main import RobotSeleniumBasic
10
+
11
+
12
+ class RobotFrameworkSelenium(RobotSeleniumBasic):
13
+ pass
@@ -0,0 +1,9 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ # File : __init__.py
5
+ # Author : Sun YiFan-Movoid
6
+ # Time : 2024/1/30 21:16
7
+ # Description :
8
+ """
9
+ from .main import RobotSeleniumBasic
@@ -0,0 +1,9 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ # File : __init__.py
5
+ # Author : Sun YiFan-Movoid
6
+ # Time : 2024/2/16 20:10
7
+ # Description :
8
+ """
9
+ from .action import SeleniumAction
@@ -0,0 +1,204 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ # File : basic
5
+ # Author : Sun YiFan-Movoid
6
+ # Time : 2024/2/16 20:12
7
+ # Description :
8
+ """
9
+
10
+ import os
11
+ import pathlib
12
+ import re
13
+ import time
14
+ from typing import List
15
+
16
+ from movoid_robotframework import robot_log_keyword, do_until_check, do_when_error
17
+ from movoid_robotframework.error import RfError
18
+ from selenium.webdriver import Keys
19
+ from selenium.webdriver.remote.webelement import WebElement
20
+
21
+ from ..common import BasicCommon
22
+
23
+
24
+ class SeleniumAction(BasicCommon):
25
+ def __init__(self):
26
+ super().__init__()
27
+ self._check_element_attribute_change_value = None
28
+
29
+ @robot_log_keyword
30
+ def selenium_take_full_screenshot(self, screenshot_name='python-screenshot.png'):
31
+ return self.selenium_take_screenshot(image_name=screenshot_name)
32
+
33
+ @robot_log_keyword
34
+ def selenium_click_element_with_offset(self, click_locator, x, y, operate='click'):
35
+ tar_element = self.selenium_analyse_element(click_locator)
36
+ self.action_chains.move_to_element_with_offset(tar_element, x, y)
37
+ if operate == 'click':
38
+ self.action_chains.click()
39
+ elif operate in ('double_click', 'doubleclick'):
40
+ self.action_chains.double_click()
41
+ self.action_chains.perform()
42
+
43
+ @robot_log_keyword
44
+ def selenium_check_element_attribute(self, check_locator, check_attribute='innerText', check_value='', check_regex=True, check_check_bool=True):
45
+ """
46
+ 检查所有元素中,是否存在一个属性满足要求的元素
47
+ :param check_locator: 元素定位
48
+ :param check_attribute: 属性名
49
+ :param check_value: 属性值
50
+ :param check_regex: 是否做正则匹配
51
+ :param check_check_bool: 要求满足条件还是不满足条件的
52
+ :return: 判定结果
53
+ """
54
+ tar_elements = self.selenium_find_elements_by_locator(check_locator)
55
+ tar_exist = False
56
+ for i_element, one_element in enumerate(tar_elements):
57
+ tar_value = one_element.get_attribute(check_attribute)
58
+ self.print(f'{check_attribute} of <{check_locator}>({i_element}) is:{tar_value}')
59
+ if check_regex:
60
+ check_result = bool(re.search(check_value, tar_value))
61
+ self.print(f'{check_result}: <{check_value}> in <{tar_value}>')
62
+ else:
63
+ check_result = check_value == tar_value
64
+ self.print(f'{check_result}: <{check_value}> == <{tar_value}>')
65
+ tar_exist = tar_exist or check_result == check_check_bool
66
+ self.print(f'check result is:{tar_exist}')
67
+ return tar_exist
68
+
69
+ @robot_log_keyword
70
+ def selenium_find_elements_with_attribute(self, find_locator, find_value='', find_attribute='innerText', find_regex=True, find_check_bool=True) -> List[WebElement]:
71
+ tar_elements = self.selenium_analyse_elements(find_locator)
72
+ find_elements = []
73
+ if find_attribute is None:
74
+ find_elements = tar_elements
75
+ self.print(f'find {len(find_elements)} elements only locator <{find_locator}>')
76
+ else:
77
+ self.print(f'find {len(tar_elements)} elements <{find_locator}> first')
78
+ for i_element, one_element in enumerate(tar_elements):
79
+ tar_value = one_element.get_attribute(find_attribute)
80
+ self.print(f'{find_attribute} of <{find_locator}>({i_element}) is:{tar_value}')
81
+ if find_regex:
82
+ check_result = bool(re.search(find_value, tar_value))
83
+ self.print(f'{check_result}: <{find_value}> in <{tar_value}>')
84
+ else:
85
+ check_result = find_value == tar_value
86
+ self.print(f'{check_result}: <{find_value}> == <{tar_value}>')
87
+ if check_result == find_check_bool:
88
+ find_elements.append(one_element)
89
+ self.print(f'find {len(find_elements)} elements <{find_locator}> <{find_attribute}> is <{find_value}>(regex={find_regex},check={find_check_bool})')
90
+ return find_elements
91
+
92
+ @robot_log_keyword
93
+ def selenium_find_element_with_attribute(self, find_locator, find_value='', find_attribute='innerText', find_regex=True, find_check_bool=True):
94
+ find_elements = self.selenium_find_elements_with_attribute(find_locator, find_value=find_value, find_attribute=find_attribute, find_regex=find_regex, find_check_bool=find_check_bool)
95
+ if len(find_elements) == 0:
96
+ raise RfError(f'fail to find <{find_locator}> with <{find_attribute}> is <{find_value}>(re={find_regex},bool={find_check_bool})')
97
+ return find_elements[0]
98
+
99
+ @robot_log_keyword
100
+ def selenium_get_locator_attribute(self, target_locator, target_attribute='innerText'):
101
+ tar_element = self.selenium_find_element_by_locator(target_locator)
102
+ return tar_element.get_attribute(target_attribute)
103
+
104
+ @robot_log_keyword
105
+ def selenium_new_screenshot_folder(self):
106
+ screen_path = self.get_robot_variable("Screenshot_path")
107
+ if screen_path:
108
+ screen_pathlib = pathlib.Path(screen_path)
109
+ if not screen_pathlib.exists():
110
+ os.mkdir(screen_path)
111
+ self.print('create dir : {}'.format(screen_path))
112
+
113
+ @robot_log_keyword
114
+ def selenium_delete_elements(self, delete_locator):
115
+ elements = self.selenium_find_elements_by_locator(delete_locator)
116
+ self.print(f'find {len(elements)} elements:{delete_locator}')
117
+ for one_element in elements:
118
+ self.selenium_execute_js_script('arguments[0].remove();', one_element)
119
+ self.print(f'delete all {len(elements)} elements:{delete_locator}')
120
+
121
+ @robot_log_keyword
122
+ def selenium_input_delete_all_and_input(self, input_locator, input_text):
123
+ input_element = self.selenium_analyse_element(input_locator)
124
+ self.print(f'try to input ({str(input_text)}) by ({input_text})')
125
+ input_text = str(input_text)
126
+ self.print(f'find element:{input_element.get_attribute("outerHTML")},')
127
+ now_str = input_element.get_attribute('value')
128
+ self.print(f'element has text({len(now_str)}):{now_str}')
129
+ for _ in now_str:
130
+ input_element.send_keys(Keys.BACK_SPACE)
131
+ for i in input_text:
132
+ input_element.send_keys(i)
133
+ time.sleep(0.01)
134
+ self.print(f'input {input_text} success')
135
+ self.selenium_wait_until_find_element_attribute(input_locator, input_text, 'value')
136
+
137
+ @robot_log_keyword
138
+ def selenium_check_contain_element(self, check_locator, check_exist=True):
139
+ find_elements = self.selenium_find_elements_by_locator(check_locator)
140
+ find_elements_bool = len(find_elements) > 0
141
+ self.print(f'we find {find_elements_bool}→{check_exist} {check_locator}')
142
+ return find_elements_bool == check_exist
143
+
144
+ @robot_log_keyword
145
+ def selenium_check_contain_elements(self, check_locator, check_count=1):
146
+ check_count = int(check_count)
147
+ find_elements = self.selenium_find_elements_by_locator(check_locator)
148
+ find_elements_num = len(find_elements)
149
+ self.print(f'we find {find_elements_num}→{check_count} {check_locator}')
150
+ return find_elements_num == check_count
151
+
152
+ @robot_log_keyword
153
+ def selenium_check_element_attribute_change_init(self, check_locator, check_attribute=''):
154
+ tar_element = self.selenium_find_element_by_locator(check_locator)
155
+ self._check_element_attribute_change_value = tar_element.get_attribute(check_attribute)
156
+ self.print(f'we find {check_attribute} of {check_locator} is {self._check_element_attribute_change_value}')
157
+ return False
158
+
159
+ @robot_log_keyword
160
+ def selenium_check_element_attribute_change_loop(self, check_locator, check_attribute=''):
161
+ tar_element = self.selenium_find_element_by_locator(check_locator)
162
+ temp_value = tar_element.get_attribute(check_attribute)
163
+ re_bool = self._check_element_attribute_change_value == temp_value
164
+ self.print(f'we find {check_attribute} of {check_locator} is {temp_value}{"==" if re_bool else "!="}{self._check_element_attribute_change_value}')
165
+ return re_bool
166
+
167
+ def always_true(self):
168
+ return True
169
+
170
+ @robot_log_keyword
171
+ @do_when_error(selenium_take_full_screenshot)
172
+ @do_until_check(selenium_click_element_with_offset, always_true)
173
+ def selenium_click_until_available(self):
174
+ pass
175
+
176
+ @robot_log_keyword
177
+ @do_when_error(selenium_take_full_screenshot)
178
+ @do_until_check(selenium_click_element_with_offset, selenium_check_contain_element)
179
+ def selenium_click_until_find_element(self):
180
+ pass
181
+
182
+ @robot_log_keyword
183
+ @do_when_error(selenium_take_full_screenshot)
184
+ @do_until_check(selenium_click_element_with_offset, selenium_check_contain_elements)
185
+ def selenium_click_until_find_elements(self):
186
+ pass
187
+
188
+ @robot_log_keyword
189
+ @do_when_error(selenium_take_full_screenshot)
190
+ @do_until_check(selenium_click_element_with_offset, selenium_find_element_with_attribute)
191
+ def selenium_click_until_find_element_attribute(self):
192
+ pass
193
+
194
+ @robot_log_keyword
195
+ @do_when_error(selenium_take_full_screenshot)
196
+ @do_until_check(always_true, selenium_find_element_with_attribute)
197
+ def selenium_wait_until_find_element_attribute(self):
198
+ pass
199
+
200
+ @robot_log_keyword
201
+ @do_when_error(selenium_take_full_screenshot)
202
+ @do_until_check(selenium_click_element_with_offset, selenium_check_element_attribute_change_loop, init_check_function=selenium_check_element_attribute_change_init)
203
+ def selenium_click_until_attribute_change(self):
204
+ pass
@@ -0,0 +1,150 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ # File : common
5
+ # Author : Sun YiFan-Movoid
6
+ # Time : 2024/2/16 18:47
7
+ # Description :
8
+ """
9
+ import math
10
+ import os
11
+ from typing import List, Tuple, Union
12
+
13
+ import cv2
14
+ import robot.libraries.BuiltIn
15
+ import selenium.webdriver.chrome.webdriver
16
+ from Selenium2Library import Selenium2Library
17
+ from movoid_robotframework.error import RfError
18
+ from selenium.webdriver import ActionChains
19
+ from selenium.webdriver.remote.webelement import WebElement
20
+ from movoid_robotframework import RobotBasic, robot_log_keyword
21
+
22
+
23
+ class BasicCommon(RobotBasic):
24
+ def __init__(self):
25
+ super().__init__()
26
+ self.built: robot.libraries.BuiltIn.BuiltIn = getattr(self, 'built', None)
27
+ self.selenium_lib: Selenium2Library = getattr(self, 'built', None)
28
+ self.driver: selenium.webdriver.chrome.webdriver.WebDriver = getattr(self, 'driver', None)
29
+ self.action_chains: ActionChains = getattr(self, 'action_chains', None)
30
+ self.screenshot_root: str = getattr(self, 'screenshot_root', None)
31
+ self.outer_coordinate: Tuple[float] = getattr(self, 'outer_coordinate', None)
32
+ self.inner_coordinate: Tuple[float] = getattr(self, 'inner_coordinate', None)
33
+ self.window_x: float = getattr(self, 'window_x', None)
34
+ self.window_y: float = getattr(self, 'window_y', None)
35
+
36
+ @robot_log_keyword
37
+ def selenium_init(self):
38
+ self.selenium_lib = self.built.get_library_instance('Selenium2Library')
39
+ self.driver = self.selenium_lib.driver
40
+ self.action_chains = ActionChains(self.driver)
41
+ self.screenshot_root = self.selenium_lib.screenshot_root_directory
42
+
43
+ @robot_log_keyword
44
+ def selenium_find_elements_by_locator(self, locator) -> List[WebElement]:
45
+ by, path = locator.split('=', 1)
46
+ return self.driver.find_elements(by, path)
47
+
48
+ @robot_log_keyword
49
+ def selenium_find_element_by_locator(self, locator) -> WebElement:
50
+ by, path = locator.split('=', 1)
51
+ return self.driver.find_element(by, path)
52
+
53
+ @robot_log_keyword
54
+ def selenium_execute_js_script(self, js_code: str, *args):
55
+ return self.driver.execute_script(js_code, *args)
56
+
57
+ @robot_log_keyword
58
+ def analyse_color_function(self, color_function):
59
+ re_func = None
60
+ if callable(color_function):
61
+ return color_function
62
+ elif isinstance(color_function, str):
63
+ if ',' in color_function:
64
+ re_func = self.exchange_list3_to_color_function(color_function.split(',', 2))
65
+ else:
66
+ raise RfError('you input [{}] to find a color function, but it is not in default_color_function'.format(color_function))
67
+ elif isinstance(color_function, list):
68
+ re_func = self.exchange_list3_to_color_function(color_function)
69
+ return re_func
70
+
71
+ @robot_log_keyword
72
+ def exchange_list3_to_color_function(self, formula_list):
73
+ return lambda r, g, b: eval('r' + formula_list[0]) and eval('g' + formula_list[1]) and eval('b' + formula_list[2])
74
+
75
+ @robot_log_keyword
76
+ def selenium_get_full_screenshot_path(self, screenshot_name):
77
+ suite = self.get_robot_variable('SUITE NAME').replace(' ', '_')
78
+ case_ori = self.get_robot_variable('TEST NAME')
79
+ folder_name = suite if case_ori is None else f"{suite}-{case_ori.replace(' ', '_')}"
80
+ full_folder_path = os.path.join(self.screenshot_root, folder_name)
81
+ if not os.path.exists(full_folder_path):
82
+ os.mkdir(full_folder_path)
83
+ self.print(f'create image folder:{folder_name}')
84
+ return os.path.join(full_folder_path, screenshot_name)
85
+
86
+ @robot_log_keyword
87
+ def selenium_cut_screenshot(self, screenshot_locator, image_name='element-cut-image.png'):
88
+ tar_name, tar_path = self.selenium_take_screenshot(None, image_name)
89
+ full_image = self.selenium_analyse_image(tar_name)
90
+ if screenshot_locator is None:
91
+ return full_image
92
+ else:
93
+ tar_element = self.selenium_analyse_element(screenshot_locator)
94
+ element_position = self.selenium_execute_js_script('return arguments[0].getBoundingClientRect();', tar_element)
95
+ self.print(element_position)
96
+ cut_rect = [math.floor(element_position['left']), math.floor(element_position['top']), math.floor(element_position['right']), math.floor(element_position['bottom'])]
97
+ cut_image = full_image[cut_rect[1]:cut_rect[3], cut_rect[0]:cut_rect[2]]
98
+ self.print(cut_image.shape)
99
+ tar_path_split = os.path.splitext(tar_path)
100
+ cv2.imwrite(tar_path_split[0] + '(cut)' + tar_path_split[1], cut_image)
101
+ return cut_image
102
+
103
+ @robot_log_keyword
104
+ def selenium_take_screenshot(self, screenshot_locator=None, image_name='python-screenshot.png', rename=True):
105
+ tar_name = image_name
106
+ ind = 1
107
+ tar_path = self.selenium_get_full_screenshot_path(tar_name)
108
+ while rename and os.path.isfile(tar_path):
109
+ ind += 1
110
+ name, post = os.path.splitext(image_name)
111
+ tar_name = f'{name}-{ind}{post}'
112
+ tar_path = self.selenium_get_full_screenshot_path(tar_name)
113
+ if screenshot_locator is None:
114
+ self.selenium_lib.capture_page_screenshot(tar_path)
115
+ self.print(f'take a full window screenshot:{tar_name}')
116
+ else:
117
+ self.selenium_lib.capture_element_screenshot(screenshot_locator, tar_path)
118
+ self.print(f'take a DOM({screenshot_locator}) screenshot:{tar_name}')
119
+ return tar_name, tar_path
120
+
121
+ @robot_log_keyword
122
+ def selenium_take_full_screenshot(self, screenshot_name='python-screenshot.png'):
123
+ return self.selenium_take_screenshot(image_name=screenshot_name)
124
+
125
+ @robot_log_keyword
126
+ def selenium_analyse_image(self, image):
127
+ if isinstance(image, str):
128
+ image_full_path = image if os.path.isfile(image) else self.selenium_get_full_screenshot_path(image)
129
+ self.print(f'try to read image:{image_full_path}')
130
+ return cv2.imread(image_full_path)
131
+ else:
132
+ return image
133
+
134
+ @robot_log_keyword
135
+ def selenium_analyse_element(self, locator: Union[WebElement, str]) -> WebElement:
136
+ if isinstance(locator, str):
137
+ return self.selenium_find_element_by_locator(locator)
138
+ elif isinstance(locator, list):
139
+ return locator[0]
140
+ else:
141
+ return locator
142
+
143
+ @robot_log_keyword
144
+ def selenium_analyse_elements(self, locator: Union[List[WebElement], str]) -> List[WebElement]:
145
+ if isinstance(locator, str):
146
+ return self.selenium_find_elements_by_locator(locator)
147
+ elif isinstance(locator, WebElement):
148
+ return [locator]
149
+ else:
150
+ return locator
@@ -0,0 +1,13 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ # File : main
5
+ # Author : Sun YiFan-Movoid
6
+ # Time : 2024/2/16 18:47
7
+ # Description :
8
+ """
9
+ from .action import SeleniumAction
10
+
11
+
12
+ class RobotSeleniumBasic(SeleniumAction):
13
+ pass
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.1
2
+ Name: movoid_robotframework_selenium
3
+ Version: 1.0.0
4
+ Home-page:
5
+ Author: movoid
6
+ Author-email: bobrobotsun@163.com
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: selenium
9
+ Requires-Dist: movoid_function
10
+ Requires-Dist: movoid_robotframework
11
+ Requires-Dist: robotframework_selenium2library
12
+ Requires-Dist: opencv-python
13
+
14
+ This is a simple program for developer to
@@ -0,0 +1,13 @@
1
+ README.md
2
+ setup.py
3
+ movoid_robotframework_selenium/RobotFrameworkSelenium.py
4
+ movoid_robotframework_selenium/__init__.py
5
+ movoid_robotframework_selenium/common.py
6
+ movoid_robotframework_selenium/main.py
7
+ movoid_robotframework_selenium.egg-info/PKG-INFO
8
+ movoid_robotframework_selenium.egg-info/SOURCES.txt
9
+ movoid_robotframework_selenium.egg-info/dependency_links.txt
10
+ movoid_robotframework_selenium.egg-info/requires.txt
11
+ movoid_robotframework_selenium.egg-info/top_level.txt
12
+ movoid_robotframework_selenium/action/__init__.py
13
+ movoid_robotframework_selenium/action/action.py
@@ -0,0 +1,5 @@
1
+ selenium
2
+ movoid_function
3
+ movoid_robotframework
4
+ robotframework_selenium2library
5
+ opencv-python
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,23 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding='utf-8') as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name='movoid_robotframework_selenium',
8
+ version='1.0.0',
9
+ packages=find_packages(),
10
+ url='',
11
+ license='',
12
+ author='movoid',
13
+ author_email='bobrobotsun@163.com',
14
+ description='',
15
+ long_description=long_description,
16
+ long_description_content_type="text/markdown",
17
+ install_requires=['selenium',
18
+ 'movoid_function',
19
+ 'movoid_robotframework',
20
+ 'robotframework_selenium2library',
21
+ 'opencv-python',
22
+ ],
23
+ )