import re from typing import Dict, Optional, Tuple, Type, Union, cast import pytest from playwright.sync_api import Page, expect from browser_env import ( ScriptBrowserEnv, create_id_based_action, create_key_press_action, create_playwright_action, create_scroll_action, ) HEADLESS = True SLOW_MO = 0 def test_frame_locator(script_browser_env: ScriptBrowserEnv) -> None: env = script_browser_env seq = """page.goto("https://www.littlewebhut.com/articles/html_iframe_example/") page.frame_locator("iframe[name=\\"imgbox\\"]").get_by_role("img").click()""" env.reset() for action in seq.split("\n"): action = action.strip() _, success, _, _, info = env.step(create_playwright_action(action)) assert success def test_basic(script_browser_env: ScriptBrowserEnv) -> None: # click, fill, press, check, goto env = script_browser_env seq = """page.goto("https://demo.playwright.dev/todomvc/") page.get_by_placeholder("What needs to be done?").click() page.get_by_placeholder("What needs to be done?").fill("hello") page.get_by_placeholder("What needs to be done?").press("Enter") page.get_by_placeholder("What needs to be done?").fill("world") page.get_by_placeholder("What needs to be done?").press("Enter") page.get_by_placeholder("What needs to be done?").fill("yes") page.get_by_placeholder("What needs to be done?").press("Enter") page.get_by_placeholder("What needs to be done?").fill("no") page.get_by_placeholder("What needs to be done?").press("Enter") page.get_by_role("listitem").filter(has_text="world").get_by_role("checkbox", name="Toggle Todo").check() page.get_by_role("button", name="Clear completed").click()""" env.reset() for action in seq.split("\n"): action = action.strip() _, success, _, _, info = env.step(create_playwright_action(action)) assert success def test_hover(script_browser_env: ScriptBrowserEnv) -> None: env = script_browser_env seq = """page.goto("https://ianlunn.github.io/Hover/") page.get_by_role("link", name="Download on GitHub").hover()""" env.reset() for action in seq.split("\n"): action = action.strip() _, success, _, _, info = env.step(create_playwright_action(action)) assert success def test_select_option(script_browser_env: ScriptBrowserEnv) -> None: env = script_browser_env seq = """page.goto("https://russmaxdesign.github.io/exercise/#link-two") page.get_by_role("combobox", name="Favourite mammal").select_option("African Wild Dog")""" env.reset() for action in seq.split("\n"): action = action.strip() _, success, _, _, info = env.step(create_playwright_action(action)) assert success def test_xpath(script_browser_env: ScriptBrowserEnv) -> None: env = script_browser_env seq = """page.goto("https://demo.playwright.dev/todomvc/") page.goto("https://demo.playwright.dev/todomvc/#/") page.get_by_placeholder("What needs to be done?").click() page.get_by_placeholder("What needs to be done?").fill("hello") page.get_by_placeholder("What needs to be done?").press("Enter") page.get_by_role("link", name="Completed").click() page.locator("xpath=/html/body/section/div/header/input").fill("no") page.get_by_placeholder("What needs to be done?").press("Enter") page.goto("https://bic-berkeley.github.io/psych-214-fall-2016/string_literals.html") page.locator("xpath=//*[@id=\'searchbox\']/div/form/input[1]").fill("type")""" env.reset() for action in seq.split("\n"): action = action.strip() _, success, _, _, info = env.step(create_playwright_action(action)) assert success def test_inter_page_actions( script_browser_env: ScriptBrowserEnv, ) -> None: env = script_browser_env seq = """page.goto("https://demo.playwright.dev/todomvc/") browser.new_tab() browser.page_focus(0) browser.page_focus(1) page.page_close() page.goto("https://google.com") page.goto("https://demo.playwright.dev/todomvc/") page.go_back() page.go_forward()""" env.reset() for action in seq.split("\n"): action = action.strip() _, success, _, _, info = env.step(create_playwright_action(action)) assert success assert "https://demo.playwright.dev/todomvc" in info["page"].url def test_scroll( current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: env = current_viewport_script_browser_env env.reset() _, success, _, _, _ = env.step(create_scroll_action("down")) assert success _, success, _, _, _ = env.step(create_scroll_action("up")) assert success def test_id_click( accessibility_tree_current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: env = accessibility_tree_current_viewport_script_browser_env env.reset() obs, success, _, _, info = env.step( create_playwright_action( 'page.goto("https://russmaxdesign.github.io/exercise/")' ) ) assert success assert "link 'McKenna/Bell'" in obs["text"] # get the id of the link element_id = re.search(r"\[(\d+)\] link 'McKenna/Bell'", obs["text"]).group(1) # type: ignore obs, success, _, _, info = env.step( create_id_based_action(f"click [{element_id}]") ) assert success assert ( info["page"].url == "https://russmaxdesign.github.io/exercise/#link-four" ) obs, success, _, _, info = env.step(create_scroll_action("down")) assert "link 'Classification'" in obs["text"] element_id = re.search(r"\[(\d+)\] link 'Classification'", obs["text"]).group(1) # type: ignore obs, success, _, _, info = env.step( create_id_based_action(f"click [{element_id}]") ) assert success assert ( info["page"].url == "https://russmaxdesign.github.io/exercise/#link-two" ) assert "radio 'Weekly'" in obs["text"] element_id = re.search(r"\[(\d+)\] radio 'Weekly'", obs["text"]).group(1) # type: ignore obs, success, _, _, info = env.step( create_id_based_action(f"click [{element_id}]") ) assert success assert "radio 'Weekly'" in obs["text"] def test_id_hover( accessibility_tree_current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: env = accessibility_tree_current_viewport_script_browser_env env.reset() obs, success, _, _, info = env.step( create_playwright_action( 'page.goto("https://ianlunn.github.io/Hover/")' ) ) assert success assert "link 'Download on GitHub'" in obs["text"] element_id = re.search(r"\[(\d+)\] link 'Download on GitHub'", obs["text"]).group(1) # type: ignore obs, success, _, _, info = env.step( create_id_based_action(f"hover [{element_id}]") ) assert success def test_key_press( accessibility_tree_current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: env = accessibility_tree_current_viewport_script_browser_env env.reset() obs, success, _, _, info = env.step( create_playwright_action( 'page.goto("https://russmaxdesign.github.io/exercise/")' ) ) assert success print(obs["text"]) assert "StaticText 'Full name'" in obs["text"] element_id = re.search(r"\[(\d+)\] StaticText 'Full name'", obs["text"]).group(1) # type: ignore s = "My Name IS XYZ" obs, success, _, _, info = env.step( create_id_based_action(f"type [{element_id}] [{s}] [0]") ) assert success expect(env.page.get_by_label("Full name")).to_be_focused() expect(env.page.get_by_label("Full name")).to_have_value(s) obs, success, _, _, info = env.step( create_id_based_action("press [meta+a]") ) assert success env.page.get_by_label("Full name").type(s) expect(env.page.get_by_label("Full name")).to_have_value(s) obs, success, _, _, info = env.step(create_key_press_action("Enter")) assert success expect(env.page.get_by_label("Email")).to_be_focused() def test_id_type( accessibility_tree_current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: env = accessibility_tree_current_viewport_script_browser_env env.reset() obs, success, _, _, info = env.step( create_playwright_action( 'page.goto("https://russmaxdesign.github.io/exercise/")' ) ) assert success assert "StaticText 'Full name'" in obs["text"] s = "My Name IS XYZ" element_id = re.search(r"\[(\d+)\] StaticText 'Full name'", obs["text"]).group(1) # type: ignore obs, success, _, _, info = env.step( create_id_based_action(f"type [{element_id}] [{s}]") ) assert success locator = env.page.get_by_label("Full name") expect(locator).to_have_value(s) def test_e2e_id_based_actions( accessibility_tree_script_browser_env: ScriptBrowserEnv, ) -> None: env = accessibility_tree_script_browser_env env.reset() obs, *_ = env.step( create_id_based_action( "goto [https://russmaxdesign.github.io/exercise/]" ) ) element_id = re.search(r"\[(\d+)\] link 'What are mammals\?'", obs["text"]).group(1) # type: ignore obs, *_ = env.step(create_id_based_action(f"click [{element_id}]")) element_id = re.search(r"\[(\d+)\] textbox 'Email'", obs["text"]).group(1) # type: ignore env.step( create_id_based_action(f"type [{element_id}] [test@gmail.com] [0]") ) env.step(create_id_based_action("scroll [down]")) env.step(create_id_based_action("scroll [up]")) env.step(create_id_based_action("new_tab")) env.step(create_id_based_action("tab_focus [0]")) env.step(create_id_based_action("tab_focus [1]")) env.step(create_id_based_action("goto [https://example.com/]")) env.step(create_id_based_action("go_back")) x = env.step(create_id_based_action("go_forward")) assert x[-1]["page"].url == "https://example.com/" x = env.step(create_id_based_action("tab_focus [0]")) assert ( x[-1]["page"].url == "https://russmaxdesign.github.io/exercise/#link-one" ) def test_id_delete_input( accessibility_tree_current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: env = accessibility_tree_current_viewport_script_browser_env env.reset() obs, success, _, _, info = env.step( create_playwright_action( 'page.goto("https://russmaxdesign.github.io/exercise/")' ) ) assert success assert "StaticText 'Full name'" in obs["text"] s = "My Name IS XYZ" element_id = re.search(r"\[(\d+)\] StaticText 'Full name'", obs["text"]).group(1) # type: ignore obs, success, _, _, info = env.step( create_id_based_action(f"type [{element_id}] [{s}]") ) assert success locator = env.page.get_by_label("Full name") expect(locator).to_have_value(s) obs, success, _, _, info = env.step( create_id_based_action(f"click [{element_id}]") ) assert success obs, success, _, _, info = env.step( create_id_based_action(f"press [Meta+a]") ) assert success obs, success, _, _, info = env.step( create_id_based_action("press [backspace]") ) assert success new_s = "NEW" obs, success, _, _, info = env.step( create_id_based_action(f"type [{element_id}] [{new_s}]") ) locator = env.page.get_by_label("Full name") expect(locator).to_have_value(new_s) @pytest.mark.skip(reason="The current implementation does not deal with iframes") def test_frame_action( accessibility_tree_current_viewport_script_browser_env: ScriptBrowserEnv, ) -> None: """Test when multiple frames are present on the page""" env = accessibility_tree_current_viewport_script_browser_env env.reset() obs, success, _, _, info = env.step( create_playwright_action( 'page.goto("https://www.in-n-out.com/locations")' ) ) assert success assert "StaticText 'Search by Address or Zip'" in obs["text"] element_id = re.search(r"\[(\d+)\] StaticText 'Search by Address or Zip'", obs["text"]).group(1) # type: ignore s = "random location" obs, success, _, _, info = env.step( create_id_based_action(f"type [{element_id}] [{s}]") ) assert success assert s in obs["text"]