elixir-wallaby / wallaby

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

Ensure selenium image v4 works #569

Open peaceful-james opened 4 years ago

peaceful-james commented 4 years ago

As per https://elixirforum.com/t/setting-up-wallaby-with-docker-compose-chrome-and-selenium/32296/14?u=slouchpie

i am opening a reminder issue to test against v4 selenium.

michallepicki commented 4 years ago

Related: https://github.com/elixir-wallaby/wallaby/issues/455 I think Selenium v4 might have deprecated the JSON Wire Protocol and now requires the W3C one, but that will have to be confirmed.

blackham commented 3 years ago

Not sure if this is a Docker HUB v4 issue or Selenium itself (or my bad programming). It looks like it's a wallaby issue since it works with Ruby.

Here is what worked and didn't: single selenium v4 docker instance with Ruby "selenium-webdriver" - Good single selenium v4 docker instance with Wallaby - Good selenium-hub v4 docker-compose with Ruby "selenium-webdriver" - Good selenium-hub v4 docker-compose with Wallaby - Sub-par results

Start TL;DR;

Wallaby results with v4 hub: Wallaby.start_session returns :ok but the commands I send to that session fail. The error from the selenium-hub log includes this bit:

..."attributes": {"exception.message": "Unable to execute request for an existing session: Unable to find session with ID: \nBuild info: version: '4.0.0-rc-2',...

My guess is the ID isn't being loaded, stored or sent correctly by Wallaby.

End TL;DR;

To reproduce: From LInux install docker and docker-composer (pacman -S docker docker-composer). Configure docker to use TCP (see: https://gist.github.com/styblope/dc55e0ad2a9848f2cc3307d4819d819f .. if any selenium docker dev guys read this, PLEASE add this note to your README.md)

Create a hub config file in /tmp/config.toml

[docker]                                                                                                                                                                         
configs = [
    "selenium/standalone-firefox:4.0.0-rc-2-prerelease-20210923", "{\"browserName\": \"firefox\"}",
    "selenium/standalone-chrome:4.0.0-rc-2-prerelease-20210923", "{\"browserName\": \"chrome\"}"
    ]

url = "http://172.17.0.1:2375"
video-image = "selenium/video:ffmpeg-4.3.1-20210923"

Create a place to save the sessions (video?): mkdir /tmp/assets

Create a docker-compose file /tmp/docker-compose-v3-dynamic-grid.yml

version: "3"
services:
  node-docker:
    image: selenium/node-docker:4.0.0-rc-2-prerelease-20210923
    volumes:
      - /tmp/assets:/opt/selenium/assets
      - /tmp/config.toml:/opt/bin/config.toml
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

  selenium-hub:
    image: selenium/hub:4.0.0-rc-2-prerelease-20210923
    container_name: selenium-hub
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"

Start the hub docker-compose -f docker-compose-v3-dynamic-grid.yml up

You can verify the hub is up by checking out http://localhost:4444. Now from an elixir app with wallaby installed.

vi ./config/config.exs

config :wallaby,
  driver: Wallaby.Selenium,
  hackney_options: [timeout: 360_000, recv_timeout: 360_000]

Then form iex fire up a chrome and firefox session.

iex -S mix

{:ok, session1} = Wallaby.start_session(
  remote_url: "http://localhost:4444/wd/hub/",
  capabilities: %{browserName: "firefox"}
)    

{:ok, session2} = Wallaby.start_session(
  remote_url: "http://localhost:4444/",
  capabilities: %{
    browserName: "chrome",
  }
)   

Yes, I know one URL has the path /wd/hub/. This was how it worked in v3, but is no longer needed with v4 (optional). I did it each way to test that it's not a path issue.

These will both return {:ok, session}. You should also see two new dynamically created selenium sessions in http://localhost:4444. Now blow it up by running this in iex:

Wallaby.Browser.visit(session1, "https://www.google.com")
Wallaby.Browser.visit(session2, "https://www.yahoo.com")

These will both fail. If you look at the shell running the selenium-hub (via docker-compose) you'll see WARN messages with more details. But I think the key was already pointed out earlier in my message about the ID: being blank.

To see it work, run this


gem install selenium-webdriver
irb

require "selenium-webdriver"

puts "This bit is to fix an issue with WebDriver not being ready for ruby 3.0"
module Selenium
  module WebDriver
    module Remote
      class Bridge
        class << self
          alias_method :original_handshake, :handshake

          def handshake(opts = {})
            original_handshake(**opts)
          end
        end
      end
    end
  end
end

driver_firefox = Selenium::WebDriver.for :remote, url: "http://localhost:4444/", desired_capabilities: :firefox
driver_chrome = Selenium::WebDriver.for :remote, url: "http://localhost:4444/", desired_capabilities: :chrome

driver_firefox.session_id
driver_chrome.session_id

driver_firefox.navigate.to "http://www.google.com"
driver_chrome.navigate.to "http://yahoo.com"

If you want to see that these ruby sessions are working, from http://localhost:4444 find the movie icon on the left of the session ID. Click that. Password is "secret". Should load a VNC of the browser on google or yahoo.

(To view the VNC session via noVNC) image

Selenium's v4 hub feature is going to be pretty cool. Especially with elixir's parallel processing ability. I hope we (you) can get this working.

james-the-elixir-guy commented 2 years ago

The error described in the OP-linked elixirforum discussion is actually fixed by an existing PR: https://github.com/elixir-wallaby/wallaby/pull/649

I'm not sure if this PR can be merged or not but it would be great if it could. I believe it would fix this issue.

mhanberg commented 2 years ago

I am going to go through recent PRs in the next week, I can check out this issue as well.

mhanberg commented 2 years ago

GitHub Actions updated selenium to be v4 and I am trying to get the tests to pass.

Running v4 locally (on my M1 mac) works fine, but for some reason the tests are timing out when attempting to create a session on GitHub Actions.

Anyone have any idea? https://github.com/elixir-wallaby/wallaby/runs/6316788812?check_suite_focus=true

matthewbrown48 commented 1 year ago

adding more context on this - selenium 4.9.0 was when the json wire protocol was removed. I'm able to run wallaby against selenium standalone 4.8.0 for both chrome and firefox, but not against 4.9.0. Release notes here https://www.selenium.dev/blog/2022/legacy-protocol-support/