Skip to content

W3C-compliant implementation, native geckodriver support #560

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

Merged
merged 6 commits into from
Nov 9, 2019

Conversation

dunglas
Copy link
Contributor

@dunglas dunglas commented Apr 9, 2018

This PR provides an implementation of the W3C flavor of the WebDriver protocol.This implem is good enough to make the Symfony Panther's test suite green when using the latest version of geckodriver.
It is 100% backward compatible with the current (JsonWire) implementation.

The (only?) missing part is the capabilities support. It's a step to close #469.

TODO:

  • Add geckodriver in Travis to run the project's test suite against a valid implementation of the W3C protocol.

Subsequent work (in other PRs?):

  • Add new classes for exceptions that wasn't part of JsonWire
  • Add support for capabilities and other missing parts

@dunglas dunglas force-pushed the geckodriver branch 3 times, most recently from f66a990 to 30862ff Compare April 9, 2018 14:47
@dunglas dunglas force-pushed the geckodriver branch 3 times, most recently from 161bcca to be980ed Compare June 11, 2018 14:40
Copy link
Collaborator

@OndraM OndraM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dunglas , thanks for the great PR! And sorry for delay... I have few minor notes in the PR, and besides I' have a question - I see you plan to hardcode in Panther the w3c_compliant parameter when using Firefox, but I see this as temporary workaround - in future (and perhaps in different PR) there should be implemented some kind of handshake with the remote end, based on which the protocol can be autodetected. Do you plan implementing this or you don't need it right now? Because until this is implemented, people using php-webdriver directly won't benefit from the W3C protocol support, as they would not have an easy way how to trigger the W3C-compliant mode.

return $this->cookie;
$cookie = $this->cookie;
if (null === $cookie['secure']) {
// Passing a boolean value for the "secure" flag is mandatory when using geckodriver
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this? Is it bug or feature? Is there an issue in geckodriver for this?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's indeed a bug. The W3C spec marks it as optional: https://www.w3.org/TR/webdriver1/#dfn-table-for-cookie-conversion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's a bug... But we have to workaround it for Geckodriver support.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you reported it to the geckodriver team ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not yet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chrome now has the same behavior: Codeception/Codeception@ec2fc73#diff-b69c529efcc6368b5c564f8b36665a22R827

We should leave this as is.

@@ -242,7 +262,7 @@ public function execute(WebDriverCommand $command)
}
}

if ($params && is_array($params) && $http_method !== 'POST') {
if ($params && \is_array($params) && $http_method !== 'POST') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't change this as part of this PR (also on other lines).

The codestyle may be changed, but then we can do this at once in whole codebase, and do not change it randomly to keep this PR self-contained.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert these changes (can't remember why I've done that)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably phpstorm suggestion :)

@@ -371,6 +388,18 @@ public function setFileDetector(FileDetector $detector)
*/
public function submit()
{
if ($this->w3cCompliant) {
$this->executor->execute(DriverCommand::EXECUTE_SCRIPT, [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this will face this issue SeleniumHQ/selenium#3398 in some forms:

If a form control (such as a submit button) has a name or id of submit it will mask the form's submit method.

See referenced issue for more universal way (using prototype method).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already use the prototype method. Am I missing something?

@OndraM
Copy link
Collaborator

OndraM commented Sep 12, 2018

@stof
Copy link

stof commented Sep 12, 2018

@OndraM IIRC, the body of the New session response allows to identify whether it is a W3C or JsonWire response (and the request for the new session works the same in both protocols IIRC). so this would allow detecting automatically whether the session runs in W3C mode or JsonWire mode.

@OndraM
Copy link
Collaborator

OndraM commented Sep 12, 2018

@stof Right, for example how its done in:

This was referenced Sep 20, 2018
Closed
@OndraM OndraM changed the title native geckodriver support, partial W3C implementation Partial W3C implementation, native geckodriver support Sep 20, 2018
@dunglas
Copy link
Contributor Author

dunglas commented Sep 25, 2018 via email

@dunglas
Copy link
Contributor Author

dunglas commented Sep 28, 2018

Protocol handshake added. And tests are all green locally with Geckodriver.

];

// Legacy protocol
if (null !== $required_capabilities && $required_capabilities_array = $required_capabilities->toArray()) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this case really part of the legacy protocol, or should the comment placed above the next if instead ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure... ping @OndraM

@@ -149,15 +182,17 @@ public static function createBySessionID(
$connection_timeout_in_ms = null,
$request_timeout_in_ms = null
) {
$executor = new HttpCommandExecutor($selenium_server_url);
// BC layer to not break the method signature
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should you trigger a deprecation warning if a child class extends this method without adding the argument ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not done added it because the library currently doesn't trigger any deprecation. But why not. WDYT @OndraM?

@dunglas
Copy link
Contributor Author

dunglas commented Oct 1, 2018

Tests are green (including when using Geckodriver directly), and all issues are resolved.
As Geckodriver is working, it's already a large step forward to full W3C compatibility.

Do you think we can merge it as an "experimental" feature @OndraM? We'll still be able to improve things if needed after.

@dunglas
Copy link
Contributor Author

dunglas commented Oct 28, 2019

@OndraM while I'm here... :) It would be awesome if this patch could be included in the release adding support for Symfony 5 (#670)!

@OndraM
Copy link
Collaborator

OndraM commented Nov 5, 2019

It seems Geckodriver meanwhile started enforcing more parts of W3C protocol - in this case it requires POST body to be always valid JSON (even if empty), as per Processing model (5.1).

So I updated HttpCommandExecutor accordingly - lets see if it fixes the builds 🍀 .

@dunglas
Copy link
Contributor Author

dunglas commented Nov 5, 2019

And it's now green! Thank you for rebasing and fixing the remaining issues!

@OndraM OndraM merged commit 6dd8b58 into php-webdriver:community Nov 9, 2019
@OndraM
Copy link
Collaborator

OndraM commented Nov 9, 2019

Well, finally merged to community branch! 🎉 I will try to merge few other active PRs now, then tag a new version and get things rolling.

Once again thanks @dunglas for your work!

@OndraM
Copy link
Collaborator

OndraM commented Nov 10, 2019

Now I'm working on issue with ChromeOptions capability which emerged after this was merged.

The handshake now breaks newer selenium servers - which will not allow chromeOptions in firstMatch W3C capabilities (because it is against the spec).

Facebook\WebDriver\Exception\UnknownServerException: Illegal key values seen in w3c capabilities: [chromeOptions]

However if we just rename chromeOptions to goog:chromeOptions, we would break it for Chromedriver <2.31 which added support for both of them...

@OndraM
Copy link
Collaborator

OndraM commented Nov 11, 2019

Ok, having some good news.

Issue with chromeOptions was resolved and merged in #673.

In #674 I also removed workaround which forced Chrome to always use JsonWire OSS protocol. Now we always let the handshake determine the proper protocol. I also added Chromedriver builds to make sure it works with both OSS and W3C protocols - and the tests are passing 🎉 . (The coverage we have is far from being perfect, so there may be some unresolved issues with W3C protocol - in this case one can explicitly disable W3C protocol on Chromedriver, see issue description in #674.)

So the community branch could now officialy undergo some testing of W3C protocol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

W3C WebDriver protocol support
7 participants