Search code examples
testingwebdriverautomated-testswebdriver-io

What does 'the key input state' mean in the Webdriver spec?


I've been trying to digest the Webdriver spec and its more friendly version. And I'm having trouble understanding what do these words mean (in the description of the 'Element Send Keys' command):

The key input state used for input may be cleared mid-way through "typing" by sending the null key, which is U+E000 (NULL)

I had several ideas of what it might mean, I mention some below as a sort of evidence of my 'prior research'*).

Could somebody, please, explain what does it mean and, if possible, give an example, preferably in JavaScript?


*Attempts to figure it out myself: I thought, one may skip calling releaseActions() if he previously pressed, say, the Shift key, like:

await browser.performActions([
  {
    type: 'key',
    id: 'key1',
    actions: [
      { type: 'keyDown', value: '\u0010', },
    ],
  },
]);
await browser.elementSendKeys(elemUUID, '\uE000ABC');

But no, the shift key was still pressed, when the elementSendKeys() was called.

Also I thought the null character clears text in the element, no, it doesn't.


Solution

  • My original idea about what the words mean was correct, only the example to test it had errors.

    From an abstract point of view, one need to understand, how the spec defines the Actions API. Simplified, it's this:

    In the Webdriver implementation environment there are certain input sources, like null, keyboard, pointer (probably others). And each input source has an associated input state object, which (simplified) is the current state of the source, like (for a keyboard source) which keys are now being held down, or (for a pointer source) where is the cursor now on the screen etc.

    So if one performs a keyDownkeyboard action the key will remain pressed until a keyUp action for the key is performed, or the state is reset.

    The null unicode code point may be used in string literals to reset the state of the keyboard input source, namely release all currently held down keys.

    Here is an example:

    // elemUUID can be taken from the return values
    // of methods like `findElement()` etc.
    
    await browser.performActions([
      {
        type: 'key',
        id: 'key1',
        actions: [
          // \u0008 is used for a Shift key in Webdriver
          // I don't actually know, where it's specified
          { type: 'keyDown', value: '\u0008', },
        ],
      },
    ]);
    
    // Here the remote end (the automated browser)
    // will type a capital A, since the shift key
    // is still being pressed
    await browser.elementSendKeys(elemUUID, 'a');
    
    // One can include the null char somewhere in
    // the string, and all subsequent chars will be
    // 'pressed' without the pressed Shift
    // This will type Aa
    await browser.elementSendKeys(elemUUID, 'a\uE000a');
    

    In my question's example errors were: the wrong unicode code point value for the Shift key, and the capital letters in the text argument to the elementSendKeys() method, which made the driver use the Shift key, despite the null character had been provided, i.e. in:

    await browser.elementSendKeys(elemUUID, '\uE000A');
    

    The shift key will always be pressed, since 'A' implies it.