-
-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experimental selenium driver #198
Conversation
lib/wallaby/experimental/selenium.ex
Outdated
base_url = Keyword.get(opts, :remote_url, "http://localhost:4444/wd/hub/") | ||
capabilities = Keyword.get(opts, :capabilities, %{}) | ||
create_session_fn = Keyword.get(opts, :create_session_fn, | ||
&Wallaby.Phantom.Driver.create_session/2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still calling Wallaby.Phantom.Driver.create_session
to make the http request to selenium to start the session. Do you think all of the webdriver http requests should live in a common module like in #195, or would you prefer if each driver implements its own http requests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally they could live in their own module but for now lets separate them. Once we have support for 3 drivers (phantomjs, selenium, chromedriver, etc.) then we can see if they share enough functionality to merge the driver implementations.
18d83a8
to
1e67d27
Compare
I'd also be interested in how you'd like to see the driver modules designed. Should I be writing each one of the browser interaction functions (like I'm looking forward to hearing your ideas so I can build it right the first time. |
lib/wallaby/experimental/selenium.ex
Outdated
base_url = Keyword.get(opts, :remote_url, "http://localhost:4444/wd/hub/") | ||
capabilities = Keyword.get(opts, :capabilities, %{}) | ||
create_session_fn = Keyword.get(opts, :create_session_fn, | ||
&Wallaby.Phantom.Driver.create_session/2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally they could live in their own module but for now lets separate them. Once we have support for 3 drivers (phantomjs, selenium, chromedriver, etc.) then we can see if they share enough functionality to merge the driver implementations.
lib/wallaby/session.ex
Outdated
screenshots: list | ||
server: pid | nil, | ||
screenshots: list, | ||
driver: module |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a big fan of this idea. This gives us a lot of flexibility for running different browsers against each other.
test/support/session_case.ex
Outdated
@@ -8,7 +8,19 @@ defmodule Wallaby.SessionCase do | |||
end | |||
|
|||
setup do | |||
{:ok, session} = Wallaby.start_session | |||
session_opts = case System.get_env("WEBDRIVER") do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize that this is just for testing so it doesn't matter right now, but if we decide to stick with an implementation like this we should probably prefix the env variable with WALLABY_
. Totally not important right now though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just changed the variable name to WALLABY_WEBDRIVER
.
I think for now we shouldn't try to share functionality between the different driver implementations. Once we have multiple implementations we can see exactly where the common code / patterns are and we can use shared code at that point. Its easier to remove common code once you can see all of it. For now it would be a good idea to share a common api between the drivers. We should create a behaviour that each driver needs to conform to. If you want I can work on that tonight. Then we can use that as a basis for the other drivers. |
1e67d27
to
5bf37f5
Compare
I was thinking all of the drivers would share the following functions:
If a driver didn't support one of these functions, we could return |
5bf37f5
to
2d4ed0c
Compare
I just checked in the |
9b8582f
to
bc1c5bf
Compare
@aaronrenner Regarding the issue with selenium waiting for page loads we may need to look at this: https://www.w3.org/TR/webdriver/#navigation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Just a few small comments. I'll pull down the branch and play with it tonight. I can merge it after that.
@@ -1,6 +1,8 @@ | |||
defmodule Wallaby.Integration.Browser.Actions.ClickButtonTest do | |||
use Wallaby.Integration.SessionCase, async: true | |||
|
|||
alias Wallaby.Integration.PageObjects.IndexPage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small note but it might be misleading to call these Objects
. I just call them Pages
typically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seconded! :)
|> click_link("Page 1") | ||
|> IndexPage.visit() | ||
|> IndexPage.click_page_1_link() | ||
|> Page1.ensure_page_loaded() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love seeing all of these! Using best practices in our own tests is awesome!
|
||
def click_page_1_link(session) do | ||
session | ||
|> click_link("Page 1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to update this to use click(link("Page 1"))
.
|
||
@spec start_session([start_session_opts]) :: {:ok, Session.t} | ||
def start_session(opts \\ []) do | ||
base_url = Keyword.get(opts, :remote_url, "http://localhost:4444/wd/hub/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this option will need to change to something like :selenium_remote_url
once we add chromedriver support as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd start a session by calling:
Wallaby.start_session(driver: Wallaby.Experimental.Selenium, remote_url: "http://localhost:4444/wd/hub")
The :driver
option determines which module to call start_session/1
on and the rest of the options are passed through directly to the driver. That way chromedriver could look like this:
Wallaby.start_session(driver: Wallaby.Experimental.ChromeDriver, remote_url: "http://localhost:4444/wd/hub")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense.
lib/wallaby/experimental/selenium.ex
Outdated
WebdriverClient.send_keys(parent, keys) | ||
end | ||
|
||
# Unsupported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this.
lib/wallaby/session.ex
Outdated
@@ -44,7 +44,7 @@ defmodule Wallaby.Session do | |||
id: String.t, | |||
session_url: String.t, | |||
url: String.t, | |||
server: pid(), | |||
server: pid | nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a super small nitpick but could we use an atom here like :empty
or :none
or maybe even :selenium
? Just to signify that we don't actually use the server key for certain drivers.
@keathley I looked into the webdriver Please let me know if there's anything else you'd like to see on this PR. I think it should be good to go after #209 is merged. |
Updates to build
I have to return %{“value” => nil} because everywhere uses Map.fetch(body, “value”) and if I didn’t have a value key in the map, this would errors. This API really needs to be changed.
I added page objects so I have somewhere to add checking to see if the page is loaded yet. With selenium, when we send a visit command, it doesn't wait until the page is completely loaded to run the next command.
If the screen height was less then 1234 pixels, the test would fail. This uses a much smaller screen height.
There were a couple issues with click_button test. 1. Selenium wasn't waiting until the page finished loading to get the current url, so these tests were failing 2. When the form was submitted it sent a POST request to the test server, which resulted in a 500 error. I updated it to send a get request, but then had to update the current url assertion since the form data was being included as url parameters.
The older version of Firefox injects the xmlns attribute in the html tag. We could probably improve this test if it continues to be an issue.
Also fixed an instance where I was using a deprecated api
I have been having issues on travis ci where selenium times out when starting a session. This should take care of it.
I think I finally took care of the flake tests and it's ready to merge. I added some retry logic to |
I was sort of thinking about giving this another look but honestly 1000 lines is a bit more than my casual evening read :D If you're both 👍 on it then I'm in as well, otherwise I might get to look at it on the weekend but no promises. :) |
Sorry it's such a big PR. I'll make my next one much smaller. 😄 |
Ran through it one last time. Looks good to me 👍 @aaronrenner Do you feel good about merging this now? |
* Was accidentally removed as part of #198
* Was accidentally removed as part of #198
This is a work in progress to add selenium support and allows the existing test suite to be run against a local instance of geckodriver or chromedriver. This is definitely a work in progress, but will show us how the existing test suite runs against different webdriver backends.