Skip to content

💡 feat: add new driver endpoints to retrieve available commands and extensions #20881

@eglitise

Description

@eglitise

Is your feature request related to a problem?

Appium Inspector has a Commands tab, which allows the user to execute various driver commands and extensions. However, different drivers support different commands and extensions, and currently there is no way to identify the commands and extensions supported by the active driver.

Describe the solution you'd like.

Add two new endpoints:

  • GET /session/:sessionId/appium/commands
  • GET /session/:sessionId/appium/extensions

GET /session/:sessionId/appium/commands

This endpoint should return all commands defined as endpoints in the active driver, the base driver, and any active plugins.

The response format should be largely based around the data structure format currently used for the base driver's method map. The same format should also be used by the active driver and plugins. The endpoint response will then combine all of these responses into one object.

In short, the format of each response should be an object where each key-value pair corresponds to a command. The key should be the command endpoint URL, and its value should also be an object, where each key-value pair corresponds to a supported HTTP method. For this command value object, the key should be the HTTP method name, and the value should be an object with the following properties:

  • info (string, optional) - description with additional information about the command, e.g. 'Simulator only'
  • deprecated (boolean, optional) - indicates whether the command is deprecated. false if omitted
  • payloadParams (object, optional) - an object containing all the supported command parameters. It supports the following keys:
    • required (array, optional) - an array listing the names of all required parameters
    • optional (array, optional) - an array listing the names of all optional parameters

Example response for GET /session/:sessionId/appium/commands:

{
  "basedriver": {
    "/session/:sessionId/url": {
      "GET": {"command": "getUrl"},
      "POST": {"command": "setUrl", "payloadParams": {"required": ["url"]}},
    },
    ...
  },
  "endpointdriver": {
    "/session/:sessionId/appium/device/lock": {
      "POST": {"command": "lock", "payloadParams": {"optional": ["seconds"]}},
    },
    ...
  },
  "plugins": {
    "images": {
      "/session/:sessionId/appium/compare_images": {
        "POST": {
          "command": "compareImages",
          "payloadParams": {
            "required": ["mode", "firstImage", "secondImage"],
            "optional": ["options"],
          }
        }
      }
      ...
    }
    ...
  }
}

Remaining questions:

  • The method map cannot be returned as-is and will require additional processing:
    • Not all methods make sense in the context of user-facing driver/plugin commands, for example createSession, deleteSession, any methods operating on individual elements, etc. These can be either excluded from the response, or excluded on the consumer end.
    • Some methods have more than just the required and optional keys, such as validate and makeArgs. Unclear how these should be handled, but I don't think they can be returned as-is.
  • The Inspector would benefit from a way to distinguish commands that only retrieve data, from commands that change something - in the former case, the Inspector should not refresh the source/screenshot. For now this can be accomplished by treating all GET commands as retrieval-only, though some POST commands also do this, so a better solution is needed. However, this is not a blocker issue and can be resolved later while keeping backwards compatibility.
  • The Inspector would benefit from a way to identify the parameter value types - this would be used to adjust the input fields in the Inspector GUI (e.g. string input, numerical input, toggle for a boolean value). At the moment, all parameters would have to be converted to string, and any type conversion would need to be done on the driver/plugin side.

GET /session/:sessionId/appium/extensions

This endpoint should return the extension commands supported by the active driver when using the W3C /session/:sessionId/execute/sync endpoint.

The response format should be largely based around the data structure format currently used for the XCUITest driver's execute method map. In short, it should be an object where each key-value pair corresponds to an extension command. The key should be the command name, and its value should be an object with the following properties:

  • info (string, optional) - description with additional information about the extension command, e.g. 'Simulator only'
  • deprecated (boolean, optional) - indicates whether the extension command is deprecated. false if omitted
  • params (object, optional) - an object containing all the supported extension command parameters. It supports the following keys:
    • required (array, optional) - an array listing the names of all required parameters
    • optional (array, optional) - an array listing the names of all optional parameters

Example response for GET /session/:sessionId/appium/extensions:

{
  "mobile: sendSms": {
    "info": "Emulator only",
    "params": {
      "required": ["phoneNumber", "message"]
    }
  },
  ...
}

Remaining questions:

  • The XCUITest driver's execute method map also includes the command property. I don't think this property is relevant for the end user, therefore it can be excluded from the response - or it could just be handled on the consumer end.
  • Same as for commands, the Inspector would benefit from a way to distinguish extension commands that only retrieve data, from commands that change something. Unlike commands, the execute method map does not use HTTP methods, so all methods will be assumed to change something, but this, too, is not a blocker issue.
  • Same as for commands, the Inspector would benefit from a way to identify the parameter value types.

Describe alternatives you've considered.

The current approach used in the Inspector relies on hardcoding some known commands, but this list must be continuously updated as drivers add and remove commands and extensions.

Additional context

Any suggested changes to this format can be discussed in this issue 🙂

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions