code: async function toWireValue(obj) {
    let value = await Promise.resolve(obj);
    if (value === void 0 || value === null) {
      return value;
    }
  
    if (typeof value === 'boolean'
        || typeof value === 'number'
        || typeof value === 'string') {
      return value;
    }
  
    if (Array.isArray(value)) {
      return convertKeys(value);
    }
  
    if (typeof value === 'function') {
      return '' + value;
    }
  
    if (typeof value[Symbols.serialize] === 'function') {
      return toWireValue(value[Symbols.serialize]());
    } else if (typeof value.toJSON === 'function') {
      return toWireValue(value.toJSON());
    }
    return convertKeys(value);
  }
docs: Converts an object to its JSON representation in the WebDriver wire protocol.
  When converting values of type object, the following steps will be taken:
  <ol>
  <li>if the object is a WebElement, the return value will be the element's
  server ID
  <li>if the object defines a {@link Symbols.serialize} method, this algorithm
  will be recursively applied to the object's serialized representation
  <li>if the object provides a "toJSON" function, this algorithm will
  recursively be applied to the result of that function
  <li>otherwise, the value of each key will be recursively converted according
  to the rules above.
  </ol>
  
  @param {*} obj The object to convert.
  @return {!Promise<?>} A promise that will resolve to the input value's JSON
  representation.