Dance of the Automation Marionette

As many automation engineers know, we’ve been dealing with Marionette, the successor to the Firefox Selenium driver, for some time now. We’re starting to see a light at the end of the tunnel. However, I’m finding a lot of teams are still struggling with what all of this means. Here I’ll talk real briefly. To give some context, Mozilla is moving away from the FirefoxDriver and into what it calls Marionette or a “geckodriver.” (The latter name started being used as of version 0.8.0.) Depending on who you ask, this has been handled “just okay” or downright terribly. Part of the problem is that changes are happening not just to how Firefox style browsers are driven but to how Selenium itself needs to support that driver. The communication between the Mozilla team and the Selenium team — at least to outside appearances — has been less than stellar. So just know a few facts:
  • Marionette is the Mozilla version of FirefoxDriver to drive Firefox. This has been in Firefox since about version 24.
  • With the release of Firefox 47, the extension-based version of FirefoxDriver is no longer working.
  • With the release of Firefox 47, incompatibilities were introduced with Selenium 2.53.0.
  • Firefox 47.1 is compatible with Selenium 2.53.1, which does allow you to use the FirefoxDriver.
  • Marionette will be turned on by default in Selenium 3.
  • Full support for Marionette/Geckodriver is planned for Firefox 52.
So what this means is that, assuming all goes well, when Firefox 52 and Selenium 3 are here, the world will go back to being relatively simple in terms of a bundled driver for Selenium. Many have opted for simply using Chrome or any other browser until everything gets sorted out. But if you want or need to keep Firefox as your primary drive, and if you don’t want to worry about Marionette, another option is to downgrade to Firefox 45, preferably the ESR. I say 45 rather than 46 because 45 won’t update to 47.

Get the Marionette

For any language you care to work with, download and extract the geckodriver binary. You’ll want to put this binary somewhere on your system path. Note that if you are using a Selenium version prior to 2.53.0 you may need to rename the ‘geckodriver’ executable to ‘wires’. This is because earlier versions of Selenium expected that name. However, on the most up-to-date Selenium, you don’t need to do that. Now let’s consider some examples in specific languages.

JavaScript

Let’s take an example using JavaScript. Here I’ll assume you can install Node.js and NPM. Once you’ve done that, install selenium-webdriver using npm:
npm install selenium-webdriver
You would then create a script like this: Then you could do your normal JavaScript actions against the Selenium API and run the script accordingly via Node.

Ruby

In Ruby, I’ll assume you can install Ruby and RubyGems. Then just make sure you have the Selenium WebDriver gem:
gem install selenium-webdriver
Then create a script like this: Do note, however, that some test libraries, like Capybara, are still having issues with Marionette support.

Python

For Python, I’ll assume you can install Python and PIP. Make sure you install Selenium drivers:
pip install selenium
Then you could create a script like this:

Java

For Java, make sure the Selenium WebDriver JARs you need are on your classpath. I’ll assume you know how to set this all up via Ant, Maven, Gradle or whatever other build tool you use. Then use this in your logic:

C#

For C#, you’ll want to make sure you get the NuGet package for Selenium or get the appropriate DLLs and make sure they are referenced assemblies in your project. Then use this in your logic:

And That’s It

While the switchover to Marionette has caused a lot of problems across the board, it’s not the entirely opaque thing that it is sometimes made out to be. All this being said, do keep in mind that there are still possible issues you will encounter with Marionette/GeckoDriver and Selenium as everything ramps up. Keep that Selenium 3 / Firefox 52 distinction in mind. Also note that you might find it a lot easier to use a WebDriver binary manager. For example, there is a WebDriverManager for Java as well as a WebDriverManager for .NET, both of which support Marionette. For JavaScript, some people like using Selenium Binaries. This, too, supports Marionette.
Share

This article was written by Jeff Nyman

Anything I put here is an approximation of the truth. You're getting a particular view of myself ... and it's the view I'm choosing to present to you. If you've never met me before in person, please realize I'm not the same in person as I am in writing. That's because I can only put part of myself down into words. If you have met me before in person then I'd ask you to consider that the view you've formed that way and the view you come to by reading what I say here may, in fact, both be true. I'd advise that you not automatically discard either viewpoint when they conflict or accept either as truth when they agree.

6 thoughts on “Dance of the Automation Marionette”

  1. An interesting read. I have a question, though – which version of Python are you using for this example?

    I’ve tried your advice and some other incantations, even going as far as changing the default Marionette setting value in the desired_capabilities file, but to no avail (I’m using Python 3.5). Is the 2.7 branch better or more suitable for talking to Firebork, oops, Firefox?

     

    1. It looks like the Python bindings for Selenium are having issues again. (They are not updated with near the frequency of the Ruby and Java versions.)

      For example, a full script that should work just fine in Python 2 or 3:

      However, you might be seeing an error like this: “Service wires unexpectedly exited. Status code was: 1”. That’s the case in both Python 2 and 3. I can get that error to happen with the bindings for Selenium 2.53.6 and Firefox 48.0.2 as well as 49.0.

      Do keep in mind that currently the Python bindings still look for “wires” rather than “geckodriver.” Sometimes putting the binary for your Firefox as a capability will work. For example (on a Mac):

      However, I’ve found that if you have “unexpected exits” or “connection refused”, this rarely fixes the problem.

  2. Thanks for the swift response. Actually, something must be botched harder than one might expect and the Firefox and Python WebDriver bindings duo are have in big trouble in the strictly come automation dancing arena, at least on Windows (I’m on Windows 10, Firefox version 49.0.1). The point is, whatever method I’ve been trying to use so far to make the two cooperate seems to fail, the only ‘success’ in one case being that a browser window opens but the requested page does not load and the Firefox window closes with an error message – this is when I replace the ‘marionette’ capability with ‘wires’, and the error message is”can’t load profile”. The interesting thing is that while trying to use the settings that ‘should’ work, errors still come up, like FileNotFoundError, AttributeError (with the message “‘Service’ object has no attribute ‘process'”), WebDriverException (with the message “‘wires’ executable needs to be in PATH” – it IS in PATH). The trick with Firefox binary also yields an error – ‘str’ has no attribute launch_browser.

    To Firefox’s disadvantage, both Edge and Chrome drivers seem to (and for the time being, DO) work, so that will probably have to suffice. Sorry for bothering you with my whining and thanks for your support.

    1. I don’t see you as whining at all! You are expressing a lot of the frustration that many of us feel.

      I share your frustration with this. Firefox has long been the default driver for Selenium. I get that they want to update it with the GeckoDriver (Marionette). But the roll-out and the communication between the development teams has not been very good, at least when looking in from the outside. This is then coupled with the fact that the bindings for each language need to be updated with at least some eye towards parity.

      I’m going to play around a bit more and see if I can update this post with some more helpful information.

  3. Great post – as someone who hadn’t used Selenium for a while , coming back to it and trying to get Firefox working (for users on different OS) – has been a nightmare

    1. I almost lost hope of getting the F-word browser to cooperate with Python – like other people who also tried to get help via google searches using error messages as keywords (the web is full of requests for help). What turned out that works in my case (I’m on Windows 10) is a combination of two solutions found on stack overflow and some trial and error on my part (or some weird hackity hack similar to making something stick together with a string as nothing else is available) – I have removed geckodriver from PATH and put the exe file in the same folder where I keep my ‘project’. The other part (stack overflow to the rescue) of the trick included importing the firefox binary (instead of desired capabilities), supplying access path to the binary and passing it as an argument to the browser instance (OOPese giving me headaches); my geckodriver version must be 0.11.0 (judging by its modification date). For the moment the basic code to get a website works, but I still have to try more elaborate actions, so time will tell.

      And here’s the code:

      from selenium import webdriver
      from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
      
      binary = FirefoxBinary(r'C:\Program Files (x86)\Mozilla Firefox\firefox.exe')
      
      browser = webdriver.Firefox(firefox_binary=binary)
      browser.get('http://seleniumhq.org/')

       

       

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.