Skip to content

Commit

Permalink
Sync files from main repository
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions committed Nov 6, 2024
1 parent c833277 commit b2851c0
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 110 deletions.
4 changes: 2 additions & 2 deletions cognisim/device/android/android_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ async def stop_device(self):
Stops a test
'''
pass

async def capture_screenshot_with_bounding_box(self, bounds: dict, image_state: bytes = None) -> bytes:
"""
Capture a screenshot with a bounding box drawn around a specified element.
Expand Down Expand Up @@ -296,7 +297,7 @@ async def capture_screenshot_with_bounding_box(self, bounds: dict, image_state:
screenshot_with_bounding_box = encoded_image.tobytes()

return screenshot_with_bounding_box

def generate_set_of_mark(self,
ui,
image: bytes,
Expand Down Expand Up @@ -364,7 +365,6 @@ def generate_set_of_mark(self,

return img_bytes


async def start_device(self):
'''
Start the Android device and connect to the appium server
Expand Down
3 changes: 1 addition & 2 deletions cognisim/device/android/android_view_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import json
import re
import numpy as np
from loguru import logger
import attr
from str2bool import str2bool as strtobool
from enum import Enum
Expand Down Expand Up @@ -149,7 +148,7 @@ def _build_bounding_box(bounds):
"""
match = re.compile(r'\[(\d+),(\d+)\]\[(\d+),(\d+)\]').match(bounds)
assert match, f"Invalid bounds format: {bounds}"

x1, y1, x2, y2 = map(int, match.groups())
# logger.info(type(x1))
return BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)
Expand Down
58 changes: 27 additions & 31 deletions cognisim/device/ios/ios_device.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import base64
from datetime import datetime
from appium.webdriver.common.appiumby import AppiumBy
from cognisim.device.device import Device
from appium.options.ios import XCUITestOptions
from appium import webdriver
Expand All @@ -11,9 +14,7 @@
SCREEN_HEIGHT = 932

SCREEN_CHANNEL = 4
from appium.webdriver.common.appiumby import AppiumBy
from datetime import datetime
import base64


class IOSDevice(Device):
def __init__(self, app_package=None, download_directory='default', session_id=None):
Expand All @@ -33,7 +34,7 @@ def __init__(self, app_package=None, download_directory='default', session_id=No
}

self.options = XCUITestOptions().load_capabilities(self.desired_caps)

async def start_device(self):
'''
Start the IOS device and connect to the appium server
Expand All @@ -44,11 +45,12 @@ async def start_device(self):
self.desired_caps.pop('mjpegScreenshotUrl')
self.options = XCUITestOptions().load_capabilities(self.desired_caps)
self.driver = webdriver.Remote('http://localhost:4723', options=self.options)

self.driver.update_settings({'waitForIdleTimeout': 0, 'shouldWaitForQuiescence': False, 'maxTypingFrequency': 60})
async def mobile_get_source(self,format='json'):

async def mobile_get_source(self, format='json'):
return self.driver.execute_script('mobile: source', {'format': format, 'excludedAttributes': 'visible'})

async def start_recording(self):
'''
Start recording screen on the IOS device
Expand All @@ -66,7 +68,7 @@ async def stop_recording(self, save_path=None):
Args:
save_path (str, optional): Path to save the video file. If not provided, a default path will be used.
Returns:
str: Path to the saved video file
Expand All @@ -84,9 +86,7 @@ async def stop_recording(self, save_path=None):

logger.info(f"Screen recording saved to: {save_path}")
return save_path



async def get_state(self):
try:
raw_appium_state = await self.mobile_get_source()
Expand All @@ -104,21 +104,21 @@ async def get_state(self):
self.ui = ui
encoded_ui: str = ui.encoding()
logger.info(f"Encoded UI: {encoded_ui}")
screenshot:bytes = self.driver.get_screenshot_as_png()
screenshot: bytes = self.driver.get_screenshot_as_png()
return encoded_ui, screenshot, ui

def generate_set_of_mark(self,
ui,
image:bytes,
image: bytes,
position='top-left') -> bytes:
'''
Code to generate a set of mark for a given image and UI state
ui: UI object
ui: UI object
image: bytes of the image
step_i: step number
position: position of the annotation, defaults to 'top-lefts, can also be 'center
'''
nparr = np.frombuffer(image,np.uint8)
nparr = np.frombuffer(image, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
height, width, _ = img.shape
k = 3000
Expand All @@ -131,19 +131,19 @@ def generate_set_of_mark(self,
ui.elements[element_id].bounding_box.y2
]
# Calculate the area of the bounding box
area = (bounds[2]-bounds[0])*(bounds[3]-bounds[1])
area = (bounds[2] - bounds[0]) * (bounds[3] - bounds[1])

# Only label elements with area over k
# Only label elements with area over k
if area > k:
# Draw a rectangle around the element
cv2.rectangle(
img, (int(bounds[0]), int(bounds[1])),
(int(bounds[2]), int(bounds[3])), (0, 0, 255), 5)

text = str(element_id)
text_size = 2 # Fixed text size
text_size = 2 # Fixed text size
font = cv2.FONT_HERSHEY_SIMPLEX

# Calculate the width and height of the text
text_width, text_height = cv2.getTextSize(text, font, text_size, 2)[0]

Expand All @@ -154,28 +154,26 @@ def generate_set_of_mark(self,
text_x = (int(bounds[0]) + int(bounds[2])) // 2 - text_width // 2
text_y = (int(bounds[1]) + int(bounds[3])) // 2 + text_height // 2

# Draw a black rectangle behind the text
# Draw a black rectangle behind the text
cv2.rectangle(img, (text_x, text_y - text_height),
(text_x + text_width, text_y), (0, 0, 0), thickness=cv2.FILLED)

# Draw the text in white
cv2.putText(img, text, (text_x, text_y), font,
text_size, (255, 255, 255), 4)

_, img_encoded = cv2.imencode('.png', img)
img_bytes = img_encoded.tobytes()

return img_bytes



async def tap(self, x, y):
self.driver.execute_script('mobile: tap', {'x': x, 'y': y})

async def input(self, x, y, text):
self.driver.execute_script('mobile: tap', {'x': x, 'y': y})
self.driver.find_element(AppiumBy.IOS_PREDICATE, "type == 'XCUIElementTypeApplication'").send_keys(text)
#self.driver.execute_script('mobile: type', {'text': text})
# self.driver.execute_script('mobile: type', {'text': text})

async def swipe(self, x, y, direction):
# TODO: Implement swipe for iOS device
Expand All @@ -194,9 +192,9 @@ async def get_screenshot(self) -> bytes:
'''
Get Screenshot as bytes
'''
screenshot:bytes = self.driver.get_screenshot_as_png()
screenshot: bytes = self.driver.get_screenshot_as_png()
return screenshot

async def capture_screenshot_with_bounding_box(self, bounds: dict, image_state: bytes = None) -> bytes:
"""
Capture a screenshot with a bounding box drawn around a specified element.
Expand Down Expand Up @@ -238,20 +236,18 @@ async def capture_screenshot_with_bounding_box(self, bounds: dict, image_state:
screenshot_with_bounding_box = encoded_image.tobytes()

return screenshot_with_bounding_box


async def navigate(self, package_name:str):

async def navigate(self, package_name: str):
self.driver.activate_app(package_name)


async def stop_device(self):
'''
Stops the device
'''
pass


if __name__ == "__main__":
ui = UI(os.path.join(os.path.dirname(__file__), 'ios_view_hierarchy.xml'))
encoded_ui = ui.encoding()
logger.info(f"Encoded UI: {encoded_ui}")

Loading

0 comments on commit b2851c0

Please sign in to comment.