def close_popup(global_handler, browser): browser.CloseBrowser() global_handler.PopupClosed_True = True # Test developer tools popup main_browser = cef.GetBrowserByIdentifier(MAIN_BROWSER_ID) main_browser.ShowDevTools() cef.PostDelayedTask(cef.TID_UI, 1500, close_devtools, global_handler) cef.PostDelayedTask(cef.TID_UI, 500, main_browser.SetFocus, True)
def click_after_2_seconds(browser): print("Click after 2 seconds") browser.SendMouseMoveEvent(0, 90, False, 0) browser.SendMouseClickEvent(0, 90, cef.MOUSEBUTTON_LEFT, False, 1) browser.SendMouseMoveEvent(400, 99, False, cef.EVENTFLAG_LEFT_MOUSE_BUTTON) browser.SendMouseClickEvent(400, 99, cef.MOUSEBUTTON_LEFT, True, 1) cef.PostDelayedTask(cef.TID_UI, 1000, click_after_1_second, browser)
def _OnAfterCreated(self, browser, **_): # For asserts that are checked automatically before shutdown its # values should be set first, so that when other asserts fail # (the ones called through the test_case member) they are reported # correctly. if not self.OnAfterCreatedMain_True: # First call for main browser. # browser.GetUrl() returns empty at this moment. self.OnAfterCreatedMain_True = True self.test_case.assertEqual(browser.GetIdentifier(), MAIN_BROWSER_ID) self.test_case.assertFalse(browser.IsPopup()) else: # Second call for implicit popup browser opened via js. # Should execute only for main test. # Should not execute for DevTools window. assert "main_test" in self.test_case.id() assert not self.OnAfterCreatedPopup_True self.OnAfterCreatedPopup_True = True self.test_case.assertEqual(browser.GetIdentifier(), POPUP_BROWSER_ID) # browser.GetUrl() returns empty at this moment. self.test_case.assertTrue(browser.IsPopup()) if WINDOWS: cef.WindowUtils.SetTitle(browser, "Popup test") # Close the popup browser after 250 ms cef.PostDelayedTask(cef.TID_UI, 250, close_popup, self, browser)
def wait_retrieve_transforms(bc: BrowserContext, browser): if bc.transforms is None: cef.PostDelayedTask(cef.TID_UI, 100, wait_retrieve_transforms, bc, browser) else: bc.current_transform = NOP exec_retrieve_rects(bc, browser) return
def OnLoadingStateChange(self, browser, is_loading, **_): """Called when the loading state has changed.""" try: if not is_loading: # Loading is complete def yield_transforms(transforms): self.browser_context.transforms = set(transforms) def yield_rects(rects): self.browser_context.rects = rects bindings = cef.JavascriptBindings(bindToFrames=False, bindToPopups=False) bindings.SetFunction("yieldTransforms", yield_transforms) bindings.SetFunction("yieldRects", yield_rects) browser.SetJavascriptBindings(bindings) with open(self.browser_context.kle_json_file, 'r', encoding='utf-8') as f: json = f.read() browser.ExecuteJavascript(r'''(function(){ window.deserializeAndRenderAndApply(''' + json + r'''); yieldTransforms(window.retrieveTransforms()); })(); ''') cef.PostDelayedTask(cef.TID_UI, 2000, wait_retrieve_transforms, self.browser_context, browser) except: import traceback print("[kle_scraper] ERROR: Failed in OnLoadingStateChange()") traceback.print_exc() cef.PostTask(cef.TID_UI, exit_scraping, browser)
def OnLoadingStateChange(self, browser, is_loading, **_): """Called when the loading state has changed.""" if not is_loading: # Loading is complete sys.stdout.write(os.linesep) print("[screenshot.py] Web page loading is complete") print("[screenshot.py] Will save screenshot in 2 seconds") # Give up to 2 seconds for the OnPaint call. Most of the time # it is already called, but sometimes it may be called later. cef.PostDelayedTask(cef.TID_UI, 2000, save_screenshot, browser)
def click_after_1_second(browser): print("Click after 1 second") # Mouse move to the top-left corner of the text browser.SendMouseMoveEvent(0, 70, False, 0) # Left mouse button click in the top-left corner of the text browser.SendMouseClickEvent(0, 70, cef.MOUSEBUTTON_LEFT, False, 1) # Mouse move to the bottom-right corner of the text, # while holding left mouse button. browser.SendMouseMoveEvent(400, 80, False, cef.EVENTFLAG_LEFT_MOUSE_BUTTON) # Release left mouse button browser.SendMouseClickEvent(400, 80, cef.MOUSEBUTTON_LEFT, True, 1) cef.PostDelayedTask(cef.TID_UI, 1000, click_after_2_seconds, browser)
def wait_screenshot(bc: BrowserContext, browser): if bc.capturing_screenshot: cef.PostDelayedTask(cef.TID_UI, 100, wait_screenshot, bc, browser) return buffer_string = browser.GetUserData("OnPaint.buffer_string") if not buffer_string: raise Exception("buffer_string is empty, OnPaint never called?") image = Image.frombytes("RGBA", VIEWPORT_SIZE, buffer_string, "raw", "RGBA", 0, 1) # check bottom right pixel of rendered image _, _, _, rb_pixel_a = image.getpixel((VIEWPORT_SIZE[0] - 18, VIEWPORT_SIZE[1] - 18)) if rb_pixel_a == 0: # Rendering is not completed. Capture again. bc.capturing_screenshot = True browser.Invalidate(cef.PET_VIEW) cef.PostDelayedTask(cef.TID_UI, 100, wait_screenshot, bc, browser) return # tr = bc.current_transform.replace('\n', '_') # image.save(os.path.join(bc.image_output_dir, f"full-{tr}.png")) for i, (idx, br) in enumerate(bc.rects): p = os.path.join(bc.image_output_dir, f"{str(idx)}.png") keylabel_image = image.crop([br['left'], br['top'], br['right'], br['bottom'], ]) keylabel_image.save(p) bc.shot_transforms.add(bc.current_transform) rest_trs = bc.transforms - bc.shot_transforms if len(rest_trs) > 0: bc.current_transform = next(iter(rest_trs)) exec_retrieve_rects(bc, browser) return with open(bc.kle_json_file, 'r', encoding='utf-8') as f: json = f.read() bc.kle_keyboard = kle_serial.parse(json) cef.PostTask(cef.TID_UI, exit_scraping, browser)
def exec_retrieve_rects(bc: BrowserContext, browser): bc.rects = None tr = bc.current_transform.replace('\n', r'\n') browser.ExecuteJavascript(r'''(function(){ document.querySelectorAll(".keycap > div").forEach(e => { e.style.backgroundColor = "#ffffff"; }); document.querySelectorAll(".keytop").forEach(e => { e.style.borderColor = "#ffffff"; });''' + f"yieldRects(window.retrieveRects('{tr}'));" + '''})(); ''') cef.PostDelayedTask(cef.TID_UI, 100, wait_retrieve_rects, bc, browser)
def save_screenshot(browser): # Browser object provides GetUserData/SetUserData methods # for storing custom data associated with browser. The # "OnPaint.buffer_string" data is set in RenderHandler.OnPaint. buffer_string = browser.GetUserData("OnPaint.buffer_string") if not buffer_string: # Sometimes LoadHandler.OnLoadingStateChange gets called # before RenderHandler.OnPaint. if not browser.GetUserData("save_screenshot.delay_printed"): sys.stdout.write("[screenshot.py] Delay") sys.stdout.flush() browser.SetUserData("save_screenshot.delay_printed", True) else: sys.stdout.write(".") sys.stdout.flush() cef.PostDelayedTask(cef.TID_UI, 13, save_screenshot, browser) return image = Image.frombytes("RGBA", VIEWPORT_SIZE, buffer_string, "raw", "RGBA", 0, 1) image.save(SCREENSHOT_PATH, "PNG") sys.stdout.write(os.linesep) print("[screenshot.py] Saved image: {path}".format(path=SCREENSHOT_PATH)) # See comments in exit_app() why PostTask must be used cef.PostTask(cef.TID_UI, exit_app, browser)
def OnLoadEnd(self, browser, **_): # Execute function with a delay of 1 second after page # has completed loading. print("Page loading is complete") cef.PostDelayedTask(cef.TID_UI, 1000, click_after_1_second, browser)
def wait_retrieve_rects(bc: BrowserContext, browser): if bc.rects is None: cef.PostDelayedTask(cef.TID_UI, 100, wait_retrieve_rects, bc, browser) return cef.PostDelayedTask(cef.TID_UI, 500, delay_screenshot, bc, browser)
def delay_screenshot(bc: BrowserContext, browser): bc.capturing_screenshot = True browser.Invalidate(cef.PET_VIEW) cef.PostDelayedTask(cef.TID_UI, 100, wait_screenshot, bc, browser)