Merge inbound to mozilla-central. a=merge
authorNoemi Erli <nerli@mozilla.com>
Sun, 16 Sep 2018 12:50:28 +0300
changeset 436624 7ed950e60f3c
parent 436614 300d0f16cf6f (current diff)
parent 436623 b58b63ffcf08 (diff)
child 436633 bf8ae063de6a
child 436642 1e167ef58df9
push id34651
push usernerli@mozilla.com
push date2018-09-16 09:50 +0000
treeherdermozilla-central@7ed950e60f3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
7ed950e60f3c / 64.0a1 / 20180916100118 / files
nightly linux64
7ed950e60f3c / 64.0a1 / 20180916100118 / files
nightly mac
7ed950e60f3c / 64.0a1 / 20180916100118 / files
nightly win32
7ed950e60f3c / 64.0a1 / 20180916100118 / files
nightly win64
7ed950e60f3c / 64.0a1 / 20180916100118 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -822,26 +822,26 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckodriver"
-version = "0.21.0"
+version = "0.22.0"
 dependencies = [
  "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "mozprofile 0.3.0",
- "mozrunner 0.7.0",
+ "mozprofile 0.4.0",
+ "mozrunner 0.8.0",
  "mozversion 0.1.3",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)",
  "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.37.0",
  "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1373,27 +1373,27 @@ version = "0.0.0"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mozprofile"
-version = "0.3.0"
+version = "0.4.0"
 dependencies = [
  "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mozrunner"
-version = "0.7.0"
+version = "0.8.0"
 dependencies = [
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "mozprofile 0.3.0",
+ "mozprofile 0.4.0",
  "winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mozurl"
 version = "0.0.1"
 dependencies = [
  "nserror 0.1.0",
--- a/browser/components/extensions/parent/ext-search.js
+++ b/browser/components/extensions/parent/ext-search.js
@@ -29,18 +29,17 @@ async function getDataURI(resourceURI) {
 }
 
 this.search = class extends ExtensionAPI {
   getAPI(context) {
     return {
       search: {
         async get() {
           await searchInitialized;
-          let engines = Services.search.getEngines();
-          let visibleEngines = engines.filter(engine => !engine.hidden);
+          let visibleEngines = Services.search.getVisibleEngines();
           return Promise.all(visibleEngines.map(async engine => {
             let favIconUrl;
             if (engine.iconURI) {
               if (engine.iconURI.schemeIs("resource") ||
                   engine.iconURI.schemeIs("chrome")) {
                 // Convert internal URLs to data URLs
                 favIconUrl = await getDataURI(engine.iconURI.spec);
               } else {
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -147,17 +147,17 @@
 #include "nsIObserverService.h"
 #include "nsIParentChannel.h"
 #include "nsIPresShell.h"
 #include "nsIRemoteWindowContext.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISiteSecurityService.h"
 #include "nsISound.h"
-#include "nsISpellChecker.h"
+#include "mozilla/mozSpellChecker.h"
 #include "nsIStringBundle.h"
 #include "nsISupportsPrimitives.h"
 #include "nsITimer.h"
 #include "nsIURIFixup.h"
 #include "nsIURL.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIXULWindow.h"
 #include "nsIDOMChromeWindow.h"
@@ -2400,17 +2400,17 @@ ContentParent::InitInternal(ProcessPrior
 
   xpcomInit.isLangRTL() = false;
   xpcomInit.haveBidiKeyboards() = false;
   if (bidi) {
     bidi->IsLangRTL(&xpcomInit.isLangRTL());
     bidi->GetHaveBidiKeyboards(&xpcomInit.haveBidiKeyboards());
   }
 
-  nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
+  nsCOMPtr<nsISpellChecker> spellChecker(mozSpellChecker::Create());
   MOZ_ASSERT(spellChecker, "No spell checker?");
 
   spellChecker->GetDictionaryList(&xpcomInit.dictionaries());
 
   LocaleService::GetInstance()->GetAppLocalesAsLangTags(xpcomInit.appLocales());
   LocaleService::GetInstance()->GetRequestedLocales(xpcomInit.requestedLocales());
 
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1"));
@@ -4610,17 +4610,17 @@ ContentParent::IgnoreIPCPrincipal()
                                  "dom.testing.ignore_ipc_principal", false);
   }
   return sIgnoreIPCPrincipal;
 }
 
 void
 ContentParent::NotifyUpdatedDictionaries()
 {
-  nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
+  nsCOMPtr<nsISpellChecker> spellChecker(mozSpellChecker::Create());
   MOZ_ASSERT(spellChecker, "No spell checker?");
 
   InfallibleTArray<nsString> dictionaries;
   spellChecker->GetDictionaryList(&dictionaries);
 
   for (auto* cp : AllProcesses(eLive)) {
     Unused << cp->SendUpdateDictionaryList(dictionaries);
   }
--- a/editor/spellchecker/EditorSpellCheck.cpp
+++ b/editor/spellchecker/EditorSpellCheck.cpp
@@ -318,19 +318,18 @@ EditorSpellCheck::GetSpellChecker()
 // allowing callers to ask if we can spell check without actually doing so (and
 // enabling or disabling UI as necessary). This just creates a spellcheck
 // object if needed and asks it for the dictionary list.
 NS_IMETHODIMP
 EditorSpellCheck::CanSpellCheck(bool* aCanSpellCheck)
 {
   RefPtr<mozSpellChecker> spellChecker = mSpellChecker;
   if (!spellChecker) {
-    spellChecker = new mozSpellChecker();
-    DebugOnly<nsresult> rv = spellChecker->Init();
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
+    spellChecker = mozSpellChecker::Create();
+    MOZ_ASSERT(spellChecker);
   }
   nsTArray<nsString> dictList;
   nsresult rv = spellChecker->GetDictionaryList(&dictList);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   *aCanSpellCheck = !dictList.IsEmpty();
@@ -384,17 +383,18 @@ EditorSpellCheck::InitSpellChecker(nsIEd
   RefPtr<TextServicesDocument> textServicesDocument =
     new TextServicesDocument();
   textServicesDocument->SetFilterType(mTxtSrvFilterType);
 
   // EditorBase::AddEditActionListener() needs to access mSpellChecker and
   // mSpellChecker->GetTextServicesDocument().  Therefore, we need to
   // initialize them before calling TextServicesDocument::InitWithEditor()
   // since it calls EditorBase::AddEditActionListener().
-  mSpellChecker = new mozSpellChecker();
+  mSpellChecker = mozSpellChecker::Create();
+  MOZ_ASSERT(mSpellChecker);
   rv = mSpellChecker->SetDocument(textServicesDocument, true);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Pass the editor to the text services document
   rv = textServicesDocument->InitWithEditor(aEditor);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -427,19 +427,16 @@ EditorSpellCheck::InitSpellChecker(nsIEd
         // Now tell the text services that you only want
         // to iterate over the text in this range.
 
         rv = textServicesDocument->SetExtent(rangeBounds);
         NS_ENSURE_SUCCESS(rv, rv);
       }
     }
   }
-
-  rv = mSpellChecker->Init();
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
   // do not fail if UpdateCurrentDictionary fails because this method may
   // succeed later.
   rv = UpdateCurrentDictionary(aCallback);
   if (NS_FAILED(rv) && aCallback) {
     // However, if it does fail, we still need to call the callback since we
     // discard the failure.  Do it asynchronously so that the caller is always
     // guaranteed async behavior.
     RefPtr<CallbackCaller> caller = new CallbackCaller(aCallback);
--- a/editor/spellchecker/nsISpellChecker.h
+++ b/editor/spellchecker/nsISpellChecker.h
@@ -6,18 +6,16 @@
 #ifndef nsISpellChecker_h__
 #define nsISpellChecker_h__
 
 #include "mozilla/MozPromise.h"
 #include "nsISupports.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
 
-#define NS_SPELLCHECKER_CONTRACTID "@mozilla.org/spellchecker;1"
-
 #define NS_ISPELLCHECKER_IID                    \
 { /* 27bff957-b486-40ae-9f5d-af0cdd211868 */    \
 0x27bff957, 0xb486, 0x40ae, \
   { 0x9f, 0x5d, 0xaf, 0x0c, 0xdd, 0x21, 0x18, 0x68 } }
 
 namespace mozilla {
 class TextServicesDocument;
 } // namespace mozilla
--- a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp
+++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp
@@ -1,23 +1,23 @@
 /* vim: set ts=2 sw=2 sts=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RemoteSpellCheckEngineParent.h"
 #include "mozilla/Unused.h"
-#include "nsISpellChecker.h"
+#include "mozilla/mozSpellChecker.h"
 #include "nsServiceManagerUtils.h"
 
 namespace mozilla {
 
 RemoteSpellcheckEngineParent::RemoteSpellcheckEngineParent()
 {
-  mSpellChecker = do_CreateInstance(NS_SPELLCHECKER_CONTRACTID);
+  mSpellChecker = mozSpellChecker::Create();
 }
 
 RemoteSpellcheckEngineParent::~RemoteSpellcheckEngineParent()
 {
 }
 
 mozilla::ipc::IPCResult
 RemoteSpellcheckEngineParent::RecvSetDictionary(
--- a/extensions/spellcheck/src/mozSpellChecker.h
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -17,25 +17,30 @@
 #include "nsCycleCollectionParticipant.h"
 
 class mozEnglishWordUtils;
 
 namespace mozilla {
 class RemoteSpellcheckEngineChild;
 } // namespace mozilla
 
-class mozSpellChecker : public nsISpellChecker
+class mozSpellChecker final : public nsISpellChecker
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(mozSpellChecker)
 
-  mozSpellChecker();
-
-  nsresult Init();
+  static already_AddRefed<mozSpellChecker>
+  Create()
+  {
+    RefPtr<mozSpellChecker> spellChecker = new mozSpellChecker();
+    nsresult rv = spellChecker->Init();
+    NS_ENSURE_SUCCESS(rv, nullptr);
+    return spellChecker.forget();
+  }
 
   // nsISpellChecker
   NS_IMETHOD SetDocument(mozilla::TextServicesDocument* aTextServicesDocument,
                          bool aFromStartofDoc) override;
   NS_IMETHOD NextMisspelledWord(nsAString &aWord, nsTArray<nsString> *aSuggestions) override;
   NS_IMETHOD CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray<nsString> *aSuggestions) override;
   NS_IMETHOD Replace(const nsAString &aOldWord, const nsAString &aNewWord, bool aAllOccurrences) override;
   NS_IMETHOD IgnoreAll(const nsAString &aWord) override;
@@ -52,18 +57,21 @@ public:
 
   void DeleteRemoteEngine() {
     mEngine = nullptr;
   }
 
   mozilla::TextServicesDocument* GetTextServicesDocument();
 
 protected:
+  mozSpellChecker();
   virtual ~mozSpellChecker();
 
+  nsresult Init();
+
   RefPtr<mozEnglishWordUtils> mConverter;
   RefPtr<mozilla::TextServicesDocument> mTextServicesDocument;
   nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
 
   nsCOMPtr<mozISpellCheckingEngine>  mSpellCheckingEngine;
   bool mFromStart;
 
   nsString mCurrentDictionary;
--- a/extensions/spellcheck/src/mozSpellCheckerFactory.cpp
+++ b/extensions/spellcheck/src/mozSpellCheckerFactory.cpp
@@ -1,43 +1,33 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #include "mozilla/ModuleUtils.h"
 #include "mozHunspell.h"
-#include "mozSpellChecker.h"
 #include "mozPersonalDictionary.h"
 #include "nsIFile.h"
 
-#define NS_SPELLCHECKER_CID         \
-{ /* 8227f019-afc7-461e-b030-9f185d7a0e29 */    \
-0x8227F019, 0xAFC7, 0x461e,                     \
-{ 0xB0, 0x30, 0x9F, 0x18, 0x5D, 0x7A, 0x0E, 0x29} }
-
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozHunspell, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozSpellChecker, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozPersonalDictionary, Init)
 
 NS_DEFINE_NAMED_CID(MOZ_HUNSPELL_CID);
-NS_DEFINE_NAMED_CID(NS_SPELLCHECKER_CID);
 NS_DEFINE_NAMED_CID(MOZ_PERSONALDICTIONARY_CID);
 
 static const mozilla::Module::CIDEntry kSpellcheckCIDs[] = {
     { &kMOZ_HUNSPELL_CID, false, nullptr, mozHunspellConstructor },
-    { &kNS_SPELLCHECKER_CID, false, nullptr, mozSpellCheckerConstructor },
     { &kMOZ_PERSONALDICTIONARY_CID, false, nullptr, mozPersonalDictionaryConstructor },
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kSpellcheckContracts[] = {
     { MOZ_HUNSPELL_CONTRACTID, &kMOZ_HUNSPELL_CID },
-    { NS_SPELLCHECKER_CONTRACTID, &kNS_SPELLCHECKER_CID },
     { MOZ_PERSONALDICTIONARY_CONTRACTID, &kMOZ_PERSONALDICTIONARY_CID },
     { nullptr }
 };
 
 const mozilla::Module kSpellcheckModule = {
     mozilla::Module::kVersion,
     kSpellcheckCIDs,
     kSpellcheckContracts,
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -43,26 +43,16 @@ namespace mozilla {
 using namespace gfx;
 
 namespace layers {
 
 bool CanUsePartialPresents(ID3D11Device* aDevice);
 
 const FLOAT sBlendFactor[] = { 0, 0, 0, 0 };
 
-namespace TexSlot {
-  static const int RGB = 0;
-  static const int Y = 1;
-  static const int Cb = 2;
-  static const int Cr = 3;
-  static const int RGBWhite = 4;
-  static const int Mask = 5;
-  static const int Backdrop = 6;
-}
-
 CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent, widget::CompositorWidget* aWidget)
   : Compositor(aWidget, aParent)
   , mAttachments(nullptr)
   , mHwnd(nullptr)
   , mDisableSequenceForNextFrame(false)
   , mAllowPartialPresents(false)
   , mIsDoubleBuffered(false)
   , mVerifyBuffersFailed(false)
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -235,12 +235,22 @@ private:
   gfx::IntRegion mBackBufferInvalid;
   // This is the clip rect applied to the default DrawTarget (i.e. the window)
   gfx::IntRect mCurrentClip;
 
   bool mVerifyBuffersFailed;
   bool mUseMutexOnPresent;
 };
 
+namespace TexSlot {
+  static const int RGB = 0;
+  static const int Y = 1;
+  static const int Cb = 2;
+  static const int Cr = 3;
+  static const int RGBWhite = 4;
+  static const int Mask = 5;
+  static const int Backdrop = 6;
+}
+
 }
 }
 
 #endif
--- a/gfx/layers/d3d11/MLGDeviceD3D11.cpp
+++ b/gfx/layers/d3d11/MLGDeviceD3D11.cpp
@@ -1578,16 +1578,17 @@ MLGDeviceD3D11::SetPrimitiveTopology(MLG
     topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
     break;
   case MLGPrimitiveTopology::UnitTriangle:
     SetVertexBuffer(0, mUnitTriangleVB, sizeof(float) * 3, 0);
     topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
     break;
   default:
     MOZ_ASSERT_UNREACHABLE("Unknown topology");
+    topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
     break;
   }
 
   mCtx->IASetPrimitiveTopology(topology);
 }
 
 RefPtr<MLGBuffer>
 MLGDeviceD3D11::CreateBuffer(MLGBufferType aType,
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -577,11 +577,8 @@ if CONFIG['CC_TYPE'] in ('clang', 'gcc')
     CXXFLAGS += [
         '-Wno-maybe-uninitialized'
     ]
 
 if CONFIG['MOZ_ENABLE_SKIA']:
   UNIFIED_SOURCES += [
     'composite/PaintCounter.cpp',
   ]
-
-if CONFIG['CC_TYPE'] == 'clang-cl':
-    AllowCompilerWarnings()  # workaround for bug 1090497
--- a/testing/geckodriver/CHANGES.md
+++ b/testing/geckodriver/CHANGES.md
@@ -1,30 +1,92 @@
 Change log
 ==========
 
 All notable changes to this program is documented in this file.
 
 
-Unreleased
-----------
+0.22.0 (2018-09-15)
+-------------------
+
+This release marks an important milestone on the path towards
+a stable release of geckodriver.  Large portions of geckodriver
+and the [webdriver] library it is based on has been refactored to
+accommodate using [serde] for JSON serialization.
+
+We have also made great strides to improving [WebDriver conformance],
+to the extent that geckodriver is now _almost_ entirely conforming
+to the standard.
 
 ### Added
 
-- Support for WebDriver web element, web frame, and web window
+- Support for WebDriver web element-, web frame-, and web window
   identifiers from Firefox.
 
+- Added support for the non-configurable `setWindowRect` capability
+  from WebDriver.
+
+  This capability informs whether the attached browser supports
+  manipulating the window dimensions and position.
+
+- A new extension capability `moz:geckodriverVersion` is returned
+  upon session creation.
+
 ### Changed
 
-- The HTTP status codes used for [`ScriptTimeout`] and [`Timeout`]
+- All JSON serialization and deserialisation has moved from
+  rustc_serialize to [serde].
+
+- The HTTP status codes used for [script timeout] and [timeout]
   errors has changed from Request Timeout (408) to Internal Server
   Error (500) in order to not break HTTP/1.1 `Keep-Alive` support,
   as HTTP clients interpret the old status code to mean they should
   duplicate the request.
 
+- The HTTP/1.1 `Keep-Alive` timeout for persistent connections  has
+  been increased to 90 seconds.
+
+- An [invalid session ID] error is now returned when there is no
+  active session.
+
+- An [invalid argument] error is now returned when [Add Cookie]
+  is given invalid parameters.
+
+- The handshake when geckodriver connects to Marionette has been
+  hardened by killing the Firefox process if it fails.
+
+- The handshake read timeout has been reduced to 10 seconds instead
+  of waiting forever.
+
+- The HTTP server geckodriver uses, [hyper], has been upgraded to
+  version 0.12, thanks to [Bastien Orivel].
+
+- geckodriver version number is no longer logged on startup, as
+  the log level is not configured until a session is created.
+
+  The version number is available through `--version`, and now
+  also through a new `moz:geckodriverVersion` field in the matched
+  capabilities.
+
+- The webdriver library has been updated to version 0.37.0.
+
+### Fixed
+
+- Parsing [timeout object] values has been made WebDriver conforming,
+  by allowing floats as input.
+
+- Implicit downloads of OpenH264 and Widevine plugins has been disabled.
+
+- The commit hash and date displayed when invoking `--version`
+  is now well-formatted when built from an hg repository, thanks to
+  [Jeremy Lempereur].
+
+- Many documentation improvements, now published on
+  https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/.
+
 
 0.21.0 (2018-06-15)
 -------------------
 
 Note that with this release of geckodriver the minimum recommended
 Firefox and Selenium versions have changed:
 
   - Firefox 57 (and greater)
@@ -909,16 +971,17 @@ 0.1.0 (2015-04-09)
 - Fixed build by updating Cargo.lock with new dependencies for building
 
 - Squash compile warnings
 
 
 
 [README]: https://github.com/mozilla/geckodriver/blob/master/README.md
 [Browser Toolbox]: https://developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox
+[WebDriver conformance]: https://wpt.fyi/results/webdriver/tests?label=experimental
 
 [`CloseWindowResponse`]: https://docs.rs/webdriver/newest/webdriver/response/struct.CloseWindowResponse.html
 [`CookieResponse`]: https://docs.rs/webdriver/newest/webdriver/response/struct.CookieResponse.html
 [`DeleteSession`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.DeleteSession
 [`ElementClickIntercepted`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.ElementClickIntercepted
 [`ElementNotInteractable`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.ElementNotInteractable
 [`FullscreenWindow`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.FullscreenWindow
 [`GetNamedCookie`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.GetNamedCookie
@@ -934,17 +997,26 @@ 0.1.0 (2015-04-09)
 [`SetTimeouts`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.SetTimeouts
 [`SetWindowRect`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.SetWindowRect
 [`StaleElementReference`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.StaleElementReference
 [`UnableToCaptureScreen`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.UnableToCaptureScreen
 [`UnknownCommand`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.UnknownCommand
 [`UnknownError`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.UnknownError
 [`WindowRectParameters`]: https://docs.rs/webdriver/newest/webdriver/command/struct.WindowRectParameters.html
 
+[Add Cookie]: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Commands/AddCookie
+[invalid argument]: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidArgument
+[invalid session id]: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID
+[script timeout]: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/ScriptTimeout
+[timeout]: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/Timeout
+[timeout object]: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Timeouts
+
+[hyper]: https://hyper.rs/
 [mozrunner crate]: https://crates.io/crates/mozrunner
+[serde]: https://serde.rs/
 [webdriver crate]: https://crates.io/crates/webdriver
 
 [Actions]: https://w3c.github.io/webdriver/webdriver-spec.html#actions
 [Delete Session]: https://w3c.github.io/webdriver/webdriver-spec.html#delete-session
 [Element Click]: https://w3c.github.io/webdriver/webdriver-spec.html#element-click
 [Get Timeouts]: https://w3c.github.io/webdriver/webdriver-spec.html#get-timeouts
 [Get Window Rect]: https://w3c.github.io/webdriver/webdriver-spec.html#get-window-rect
 [insecure certificate]: https://w3c.github.io/webdriver/webdriver-spec.html#dfn-insecure-certificate
@@ -952,14 +1024,16 @@ 0.1.0 (2015-04-09)
 [New Session]: https://w3c.github.io/webdriver/webdriver-spec.html#new-session
 [Send Alert Text]: https://w3c.github.io/webdriver/webdriver-spec.html#send-alert-text
 [Set Timeouts]: https://w3c.github.io/webdriver/webdriver-spec.html#set-timeouts
 [Set Window Rect]: https://w3c.github.io/webdriver/webdriver-spec.html#set-window-rect
 [Status]: https://w3c.github.io/webdriver/webdriver-spec.html#status
 [Take Element Screenshot]: https://w3c.github.io/webdriver/webdriver-spec.html#take-element-screenshot
 [WebDriver errors]: https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors
 
+[Bastien Orivel]: https://github.com/Eijebong
 [Jason Juang]: https://github.com/juangj
+[Jeremy Lempereur]: https://github.com/o0Ignition0o
 [Joshua Bruning]: https://github.com/joshbruning
 [Kalpesh Krishna]: https://github.com/martiansideofthemoon
 [Mike Pennisi]: https://github.com/jugglinmike
 [Sven Jost]: https://github/mythsunwind
 [Vlad Filippov]: https://github.com/vladikoff
--- a/testing/geckodriver/Cargo.toml
+++ b/testing/geckodriver/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "geckodriver"
-version = "0.21.0"
+version = "0.22.0"
 description = "Proxy for using WebDriver clients to interact with Gecko-based browsers."
 keywords = ["webdriver", "w3c", "httpd", "mozilla", "firefox"]
 repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/geckodriver"
 readme = "README.md"
 license = "MPL-2.0"
 publish = false
 
 [dependencies]
--- a/testing/geckodriver/doc/Support.md
+++ b/testing/geckodriver/doc/Support.md
@@ -1,11 +1,68 @@
 Supported platforms
 ===================
 
+The following table shows a mapping between [geckodriver releases],
+supported versions of Firefox, and required Selenium version:
+
+<table>
+ <thead>
+  <tr>
+    <th rowspan="2">geckodriver
+    <th rowspan="2">Selenium
+    <th colspan="2">Supported versions of Firefox
+  </tr>
+  <tr>
+    <th>min
+    <th>max
+  </tr>
+ </thead>
+
+ <tr>
+  <td>0.22.0
+  <td>≥ 3.11 (3.14 Python)
+  <td>57
+  <td>n/a
+ <tr>
+  <td>0.21.0
+  <td>≥ 3.11 (3.14 Python)
+  <td>57
+  <td>n/a
+ <tr>
+  <td>0.20.1
+  <td>≥ 3.5
+  <td>55
+  <td>62
+ <tr>
+  <td>0.20.0
+  <td>≥ 3.5
+  <td>55
+  <td>62
+ <tr>
+  <td>0.19.1
+  <td>≥ 3.5
+  <td>55
+  <td>62
+ <tr>
+  <td>0.19.0
+  <td>≥ 3.5
+  <td>55
+  <td>62
+ <tr>
+  <td>0.18.0
+  <td>≥ 3.4
+  <td>53
+  <td>62
+ <tr>
+  <td>0.17.0
+  <td>≥ 3.4
+  <td>52
+  <td>62
+
 
 Clients
 -------
 
 [Selenium] users must update to version 3.11 or later to use geckodriver.
 Other clients that follow the [W3C WebDriver specification][WebDriver]
 are also supported.
 
@@ -23,16 +80,17 @@ We also keep track of known [Selenium], 
 Support is best in Firefox 57 and greater, although generally the more
 recent the Firefox version, the better the experience as they have
 more bug fixes and features.  Some features will only be available
 in the most recent Firefox versions, and we strongly advise using the
 latest [Firefox Nightly] with geckodriver.  Since Windows XP support
 in Firefox was dropped with Firefox 53, we do not support this platform.
 
 
+[geckodriver releases]: https://github.com/mozilla/geckodriver/releases
 [Selenium]: https://github.com/seleniumhq/selenium
 [WebDriver]: https://w3c.github.io/webdriver/
 [implementation status]: https://bugzilla.mozilla.org/showdependencytree.cgi?id=721859&hide_resolved=1
 [Firefox Nightly]: https://whattrainisitnow.com/
 [remote protocol]: https://github.com/mozilla/geckodriver/issues?q=is%3Aissue+is%3Aopen+label%3Amarionette
 [specification]: https://github.com/mozilla/geckodriver/issues?q=is%3Aissue+is%3Aopen+label%3Aspec
 [issue tracker]: https://github.com/mozilla/geckodriver/issues
 [Firefox Nightly]: https://nightly.mozilla.org/
--- a/testing/mozbase/rust/mozprofile/Cargo.toml
+++ b/testing/mozbase/rust/mozprofile/Cargo.toml
@@ -1,10 +1,10 @@
 [package]
 name = "mozprofile"
-version = "0.3.0"
-authors = ["Mozilla Tools and Automation <auto-tools@mozilla.com>"]
+version = "0.4.0"
+authors = ["Mozilla"]
 description = "Library for working with Mozilla profiles."
 repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/mozbase/rust/mozprofile"
 license = "MPL-2.0"
 
 [dependencies]
 tempdir = "0.3.4"
--- a/testing/mozbase/rust/mozrunner/Cargo.toml
+++ b/testing/mozbase/rust/mozrunner/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "mozrunner"
-version = "0.7.0"
+version = "0.8.0"
 authors = ["Mozilla"]
 description = "Reliable Firefox process management."
 repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/mozbase/rust/mozrunner"
 license = "MPL-2.0"
 
 [dependencies]
 log = "0.4"
 mozprofile = { path = "../mozprofile" }