Neil's Place

September 8, 2009

How to Fix Focus Related Problems in Tests

Filed under: Uncategorized — enndeakin @ 10:27 pm

One common problem with the existing tests is that they make a number of assumptions about a window being focused. For instance, tests tend to assume that once the load event fires, everything is ready to go. This is incorrect. In fact, the window may not even be visible yet. Because of this, some tests tend to fail randomly, especially on Linux.

The focusing of a window can occur before or after the load event, depending on circumstances and platform specific variations. For instance, an incrementally loaded page can be focused long before the page has finished loading, whereas a new XUL window can be focused afterwards, since the entire XUL file needs to be parsed and laid out before the window size is known.

Even the performance tests aren’t immune to this. If they operate based on the load event, they test only the time it takes to load, not the time to focus a window or page.

A number of things rely on a window being focused in order to work. For instance, tests that synthesize key presses or open popups. These are kinds of things that will fail when the window isn’t focused.

One common, yet not actually correct solution is to call window.focus(). This function is typically used to raise (bring a window to the front) and focus the window. However, it should not be assumed that the window.focus() method will do so before it returns. (Technically, on Linux the window manager isn’t required to honour this request at all). For this reason, it is best to wait for a focus event on the window before proceeding.

This can be a bit of hassle, so a few days ago I added a new function to do this for you, called waitForFocus. It’s very easy to use, and does lots of magical incantations for you. Just add something like the following at the end of the test’s script:

SimpleTest.waitForFocus(callback, window)

Set callback to a callback function to be called when the specified window has been loaded and focused, typically this will be the function that executes the actual tests. (The window argument is optional, if it happens to be ‘window’) If the window is not focused, an attempt is made to focus it. Don’t worry if the window has already loaded or is already focused, the function will take care of checking that for you. All you need to do is add the line above and everything will work out. No need to listen to any load or focus events. At least that’s the intent. The tests that now use this function haven’t failed due to focus issues yet.

Currently, waitForFocus also logs some debugging output. I’d expect this to be removed at some point — for now it’s being used to look for problems that might occur in the near future.

This method should be used for tests that:

  • synthesize key presses
  • tests that open popups
  • tests that open a new window
  • tests that close a window
  • tests that rely on focus rings to be drawn
  • tests that rely on focus or blur events to occur

Know any tests that could have problems? Why not fix them?

Advertisements

September 1, 2009

Resizing Text Boxes

Filed under: Mozilla — enndeakin @ 7:42 pm

In bug 167951, I am implementing text areas which can be resized, which will look something like the following:

The notch in the corner will allow the box to be resized smaller and larger. This will be available for all HTML <textarea> elements as well as XUL multiline textbox elements. However, for XUL elements, a resizable attribute set to either true or false may be used to enable or disable this feature. The default is false as it is likely that multiline textboxes in dialog boxes won’t have room to be resized anyway.

Adding support for this feature involved adding a number of other XUL features. The first, in bug 510335, adds support to the <stack> element for right and bottom attributes, in addition to supporting left as top as it does currently. This allows alignment of the children of a stack to any of the four sides by specifying a margin. For instance, this example positions a button 10 pixels from the right edge and 5 pixels from the bottom edge.

<stack width="100" height="100">
  <button label="Hello" right="10" bottom="5"/>
</stack>

You can also specify all four positions, and they then just act like margins from the stack’s edge.

The second feature is extending the <resizer> element in bug 511180 to allow resizing any element. Currently, the <resizer> is always used to resize the window. You can see this kind of resizing notch in use in Firefox in the lower right corner of a window below the scrollbar.

But, by adding an element attribute, you can specify the id of a specific element to resize. Most common, you would use the special value ‘_parent’ which means to resize the parent element. The following pattern might be common:

<stack>
  <button label="Resizable"/>
  <resizer dir="bottomend" right="0" bottom="0" element="_parent"/>
</stack>

All of these features are works in progress, so note that the specifics may change.

Create a free website or blog at WordPress.com.