elixir-wallaby / wallaby

Concurrent browser tests for your Elixir web apps.
https://twitter.com/elixir_wallaby
MIT License
1.65k stars 196 forks source link

Wallaby does not set Selenium sessionId correctly. #706

Open blackham opened 2 years ago

blackham commented 2 years ago

Elixir and Erlang/OTP versions

Erlang/OTP 25 [erts-13.0.3] [source] [64-bit] [smp:128:128] [ds:128:128:10] [async-threads:1] [jit:ns]

Elixir 1.13.2 (compiled with Erlang/OTP 24)

Operating system

Linux

Browser

Chrome

Driver

Selenium

Correct Configuration

Current behavior

{:ok, session} = Wallaby.start_session(capabilities: %{browserName: "chrome"})

%Wallaby.Session{
capabilities: %{browserName: "chrome"},
driver: Wallaby.Selenium,
id: nil,
screenshots: [],
server: :none,
session_url: "http://localhost:4444/wd/hub/session/",
url: "http://localhost:4444/wd/hub/session/"
}

Expected behavior

%Wallaby.Session{
capabilities: %{browserName: "chrome"},
driver: Wallaby.Selenium,
id: 1a2960426d5a3a6c369a1eec379ae06c,
screenshots: [],
server: :none,
session_url: "http://localhost:4444/wd/hub/session/1a2960426d5a3a6c369a1eec379ae06c",
url: "http://localhost:4444/wd/hub/session/1a2960426d5a3a6c369a1eec379ae06c"
}

Test Code & HTML

TL;DR;

diff lib/wallaby/selenium.ex:109
-  id = response["sessionId"]
+ id = response["value"]["sessionId"]

The response map is blow. Note that "sessionId" is a child of "value", not a sibling. %{"value" => %{"capabilities" => %{"acceptInsecureCerts" => false, "browserName" => "chrome", "browserVersion" => "104.0.5112.79", "chrome" => %{"chromedriverVersion" => "104.0.5112.79 (3cf3e8c8a07d104b9e1260c910efb8f383285dc5-refs/branch-heads/5112@{#1307})", "userDataDir" => "/tmp/.com.google.Chrome.jtS7T2"}, "goog:chromeOptions" => %{"debuggerAddress" => "localhost:41055"}, "networkConnectionEnabled" => false, "pageLoadStrategy" => "normal", "platformName" => "LINUX", "proxy" => %{}, "se:cdp" => "ws://172.19.0.3:4444/session/5d5bb508ca9af813883d1a1908ac60f4/se/cdp", "se:cdpVersion" => "104.0.5112.79", "se:forwardCdp" => "ws://172.19.0.4:4444/session/5d5bb508ca9af813883d1a1908ac60f4/se/fwd", "se:vnc" => "ws://172.19.0.3:4444/session/5d5bb508ca9af813883d1a1908ac60f4/se/vnc", "se:vncEnabled" => true, "se:vncLocalAddress" => "ws://172.19.0.4:7900", "setWindowRect" => true, "strictFileInteractability" => false, "timeouts" => %{"implicit" => 0, "pageLoad" => 300000, "script" => 30000}, "unhandledPromptBehavior" => "dismiss and notify", "webauthn:extension:credBlob" => true, "webauthn:extension:largeBlob" => true, "webauthn:virtualAuthenticators" => true}, "sessionId" => "5d5bb508ca9af813883d1a1908ac60f4"}}

The hack above works but.. I do not know how the other drivers work or how this code should look. You might want to remove the "value" key in httpclient.ex and return just the value of "value".

To reproduce, fire up docker

docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub
docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \
-e SE_EVENT_BUS_PUBLISH_PORT=4442 \
-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
-v ${PWD}/config.toml:/opt/bin/config.toml \
-v /tmp/assets:/opt/selenium/assets \
-v /var/run/docker.sock:/var/run/docker.sock \
selenium/node-docker

Then run {:ok, session} = Wallaby.start_session(capabilities: %{browserName: "chrome"})

Note your nil sessionId

Demonstration Project

No response

blackham commented 2 years ago

And for anyone looking to setup Selenium with dynamic guests, you will need to hack hackney's timeout option in wallaby

config :wallaby,
  driver: Wallaby.Selenium,
  hackney_options: [timeout: 120_000, recv_timeout: 120_000,  pool: :wallaby_pool]
oliver-kriska commented 1 year ago

this should help:

@@ -106,7 +106,7 @@ defmodule Wallaby.Selenium do
     capabilities = Keyword.get(opts, :capabilities, capabilities_from_config(opts))

     with {:ok, response} <- create_session.(base_url, capabilities) do
-      id = response["sessionId"]
+      id = get_session_id(response)

       session = %Session{
         session_url: base_url <> "session/#{id}",
@@ -123,6 +123,9 @@ defmodule Wallaby.Selenium do
     end
   end

+  defp get_session_id(%{"value" => %{"sessionId" => id}}), do: id
+  defp get_session_id(%{"sessionId" => id}), do: id
+
michallepicki commented 1 year ago

Related: https://github.com/elixir-wallaby/wallaby/issues/455