def test_complex(): @wtl.single_tab def policy(w, view): menu_actions = view.actions.by_type(Click).by_score("menu") w.metadata["clicks"] = w.metadata["clicks"] + 1 return random.choice(menu_actions) def menu_classifier_func(elements, _): return [ elem for elem in elements if elem.location.x < 10 and elem.location.y < 200 and elem.metadata["tag"] == "a" ] config = Config.default(["headless", "desktop"]) workflow = wtl.Workflow(url=TESTURL, config=config, policy=policy, goal=wtl.goals.N_STEPS(3)) workflow.metadata["clicks"] = 0 workflow.classifiers.add(wtl.ActiveElementFilter(action=Click)) workflow.classifiers.add( wtl.ElementClassifier(name="menu", action=Click, subset="is_active", highlight=True, callback=menu_classifier_func)) workflow.run() assert workflow.success assert workflow.metadata["clicks"] == 3 workflow.quit()
# After seven deletions, start over from step 3 if workflow.loop_idx == 7: return wtl.actions.Revert(3) # Randomly pick one of the deleting actions return [ random.choice(view.actions.by_type(wtl.actions.Remove)), wtl.actions.Wait(0.25), wtl.actions.Clear(viewport=False), wtl.actions.WaitForUser(), ] if __name__ == "__main__": cli_args = parse_cli_args() wf = wtl.Workflow(config=wtl.Config(cli_args.config), policy=policy, url=cli_args.url, output=cli_args.output) wf.classifiers.add( wtl.ElementClassifier( name="dementor", enabled=True, highlight=False, action=wtl.actions.Remove, callback=lambda e, _: e, # Will label _all_ elements removable ) ) wf.run() wf.quit()
def text_field_classifier_func(elements: wtl.Elements, _) -> List[wtl.PageElement]: return [ e for e in elements if e.metadata["tag"] == "input" and e.metadata["type"] in ("text", "email", "password") ] if __name__ == "__main__": cli_args = parse_cli_args() workflow = wtl.Workflow(config=wtl.Config(cli_args.config), policy=policy, url=cli_args.url, output=cli_args.output) workflow.classifiers.add(wtl.ActiveElementFilter(action=wtl.actions.Click)) workflow.classifiers.add( wtl.ElementClassifier(name="textfield", action=wtl.actions.FillText, callback=text_field_classifier_func, highlight=True)) logging.getLogger("wtl").setLevel(logging.CRITICAL) workflow.run() workflow.quit()
def menu_classifier_func(elements: wtl.Elements, _) -> List[wtl.PageElement]: # The condition here is completely hard-coded for the given page. return [ elem for elem in elements if elem.location.x < 10 and elem.location.y < 200 and elem.metadata["tag"] == "a" ] if __name__ == "__main__": cli_args = parse_cli_args() workflow = wtl.Workflow(config=wtl.Config(cli_args.config), policy=policy, url=cli_args.url, output=cli_args.output) workflow.classifiers.add(wtl.ActiveElementFilter(action=Click)) workflow.classifiers.add( wtl.ElementClassifier( name="menu", action=Click, subset="is_active", # Consider only active elements highlight=True, callback=menu_classifier_func, )) workflow.run() workflow.quit()
for e in elements: zIndex = workflow.js.execute_script(Z_INDEX_JS, e.selector.css) or 0 result.append((e, int(zIndex))) return result if __name__ == "__main__": cli_args = parse_cli_args() wf = wtl.Workflow(config=wtl.Config(cli_args.config), policy=policy, url=cli_args.url, output=cli_args.output) wf.classifiers.add(wtl.ActiveElementFilter(action=wtl.actions.Click)) wf.classifiers.add( wtl.ElementClassifier( name="zIndex", subset="is_active", enabled=True, highlight=0.99, mode=wtl.ScalingMode.LINEAR, callback=_compute_z_index, )) setup_logging(logging_level=logging.DEBUG) wf.run() wf.quit()
def score(element): return element.bounds.area / largest_area return { "big": [(e, score(e)) for e in elements if score(e) > 0.75], "average": [(e, abs(0.5 - score(e))) for e in elements if 0.25 < score(e) <= 0.75], } if __name__ == "__main__": cli_args = parse_cli_args() workflow = wtl.Workflow(config=wtl.Config(cli_args.config), policy=policy, url=cli_args.url, output=cli_args.output) workflow.classifiers.add(wtl.ActiveElementFilter()) workflow.classifiers.add( wtl.ElementClassifier(name="size", subset="is_active", highlight=0.5, action=Click, callback=size_classifier_func)) with workflow: workflow.run()
wtl.actions.Navigate(search_url), Click(search_results[i + 1]) ] i += 1 except IndexError: print("Search result exhausted!!") break yield None if __name__ == "__main__": cli_args = parse_cli_args() wf = wtl.Workflow( config=wtl.Config(cli_args.config), policy=policy, url="https://en.wikipedia.org/wiki/Special:Random", output=cli_args.output, ) wf.classifiers.add(wtl.ActiveElementFilter(action=Click)) wf.classifiers.add( wtl.ElementClassifier(name="textfield", action=wtl.actions.FillText, highlight=True)) wf.run() wf.quit()
def url_length_classifier_func(elements, _): # Score all elements with an href attribute with a score of the length of the href attribute href_elements = [ element for element in elements if element.metadata["href"] ] return [(element, len(element.metadata["href"])) for element in href_elements] if __name__ == "__main__": cli_args = parse_cli_args() workflow = wtl.Workflow(config=wtl.Config(cli_args.config), policy=policy, url=cli_args.url, output=cli_args.output) workflow.classifiers.add( wtl.ElementClassifier( name="url_length", highlight=True, mode=wtl.ScalingMode.LINEAR, highlight_color=wtl.Color(0, 0, 255), callback=url_length_classifier_func, )) workflow.run() workflow.quit()
goal = N_STEPS(2) @wtl.single_tab def policy(workflow: wtl.Workflow, view: wtl.View) -> Optional[wtl.Action]: if len(workflow.history) == 1: images_by_size = sorted( view.snapshot.elements.by_score("image"), key=lambda element: element.bounds.area, reverse=True ) return Click(images_by_size[0]) print("\n", view.snapshot.page_metadata["url"] != workflow.history[0].snapshot.page_metadata["url"], "\n") return None def image_classifier_func(elements, _): return [elem for elem in elements if elem.metadata["tag"] == "img"] if __name__ == "__main__": cli_args = parse_cli_args() wf = wtl.Workflow( config=wtl.Config(cli_args.config), policy=policy, goal=goal, url=cli_args.url, output=cli_args.output ) wf.classifiers.add(wtl.ElementClassifier(name="image", highlight=True, callback=image_classifier_func)) wf.run() wf.quit()