robot-appium-vision 0.1.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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Khajavali
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,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+
5
+ recursive-include Configurations *.ini
6
+ recursive-include Resources *.json *.png
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: robot-appium-vision
3
+ Version: 0.1.0
4
+ Summary: Robot Framework Appium keyword library with OCR and image-based actions
5
+ Author-email: Khajavali <dudekulakhaja786@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Khajavali
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/khaja786431/robot-appium-vision
29
+ Classifier: Programming Language :: Python :: 3
30
+ Classifier: Framework :: Robot Framework
31
+ Classifier: Topic :: Software Development :: Testing
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Requires-Python: >=3.10
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: robotframework
37
+ Requires-Dist: appium-python-client
38
+ Requires-Dist: selenium
39
+ Requires-Dist: opencv-python
40
+ Requires-Dist: pytesseract
41
+ Dynamic: license-file
42
+
43
+ # Robot Appium Vision Library
44
+
45
+ Advanced Robot Framework keyword library for Appium automation with:
46
+ - OCR-based text detection
47
+ - Image-based verification and clicking
48
+ - Coordinate tapping
49
+ - Safe scroll & swipe
50
+ - Android shell commands
51
+ - Screen recording with video embedding
52
+
53
+ ## Installation
54
+
55
+ pip install robot-appium-vision
56
+
57
+
58
+ ## Installation
59
+
60
+ *** Settings ***
61
+ Library AppiumKeywords
62
+
63
+ *** Test Cases ***
64
+ Verify Text
65
+ Verify Text Appium Full Settings Phone
66
+
67
+ ## OCR Setup (Windows)
68
+ set TESSERACT_CMD=C:\Program Files\Tesseract-OCR\tesseract.exe
69
+
70
+
71
+ ## Dependencies
72
+ - Appium Server
73
+ - Android device / emulator
74
+ - OpenCV
75
+ - Tesseract OCR
@@ -0,0 +1,33 @@
1
+ # Robot Appium Vision Library
2
+
3
+ Advanced Robot Framework keyword library for Appium automation with:
4
+ - OCR-based text detection
5
+ - Image-based verification and clicking
6
+ - Coordinate tapping
7
+ - Safe scroll & swipe
8
+ - Android shell commands
9
+ - Screen recording with video embedding
10
+
11
+ ## Installation
12
+
13
+ pip install robot-appium-vision
14
+
15
+
16
+ ## Installation
17
+
18
+ *** Settings ***
19
+ Library AppiumKeywords
20
+
21
+ *** Test Cases ***
22
+ Verify Text
23
+ Verify Text Appium Full Settings Phone
24
+
25
+ ## OCR Setup (Windows)
26
+ set TESSERACT_CMD=C:\Program Files\Tesseract-OCR\tesseract.exe
27
+
28
+
29
+ ## Dependencies
30
+ - Appium Server
31
+ - Android device / emulator
32
+ - OpenCV
33
+ - Tesseract OCR
@@ -0,0 +1,3 @@
1
+ from .keywords import AppiumKeywords
2
+
3
+ __all__ = ["AppiumKeywords"]
@@ -0,0 +1,515 @@
1
+ from appium import webdriver
2
+ from robot.api.deco import keyword
3
+ from appium.options.android import UiAutomator2Options
4
+ from robot.api import logger
5
+ from robot.libraries.BuiltIn import BuiltIn
6
+ from datetime import datetime
7
+ import subprocess
8
+ import configparser
9
+ import time
10
+ import os
11
+ import json
12
+ import cv2
13
+ import shutil
14
+ import importlib.util
15
+ import pytesseract
16
+
17
+
18
+ class AppiumKeywords:
19
+ """
20
+ Robot Framework keyword library for Android automation using Appium.
21
+
22
+ Capabilities:
23
+ - Multi-DUT Appium session management
24
+ - OCR-based text verification and tapping
25
+ - Image-based verification and clicking using OpenCV
26
+ - Coordinate-based tap actions
27
+ - Android shell command execution
28
+ - Safe swipe and scroll gestures
29
+ - Screen recording with embedded video reporting
30
+ """
31
+
32
+ def __init__(self):
33
+ """
34
+ Initializes keyword library.
35
+ - Loads DUT configuration from configurations.ini
36
+ - Initializes driver dictionary
37
+ """
38
+ self.drivers = {}
39
+
40
+ base_path = os.path.dirname(os.path.abspath(__file__))
41
+ ini_path = os.path.join(base_path, "..", "Configurations", "configurations.ini")
42
+
43
+ self.config = configparser.ConfigParser()
44
+ self.config.read(ini_path)
45
+
46
+ # Optional Tesseract override (recommended for PyPI users)
47
+ tesseract_cmd = os.getenv("TESSERACT_CMD")
48
+ if tesseract_cmd:
49
+ pytesseract.pytesseract.tesseract_cmd = tesseract_cmd
50
+
51
+ # Runtime dependency validation
52
+ self._check_runtime_dependencies()
53
+
54
+ # ---------------------------------------------------------------------
55
+ @keyword
56
+ def get_device_id(self, dut_name):
57
+ """
58
+ Returns DUT configuration section for the given DUT name.
59
+
60
+ Arguments:
61
+ - dut_name (str): Logical DUT name (Phone / Main / Cluster)
62
+
63
+ Returns:
64
+ - Config section containing device capabilities
65
+
66
+ Fails If:
67
+ - DUT section is not found
68
+ """
69
+ section = f"DUT.{dut_name}"
70
+ if section not in self.config:
71
+ raise Exception(f"DUT section '{section}' not found")
72
+ return self.config[section]
73
+
74
+ # ---------------------------------------------------------------------
75
+ @keyword
76
+ def start_appium_session(self, dut_name):
77
+ """
78
+ Starts or reuses an Appium session for the given DUT.
79
+
80
+ Maintains one Appium driver per DUT.
81
+
82
+ Arguments:
83
+ - dut_name (str): Logical DUT name
84
+
85
+ Returns:
86
+ - Appium WebDriver instance
87
+ """
88
+ if dut_name in self.drivers:
89
+ return self.drivers[dut_name]
90
+
91
+ caps = self.get_device_id(dut_name)
92
+ options = UiAutomator2Options().load_capabilities(caps)
93
+
94
+ driver = webdriver.Remote(
95
+ command_executor="http://127.0.0.1:4723",
96
+ options=options
97
+ )
98
+
99
+ self.drivers[dut_name] = driver
100
+ return driver
101
+
102
+ # ---------------------------------------------------------------------
103
+ @keyword
104
+ def stop_appium_session(self):
105
+ """
106
+ Stops all active Appium sessions.
107
+ """
108
+ for driver in self.drivers.values():
109
+ driver.quit()
110
+ self.drivers.clear()
111
+
112
+ # ---------------------------------------------------------------------
113
+ @keyword
114
+ def verify_text_appium_full(self, expected_text, dut_name):
115
+ """
116
+ Verifies that exact visible text is present on screen using Appium.
117
+
118
+ Arguments:
119
+ - expected_text (str): Exact text to verify
120
+ - dut_name (str): Logical DUT name
121
+
122
+ Returns:
123
+ - True if text is found
124
+
125
+ Fails If:
126
+ - Text is not present
127
+ """
128
+ driver = self.start_appium_session(dut_name)
129
+
130
+ elements = driver.find_elements(
131
+ by="xpath",
132
+ value="//*[normalize-space(@text) != '']"
133
+ )
134
+
135
+ visible_texts = [el.text.strip() for el in elements if el.text.strip()]
136
+
137
+ if expected_text in visible_texts:
138
+ logger.info(f"<b style='color:green'>Text verified:</b> {expected_text}", html=True)
139
+ return True
140
+
141
+ raise AssertionError(f"Exact text '{expected_text}' not found")
142
+
143
+ # ---------------------------------------------------------------------
144
+ @keyword
145
+ def tap_by_coordinates(self, json_name, key_name, dut_name):
146
+ """
147
+ Taps on screen using X,Y coordinates from a JSON file.
148
+
149
+ Arguments:
150
+ - json_name (str): JSON file name
151
+ - key_name (str): Key containing x,y values
152
+ - dut_name (str): Logical DUT name
153
+
154
+ Returns:
155
+ - Success message
156
+ """
157
+ driver = self.start_appium_session(dut_name)
158
+ project_root = BuiltIn().get_variable_value("${EXECDIR}")
159
+
160
+ json_file = os.path.join(project_root, "Resources", "Coordinates", json_name)
161
+ if not os.path.isfile(json_file):
162
+ raise AssertionError(f"JSON file not found: {json_file}")
163
+
164
+ with open(json_file) as f:
165
+ data = json.load(f)
166
+
167
+ if key_name not in data:
168
+ raise AssertionError(f"Key '{key_name}' not found")
169
+
170
+ x = int(data[key_name]["x"])
171
+ y = int(data[key_name]["y"])
172
+
173
+ driver.execute_script("mobile: clickGesture", {"x": x, "y": y})
174
+ return f"Tapped at ({x},{y}) on {dut_name}"
175
+
176
+ # ---------------------------------------------------------------------
177
+ @keyword
178
+ def tap_by_text(self, expected_text, dut_name):
179
+ """
180
+ Taps on visible text using OCR instead of UI hierarchy.
181
+
182
+ Arguments:
183
+ - expected_text (str): Text to tap
184
+ - dut_name (str): Logical DUT name
185
+
186
+ Returns:
187
+ - True if text is tapped
188
+
189
+ Fails If:
190
+ - Text not found via OCR
191
+ """
192
+ driver = self.start_appium_session(dut_name)
193
+ output_dir = BuiltIn().get_variable_value("${OUTPUTDIR}")
194
+ screenshot_path = os.path.join(output_dir, "ocr_screen.png")
195
+
196
+ driver.save_screenshot(screenshot_path)
197
+ img = cv2.imread(screenshot_path)
198
+
199
+ ocr_data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
200
+
201
+ for i, text in enumerate(ocr_data["text"]):
202
+ if text.strip() == expected_text:
203
+ x = ocr_data["left"][i]
204
+ y = ocr_data["top"][i]
205
+ w = ocr_data["width"][i]
206
+ h = ocr_data["height"][i]
207
+
208
+ driver.execute_script(
209
+ "mobile: clickGesture",
210
+ {"x": int(x + w / 2), "y": int(y + h / 2)}
211
+ )
212
+ return True
213
+
214
+ raise AssertionError(f"Text '{expected_text}' not found via OCR")
215
+
216
+ # ---------------------------------------------------------------------
217
+ @keyword
218
+ def verify_image_element(self, image_name, dut_name, threshold=0.9):
219
+ """
220
+ Verifies an image on screen using OpenCV template matching.
221
+
222
+ Arguments:
223
+ - image_name (str): Reference image
224
+ - dut_name (str): Logical DUT name
225
+ - threshold (float): Similarity threshold
226
+
227
+ Returns:
228
+ - True if image is matched
229
+ """
230
+ driver = self.start_appium_session(dut_name)
231
+ project_root = BuiltIn().get_variable_value("${EXECDIR}")
232
+ output_dir = BuiltIn().get_variable_value("${OUTPUTDIR}")
233
+
234
+ ref_img = cv2.imread(os.path.join(project_root, "Resources", "images", image_name))
235
+ screenshot_path = os.path.join(output_dir, f"verify_{time.time()}.png")
236
+ driver.save_screenshot(screenshot_path)
237
+
238
+ screen = cv2.imread(screenshot_path)
239
+ res = cv2.matchTemplate(
240
+ cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY),
241
+ cv2.cvtColor(ref_img, cv2.COLOR_BGR2GRAY),
242
+ cv2.TM_CCOEFF_NORMED
243
+ )
244
+
245
+ _, max_val, _, _ = cv2.minMaxLoc(res)
246
+ if max_val >= threshold:
247
+ return True
248
+
249
+ raise AssertionError(f"Image match failed: score={max_val:.3f}")
250
+
251
+ # ---------------------------------------------------------------------
252
+ @keyword
253
+ def click_by_image(self, image_name, dut_name, threshold=0.8):
254
+ """
255
+ Clicks on UI element using image recognition.
256
+
257
+ Arguments:
258
+ - image_name (str): Reference image
259
+ - dut_name (str): Logical DUT name
260
+ - threshold (float): Confidence threshold
261
+
262
+ Returns:
263
+ - Click success message
264
+ """
265
+ driver = self.start_appium_session(dut_name)
266
+ project_root = BuiltIn().get_variable_value("${EXECDIR}")
267
+ output_dir = BuiltIn().get_variable_value("${OUTPUTDIR}")
268
+
269
+ ref = cv2.imread(os.path.join(project_root, "Resources", "images", image_name))
270
+ screenshot = os.path.join(output_dir, f"click_{time.time()}.png")
271
+ driver.save_screenshot(screenshot)
272
+
273
+ screen = cv2.imread(screenshot)
274
+ res = cv2.matchTemplate(
275
+ cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY),
276
+ cv2.cvtColor(ref, cv2.COLOR_BGR2GRAY),
277
+ cv2.TM_CCOEFF_NORMED
278
+ )
279
+
280
+ _, max_val, _, max_loc = cv2.minMaxLoc(res)
281
+ if max_val < threshold:
282
+ raise AssertionError("Image not found")
283
+
284
+ h, w = ref.shape[:2]
285
+ x = max_loc[0] + w // 2
286
+ y = max_loc[1] + h // 2
287
+
288
+ driver.execute_script("mobile: clickGesture", {"x": x, "y": y})
289
+ return f"Clicked image at ({x},{y})"
290
+
291
+ # ---------------------------------------------------------------------
292
+ @keyword
293
+ def run_command(self, command, dut_name, timeout_ms=5000):
294
+ """
295
+ Executes Android shell command using Appium.
296
+
297
+ Arguments:
298
+ - command (str): Shell command
299
+ - dut_name (str): Logical DUT name
300
+ - timeout_ms (int): Timeout
301
+
302
+ Returns:
303
+ - Command output
304
+ """
305
+ driver = self.start_appium_session(dut_name)
306
+ parts = command.split()
307
+
308
+ result = driver.execute_script(
309
+ "mobile: shell",
310
+ {"command": parts[0], "args": parts[1:], "timeout": timeout_ms}
311
+ )
312
+
313
+ if isinstance(result, dict):
314
+ return result.get("stdout", "").strip()
315
+ return result.strip()
316
+
317
+ # ---------------------------------------------------------------------
318
+ @keyword
319
+ def press_key(self, keycode, dut_name):
320
+ """
321
+ Presses Android hardware/system key.
322
+
323
+ Arguments:
324
+ - keycode (int): Android keycode
325
+ - dut_name (str): Logical DUT name
326
+ """
327
+ driver = self.start_appium_session(dut_name)
328
+ driver.execute_script(
329
+ "mobile: shell",
330
+ {"command": "input", "args": ["keyevent", str(keycode)]}
331
+ )
332
+
333
+ # ---------------------------------------------------------------------
334
+ @keyword
335
+ def swipe_left_right(self, dut_name, direction="left", percent=0.9):
336
+ """
337
+ Performs safe horizontal swipe.
338
+
339
+ Arguments:
340
+ - dut_name (str): Logical DUT name
341
+ - direction (str): left / right
342
+ - percent (float): Swipe distance
343
+ """
344
+ driver = self.start_appium_session(dut_name)
345
+ size = driver.get_window_size()
346
+
347
+ driver.execute_script(
348
+ "mobile: scrollGesture",
349
+ {
350
+ "direction": direction,
351
+ "percent": percent,
352
+ "left": int(size["width"] * 0.1),
353
+ "top": int(size["height"] * 0.35),
354
+ "width": int(size["width"] * 0.8),
355
+ "height": int(size["height"] * 0.3),
356
+ }
357
+ )
358
+
359
+ # ---------------------------------------------------------------------
360
+ @keyword
361
+ def scroll_top_bottom(self, dut_name, direction="down", percent=0.9):
362
+ """
363
+ Performs safe vertical scroll.
364
+
365
+ Arguments:
366
+ - dut_name (str): Logical DUT name
367
+ - direction (str): up / down
368
+ - percent (float): Scroll distance
369
+ """
370
+ driver = self.start_appium_session(dut_name)
371
+ size = driver.get_window_size()
372
+
373
+ driver.execute_script(
374
+ "mobile: scrollGesture",
375
+ {
376
+ "direction": direction,
377
+ "percent": percent,
378
+ "left": int(size["width"] * 0.1),
379
+ "top": int(size["height"] * 0.15),
380
+ "width": int(size["width"] * 0.8),
381
+ "height": int(size["height"] * 0.7),
382
+ }
383
+ )
384
+
385
+ # ---------------------------------------------------------------------
386
+ @keyword
387
+ def start_screen_recording(self, dut_name, test_name):
388
+ """
389
+ Starts Android screen recording using adb.
390
+
391
+ Arguments:
392
+ - dut_name (str): Logical DUT name
393
+ - test_name (str): Test case name
394
+
395
+ Returns:
396
+ - Device video path
397
+ """
398
+ device_id = self.get_device_id(dut_name).get("device_id")
399
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
400
+ path = f"/sdcard/{device_id}_{timestamp}_{test_name}.mp4"
401
+
402
+ self._screen_proc = subprocess.Popen(
403
+ ["adb", "-s", device_id, "shell", "screenrecord", path],
404
+ stdout=subprocess.DEVNULL,
405
+ stderr=subprocess.DEVNULL
406
+ )
407
+
408
+ self._device_video_path = path
409
+ self._device_id = device_id
410
+ return path
411
+
412
+ # ---------------------------------------------------------------------
413
+ @keyword
414
+ def stop_screen_recording(self, dut_name, local_video_path):
415
+ """
416
+ Stops screen recording and pulls video to local system.
417
+
418
+ Arguments:
419
+ - dut_name (str): Logical DUT name
420
+ - local_video_path (str): Local save path
421
+
422
+ Returns:
423
+ - Local video path
424
+ """
425
+ if self._screen_proc:
426
+ self._screen_proc.terminate()
427
+ self._screen_proc.wait()
428
+
429
+ subprocess.run(
430
+ ["adb", "-s", self._device_id, "pull", self._device_video_path, local_video_path],
431
+ check=True
432
+ )
433
+ return local_video_path
434
+
435
+ # ---------------------------------------------------------------------
436
+ @keyword
437
+ def Test_Video(self, video_path, width=480, title="Screen Recording"):
438
+ """
439
+ Embeds video in Robot Framework HTML report.
440
+
441
+ Arguments:
442
+ - video_path (str): MP4 file path
443
+ - width (int): Video width
444
+ - title (str): Video title
445
+ """
446
+ if not os.path.exists(video_path):
447
+ logger.warn(f"Video not found: {video_path}")
448
+ return
449
+
450
+ html = f"""
451
+ <b>{title}</b><br>
452
+ <video width="{width}" controls>
453
+ <source src="{video_path}" type="video/mp4">
454
+ </video>
455
+ """
456
+ logger.info(html, html=True)
457
+
458
+
459
+ def _check_runtime_dependencies(self):
460
+ """
461
+ Performs runtime dependency checks.
462
+
463
+ - Verifies required Python packages
464
+ - Verifies optional system tools (adb, tesseract)
465
+ - Logs warnings instead of crashing where possible
466
+ """
467
+
468
+ # -------------------------------
469
+ # Required Python packages
470
+ # -------------------------------
471
+ required_packages = {
472
+ "robotframework": "robot",
473
+ "appium-python-client": "appium",
474
+ "selenium": "selenium",
475
+ "opencv-python": "cv2",
476
+ "pytesseract": "pytesseract",
477
+ }
478
+
479
+ for pkg_name, import_name in required_packages.items():
480
+ if importlib.util.find_spec(import_name) is None:
481
+ raise RuntimeError(
482
+ f"❌ Required dependency '{pkg_name}' is not installed.\n"
483
+ f"Install it using: pip install {pkg_name}"
484
+ )
485
+
486
+ logger.info("✅ All required Python dependencies are installed")
487
+
488
+ # -------------------------------
489
+ # adb check (required for shell & recording)
490
+ # -------------------------------
491
+ if shutil.which("adb") is None:
492
+ logger.warn(
493
+ "⚠️ adb not found in PATH.\n"
494
+ "Keywords using shell commands and screen recording may fail."
495
+ )
496
+ else:
497
+ logger.info("✅ adb detected")
498
+
499
+ # -------------------------------
500
+ # Tesseract OCR check (optional)
501
+ # -------------------------------
502
+ tesseract_path = (
503
+ os.getenv("TESSERACT_CMD")
504
+ or shutil.which("tesseract")
505
+ )
506
+
507
+ if not tesseract_path:
508
+ logger.warn(
509
+ "⚠️ Tesseract OCR not found.\n"
510
+ "OCR-based keywords (Tap By Text) will NOT work.\n"
511
+ "Install Tesseract and set TESSERACT_CMD environment variable."
512
+ )
513
+ else:
514
+ pytesseract.pytesseract.tesseract_cmd = tesseract_path
515
+ logger.info(f"✅ Tesseract OCR detected at: {tesseract_path}")
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.setuptools]
6
+ include-package-data = true
7
+
8
+ [project]
9
+ name = "robot-appium-vision"
10
+ version = "0.1.0"
11
+ description = "Robot Framework Appium keyword library with OCR and image-based actions"
12
+ authors = [
13
+ { name="Khajavali", email="dudekulakhaja786@gmail.com" }
14
+ ]
15
+ readme = "README.md"
16
+ license = { file="LICENSE" }
17
+ requires-python = ">=3.10"
18
+
19
+ dependencies = [
20
+ "robotframework",
21
+ "appium-python-client",
22
+ "selenium",
23
+ "opencv-python",
24
+ "pytesseract"
25
+ ]
26
+
27
+ classifiers = [
28
+ "Programming Language :: Python :: 3",
29
+ "Framework :: Robot Framework",
30
+ "Topic :: Software Development :: Testing",
31
+ "License :: OSI Approved :: MIT License"
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/khaja786431/robot-appium-vision"
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: robot-appium-vision
3
+ Version: 0.1.0
4
+ Summary: Robot Framework Appium keyword library with OCR and image-based actions
5
+ Author-email: Khajavali <dudekulakhaja786@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Khajavali
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/khaja786431/robot-appium-vision
29
+ Classifier: Programming Language :: Python :: 3
30
+ Classifier: Framework :: Robot Framework
31
+ Classifier: Topic :: Software Development :: Testing
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Requires-Python: >=3.10
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: robotframework
37
+ Requires-Dist: appium-python-client
38
+ Requires-Dist: selenium
39
+ Requires-Dist: opencv-python
40
+ Requires-Dist: pytesseract
41
+ Dynamic: license-file
42
+
43
+ # Robot Appium Vision Library
44
+
45
+ Advanced Robot Framework keyword library for Appium automation with:
46
+ - OCR-based text detection
47
+ - Image-based verification and clicking
48
+ - Coordinate tapping
49
+ - Safe scroll & swipe
50
+ - Android shell commands
51
+ - Screen recording with video embedding
52
+
53
+ ## Installation
54
+
55
+ pip install robot-appium-vision
56
+
57
+
58
+ ## Installation
59
+
60
+ *** Settings ***
61
+ Library AppiumKeywords
62
+
63
+ *** Test Cases ***
64
+ Verify Text
65
+ Verify Text Appium Full Settings Phone
66
+
67
+ ## OCR Setup (Windows)
68
+ set TESSERACT_CMD=C:\Program Files\Tesseract-OCR\tesseract.exe
69
+
70
+
71
+ ## Dependencies
72
+ - Appium Server
73
+ - Android device / emulator
74
+ - OpenCV
75
+ - Tesseract OCR
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ appium_vision/__init__.py
6
+ appium_vision/keywords.py
7
+ robot_appium_vision.egg-info/PKG-INFO
8
+ robot_appium_vision.egg-info/SOURCES.txt
9
+ robot_appium_vision.egg-info/dependency_links.txt
10
+ robot_appium_vision.egg-info/requires.txt
11
+ robot_appium_vision.egg-info/top_level.txt
@@ -0,0 +1,5 @@
1
+ robotframework
2
+ appium-python-client
3
+ selenium
4
+ opencv-python
5
+ pytesseract
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+