def test_recorder_performance(self): """ Tests the performance of the recorder to find a unique path """ recorder = Recorder() os.system('calc.exe') str_num = [ "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" ] with Region( "Calculator||Window->Calculator||Window->||Group->Number pad||Group" ): move("Zero||Button", duration=0) startTime = time.time() with Region( "Calculator||Window->Calculator||Window->||Group->Number pad||Group" ): for i in range(9): for num in str_num: move(num + "||Button", duration=0) wait_recorder_ready(recorder, num + "||Button", sleep=0) duration = time.time() - startTime with Region("Calculator||Window->Calculator||Window"): move("Close Calculator||Button", duration=0) wait_recorder_ready(recorder, "Close Calculator||Button") left_click("Close Calculator||Button") recorder.quit() assert duration < 37, "The duration of the loop is " + str( duration) + " s. It must be lower than 37 s"
def test_recorder_performance(start_kill_app, wait_recorder_ready): """ Tests the performance to find a unique path. """ recorder = Recorder() str_num = [ "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" ] move("Calculator||Window->*->Zero||Button", duration=0) start_time = time.time() with UIPath("Calculator||Window->*"): for _ in range(9): for num in str_num: move(num + "||Button", duration=0) wait_recorder_ready(recorder, num + "||Button", sleep=0) duration = time.time() - start_time recorder.quit() assert duration < 30, "The duration of the loop is " + str( duration) + " s. It must be lower than 30 s"
class TestMouseMethods(unittest.TestCase): def setUp(self): """Set some data and ensure the application is in the state we want""" self.app = pywinauto.Application() self.app.start("mspaint.exe") self.recorder = Recorder() self.recorder.start_recording() def tearDown(self): self.recorder.stop_recording() time.sleep(0.5) self.app.kill() @unittest.skip("This test is broken") def test_mouse_move(self): with Window(u"Sans titre - Paint||Window"): wrapper = find(u"||Pane->||Pane") wrapper.draw_outline() time.sleep(0.5) for i in range(20): x0 = random.randint(wrapper.rectangle().left, wrapper.rectangle().right) y0 = random.randint(wrapper.rectangle().top, wrapper.rectangle().bottom) move((x0, y0)) x, y = win32api.GetCursorPos() print("0 " + str(x) + " " + str(y)) self.assertEqual(x0, x) self.assertEqual(y0, y) send_keys("{VK_CONTROL down}""{VK_SHIFT down}""f""{VK_SHIFT up}""{VK_CONTROL up}", vk_packet=False) time.sleep(0.5) code = pyperclip.paste() words = code.split("%(") words = words[1].split(')"') with Window(u"Sans titre - Paint||Window"): move(u"||Pane->||Pane%(" + words[0] + ")", duration=0) x, y = win32api.GetCursorPos() print("1 " + str(x) + " " + str(y)) self.assertEqual(x0, x) self.assertEqual(y0, y)
def test_recorder_menu_click(start_kill_app, wait_recorder_ready): recorder = Recorder() recorder.process_menu_click_mode = True recorder.start_recording() with UIPath("Untitled - Notepad||Window"): for i in range(3): w = move("*->View||MenuItem", duration=0) wait_recorder_ready(recorder, "View||MenuItem", sleep=0) click(w, duration=0) time.sleep(0.5) # wait for the menu to open (it is not always instantaneous depending on the animation settings) w = move("*->Zoom||MenuItem", duration=0) wait_recorder_ready(recorder, "Zoom||MenuItem", sleep=0) click(w, duration=0) time.sleep(0.5) # wait for the menu to open (it is not always instantaneous depending on the animation settings) w = move("*->Zoom in||MenuItem", duration=0) wait_recorder_ready(recorder, "Zoom in||MenuItem", sleep=0) click(w, duration=0) time.sleep(0.5) # wait for the menu to open (it is not always instantaneous depending on the animation settings) zoom_text = find("*->Zoom||Text") regex = r"\' \d+%\'" re_percentage_zoom = re.findall(regex, str(zoom_text.window_text)) assert len(re_percentage_zoom) == 1 percentage_zoom = int(re_percentage_zoom[0][2:-2]) assert percentage_zoom == 100 + (i+1)*10 recorded_python_script = recorder.stop_recording() playback(filename=recorded_python_script) os.remove(recorded_python_script) with UIPath("Untitled - Notepad||Window"): zoom_text = find("*->Zoom||Text") regex = r"\' \d+%\'" re_percentage_zoom = re.findall(regex, str(zoom_text.window_text)) assert len(re_percentage_zoom) == 1 percentage_zoom = int(re_percentage_zoom[0][2:-2]) assert percentage_zoom == 100 + (i+1)*2*10 recorder.quit()
def test_mouse_move(self): """ Tests the precision of the relative coordinates in an element""" with Window("Untitled - Paint||Window"): find().set_focus() left_click( "*->||Custom->Home||Custom->Image||ToolBar->Resize||Button") with Region("Resize and Skew||Window"): left_click("Pixels||RadioButton") left_click("Resize Horizontal||Edit") set_text("Resize Horizontal||Edit", "1900") left_click( "*->||Custom->Home||Custom->Tools||ToolBar->Pencil||Button") send_keys("{VK_LWIN down}" "{VK_UP}" "{VK_LWIN up}") wrapper = move("||Pane->Using Pencil tool on Canvas||Pane") time.sleep(1) recorder = Recorder() recorder.relative_coordinate_mode = True recorder.start_recording() time.sleep(2.0) for i in range(9): win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0) x0 = random.randint(wrapper.rectangle().left + 22, wrapper.rectangle().right - 22) y0 = random.randint(wrapper.rectangle().top + 22, wrapper.rectangle().bottom - 22) move((x0, y0), duration=0.05) x, y = win32api.GetCursorPos() assert (x0, y0) == (x, y) send_keys( "{VK_CONTROL down}" "{VK_SHIFT down}" "f" "{VK_SHIFT up}" "{VK_CONTROL up}", vk_packet=False) #time.sleep(0.5) code = pyperclip.paste() words = code.split("%(") words = words[1].split(')"') with Window(u"Untitled - Paint||Window"): move(u"||Pane->Using Pencil tool on Canvas||Pane%(" + words[0] + ")", duration=0) x, y = win32api.GetCursorPos() assert (x0, y0) == (x, y) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0) time.sleep(0.5) # This pause is mandatory for the recorder recorded_file = recorder.stop_recording() recorder.quit() #time.sleep(5.5) # The thickness is set to 3px with Window(u"Untitled - Paint||Window"): left_click( "UIRibbonDockTop||Pane->Ribbon||Pane->Ribbon||Pane->||Pane->Ribbon||Pane->Lower Ribbon||Pane->||Custom->Home||Custom->||ToolBar->Size||SplitButton" ) with Region( u"||Pane->Size||Window->Size||List->||Custom->||Group"): left_click(u"3px||ListItem") # Now the lines are overed in white using the previously recorded drag and drops with Window("Untitled - Paint||Window"): with Region( "UIRibbonDockTop||Pane->Ribbon||Pane->Ribbon||Pane->||Pane->Ribbon||Pane" ): left_click( "Lower Ribbon||Pane->||Custom->Home||Custom->Colors||ToolBar->||Group%(-95,0)" ) data = "" with open(recorded_file) as fp: for line in fp: if not (("send_keys" in line) or ("wrapper" in line)): data = data + line print(data) with open(recorded_file, "w") as text_file: print(data, file=text_file) compiled_code = compile(data, '<string>', 'exec') eval(compiled_code) #os.remove(recorded_file) send_keys("{VK_CONTROL down}" "s" "{VK_CONTROL up}") recorded_image = str(recorded_file).replace('.py', '.png') send_keys(recorded_image, pause=0) send_keys("{ENTER}") time.sleep(2) percentage = percentage_white_pixels(recorded_image) #os.remove(recorded_image) assert percentage == 100, "All the pixels should be white"
def test_clicks(self): """ Tests the ability to record all clicks """ start_time = time.time() recorder = Recorder() recorder.start_recording() time.sleep(0.5) send_keys("{LWIN}Calculator{ENTER}", pause=0.2) with Region( "Calculator||Window->Calculator||Window->||Group->Number pad||Group" ): move("Zero||Button", duration=0) move("One||Button", duration=0) wait_recorder_ready(recorder, "One||Button") left_click("One||Button") move("Two||Button", duration=0) wait_recorder_ready(recorder, "Two||Button") double_left_click("Two||Button") move("Three||Button", duration=0) wait_recorder_ready(recorder, "Three||Button") triple_left_click("Three||Button") move("Four||Button", duration=0) wait_recorder_ready(recorder, "Four||Button") triple_left_click("Four||Button") left_click("Four||Button") move("Five||Button", duration=0) wait_recorder_ready(recorder, "Five||Button") triple_left_click("Five||Button") double_left_click("Five||Button") move("Six||Button", duration=0) wait_recorder_ready(recorder, "Six||Button") triple_left_click("Six||Button") triple_left_click("Six||Button") with Region("Calculator||Window->Calculator||Window"): move("Close Calculator||Button", duration=0) wait_recorder_ready(recorder, "Close Calculator||Button") left_click("Close Calculator||Button") record_file_name = recorder.stop_recording() time.sleep(0.5) recorder.quit() str2num = { "Zero": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5, "Six": 6 } click_count = [0, 0, 0, 0, 0, 0, 0] with open(record_file_name, 'r') as f: line = f.readline() while line: line = f.readline() for str_number, i_number in str2num.items(): if str_number in line: if "triple_left_click" in line: click_count[i_number] += 3 elif "double_left_click" in line: click_count[i_number] += 2 elif "left_click" in line: click_count[i_number] += 1 for i_number in str2num.values(): assert click_count[i_number] == i_number os.remove(record_file_name) duration = time.time() - start_time assert duration < 11, "The duration of this test is " + str( duration) + " s. It must be lower than 11 s"
def test_recorder_click(start_kill_app, wait_recorder_ready): """ Tests the ability to record all clicks. """ hwnd = None while not hwnd: time.sleep(0.1) hwnd = win32gui.FindWindow(None, 'Calculator') print(hwnd) win32gui.MoveWindow(hwnd, 0, 100, 400, 400, True) # with UIPath("Calculator||Window"): # 'UIAWrapper' object had no 'move_window' until Pywinauto 0.7.0 # find().move_window(0, 100, 400, 400, True) recorder = Recorder() recorder.start_recording() start_time = time.time() with UIPath("Calculator||Window->*"): move("Zero||Button", duration=0) move("One||Button", duration=0) wait_recorder_ready(recorder, "One||Button") click("One||Button") move("Two||Button", duration=0) wait_recorder_ready(recorder, "Two||Button") double_click("Two||Button") move("Three||Button", duration=0) wait_recorder_ready(recorder, "Three||Button") triple_click("Three||Button") move("Four||Button", duration=0) wait_recorder_ready(recorder, "Four||Button") triple_click("Four||Button") click("Four||Button") move("Five||Button", duration=0) wait_recorder_ready(recorder, "Five||Button") triple_click("Five||Button") double_click("Five||Button") move("Six||Button", duration=0) wait_recorder_ready(recorder, "Six||Button") triple_click("Six||Button") triple_click("Six||Button") duration = time.time() - start_time record_file_name = recorder.stop_recording() recorder.quit() assert duration < 8, "The duration of this test is " + str( duration) + " s. It must be lower than 8 s" str2num = { "Zero": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5, "Six": 6 } click_count = [0, 0, 0, 0, 0, 0, 0] with open(record_file_name, 'r') as f: line = f.readline() while line: line = f.readline() for str_number, i_number in str2num.items(): if str_number in line: if "triple_click" in line: click_count[i_number] += 3 elif "double_click" in line: click_count[i_number] += 2 elif "click" in line: click_count[i_number] += 1 for i_number in str2num.values(): assert click_count[i_number] == i_number os.remove(record_file_name)
def test_recorder_mouse_move(start_kill_app): """ Tests the accuracy of the relative coordinates of an element. It records a series of drag-and-drops to draw lines and then plays them back to overlay the lines in white. """ with UIPath("Untitled - Paint||Window"): find().set_focus() find().maximize() click("*->Resize||Button") with UIPath("Resize and Skew||Window->*"): click("Pixels||RadioButton") set_text("Horizontal||Edit#[0,0]", "1900") # Resize the image to 1900 pixels wide click("OK||Button") click("*->Line||Button") click("*->Size||Group->Size||Button") menu_click("3px") # The thickness is set to 3px wrapper = move("*->Using Line tool on Canvas||Pane") time.sleep(1) recorder = Recorder() recorder.relative_coordinate_mode = True recorder.start_recording() time.sleep(2.0) for _ in range(9): x0 = random.randint(wrapper.rectangle().left + 22, wrapper.rectangle().right - 22) y0 = random.randint(wrapper.rectangle().top + 22, wrapper.rectangle().bottom - 22) move((x0, y0), duration=0) x, y = win32api.GetCursorPos() assert (x, y) == (x0, y0) send_keys( "{VK_CONTROL down}{VK_SHIFT down}f{VK_SHIFT up}{VK_CONTROL up}", vk_packet=False) time.sleep(0.5) code = pyperclip.paste() words = code.split("%(") words = words[1].split(')"') move("Untitled - Paint||Window->*->Using Line tool on Canvas||Pane%(" + words[0] + ")", duration=0) x, y = win32api.GetCursorPos() assert (x, y) == (x0, y0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0) x1 = random.randint(wrapper.rectangle().left + 22, wrapper.rectangle().right - 22) y1 = random.randint(wrapper.rectangle().top + 22, wrapper.rectangle().bottom - 22) move((x1, y1), duration=0.4) # This duration is mandatory for the recorder time.sleep(0.6) # This pause is mandatory for the recorder win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0) time.sleep(0.5) # This pause is mandatory for the recorder recorded_file = recorder.stop_recording() recorder.quit() # The recorded file is patched to remove all that is not needed data = "" with open(recorded_file) as text_file: for line in text_file: if not (("send_keys" in line) or ("wrapper" in line)): if "drag_and_drop" in line: data += line.replace("drag_and_drop", "right_drag_and_drop") else: data += line print(data) # Now the lines are overed in white using the previously recorded drag and drops compiled_code = compile(data, '<string>', 'exec') eval(compiled_code) os.remove(recorded_file) send_keys("{VK_CONTROL down}s{VK_CONTROL up}") recorded_image = str(recorded_file).replace('.py', '.png') select_file("Untitled - Paint||Window->Save As||Window", recorded_image) time.sleep(2) percentage = percentage_white_pixels(recorded_image) os.remove(recorded_image) assert percentage == 100, "All the pixels should be white"
win32con.MB_OK | win32con.MB_ICONEXCLAMATION) windll.user32.ShowWindow(windll.kernel32.GetConsoleWindow(), 6) parser = argparse.ArgumentParser() parser.add_argument("filename", metavar='path', help="replay a python script", type=str, action='store', nargs='?', default='') parser.add_argument("--no_splash_screen", help="Does not display the splash screen", action='store_true') args = parser.parse_args() recorder = Recorder() if args.filename: from pywinauto_recorder.player import * if os_path_isfile(args.filename): print("Replaying: " + args.filename) recorder.playback(filename=args.filename) else: print("Error: file '" + args.filename + "' not found.") input("Press Enter to continue...") print("Exit") else: display_splash_screen() if "__compiled__" in globals(): path_icons = Path(__file__).parent.absolute() / Path("Icons") else: path_icons = Path(__file__).parent.absolute() / Path(
def test_clicks(self): recorder = Recorder() recorder.start_recording() time.sleep(0.5) send_keys("{LWIN}Calculator{ENTER}") with Region("Calculator||Window->Calculator||Window->||Group->Number pad||Group"): move("One||Button", duration=0) time.sleep(1.0) left_click("One||Button") move("Two||Button", duration=0) time.sleep(1.0) double_left_click("Two||Button") move("Three||Button", duration=0) time.sleep(1.0) triple_left_click("Three||Button") move("Four||Button", duration=0) time.sleep(1.0) triple_left_click("Four||Button") left_click("Four||Button") move("Five||Button", duration=0) time.sleep(1.0) triple_left_click("Five||Button") double_left_click("Five||Button") move("Six||Button", duration=0) time.sleep(1.0) triple_left_click("Six||Button") triple_left_click("Six||Button") move("Three||Button", duration=0) time.sleep(1.0) triple_left_click("Three||Button") move("Two||Button", duration=0) time.sleep(1.0) double_left_click("Two||Button") move("One||Button", duration=0) time.sleep(1.0) left_click("One||Button") with Region("Calculator||Window->Calculator||Window"): move("Close Calculator||Button") time.sleep(1.0) left_click("Close Calculator||Button") record_file_name = recorder.stop_recording() recorder.quit() with open(record_file_name, 'r') as f: line = f.readline() while line: line = f.readline() if "One" in line: self.assertTrue(line.find("left_click") != -1) elif "Two" in line: self.assertTrue(line.find("double_left_click") != -1) elif "Three" in line: self.assertTrue(line.find("triple_left_click") != -1) elif "Four" in line: self.assertTrue(line.find("left_click") != -1) line = f.readline() self.assertTrue(line.find("triple_left_click") != -1) elif "Five" in line: self.assertTrue(line.find("double_left_click") != -1) line = f.readline() self.assertTrue(line.find("triple_left_click") != -1) elif "Six" in line: self.assertTrue(line.find("triple_left_click") != -1) line = f.readline() self.assertTrue(line.find("triple_left_click") != -1) os.remove(record_file_name)
def setUp(self): """Set some data and ensure the application is in the state we want""" self.app = pywinauto.Application() self.app.start("mspaint.exe") self.recorder = Recorder() self.recorder.start_recording()