Opera Exec protocol

The Opera Exec protocol can be used to control an Opera instance from the outside, and various operations can be initiated. This functionality is mainly useful for QA testing.

BNF

This is the grammar describing the data.


#
# Commands (messages sent to the Opera instance to be manipulated)
#

PROTOCOL ::= (COMMAND | EVENT)*;

COMMAND ::= EXEC
          | GET-ACTION-INFO-LIST
          | SCREEN-WATCHER
          ;

EVENT ::= ACTION-INFO-LIST
        | SCREEN-WATCHER-REPLY
        ;

EXEC ::= "<exec>" OPERATION+ "</exec>" ;

# Although the EBNF does not reflect this, only one MOUSE-ACTION is
# allowed per EXEC command.

OPERATION ::= KEYDOWN
            | KEYUP
            | TYPE
            | ACTION
            | MOUSE-ACTION
            ;

KEYDOWN ::= "<keydown>"
            KEY
            "</keydown>"
            ;

KEYUP ::= "<keyup>"
          KEY
          "</keyup>"
          ;

TYPE ::= "<type>"
         TEXT
         "</type>"
         ;

ACTION ::= "<action>"
           NAME
           PARAM?
           WINDOW-ID?
           "</action>"
           ;

# PARAM to the action. E.g. "opera.com" to the command "go"
PARAM ::= "<param>"
          TEXT
          "</param>"
          ;

WINDOW-ID ::= "<window-id>"
              UNSIGNED
              "</window-id>"
              ;

# The KEY is either a key-name ("ctrl", "down", etc.)
# or a single character ("a", "b", etc.)

KEY ::= TEXT ;

# The ACTION-NAME is the name of an Action ("Page Down", "New Page", etc.)

ACTION-NAME ::= TEXT ;

# Request a list of valid actions. The reply will come as an ACTION-INFO-LIST

GET-ACTION-INFO-LIST ::= "<get-action-info-list />" ;

ACTION-INFO-LIST ::= "<action-info-list>"
                        NAME*
                     "</action-info-list>"
                     ;

NAME ::= "<name>"
            ACTION-NAME
         "</name>"
         ;


# Defaults:
#   WINDOW-ID:  current window
#   TIMEOUT:    150000 (15 seconds)
#   AREA:       x=0, y=0, w=200, h=100

SCREEN-WATCHER ::= "<screen-watcher>"
                     WINDOW-ID?
                     TIMEOUT?
                     AREA?
                     MD5*
                     COLOR-SPEC*
                     INCLUDE-IMAGE?
                  "</screen-watcher>" ;

# Timeout in milliseconds
# If omitted, defaults to 15 seconds

TIMEOUT ::= "<timeout>" UNSIGNED "</timeout>" ;

# Define an area on the page, relative to the page (not viewport)

AREA ::= "<area>"
            "<x>" UNSIGNED "</x>" # horizontal offset
            "<y>" UNSIGNED "</y>" # vertical offset
            "<w>" UNSIGNED "</w>" # width
            "<h>" UNSIGNED "</h>" # height
            "<viewport-relative />"     # are the coordinates relative to viewport or document
         "</area>" ;

# MD5 sum of an image, in hexadecimal

MD5 ::= "<md5>" "0x" [0-9a-f]{32} "</md5>" ;

# The reply SCREEN-WATCHER-REPLY will include a count of all the pixles for the
# various id's given in the colspecs. You can have multiple colspecs with the
# same id - the report will then include the total count of all the colspecs
# for that id. You can also have overlapping color specifications.
#
# Note: There can be maximum 16 colorspecs!
#
# Any LOW-* element missing will default to 0
# Any HIGH-* element missing will default to 255
#
# Returns SCREEN-WATCHER-REPLY

COLOR-SPEC ::= "<color-spec>"
                  ID
                  LOW-RED?
                  HIGH-RED?
                  LOW-GREEN?
                  HIGH-GREEN?
                  LOW-BLUE?
                  HIGH-BLUE?
               "</color-spec>" ;

# ID is used by COLOR-SPEC to identify a color. Does not need to be unique

ID ::= "<id>" UNSIGNED "</id>" ;

# Specify whether to include the image ("yes") or not ("no"). Can be used to
# reduce bandwith usage in applications where only hashes are needed.
#
# Default is YES.

INCLUDE-IMAGE ::= "<include-image>"
                     (
                        "<yes />"
                        "<no />"
                     )
                  "<include-image>" ;

# Sent as reply to SCREEN-WATCHER command.

SCREEN-WATCHER-REPLY ::= "<screen-watcher-reply>"
                            WINDOW-ID
                            MD5
                            COLOR-MATCH*
                         "</screen-watcher-reply>" ;

# The count of color IDs that matched (ID is from COLOR-SPEC).

COLOR-MATCH ::= "<color-match>"
                   ID
                   "<count>" UNSIGNED "</count>"
                "</color-match>" ;

###
# Color values ranging from 0 (no color) to 255 (maximal saturation).
# Default (meaning element missing) is 0 for LOW-* elements and 255 for HIGH-* elements.
#

LOW-RED    ::= "<low-red>"    UNSIGNED "</low-red>" ;
HIGH-RED   ::= "<high-red>"   UNSIGNED "</high-red>" ;
LOW-GREEN  ::= "<low-green>"  UNSIGNED "</low-green>" ;
HIGH-GREEN ::= "<high-green>" UNSIGNED "</high-green>" ;
LOW-BLUE   ::= "<low-blue>"   UNSIGNED "</low-blue>" ;
HIGH-BLUE  ::= "<high-blue>"  UNSIGNED "</high-blue>" ;

# Moved mouse to the given position on the screen/window.
# Note that the mouse cursor is not moved visibly.
#
# The coordinates are relative to the upper left corner of the tab
# (not including chrome).
#
# Only one MOUSE-ACTION can be sent per EXEC command.

MOUSE-ACTION ::= "<mouse-action>"
                    WINDOW-ID
                    "<x>" UNSIGNED "</x>"
                    "<y>" UNSIGNED "</y>"
                    BUTTONS
                 "</mouse-action>"
                 ;

# BUTTONS specifies the buttons to press or release
# It is specifies as the sum of button actions:
#       1 - Button 1 down
#       2 - Button 1 up
#
#       4 - Button 2 down
#       8 - Button 2 up
#
#      16 - Button 3 down
#      32 - Button 3 up
#
# For example, to press button 1 and release button 2, the value is 9 (1+8)
#
# Buttons are clicked in the sequence listed above. Note that down actions are
# listed before up actions, thus allowing single-clicking with one command
# (e.g. using value 3)

BUTTONS ::= "<buttons>" UNSIGNED "</buttons>" ;

###
# From ecmascript-debugger-protocol.html
#

UNSIGNED ::= [0-9]+ ;

TEXT ::= BASE64-ENCODED-DATA | textual-data ;

BASE64-ENCODED-DATA ::= "<base64-encoded-data>" textual-data "</base64-encoded-data>" ;

Examples

The following example will do a spatial navigation down:

<exec>
  <keydown>shift</keydown><keydown>down</keydown>
  <keyup>down</keyup><keyup>shift</keyup>
</exec>

The following will type the text "Hello":

<exec><type>Hello</type></exec>

Take note that shift-modifier key-presses are neither generated nor taken into account when processing the letters of the TYPE operation. This means that no shift key will be pressed around the 'H' in 'Hello' above, and the text typed would still be 'Hello' if the shift key was pressed (with a KEYDOWN operation) before the TYPE operation.

The following will trigger an Action of "Page down":

<exec><action>Page Down</action></exec>

Error handling

There are currently no error messages or other reports of a failed operation. Incorrect syntax, unknown keys, or other invalid input will be silently dropped.