Implement protocol handshake for Ruby bindings#3809
Conversation
0630dfe to
e92be5e
Compare
|
Hoping to take a look at this soon |
|
@lmtierney @titusfortner This is essentially done, so you can review it. I still need to fix unit tests on Travis (there should be 1 spec failing), but that will be a tiny change. Since the changes are huge and it's only one commit, it might be better to have a call with screen sharing so I could guide you through the changes - it is hard to figure this out from the diff. If not, I'll try to write down the changes in architecture and post in this PR. Just let me know what you guys prefer. |
|
|
||
| def commands(command) | ||
| case command | ||
| when :status, :is_element_displayed |
There was a problem hiding this comment.
@titusfortner Any idea why this was here? There are plenty of commands duplicated between the two, it seems odd that these were singled out
There was a problem hiding this comment.
These two commands are implemented, but aren't part of w3c spec, so they reference the oss implementation. Probably not necessary to do it this way.
| :implicit_timeout, | ||
| :page_load_timeout, | ||
| :script_timeout, | ||
| ].freeze |
There was a problem hiding this comment.
Spec has required capabilities of:
- browser_name
- browser_version
- platform_name
- accept_insecure_certs
- page_load_strategy
- proxy
- set_window_rect
- timeouts
- unhandled_prompt_behavior
There was a problem hiding this comment.
I'd like to rework the capabilities in the followup PRs, I've left a TODO for it above the constant.
lmtierney
left a comment
There was a problem hiding this comment.
Looks good to me, great work
| opts[:platform_name] = opts.delete(:platform) if opts.key?(:platform) | ||
| opts[:timeouts] = {} | ||
| opts[:timeouts]['implicit'] = opts.delete(:implicit_timeout) if opts.key?(:implicit_timeout) | ||
| opts[:timeouts]['page load'] = opts.delete(:page_load_timeout) if opts.key?(:page_load_timeout) |
There was a problem hiding this comment.
this should actually be pageLoad per the spec, which means we currently have it wrong
There was a problem hiding this comment.
let's fix it in the next PRs
| "lib/selenium/webdriver/ie.rb" | ||
| ], | ||
| resources = [ | ||
| { "//javascript/webdriver/atoms:getAttribute": "rb/lib/selenium/webdriver/atoms/getAttribute.js"} |
There was a problem hiding this comment.
Since we now have the protocol handshake, we should probably add this to common instead of including in each one. The only one that shouldn't need it in the long run would be legacy FF and it's not that much overhead
f6e9e7d to
f45ca34
Compare
|
It's been almost 2 weeks, so I'm going to merge it later today unless there will be any objections. |
|
I'm halfway through a review, but there's a lot more code here than I have time to work through right now. I can finish up tomorrow. Thanks for your patience. |
titusfortner
left a comment
There was a problem hiding this comment.
I'm not sure I fully get the move from Bridge -> Driver. It feels like this is adding a lot of complexity because there is more module extension and requiring of modules with class methods than just a straight class hierarchy as before. For what we need to do with capabilities classes, though, maybe this is necessary.
I guess it decouples capabilities from the Bridge classes. So the Bridge is now just the command interface to the server/driver, which is a positive move.
Not that it should be our primary concern, but I'm curious how much this is going to affect the Ruby Appium library since it does so much monkey patching of the internals.
Also, we've been telling people that if they want to customize their driver/server interaction to subclass a Bridge and make their own custom commands. So, I'm concerned that this change will completely break their implementation.
From a high level view, I don't think this is how I would have approached it, but sketching out a few alternate ideas this week I've come to the conclusion that a more elegant solution isn't obvious to me. :) As for the actual implementation of this design, I think I see how everything is working and I don't have any major issues.
Thanks for all the work on this.
| opts[:url] = @launcher.url | ||
| end | ||
|
|
||
| @bridge = Remote::Bridge.handshake(opts) |
There was a problem hiding this comment.
I notice you forced the Edge implementation to use W3C protocol. Since this is the "Legacy Firefox" when would this get called and need to use W3C?
There was a problem hiding this comment.
There are some weird things there. You've implemented Edge bridge as W3C bridge, however it responds like OSS one, so there is a bit of confusion here. By forcing W3C in Edge, I'm keeping the current behavior and implementation, though I'd like to rework this later.
In regards to legacy Firefox, there is actually no need to do this, so I'll change.
There was a problem hiding this comment.
Edge was implemented as W3C because that was the format of the desired capabilities it accepted, which was what I was most concerned about. Edge Driver has from the beginning supported an interesting mix of OSS & W3C commands. Yes, this distinction won't matter once we send both formats, though it could raise some other issues if this approach expects drivers to be completely compatible with either OSS or W3C.
There was a problem hiding this comment.
I've changed it so now neither Marionette::Driver nor Legacy::Driver do handshake.
|
|
||
| module Bridge | ||
|
|
||
| # Support for geckodriver < 0.15 |
There was a problem hiding this comment.
Unless you really want to, I'm ok with telling Ruby users to upgrade to the latest geckodriver. :)
There was a problem hiding this comment.
I put this in the current bridge, @p0deje you can remove these commands
There was a problem hiding this comment.
@lmtierney Sorry, I don't follow what you mean
There was a problem hiding this comment.
@p0deje you can get rid of this entire bridge file. These window commands were added for backward compatibility with older geckodriver versions. Since we are fine with requiring the latest geckodriver they aren't needed anymore
| execute :touch_scroll, {}, {element: element, | ||
| xoffset: x, | ||
| yoffset: y} | ||
| if oss_status |
There was a problem hiding this comment.
I'm not sure this is the correct toggle for this. Are we sure that Se4 Server isn't going to return a status value with a w3c response once it supports that? I think we might need to parse the capabilities themselves for this conditional. Of course we can make that a TODO for later if necessary.
There was a problem hiding this comment.
That's how Java and .NET bindings do this, so ¯_(ツ)_/¯
Yeah, that was the idea.
I know they have already created appium/ruby_lib#558 and appium/ruby_lib#559. It would be great to hear from them here, but I don't really have time to reach them out.
It's not changed, isn't it? You can still pass custom bridge so I don't see a problem here: bridge = MyCustomBridge.new
driver = Selenium::WebDriver::Driver.new(bridge)
I was attempting to also make it more consistent to other bindings. None of them have a bridge, but all of them have custom driver classes, so I actually think it is now clearer. I would have to decouple capabilities and bridge anyways and driver class seems like a best option. |
|
Ah, okay, awesome!
…On Tue, May 2, 2017 at 6:42 PM Lucas Tierney ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In rb/lib/selenium/webdriver/firefox/marionette/bridge.rb
<#3809 (comment)>:
> +# specific language governing permissions and limitations
+# under the License.
+
+module Selenium
+ module WebDriver
+ module Firefox
+ module Marionette
+
+ #
+ # Extension for the usual Remote::W3C::Bridge
+ # @api private
+ #
+
+ module Bridge
+
+ # Support for geckodriver < 0.15
@p0deje <https://github.com/p0deje> you can get rid of this entire
bridge. These window commands were added for backward compatibility with
older geckodriver versions. Since we are fine with requiring the latest
geckodriver they aren't needed anymore
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3809 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAoo9vr02xnqKIyHbvS2Vc-noYg5k9cdks5r1ySYgaJpZM4M5i0l>
.
|
Ruby bindings need to detect what protocol dialect it should talk
using protocol handshake which:
1. Prepares capabilities for both OSS and W3C dialects.
2. Sends them in a single payload like this:
{
"desiredCapabilities": {...},
"capabilities": {
"firstMatch": [{...}]
}
}
3. Based on a response, understand which dialect it needs to use.
This commit adds Remote::Bridge.handshake, refactors driver-specific
bridges into Driver classes which are responsible for preparing
driver-specific capabilities, calling handshake and using the bridge
it returns (OSS or W3C) to abstract dialect-specific communication.
For Firefox, it introduces Legacy and Marionette namespaces with its own
Driver classes and bridge extensions.
For Edge, it uses a hacky way to force W3C dialect even though
MicrosoftWebDriver responds with OSS-like body.
It also namespaces remote bridges/commands/etc. into OSS and W3C
modules respectively.
|
All the comments are addressed, now just waiting for CI. |
Description
This is currently work in progress.This is done.We need Ruby bindings to detect what protocol dialect it should talk (e.g. current IEDriver talks OSS dialect, but newer beta versions talk W3C dialect). In order to do that, we need to implement protocol handshake from Java bindings which:
See commit messages for details.
TODO
Tests
go //rb:unit-testgo //rb:chrome-test(ran against Chrome 57 and ChromeDriver 2.29)go //rb:edge-test(ran against Microsoft Edge 38.14393.67.0 and 40.15063.0.0) (there are 19 failures in master and this branch)go //rb:ff-esr-test(ran against Firefox 45 ESR to verify legacy driver)go //rb:ff-nightly-test(there are 17 failures in master and 8 failures this branch)go //rb:firefox-test(ran against Firefox 52/53 and GeckoDriver 0.15/0.16)go //rb:ie-test(ran against IE11 and master IEDriver 32-bit)go //rb:ie-test(ran against IE11 and beta IEDriver 32-bit) (there are 14 failures mostly about keyboard/mouse which I'm going to address in a followup commits)go //rb:phantomjs-test(ran against PhantomJS 2.1.1)go //rb:remote-chrome-testgo //rb:remote-edge-test(there are 2 failures in master and this branch)go //rb:remote-ff-esr-testgo //rb:remote-ff-nightly-test(there are 11 failures in master and this branch)go //rb:remote-firefox-test(there are 5 failures in master and this branch)go //rb:remote-ie-test(master IEDriver) (there are 5 failures in master and this branch)go //rb:remote-ie-test(beta IEDriver) (there are 25 failures which I'm going to work on in the followup commits)go //rb:remote-phantomjs-testgo //rb:remote-safari-preview-test(threre are 32 failures in master and this branch)go //rb:remote-safari-test(there are 10 failures in master and this branch)go //rb:remote-testgo //rb:safari-preview-test(there are 45 failures in master and this branch)go //rb:safari-test(ran against Safari 10.1)