Fixing Selenium typing errors in Firefox

Guest post by Thomas Rose

I recently updated our Selenium Remote Control (RC) testing tool to v1.0.1 so that we could test our site on Google Chrome (and, somewhat tentatively, IE8).  We have been using this tool with varying success for quite some time now, with our tests written in PHP. The update process was generally smooth but one annoying bug persisted - Selenium would no longer type the ‘y’ key in Firefox (2 and 3). As a result many of our tests broke simply because the input typed into a text box did not match what was intended.

I am by no means a keycode expert - far from it, in fact. On the surface, the bug seemed limited to a certain subset of characters: the y key, the ‘ key and the . key (and possibly others) would not type correctly, while all other characters were seemingly fine. We were not quite sure therefore what was causing this to occur.

After a little bit of digging, the source of the problem was identified: Mozilla’s event.initKeyEvent, and its implementation in htmlutils.js in Selenium. The function header is thus:

event.initKeyEvent (type, bubbles, cancelable, viewArg,
                    ctrlKeyArg, altKeyArg, shiftKeyArg,
                    metaKeyArg, keyCodeArg, charCodeArg)

The problem lies in the second-last argument, keyCodeArg. This represents the virtual key code value of the key code that was depressed, otherwise zero. The problem is that Selenium converts the desired character into its character code, but passes it to initKeyEvent as both the character code (correctly) and the virtual key code (incorrectly). The issue arises, then, because some virtual key codes are shared with character codes - in this case, ‘y’ is equivalent to ‘F10’. So instead of typing ‘yes’, Selenium would effectively hit F10 followed by ‘e’ and ‘s’.

Our application has no real need to use virtual key codes, so the problem was quickly fixed by changing the keycode argument from keycode to 0 in the line where initKeyEvent is called in htmlutils.js (in my case, line 352):

evt.initKeyEvent(eventType, true, true, window, controlKeyDown, altKeyDown,
                 shiftKeyDown, metaKeyDown, 0, keycode);

Et voila! We can type again!

Note: to find htmlutils.js, open selenium-server.jar with a utility such as WinRAR. It is located in core/scripts. You can extract the file, edit it, and replace it in the jar.

If, for whatever reason, you need to use virtual key codes, then we have also considered a couple of alternative workarounds:

1. The trivial yet not ideal solution: modify the Selenium class so that all buggy characters are replaced, e.g.

<?php
  public function type($locator, $value) {
    $value = str_replace(array('y','\'','.'), array('i','',''), $value);
    $this->doCommand("type", array($locator, $value));
  }

2. The method suggested by the authors of Selenium - use the keyDownNative(), keyPressNative() and keyUpNative() functions in place of keyDown(), keyPress() and keyUp() respectively. These methods have been available in Selenium RC since v1.0b1. However I was unable to get any characters to type which could point to an error in the PHP implementation. To use these functions you must remember to set the focus on the form element which you need to use before using the key functions (trivial with Selenium’s focus method).

I hope this helps someone - if anyone with a little more keycode/Selenium knowledge can suggest a better fix then I am all ears! Thanks also to Paul for inviting me to write on his blog.

comments powered by Disqus