Skip to content

Commit

Permalink
Merge pull request #52 from mechanical-orchard/implement-keyboard
Browse files Browse the repository at this point in the history
Implement basic versions of Page.Keyboard
  • Loading branch information
coreyti authored May 31, 2024
2 parents 650afad + 5b2171a commit c9be743
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 43 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ jobs:
otp-version: '26.2.5'
- name: Install Elixir dependencies
run: mix deps.get
- name: Install Node dependencies
run: npm install --prefix assets
- name: Install Playwright dependencies (e.g., browsers)
run: mix playwright.install
# NOTE: not needed for now, while assets are
# directly installed to `priv/static`.
# - name: Install Node dependencies
# run: npm install --prefix assets
- name: Run tests
run: mix test
44 changes: 33 additions & 11 deletions lib/playwright/page/keyboard.ex
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
defmodule Playwright.Keyboard do
defmodule Playwright.Page.Keyboard do
@moduledoc false

# @spec down(t(), binary()) :: :ok
# def down(keyboard, key)
use Playwright.SDK.ChannelOwner
alias Playwright.Page

# @spec insert_text(t(), binary()) :: :ok
# def insert_text(keyboard, text)
# API
# ---------------------------------------------------------------------------

# @spec press(t(), binary(), options()) :: :ok
# def press(keyboard, key, options \\ %{})
@spec down(Page.t(), binary()) :: :ok
def down(page, key) do
channel_post(page, :keyboard_down, %{key: key})
end

# @spec type(t(), binary(), options()) :: :ok
# def type(keyboard, text, options \\ %{})
@spec insert_text(Page.t(), binary()) :: :ok
def insert_text(page, text) do
channel_post(page, :keyboard_type, %{text: text})
end

# @spec up(t(), binary()) :: :ok
# def up(keyboard, key)
@spec press(Page.t(), binary()) :: :ok
def press(page, key) do
channel_post(page, :keyboard_press, %{key: key})
end

@spec type(Page.t(), binary()) :: :ok
def type(page, text) do
channel_post(page, :keyboard_type, %{text: text})
end

@spec up(Page.t(), binary()) :: :ok
def up(page, key) do
channel_post(page, :keyboard_up, %{key: key})
end

# private
# ---------------------------------------------------------------------------

defp channel_post(%Page{} = page, action, data) do
Channel.post(page.session, {:guid, page.guid}, action, data)
end
end
12 changes: 2 additions & 10 deletions lib/playwright/sdk/cli.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,13 @@ defmodule Playwright.SDK.CLI do
require Logger

def install do
Logger.info("Installing playwright browsers")
Logger.info("Installing playwright browsers and dependencies")
cli_path = config_cli() || default_cli()
{result, exit_status} = System.cmd(cli_path, ["install"])
{result, exit_status} = System.cmd(cli_path, ["install", "--with-deps"])
Logger.info(result)
if exit_status != 0, do: raise("Failed to install playwright browsers")
end

def install_deps do
Logger.info("Installing playwright deps")
cli_path = config_cli() || default_cli()
{result, exit_status} = System.cmd(cli_path, ["installdeps"])
Logger.info(result)
if exit_status != 0, do: raise("Failed to install playwright deps")
end

# private
# ----------------------------------------------------------------------------

Expand Down
18 changes: 9 additions & 9 deletions test/integration/locator_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ defmodule Playwright.LocatorTest do

describe "Locator.check/2" do
setup(%{assets: assets, page: page}) do
options = %{timeout: 200}
options = %{timeout: 500}

page |> Page.goto(assets.prefix <> "/empty.html")
page |> Page.set_content("<input id='checkbox' type='checkbox'/>")
Expand All @@ -59,13 +59,13 @@ defmodule Playwright.LocatorTest do
frame = Page.main_frame(page)

locator = Locator.new(frame, "input#bogus")
assert {:error, %Error{message: "Timeout 200ms exceeded."}} = Locator.check(locator, options)
assert {:error, %Error{message: "Timeout 500ms exceeded."}} = Locator.check(locator, options)
end
end

describe "Locator.click/2" do
setup(%{assets: assets, page: page}) do
options = %{timeout: 200}
options = %{timeout: 500}

page |> Page.goto(assets.prefix <> "/empty.html")
page |> Page.set_content("<a id='link' target=_blank rel=noopener href='/one-style.html'>yo</a>")
Expand All @@ -84,14 +84,14 @@ defmodule Playwright.LocatorTest do
frame = Page.main_frame(page)

locator = Locator.new(frame, "a#bogus")
assert {:error, %Error{message: "Timeout 200ms exceeded."}} = Locator.click(locator, options)
assert {:error, %Error{message: "Timeout 500ms exceeded."}} = Locator.click(locator, options)
end

test "clicking a button", %{assets: assets, page: page} do
locator = Page.locator(page, "button")
page |> Page.goto(assets.prefix <> "/input/button.html")

Locator.click(locator, %{timeout: 200})
Locator.click(locator, %{timeout: 500})
assert Page.evaluate(page, "window['result']") == "Clicked"
end
end
Expand All @@ -112,7 +112,7 @@ defmodule Playwright.LocatorTest do
}
""")

Locator.dblclick(locator, %{timeout: 200})
Locator.dblclick(locator, %{timeout: 500})
assert Page.evaluate(page, "window['double']") == true
assert Page.evaluate(page, "window['result']") == "Clicked"
end
Expand Down Expand Up @@ -694,7 +694,7 @@ defmodule Playwright.LocatorTest do

describe "Locator.uncheck/2" do
setup(%{assets: assets, page: page}) do
options = %{timeout: 200}
options = %{timeout: 500}

page |> Page.goto(assets.prefix <> "/empty.html")
page |> Page.set_content("<input id='checkbox' type='checkbox' checked/>")
Expand All @@ -712,13 +712,13 @@ defmodule Playwright.LocatorTest do

test "returns a timeout error when unable to 'uncheck'", %{options: options, page: page} do
locator = Page.locator(page, "input#bogus")
assert {:error, %Error{message: "Timeout 200ms exceeded."}} = Locator.uncheck(locator, options)
assert {:error, %Error{message: "Timeout 500ms exceeded."}} = Locator.uncheck(locator, options)
end
end

describe "Locator.wait_for/2" do
setup(%{assets: assets, page: page}) do
options = %{timeout: 200}
options = %{timeout: 500}

page |> Page.goto(assets.prefix <> "/empty.html")

Expand Down
16 changes: 8 additions & 8 deletions test/integration/page/expect_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ defmodule Playwright.Page.NetworkTest do
test "w/ an event and a timeout", %{page: page} do
{:error, %Error{message: message}} =
Page.expect_event(page, :request_finished, %{
timeout: 200
timeout: 500
})

assert message == "Timeout 200ms exceeded."
assert message == "Timeout 500ms exceeded."
end

test "w/ an event, a (truthy) predicate, and a timeout", %{assets: assets, page: page} do
Expand All @@ -51,7 +51,7 @@ defmodule Playwright.Page.NetworkTest do
predicate: fn _, _ ->
true
end,
timeout: 200
timeout: 500
})

assert event.type == :request_finished
Expand All @@ -65,10 +65,10 @@ defmodule Playwright.Page.NetworkTest do
predicate: fn _, _ ->
false
end,
timeout: 200
timeout: 500
})

assert message == "Timeout 200ms exceeded."
assert message == "Timeout 500ms exceeded."
end
end

Expand Down Expand Up @@ -115,14 +115,14 @@ defmodule Playwright.Page.NetworkTest do
predicate: fn _, _ ->
false
end,
timeout: 200
timeout: 500
},
fn ->
Page.goto(page, assets.empty)
end
)

assert message == "Timeout 200ms exceeded."
assert message == "Timeout 500ms exceeded."
end

test "w/ an event and a timeout", %{assets: assets, page: page} do
Expand All @@ -131,7 +131,7 @@ defmodule Playwright.Page.NetworkTest do
page,
:request_finished,
%{
timeout: 200
timeout: 500
},
fn ->
Page.goto(page, assets.empty)
Expand Down
78 changes: 78 additions & 0 deletions test/integration/page/keyboard_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
defmodule Playwright.Page.KeyboardTest do
use Playwright.TestCase, async: true

alias Playwright.Page
alias Playwright.Page.Keyboard

describe "type" do
test "keyboard type into a textbox", %{page: page} do
Page.evaluate(page, """
const textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.focus();
""")

text = "Hello world. I am the text that was typed!"

Keyboard.type(page, text)

assert Page.evaluate(page, ~s[document.querySelector("textarea").value]) == text
end
end

describe "insert_text" do
test "should send characters inserted", %{page: page} do
Page.evaluate(page, """
const textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.focus();
""")

text = "Hello world. I am the text that was typed!"

Keyboard.insert_text(page, text)

assert Page.evaluate(page, ~s[document.querySelector("textarea").value]) == text
end
end

describe "up" do
test "sends proper code", %{page: page, assets: assets} do
Page.goto(page, assets.prefix <> "/input/keyboard.html")

Keyboard.up(page, ";")

assert Page.evaluate(page, "() => getResult()") ==
"Keyup: ; Semicolon 186 []"
end
end

describe "down" do
test "sends proper code", %{page: page, assets: assets} do
Page.goto(page, assets.prefix <> "/input/keyboard.html")

Keyboard.down(page, "Control")

assert Page.evaluate(page, "() => getResult()") ==
"Keydown: Control ControlLeft 17 [Control]"
end
end

describe "press" do
test "test should press plus", %{page: page, assets: assets} do
Page.goto(page, assets.prefix <> "/input/keyboard.html")

Keyboard.press(page, "+")

assert Page.evaluate(page, "() => getResult()") ==
[
# 192 is ` keyCode
"Keydown: + Equal 187 []",
# 126 is ~ charCode
"Keypress: + Equal 43 43 []",
"Keyup: + Equal 187 []"
]
|> Enum.join("\n")
end
end
end
6 changes: 3 additions & 3 deletions test/integration/page_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ defmodule Playwright.PageTest do
test "with a single option given mismatched attributes, returns a timeout", %{assets: assets, page: page} do
page |> Page.goto(assets.prefix <> "/input/select.html")

assert {:error, %Error{message: "Timeout 200ms exceeded."}} =
Page.select_option(page, "select", %{value: "green", label: "Brown"}, %{timeout: 200})
assert {:error, %Error{message: "Timeout 500ms exceeded."}} =
Page.select_option(page, "select", %{value: "green", label: "Brown"}, %{timeout: 500})
end

test "with multiple options and a single-option select, selects the first", %{assets: assets, page: page} do
Expand Down Expand Up @@ -342,7 +342,7 @@ defmodule Playwright.PageTest do
assert page |> Page.get_attribute("div#outer", "name") == "value"
assert page |> Page.get_attribute("div#outer", "foo") == nil

assert({:error, %Error{}} = Page.get_attribute(page, "glorp", "foo", %{timeout: 200}))
assert({:error, %Error{}} = Page.get_attribute(page, "glorp", "foo", %{timeout: 500}))
end
end

Expand Down

0 comments on commit c9be743

Please sign in to comment.