def __init__(self): self.playback = None self.recorder = None self.log = Logger('RPTool') self.fileManager = FileManager() self.file = '' self.alert = Alert('RPTool') self.api = TestlinkAPI() self.setting = Settings('testlink.cfg') self.testFolder = 'artifacts'
def __init__(self, cam_id=0, on_guard=False): super().__init__() self.font = cv2.FONT_HERSHEY_SIMPLEX self.on_guard = on_guard #cam and dimentions self.cam_id = cam_id self.cam = None self.frame1 = None self.frame2 = None self.RELEASE_CAM = False self._ALERT = Alert() self._RECORD = Record()
def __init__(self, file_manager): self.file = '' self.fileManager = file_manager self.log = Logger('Recorder') self.mouseListener = MouseListener(on_click=self.onClick, on_scroll=self.onScroll, on_move=self.onMove) self.keyboardListener = KeyboardListener(on_press=self.onPress, on_release=self.onRelease) self.clock = Clock() self.alert = Alert('RPTool - Recording') self.drag_start = (0, 0) self.drag_end = (0, 0) self.verifier = Verifier() self.pauseTrace = False
def __init__(self, file_manager): self.fileManager = file_manager self.log = Logger('PlayBack') self.traces = [] self.hostKeys = [] self.keyboardListener = KeyboardListener(on_press=self.onPress, on_release=self.onRelease) self.stopped = False self.interval = 0 self.file = '' self.alert = Alert('RPTool - Playback') self.setting = Settings('rptool.cfg') self.verifier = Verifier()
def createAlert(options): ''' Crea una alerta con logs ''' try: Alert(options, db) except KeyboardInterrupt: db.close()
class Verifier: def __init__(self): self.checkPointIndex = 0 self.alert = Alert('Verifier') self.setting = Settings('testlink.cfg') self.config = self.setting.readConfig() self.api = TestlinkAPI() def printScreen(self, filename): """ Key F2 pressed should capture the selected area on screen """ print('check {0}'.format(filename)) filename = '{0}_{1}.png'.format(filename, self.checkPointIndex) print('Saved as {}'.format(filename)) subprocess.run(['scrot', '-s -d 2', filename]) self.checkPointIndex += 1 return filename def check(self, checkpoint): """ Check if the checkpoint image is visible on screen """ checked = pyautogui.locateOnScreen(checkpoint) if checked: self.alert.notify('checked Ok') self.report(checkpoint, 'p') else: self.alert.notify('checked Fail') self.report(checkpoint, 'f') def report(self, checkpoint, status): """ Sends the test result to Testlink """ identifier = checkpoint.split('/')[-1] test = identifier.split('_')[0] plan = self.config['plan_id'] build = self.config['build_name'] notes = '...' user = self.config['username'] platform = self.config['platform_id'] try: self.api.reportTCResult(None, plan, build, status, notes, user, platform, test) print('reporting ... ', test) except TLResponseError as err: print('error: ', err)
class Camera: def __init__(self, cam_id=0, on_guard=False): super().__init__() self.font = cv2.FONT_HERSHEY_SIMPLEX self.on_guard = on_guard #cam and dimentions self.cam_id = cam_id self.cam = None self.frame1 = None self.frame2 = None self.RELEASE_CAM = False self._ALERT = Alert() self._RECORD = Record() #initialize def initialize(self): self.settings_camera = get_settings_camera() self.RELEASE_CAM = False if self.cam and self.cam.isOpened(): return elif self.cam: self.clear() self._put_cam_video() def _put_cam_video(self): self.cam = cv2.VideoCapture(self.cam_id) fheight = int(self.cam.get(3)) fwidth = int(self.cam.get(4)) self.cam.set(3, fheight) self.cam.set(4, fwidth) self._RECORD.set_dimentions(fheight, fwidth) def _get_frame_gray(self, frame1, frame2): # Difference between frame1(image) and frame2(image) diff = cv2.absdiff(frame1, frame2) # Converting color image to gray_scale image gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) return gray def _get_frame_diff(self, frame1, frame2): # Difference between frame1(image) and frame2(image) diff = cv2.absdiff(frame1, frame2) # Converting color image to gray_scale image gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) # Converting gray scale image to GaussianBlur, so that change can be find easily blur = cv2.GaussianBlur(gray, (5, 5), 0) # If pixel value is greater than 20, it is assigned white(255) otherwise black _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY) return thresh def _get_contours(self, frame1, frame2): # Difference between frame1(image) and frame2(image) diff = cv2.absdiff(frame1, frame2) # Converting color image to gray_scale image gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) # Converting gray scale image to GaussianBlur, so that change can be find easily blur = cv2.GaussianBlur(gray, (5, 5), 0) # If pixel value is greater than 20, it is assigned white(255) otherwise black _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY) dilated = cv2.dilate(thresh, None, iterations=4) # finding contours of moving object contours, hirarchy = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) return contours, hirarchy def get_frame_gray(self): if self.frame1 is None: _, self.frame1 = self.cam.read() elif self.frame2 is None: _, self.frame1 = self.cam.read() else: self.frame1 = self.frame2 ret, self.frame2 = self.cam.read() contours, hirarchy = self._get_contours(self.frame1, self.frame2) is_mov = False # making rectangle around moving object for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) referenceArea = self._is_object(contour) if referenceArea is None: continue is_mov = True break frame = self._get_frame_gray(self.frame1, self.frame2) self._process_mov(4, is_mov, ret, frame) return frame def get_frame_diff(self): if self.frame1 is None: _, self.frame1 = self.cam.read() elif self.frame2 is None: _, self.frame1 = self.cam.read() else: self.frame1 = self.frame2 ret, self.frame2 = self.cam.read() contours, hirarchy = self._get_contours(self.frame1, self.frame2) is_mov = False # making rectangle around moving object for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) referenceArea = self._is_object(contour) if referenceArea is None: continue is_mov = True break frame = self._get_frame_diff(self.frame1, self.frame2) self._process_mov(3, is_mov, ret, frame) return frame def get_frame_normal(self): if self.frame1 is None: _, self.frame1 = self.cam.read() elif self.frame2 is None: _, self.frame1 = self.cam.read() else: self.frame1 = self.frame2 frame = cv2.flip(self.frame1, 180) ret, self.frame2 = self.cam.read() contours, hirarchy = self._get_contours(self.frame1, self.frame2) is_mov = False # making rectangle around moving object for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) referenceArea = self._is_object(contour) if referenceArea is None: continue is_mov = True break self._process_mov(1, is_mov, ret, frame) return frame def get_frame_mov(self): if self.frame1 is None: _, self.frame1 = self.cam.read() elif self.frame2 is None: _, self.frame1 = self.cam.read() else: self.frame1 = self.frame2 ret, self.frame2 = self.cam.read() contours, hirarchy = self._get_contours(self.frame1, self.frame2) is_mov = False # making rectangle around moving object for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) referenceArea = self._is_object(contour) if referenceArea is None: continue self._draw(self.frame1, x, y, w, h, "movimiento") is_mov = True self._process_mov(2, is_mov, ret, self.frame1) return self.frame1 def _draw(self, frame, x, y, w, h, text): cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.putText(frame, text, (x + 5, y - 5), self.font, 1, (255, 255, 255), 2) def _is_object(self, contour): referenceArea = cv2.contourArea(contour) if referenceArea < int(self.settings_camera["MIN_AREA_OBJECT"]): return None return referenceArea def _process_mov(self, type_cam, is_mov, ret, frame): item = { "type_cam": type_cam, "is_mov": is_mov, "ret": ret, "frame": frame } self._RECORD.put_nowait(item) if is_mov == True: if int(self.settings_camera["ON_GUARD"]) == 1: item = {"message": "Se ha detectado un movimiento."} self._ALERT.put_nowait(item=item) def get_stream(self, type_cam=1): if type_cam == 3: frame = self.get_frame_diff() ret, frame_jpeg = cv2.imencode('.jpg', frame) return frame_jpeg elif type_cam == 4: frame = self.get_frame_gray() ret, frame_jpeg = cv2.imencode('.jpg', frame) return frame_jpeg elif type_cam == 2: frame = self.get_frame_mov() ret, frame_jpeg = cv2.imencode('.jpg', frame) return frame_jpeg else: frame = self.get_frame_normal() ret, frame_jpeg = cv2.imencode('.jpg', frame) return frame_jpeg def generated_stream(self, type_cam=1): self.initialize() while self.cam.isOpened(): frame_jpeg = self.get_stream(type_cam=type_cam) if self.RELEASE_CAM == True or self.RELEASE_CAM is None: break else: yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame_jpeg.tobytes() + b'\r\n\r\n') def clear(self): try: self.frame1 = None self.frame2 = None if self.cam: self.cam.release() except Exception as e: print(e) def release(self, with_threading=False, window=False): try: self.RELEASE_CAM = True time.sleep(0.9) self.frame1 = None self.frame2 = None if self.cam: self.cam.release() if with_threading: self.cam.stop() if window: cv2.destroyAllWindows() self._RECORD.release() except Exception as e: print(e) def __del__(self): try: self.RELEASE_CAM = None time.sleep(0.9) self.frame1 = None self.frame2 = None if self.cam: self.cam.release() self._RECORD.release() self._RECORD = None self._ALERT = None cv2.destroyAllWindows() except Exception as e: print(e)
class Recorder: def __init__(self, file_manager): self.file = '' self.fileManager = file_manager self.log = Logger('Recorder') self.mouseListener = MouseListener(on_click=self.onClick, on_scroll=self.onScroll, on_move=self.onMove) self.keyboardListener = KeyboardListener(on_press=self.onPress, on_release=self.onRelease) self.clock = Clock() self.alert = Alert('RPTool - Recording') self.drag_start = (0, 0) self.drag_end = (0, 0) self.verifier = Verifier() self.pauseTrace = False def save(self, trace): self.fileManager.write(self.file, trace) def onClick(self, *args): self.clock.start() print('click: {}'.format(args)) pressed = args[3] if pressed: self.drag_start = (args[0], args[1]) if not self.pauseTrace: trace = 'click x={}, y={}, time={}\n'.format(args[0], args[1], self.clock.getTime()) self.alert.notify(trace) self.save(trace) else: self.drag_end = (args[0], args[1]) if self.drag_start != self.drag_end: x1, y1 = self.drag_start x2, y2 = self.drag_end # Ignore drag while is paused for a print screen! if not self.pauseTrace: trace = 'drag x1={0}, y1={1}, x2={2}, y2={3}\n'.format(x1, y1, x2, y2) self.alert.notify(trace) self.save(trace) else: pass def onScroll(self, *args): dx, dy = args[2], args[3] trace = 'scroll dx={0}, dy={1}\n'.format(dx, dy) self.save(trace) def onMove(self, *args): pass # x, y # self.save('move {}\n'.format(args)) def onPress(self, *args): # key if not self.pauseTrace: # Exclude the keys used as commands by the tool. if args[0] not in [Key.f2, Key.f6, Key.f7]: trace = 'press key={}\n'.format(args[0]) self.alert.notify(trace) self.save(trace) else: pass def onRelease(self, *args): # Stop recording when press 'esc' if args[0] == Key.esc: self.stop() self.log.debug('[ESC] Stop recording!') self.alert.notify('[ESC] Stop recording!') return False if args[0] == Key.f2: self.pauseTrace = True self.alert.notify('[F2] Select a region!') checkpoint = self.verifier.printScreen(self.file) trace = 'checkpoint {}\n'.format(checkpoint) self.save(trace) self.pauseTrace = False if args[0] == Key.f4: self.pauseTrace = True self.alert.notify('[F4] Select a region!') location_point = self.verifier.printScreen(self.file) trace = 'find_and_click {}\n'.format(location_point) self.save(trace) self.pauseTrace = False if args[0] == Key.f6: self.alert.notify('[F6] Pause started!') self.pauseTrace = True if args[0] == Key.f7: self.alert.notify('[F7] Pause stopped!') self.pauseTrace = False def start(self, file): self.file = file self.mouseListener.start() self.keyboardListener.start() self.log.debug('start recording') def stop(self): self.mouseListener.stop() self.keyboardListener.stop() self.log.debug('stop recording')
class PlayBack: def __init__(self, file_manager): self.fileManager = file_manager self.log = Logger('PlayBack') self.traces = [] self.hostKeys = [] self.keyboardListener = KeyboardListener(on_press=self.onPress, on_release=self.onRelease) self.stopped = False self.interval = 0 self.file = '' self.alert = Alert('RPTool - Playback') self.setting = Settings('rptool.cfg') self.verifier = Verifier() def onPress(self, *args): pass def onRelease(self, *args): # Stop recording when press 'esc' if args[0] == Key.esc: self.keyboardListener.stop() self.stopped = True self.alert.notify('[ESC] Playback stopped') return False # Stop the loop execution if args[0] == Key.f3: self.alert.notify('[F3] Loop stopped') self.setting.saveConfig({'loop': '0'}) def traceBack(self): for trace in self.traces: if not self.stopped: if trace.getType() == 'click': self.click(trace) elif trace.getType() == 'press': self.press(trace) elif trace.getType() == 'scroll': self.scroll(trace) elif trace.getType() == 'drag': self.drag(trace) elif trace.getType() == 'checkpoint': self.checkpoint(trace) elif trace.getType() == 'find_and_click': print('type find and click') self.findAndClick(trace) else: pass else: print('Stopped playback') return def findAndClick(self, trace): try: self.alert.notify('wating finding image') location = pyautogui.locateOnScreen(trace.getImage()) pyautogui.click(location) except: self.alert.notify('Image not found') def checkpoint(self, trace): self.verifier.check(trace.getCheckPoint()) def drag(self, trace): x, y = trace.getDrag() pyautogui.dragTo(x, y, 1, button='left') # TODO :: Need work here to Fix ALT+TAB ... def checkAltTab(self): if len(self.hostKeys) > 2: pyautogui.hotkey(self.hostKeys[0], self.hostKeys[1]) self.hostKeys = self.hostKeys[2:] def press(self, trace): if trace.isHotKey(): # TODO :: Need work here to Fix ALT+TAB ... self.hostKeys.append(trace.getKey()) self.checkAltTab() else: if len(self.hostKeys) > 0: self.hostKeys.append(trace.getKey()) print(self.hostKeys) if len(self.hostKeys) == 2: pyautogui.hotkey(self.hostKeys[0], self.hostKeys[1]) if len(self.hostKeys) == 3: pyautogui.hotkey(self.hostKeys[0], self.hostKeys[1], self.hostKeys[2]) self.hostKeys = [] else: key = trace.getKey() if key in ['space', 'backspace', 'enter', 'caps_lock', 'esc']: pyautogui.press(key) else: pyautogui.typewrite(key, 0.1) def click(self, trace): pyautogui.moveTo(trace.getX(), trace.getY(), trace.getTime()) pyautogui.click() def scroll(self, trace): pyautogui.scroll(trace.getDY()) def play(self, file): self.keyboardListener.start() self.traceReader(file) self.traceBack() def traceReader(self, file): try: with open(file) as traces: for rawTrace in traces: trace = Trace(rawTrace) self.traces.append(trace) except FileNotFoundError as err: self.log.debug('Error {}'.format(err))
def __init__(self): self.checkPointIndex = 0 self.alert = Alert('Verifier') self.setting = Settings('testlink.cfg') self.config = self.setting.readConfig() self.api = TestlinkAPI()
class RPTool: def __init__(self): self.playback = None self.recorder = None self.log = Logger('RPTool') self.fileManager = FileManager() self.file = '' self.alert = Alert('RPTool') self.api = TestlinkAPI() self.setting = Settings('testlink.cfg') self.testFolder = 'artifacts' def getTestFolder(self): return '{0}/{1}'.format(self.fileManager.getCurrentFolder(), self.testFolder) def getTestFiles(self): return self.fileManager.list(self.getTestFolder()) def rec(self, test_name): self.alert.notify('Recording {} ...'.format(test_name)) self.recorder = Recorder(self.fileManager) self.log.debug('recording \'{0}\'...'.format(test_name)) self.saveTestFile(test_name) self.recorder.start(self.file) def delete(self, test_name): self.log.debug('deleting \'{0}\'...'.format(test_name)) self.fileManager.delete(self.getFullFileName(test_name)) self.alert.notify('Deleting {} ...'.format(test_name)) def play(self, test_name): self.alert.notify('Playback {0}'.format(test_name)) self.playback = PlayBack(self.fileManager) self.log.debug('playback \'{0}\'...'.format(test_name)) self.playback.play(self.getFullFileName(test_name)) def saveTestFile(self, test_name): self.file = self.getFullFileName(test_name) self.fileManager.write(self.file, '') self.log.debug('saving test file {0}'.format(self.file)) def getFullFileName(self, test_name): return '{0}/{1}'.format(self.getTestFolder(), test_name) def notifyLoop(self, time): self.alert.notify('Loop enabled to repeat in {} s'.format(time)) def getUsername(self): return self.api.getUsername() def getApiKey(self): return self.api.getApiKey() def getUrl(self): return self.api.getUrl() def getProjects(self): return self.api.getProjects() def getPlans(self, project_id): return self.api.getPlans(project_id) def getPlatforms(self, project_id): platforms = [] map = self.api.getPlatforms(project_id) for key in map: platforms.append(map[key]) return platforms def getBuilds(self, plan_id): return self.api.getBuilds(plan_id) def saveConfig(self, config): print('saving config', config) self.setting.saveConfig(config) def getConfig(self): cfg = self.setting.readConfig() if cfg is None: return {} else: return cfg