![]() | Web-specific |
|---|---|
The Web Object API is only available for the Squish for Web editions, and for the Squish for Qt editions for applications using the QtWebKit module, and for the Squish for Java editions for applications using embedded Microsoft Internet Explorer. |
Squish provides a comprehensive API for web objects, which is documented here in its entirety.
Squish's global web functions are listed below in alphabetical order, and these are followed by various predefined objects and classes listed in alphabetical order and with the functions, methods, and properties they contain also alphabetically ordered.
Here are some quick links to the Web Object API's objects and classes (shown in terms of their inheritance hierarchy):
Here are some quick links to the Web Object API's functions:
This function automates a login using the native browser's
authentication dialog and passing it the given
username and password.
![]() | Mac OS X-specific |
|---|---|
On Mac OS X you must turn on Universal Access in the System Preferences
to make use of the |
This function is used to simulate the user canceling the dialog that
JavaScript pops up in response to a call to the prompt
function in a web page's JavaScript code.
Behind the scenes, when Squish tests a web application that executes a
JavaScript prompt function call, instead of Squish
allowing the dialog to pop up, Squish supresses the dialog, stops
execution of the web application, and calls the cancelPrompt
function if replaying a cancel or the closePrompt function if replaying an okay. Then
Squish resumes the web application's execution.
See also closePrompt, lastPromptDefault and lastPromptText.
This is an advanced function that may be useful when testing websites that update themselves, replacing some or all HTML elements with new ones. In such cases, it can be helpful to call this function after such an update, to force Squish to refresh its internal object cache by re-reading the web page's DOM tree.
This function clears an internal cache used by Squish for Web so that
Squish doesn't have to look up the same objects repeatedly in the
browser. After calling this function, all object
references (such as those returned by the waitForObject and findObject functions) are invalid, so new object
references must be obtained—for example, using the waitForObject function—for any objects that
you want to interact with after the cache is cleared.
See also, the rehook function.
This function clicks the specified objectOrName
button which can be a
button,
radio,
checkbox,
submit,
or
image
object.
This function clicks the mouse on the item with the specified
itemText inside the given
objectOrName view widget using the optional
modifierState modifier state (if given).
See Web Object API Function Parameters for which
values are valid for the modifierState.
This function clicks the hyperlink (anchor) identified by the
objectOrName object.
This function clicks on the expand/collapse (tree handle) for the item
that has the specified itemText on the
objectOrName tree widget.
![]() | Don't Use in Hand-written Code |
|---|---|
This function should not normally be used in test scripts since Squish can handle this interaction for all the tree widgets used by the web toolkits that are supported as standard. The primary reason for this function's existence is to support interactions with custom Web tree widgets that are not supported by Squish out of the box. |
For more details, including examples of use, see How to set up Support for Complex Widgets (Section 14.10.22.5).
This function is used to simulate the user clicking
or in the dialog
that JavaScript pops up in response to a confirm function
call in a web page's JavaScript code. The first parameter must be a fake
object name (e.g., ":dummy"); the
confirmed is a Boolean, with true
indicating the user clicked , and
false indicating that the user clicked
.
Behind the scenes, when Squish tests a web application that executes a
JavaScript confirm function call, instead of Squish allowing the
dialog to pop up, Squish supresses the dialog, stops execution of the
web application, and calls the closeConfirm function, passing
true if it was recorded that the tester clicked
or false if they clicked
. Then Squish resumes the web application's
execution, returning the true or false result
to the application as the confirm function call's return value.
See also lastConfirmText.
This function is used to simulate the user typing some text into the
dialog that JavaScript pops up in response to a prompt
function call in a web page's JavaScript code. The first parameter must
be a fake object name (e.g., ":dummy"); the
text is the text that is normally entered into
the prompt dialog's text edit.
Behind the scenes, when Squish tests a web application that executes a
JavaScript prompt function call, instead of Squish allowing the
dialog to pop up, Squish supresses the dialog, stops execution of the
web application, and calls cancelPrompt if
replaying a cancel or the closePrompt function for an okay,
passing the text that the tester entered when the test was recorded.
Then Squish resumes the web application's execution, returning the
text to the application as the prompt function call's return
value.
See also cancelPrompt, lastPromptDefault and lastPromptText.
This function closes the browser window. The parameter must be the
string ":[Window]".
This function returns the context string of the given
window. A context string is a page's “base
location”—this includes any parent locations necessary to
precisely identify the page (for example, if the page is actually a
frame or iframe element).
(See also,
contextList and
setContext.)
This function returns a list containing the URLs of the open browser
windows which can be accessed by the test script. The context of a
particular URL can be retrieved using the contextOf function.
(See also,
setContext, and
waitForContextExists.)
This function returns the context string of the currently active browser
window. A context string is a page's “base
location”—this includes any parent locations necessary to
precisely identify the page (for example, if the page is actually a
frame or iframe element).
(See also,
setFrameContext,
setContext, and
waitForContextExists.)
This function double-clicks the mouse on the
objectOrName widget at position
x and y (in the
objectOrName widget's coordinates).
This function evaluates the JavaScript code
string in the web browser's context (i.e., in the context of the active
browser window). The result of the last statement in the
code is returned. (See also How to Use evalJS (Section 13.3.5).)
This function takes a screenshot of the object
browser window (or widget) and returns it as an
Image Object (Section 14.3.12).
See the waitForObject and findObject functions for how to get an object
reference to a window or widget.
This function returns true if the window with a URL that matches
the context is open and can be accessed by the
test script; otherwise it returns false. A context string is a
page's “base location”—this includes any parent
locations necessary to precisely identify the page (for example, if the
page is actually a frame or iframe element).
(See also,
setContext, and
waitForContextExists.)
This function installs a global event handler. The script function
named in handlerFunctionName (which must be passed
as a string, not as a function reference), will be called when an event
of the eventName type occurs.
The eventName can be the name of any of the
following event types:
AlertOpened – occurs when
an alert box would be shown by the JavaScript
window.alert functionConfirmOpened – occurs when
a confirmation (OK/Cancel) box would be shown by the JavaScript
window.confirm functionCrash – occurs if the AUT
crashesModalDialogOpened – occurs
when a modal dialog is opened with the Internet Explorer-specific
JavaScript showModalDialog functionModelessDialogOpened –
occurs when a modeless dialog is opened with the Internet
Explorer-specific JavaScript showModelessDialog
functionPromptOpened – occurs when
a prompt box would be shown by the JavaScript
window.prompt functionTimeout –
occurs when the Squish response timeout is reachedWindowOpened – occurs when
a new window is opened by the JavaScript window.open
function
The function named in handlerFunctionName is
called (with no arguments) whenever one of the registered events occurs.
For examples see How to Use Event Handlers (Section 13.8).
![]() | The AUT Must be Running |
|---|---|
The |
This function returns true if a native browser dialog (such as a
login dialog, certificate dialog, etc.) is currently open; otherwise it
returns false.
![]() | Mac OS X-specific |
|---|---|
On Mac OS X you must turn on Universal Access in the System Preferences
to make use of the |
This function returns true if the page has been completely
loaded; otherwise it returns false. A complete and successful
load implies that all of the page's objects can
potentially be accessed. This function can be used
with the waitFor function to wait for a
page to be loaded before accessing it from a test script.
Since page loading, HTTP requests, and so on, are asynchronous, even
after a call to the isPageLoaded function returns
true it is essential that the waitForObject function (or another wait function)
is used to ensure that the specific objects of interest are ready to be
accessed. Also, it may be necessary to pass a longer timeout to the
waitForObject function than the default
20 000 milliseconds. (See also How to Synchronize Web Page Loading for Testing (Section 13.3.7).)
This function returns the text that appeared in the web page's most
recent alert function call (which will be empty if no
alert calls have been made).
This function returns the text that appeared in the web page's most
recent confirm function call (which will be empty if no
confirm calls have been made).
See also closeConfirm.
This function returns the default value used in the web page's most
recent prompt function call (which will be empty if no
prompt calls have been made).
See also closePrompt and
lastPromptText.
This function returns the text that appeared in the web page's most
recent prompt function call (which will be empty if no
prompt calls have been made).
See also closePrompt and lastPromptDefault.
This function opens a web browser and loads the given
url.
![]() | Internet Explorer-specific |
|---|---|
When testing a website using IE, if the website shows an
The workaround is to first call the |
This function clicks the mouse on the specified
objectOrName widget. The click occurs in the
middle of the widget or at position (x,
y)—which is relative to the widget
itself—if specified, and with the given
modifierState, if specified.
See Web Object API Function Parameters for which
values are valid for the modifierState.
This function simulates a native mouse click on the
objectOrName widget. The click occurs in the
middle of the widget or at position (x,
y)—which is relative to the widget
itself—if specified. The button parameter
is the mouse button that should be used, and must be one of
1 (left mouse button), 2 (middle mouse
button), or 3 (right mouse button).
This function tries to raise the browser window to the top of the window stack so that no overlapping windows are above it.
This is an advanced function that reloads and re-initializes the parts
of Squish for Web that run inside the browser. We recommend using the
clearObjectCache function instead of
this one whenever possible, since it is slightly faster and safer.
This function scrolls the browser so that the
objectOrName widget is visible.
This function selects the option with the given
text in the objectOrName
select form element (which may be a select or select-one element). If
the element is a multi-selection box, multiple options to be selected
can be passed in the text separated by
commas.
This function sends an event of type eventName to
the objectOrName element.
The eventName must be one of
"mouseup", "mousedown",
"mouseover",
"mouseout",
"mousemove", or
"click".
The x and y parameters are
the coordinates relative to objectOrName, where
the event should occur. The modifierState is
currently ignored, but you should always pass a value of 0 for it. The
button must be one of 1 (left
button), 2 (right button), or 4 (middle
button).
This function makes the specified context the
active window. This means that those test script commands that follow
will be executed in the context of the newly active window. A context
string is a page's “base location”—this includes any
parent locations necessary to precisely identify the page (for example,
if the page is actually a frame or iframe element).
(See also,
contextList,
currentContext,
setFrameContext,
waitForContextExists.)
This function sets the input focus on the
objectOrName element.
For web pages that use frames or iframes, this function can be used to
specify that the frame called frameName should be
used as the current context.
The context is a page's “base location”—this
includes any parent locations necessary to precisely identify the page
(for example, if the page is actually a frame or iframe element).
(See also,
contextList,
currentContext,
setContext, and
waitForContextExists.)
This function sets the text of the objectOrName
editable form element (which can be a text or textarea element) to the
given text. (Compare this with the typeText function which simulates typing the
text into the form element.)
This function types the specified text (as if the
user had used the keyboard) into the objectOrName
editable element. (Compare this with the setText function which sets the text for text
and textarea form elements programmatically.)
This function waits until the given context has
been loaded and can be accessed. The context is a
URL for a particular web page displayed in the browser—the page
itself may contain its own hierarchy of pages through the use of frame,
iframe, and similar elements.
(See also,
contextList,
currentContext,
setFrameContext,
setContext, and
waitForContextExists.)
This object's methods provide information about the browser being used.
This function returns the name of the browser which is being used for running the test.
This function returns the type of the browser which is being used for running the test. The type can have one of the following values:
Browser.Firefox – Firefox
Browser.InternetExplorer –
Internet
Explorer® (Microsoft®)
Browser.Konqueror – Konqueror (KDE)
Browser.Mozilla – Mozilla
Browser.QtWebkit –
QtWebKit-based browser (Nokia's Qt Development Frameworks)
Browser.Safari –
Safari™ (Apple)
This class provides the API for HTML anchor elements (hyperlinks). This class inherits the HTML_Object Class (Section 14.10.13).
This function clicks this anchor (hyperlink), as if the user had clicked it.
This class represents a JavaScript array, such as those returned by web
functions like
HTML_Document.getElementsById and
HTML_Document.getElementsByTagName.
This class inherits the HTML_Object Class (Section 14.10.13).
This function returns the element at position
index in the array. Valid index positions are in
the range 0 to array.length - 1.
This read-only property holds the number of elements in the array. This will be 0 if the array is empty.
This class provides the API for HTML button and submit input elements. This class inherits the HTML_ButtonBase Class (Section 14.10.5) which inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
For normal buttons, this is the same as calling HTML_ButtonBase.click. For submit buttons,
this invokes the button's form's submit action.
This is the base class of all the HTML input button elements—such as, button, submit, radio, checkbox, and image—and provides the common API shared by all of them. This class inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
Clicks this button (or checkbox, or image, and so on), as if the user had clicked it. (Some subclasses allow keyboard modifiers and the precise position where the element is clicked to be specified.)
This property holds this button's (or checkbox's, or image's, and so on's), value as a string.
This class provides the API for HTML checkbox input elements. This class inherits the HTML_ButtonBase Class (Section 14.10.5) which inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This property holds true if this checkbox is checked;
otherwise it holds false.
Clicks this checkbox as if the user had clicked it. All the arguments
are optional.
See Web Object API Function Parameters for which
values are valid for the modifierState.
The x and y are the
checkbox-relative coordindates of the click.
This class provides an abstract item API to access any supported item type contained in a custom item view (HTML_CustomItemView Class (Section 14.10.8).) This item class inherits the HTML_Object Class (Section 14.10.13). (See How to set up Support for Complex Widgets (Section 14.10.22.5) for how this API can be used to support those custom item view widgets which Squish doesn't support as standard.)
Here are some quick links to the HTML_CustomItem class's
methods and properties:
Return's a reference to this item's first child item (of type HTML_CustomItem Class (Section 14.10.7)) or returns 0 if there isn't one.
The column is optional (and not all item's
support it), but if it is specified (and supported), then the item's
first child item in the given column is returned
if there is one; otherwise 0 is returned.
This function returns a reference to this item's handle (as type HTML_Object Class (Section 14.10.13)), or returns 0 if this item doesn't have an item handle.
This function returns the view (of type HTML_CustomItemView Class (Section 14.10.8)) that contains this item.
Return's a reference to this item's next sibling item (of type HTML_CustomItem Class (Section 14.10.7)); or returns 0 if there isn't one.
The column is optional (and not all item's
support it), but if it is specified (and supported), then the item's
next sibling item for the given column is
returned if there is one; otherwise 0 is returned.
This property holds true if this item is open (i.e.,
expanded—in which case this item's children will be visible);
otherwise it holds false.
If this property is set to true, it opens (expands) this
item so that any children it has become visible. And if this property is
set to false, it closes (collapses) this item so that any
children it has become hidden.
Return's a reference to this item's parent item (of type HTML_CustomItem Class (Section 14.10.7)); or returns 0 if there isn't one, that is, if this is the root item.
The column is optional (and not all item's
support it), but if it is specified (and supported), then the item's
parent item for the given column is returned if
there is one; otherwise 0 is returned.
This read-only property holds the type name of the actual (i.e., real) type wrapped by this API as a string. The name could be the view's type name rather than the item's type name, depending on the implementation. (The example shipped with Squish returns the view's type name.)
The type name returned might be, for example “gwttree”, or “itmilltree”, or “dojotree”, and so on.
This property holds true if this item is selected;
otherwise it holds false.
If this property is set to true this item is selected. If
this property is set to false this item is deselected.
This read-only property holds the item's text as a string.
If the extension provides an itemText function, that
function's return value is returned; otherwise the item's
innerText property's value is returned.
This class provides an abstract item view API to access any supported item view, that is, any DHTML/AJAX/JS item view widget with dedicated support. This class inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13). (See How to set up Support for Complex Widgets (Section 14.10.22.5) for how this API can be used to support those custom item view widgets which Squish doesn't support as standard.)
The API for the items in the item view is provided by the HTML_CustomItem Class (Section 14.10.7).
The itemText used in many of the methods listed below
identifies the relevant item. In the example shipped with Squish, the
itemText is always the item's text as a string.
Here are some quick links to the HTML_CustomItemView class's
methods and properties:
Return's a reference to the view's first item (of type HTML_CustomItem Class (Section 14.10.7)); or returns 0 if the view is empty.
The column is optional (and not all view's
support it), but if it is specified (and supported), then the view's
first child item in the given column is returned
if there is one; otherwise 0 is returned.
Clicks the expand/collapse handle of the item called
itemName.
Clicks the item called itemName.
Return's the view's caption for the given column.
Double-clicks the item called itemName.
See Web Object API Function Parameters for which
values are valid for the optional modifierState.
This function returns a reference to the item called
itemName (of type HTML_CustomItem Class (Section 14.10.7)); otherwise it returns 0.
This function returns true if the view has an item called
itemName; otherwise it returns false.
This function returns true if the view has an item called
itemName, and the item is open (i.e., any child
items it has are visible); otherwise it returns false.
This function returns true if the view has an item called
itemName, and the item is seleced; otherwise it
returns false.
This read-only property holds the number of columns displayed in the view.
This read-only property holds the type name of the actual (i.e., real) type wrapped by this API as a string.
The type name might be, for example, “gwttree”, or “itmilltree”, or “dojotree”, and so on.
This class represents a web page's HTML document object and provides useful accessor methods. This class inherits the HTML_Object Class (Section 14.10.13).
This function returns an array of all the DOM tree's elements that have
the given id.
(See also, HTML_Array Class (Section 14.10.3).)
This function returns an array of all the DOM tree's elements that have
the given tagName.
(See also, HTML_Array Class (Section 14.10.3).)
This class provides the API a web page's HTML form elements. This class inherits the HTML_Object Class (Section 14.10.13).
Invoke's the form's “submit” action.
This class is the base class for HTML form elements such as buttons, checkboxes, and so on, and provides the common API shared by all these elements. This class inherits the HTML_Object Class (Section 14.10.13).
This property holds true if this form element is disabled;
otherwise it holds false.
Gives the keyboard focus to this form element.
This read-only property holds the name of this form element's type (such as, button, select, text, etc.).
This class provides the API for HTML image input elements—its methods are all inherited from its base classes. This class inherits the HTML_ButtonBase Class (Section 14.10.5) which inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This is the ultimate base class used for all objects that are HTML
elements. The functions and properties defined in this class are
available for all objects which are returned from Squish's findObject function.
Here are some quick links to the HTML_Object class's
methods and properties:
This function returns the subclass name of the HTML object; for example, HTML_Button Class (Section 14.10.4). (See also, HTML_Object.domClassName.)
This read-only property holds the object's class name that is used by
the DOM. (See also, HTML_Object.className.)
Evaluates the XPath statement and returns an
HTML_XPathResult Class (Section 14.10.21) object. The
XPath statement is executed relative to
this HTML_Object's XPath.
This method makes it possible to efficiently operate on a web application's DOM document, for example, to retrieve elements and access their properties.
See also How to Use XPath (Section 13.3.2).
This function returns the object's first child (as an
HTML_Object), or an invalid object if the object has no
children.
(See also,
HTML_Object.lastChild,
HTML_Object.nextSibling,
HTML_Object.numChildren,
HTML_Object.parentElement, and
HTML_Object.previousSibling.)
This read-only property holds the object's height. (See also, HTML_Object.width.)
This function returns this object's hierarchical, qualified name.
This read-only property holds the object's ID.
This read-only property holds the object's inner text—this might contain HTML markup. (See also, HTML_Object.innerText.)
This read-only property holds the object's inner text as plain text, so the returned string does not contain any HTML markup. (See also, HTML_Object.innerHTML.)
Invokes an HTML_Object method called
methodName, and returns the value returned by the
method call as a string. Both the argument1 and
argument2 arguments are optional. If either or
both are given it or they are passed as argument(s) to the method call,
so the HTML_Object.invoke method can be called with the
following combinations of arguments:
(methodName),
(methodName, argument1),
(methodName, argument1,
argument2).
This function returns the object's last child (as an
HTML_Object), or an invalid object if the object has no
children.
(See also,
HTML_Object.firstChild,
HTML_Object.nextSibling,
HTML_Object.numChildren,
HTML_Object.parentElement, and
HTML_Object.previousSibling.)
This function returns this object's internal JavaScript reference name.
This function returns the object's next sibling (as an
HTML_Object), or an invalid object if the object has no
following sibling.
(See also,
HTML_Object.firstChild,
HTML_Object.lastChild,
HTML_Object.numChildren,
HTML_Object.parentElement, and
HTML_Object.previousSibling.)
This read-only property holds how many children this object
has—this could be 0.
(See also,
HTML_Object.firstChild,
HTML_Object.lastChild,
HTML_Object.nextSibling,
HTML_Object.parentElement, and
HTML_Object.previousSibling.)
This function returns the object's parent object (as an
HTML_Object), or an invalid object, if this object has no
parent. Note that only a web site's document node has no parent; all
other nodes are children of the document or of other nodes within the
document.
(See also,
HTML_Object.firstChild,
HTML_Object.lastChild,
HTML_Object.nextSibling,
HTML_Object.numChildren, and
HTML_Object.previousSibling.)
This function returns the object's previous sibling (as an
HTML_Object), or an invalid object if the object has no
preceding sibling.
(See also,
HTML_Object.firstChild,
HTML_Object.lastChild,
HTML_Object.nextSibling,
HTML_Object.numChildren, and
HTML_Object.parentElement.)
This function returns the value of the property called
name as a string. (The returned value is always a
string even if the property was set to an integer or Boolean.) (See
also, HTML_Object.setProperty.)
Sets the property called name's value to
value. The value may be a
string, integer, or Boolean.
(See also, HTML_Object.property.)
This function returns an HTML_Style Class (Section 14.10.17) object that can be used to query this object's CSS (Cascading Style Sheet) attributes.
This read-only property holds the object's style.display
value.
This function returns the object's style.visibility value.
This read-only property holds the object's HTML tag name, for example,
DIV or INPUT.
This read-only property holds the object's title.
This read-only property holds true if the object has a
visible attribute otherwise it holds false.
See the HTML_Object.styleDisplay property
and the HTML_Object.styleVisibility and
HTML_Object.style functions for other
ways of checking the object's visibility.
This read-only property holds the object's width. (See also, HTML_Object.height.)
This read-only property holds the object's x-coordinate.
This read-only property holds the object's y-coordinate.
This class provides the API for HTML option elements which provide the contents of selection elements. This class inherits the HTML_Object Class (Section 14.10.13). (See also, HTML_Select Class (Section 14.10.16).)
This read-only property holds true if this option is
selected by default; otherwise it holds false.
This property holds the 0-based index position of this option in the selection element.
This read-only property holds true if this option is
selected; otherwise it holds false.
This property holds this option's text as a string.
This property holds this option's value as a string.
This class provides the API for HTML radio button input elements. This class inherits the HTML_ButtonBase Class (Section 14.10.5) which inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This property holds true if this radio button is
checked; otherwise it holds false.
Clicks this radio button as if the user had clicked it. All the arguments
are optional.
See Web Object API Function Parameters for which
values are valid for the modifierState.
The x and y are the
radio button-relative coordindates of the click.
This class provides the API for HTML selection input elements (select and select-one). Web browsers normally render select elements as list boxes and select-one elements as comboboxes. This class inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This function returns true if this selection element is a
multi-selection (type select); otherwise it returns false
(meaning that this element is of type select-one).
Return's the option (HTML_Option Class (Section 14.10.14)) at
position index in this selection element. (The
indexing is 0-based.)
This is a convenience function equivalent to
html_select_object.options().at(index).
This function returns an array (HTML_Array Class (Section 14.10.3)) of all the options (as HTML_Option Class (Section 14.10.14) objects) contained in this selection element.
This property holds this selection element's selected index. (This property is only really useful for single selection boxes, that is, those of type select-one.)
This property holds the selected option's text, or if this is a select (multi-selection) element, holds a string that contains a comma-separated list of the selected options' texts.
If this property is assigned to, it sets the option which has the same
text as the given text to be selected.
If this is a select (multi-selection) element, the
text string can specify a list of option texts by
separating each one with a comma. In such cases, every option that has a
text that matches one of the texts in the comma-separated list will be
selected.
This class provides the API for accessing an object's CSS (Cascading
Style Sheet). HTML_Style objects are returned by the HTML_Object.style function. This class inherits
the HTML_Object Class (Section 14.10.13).
This function returns the string value of the CSS (Cascading Style
Sheet) attribute with the given name, or an empty
string if there is no element called name.
When it comes to composite attributes (such as
background-color), Squish adopts the widely-used
JavaScript convention of capitalizing the letter following a hyphen and
then dropping hyphens. So, for example, to access the background color,
we would write something like:
var style = myobject.style();
var bgColor = style.value("backgroundColor");
This class provides the API for HTML text input elements. All the class's API is inherited from its base classes. This class inherits the HTML_TextBase Class (Section 14.10.20) which inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This class provides the API for HTML textare input elements. All the class's API is inherited from its base classes. This class inherits the HTML_TextBase Class (Section 14.10.20) which inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This is the base class for HTML text input elements (text and textarea), and provides methods common to both. This class inherits the HTML_FormElement Class (Section 14.10.11) which inherits the HTML_Object Class (Section 14.10.13).
This property holds this text or textarea's text as a string.
This is the type of the result object returned when an XPath is evaluated. This class inherits the HTML_Object Class (Section 14.10.13) .
When evauating an XPath statement on any HTML_Object Class (Section 14.10.13) (see HTML_Object.evaluateXPath), an object of type
HTML_XPathResult is returned. This object contains the results of the
XPath execution.
See also How to Use XPath (Section 13.3.2).
This read-only property holds the XPath result as Boolean value.
This read-only prototype holds the XPath result as a numerical value.
This function returns the first node (of type HTML_Object Class (Section 14.10.13)) of the node list if the result of the XPath execution was a node list.
This read-only property holds the number of nodes returned by the XPath execution. A value of -1 means that no node list has been returned.
This read-only property holds the XPath result as string value.
This function returns the node (of type HTML_Object Class (Section 14.10.13)) at the given
index position in the node list if the result of
the XPath execution was a node list.
This section shows how to use the JavaScript extension API to support the testing of custom AJAX/DHTML/JavaScript widgets.
Squish provides access to Web DOM elements, giving tests the potential for complete low-level access and control. However, working at this level is the Web equivalent of using hard-coded screen coordinates when testing GUI applications—that is, it is a rather fragile approach.
To create robust test scripts, a test framework and the automated tests should interact with the application and the HTML on high-level widgets, instead of interacting with low-level DOM elements. This way tests work on an abstract GUI level without needing any knowledge of the application's internals (i.e., without needing to directly access the application's DOM).
The advantage of using high-level tests which work on widgets rather than directly on the DOM, is that the tests will not break just because the DOM representation or widget implementation changes. And such changes are quite common as applications, and the frameworks they use, evolve.
So in addition to providing low-level access, Squish also provides a way of creating high-level tests that are likely to be a lot more reliable. This is possible because Squish comes with built-in support for popular AJAX and DHTML frameworks and recognizes their widgets. But given the amount of available AJAX, DHTML, and JavaScript frameworks and custom widgets that currently exist, and also the new ones that keep appearing, it is not possible for Squish to support all of them out-of-the box.
Fortunately, even those testing a Web framework that isn't currently supported by froglogic, can still add support for their framework to Squish. This is done by using Squish's JavaScript extension API which makes it possible to extend Squish's widget support to recognize custom AJAX, DHTML, and JavaScript widgets, to identify them properly, and to interact with them, and of course to make their APIs accessible to test scripts.
In this section we begin with the Squish Object API that is available to
extension scripts, then we present an overview and examples that show
you how to implement support for your custom widgets yourself.
Alternatively, contact <squish@froglogic.com> if you want
froglogic to implement the extension for your custom widgets or
framework for you.
The Squish Object provides an API through which Squish's web edition
can be extended to recognize custom AJAX/JavaScript/DHTML widgets. This
means that Squish can work on high-level custom widgets instead of
working on the low-level DOM objects. (Note that this API cannot be used
in test scripts—for tests use the HTML_* classes
described above.)
Using this mechanism makes it possible to create robust high-level tests for those AJAX/JavaScript/DHTML widgets that Squish doesn't support as standard.
For an extensive example of how to use the Squish Object see the subsections that follow, starting with Concepts and Setup (Section 14.10.22.2).
Here are some quick links to the Squish Object's methods:
This function registers the given function as a
handler for simulating mouse clicks. The function will be called with an
HTML element when a click on that element ought to occur. If the element
is one that the handler function wants to handle the handler function
should perform the click and return true;
otherwise it should return undefined if it wants Squish
to try other handlers (and default to Squish's own functionality if no
other handler is available or if all the handlers return
undefined).
This function registers the given function as a
handler when finding the actual object an event refers to. The function
will be called with an HTML element when an event for that element
occurs, and may return the element, or another element, or
undefined if it wants Squish to try other handlers (and
default to Squish's own functionality if no other handler is available
or if all the handlers return undefined).
This function registers the given function as an
object name matcher function that returns a Boolean to indicate whether
the real (multi-property) name matched, i.e., if the object matched by
its properties. The function will be called with an object, a property
name, and a valueObject—see the Squish.matchProperty function for more about
the parameters—and returns a Boolean or undefined if
it cannot perform the match. When matching a name, Squish will try as
many name matching functions as have been registered using this
function, and if all of them return undefined (or if there
aren't any), Squish will fall back to using its own built-in name
matching algorithm. (For an example of use, see How to Implement a Custom Name Matcher (Section 14.10.22.4.2); see also Improving Object Identification (Section 15.8).)
This function registers the given function as a
name generator function that returns a unique real (multi-property)
name for a given object. The function will be called with an object and
must return a name that uniquely identifies the object as a string in
the form of a real name—or it must return undefined
if it cannot generate a name for the object. When generating a real name
for an object, Squish will try as many name of functions as have been
registered using this function, and if all of them return
undefined (or if there aren't any), Squish will fall back
to using its own built-in name generation algorithm. (See How to Implement a Custom Name Generator (Section 14.10.22.4.1) for an example.)
This function registers the given function as a
function that returns the high-level type of a DOM object. The
typeOf function (function) takes a
single string as argument (an element) and returns a string as its
result.
When Squish encounters an HTML element that has been registered with
the Squish.registerWidget function, and
whenever it needs to know the element's type, it uses the hook function
registered here. So if, for example, we had a <span>
tag that we wanted to treat as a button, we could return
"button" as the tag's type instead of the default
(which in this example would be "span").
Here is a very simple typeOf function that we could
register with the Squish.addTypeOfHook function:
function typeOf(element)
{
if (element.className == "span")
return "button";
return undefined;
}
This function re-identifies <span> tags as buttons,
but leaves the types of all other tags unchanged. For
elements that you want Squish to treat as interactive elements, you
would normally return one of the types
button,
checkbox,
image,
radio, or
submit.
Returning undefined for cases we don't handle is
important—it means that Squish will look for another
typeOf function (since many can be registered), falling
back on its own internal typeOf function if there are no
others or if all the others return undefined for the
element.
This function returns a copy of string s with any
leading and trailing whitepace removed and each internal occurrence of
multiple whitespace (or of tabs or newlines) replaced with a single
space. Also, all occurrences of Unicode characters U+2011 (non-breaking
hyphen) and U+2013 (en-dash), are replaced with a hyphen.
This function returns the real (multi-property) name of an item in a
view. The name is produced by taking the
viewObjectName real name and adding an additional
property to hold the itemText to provide a name
that uniquely identifies the view item.
This function returns the first element that has the given
className and tagName
relative to the specified contextNode. (See Item Traversal for examples.)
This function returns an array of those elements that have the given
className and tagName
relative to the specified contextNode.
This function returns true if the given DOM object/web element
has a DOM class whose name matches the text passed as
className; otherwise it returns false.
For HTML elements that have a single name for their class name, e.g.,
<span class="warning">dangerous ducks</span>
this function works exactly as expected. For example:
if (Squish.hasClassName(element, "warning")) handleWarningElement(element)
However, HTML elements are at liberty to have multiple space-separated
class names, e.g.,
<span class="heading major">New Section</span>.
In such cases Squish tracks the class names as a list, which is very
flexible. For example:
if ((Squish.hasClassName(element, "heading") and Squish.hasClassName(element, "major")): # Both class names present handleMajorHeadingElement(element) elif Squish.hasClassName(element, "heading"): # Only "heading" class name present handleHeadingElement(element)
This function returns true if the given
valueObject's value matches the value of the given
property; otherwise it returns false.
The valueObject contains both a string value to
match and an integer flag indicating whether the match should be based
on literal string comparison (0), wildcard matching (2), or regular
expression matching (1), using the format {value:
string, modifiers:
integer}.
This function should be used in your custom matchObject
function instead of doing a straight comparison.
Custom match property functions are registered using the Squish.addMatchObjectHook function.
(For an example of use, see How to Implement a Custom Name Matcher (Section 14.10.22.4.2); see also
Improving Object Identification (Section 15.8).)
Sends a mouse click event on the given
objectOrName at the specified relative
x, y position. The
ctrl is a Boolean which if true means that the
key is pressed. Both
shift and alt are also
Booleans and work in the same way regarding the
and keys. All
the parameters except the first are optional and can be omitted.
This function returns the real (multi-property) name of the given
objectOrName.
This method might call a registered name hook function, so be careful when calling this from your custom name hook handler.
Given a DOM objectOrName/web element, this function
returns a string containing one or more space separated
propertyName='propertyValue'
pairs, one for each of the properties in the given
listOfPropertyNamess. The resultant string is
suitable for use in name generation, for example, by the Squish.uniquifyName function.
This function is used to register custom web elements with Squish so
that they can be scripted, recorded, and played back correctly. The
argumentObject is a JavaScript object (i.e., a
named argument list—an object enclosed in braces and that contains
a comma-separated list of name–value pairs), and that supports two
keys:
Event – This is a string that specifies
which type of events should be recorded; e.g., "mousedown".
Class – This is a string that specifies the
class name (i.e., the value of the className property), of
the DOM objects which Squish should recognize as a widget.
For an example see How to set up Support for Simple Widgets (Section 14.10.22.3).
The purpose of this function is to allow you to add support for the
recording of mouse clicks (mouseClick)
on HTML elements that Squish would normally ignore. This is useful if
you want to record clicks on, say, <span> tags, or on
custom tags supported by the particular web framework you're using.
Squish can tell an element's type by checking its type
attribute or its tagname but you can override this (for
example, make a <span> tag be treated as a button),
by registering a typeOf function. Such a function should
return one of the types
button,
checkbox,
image,
radio, or
submit,
and is registered using the Squish.addTypeOfHook function. Note that
although we must register each custom element with its own individual
Squish.registerWidget function call; we could call the Squish.addTypeOfHook function just once,
since in the typeOf function we can return an appropriate
type for all the custom elements we have registered.
This function returns a “uniquified” version of the
name for the given
objectOrName by adding the correct occurrence
into the name.
The name must be provided as a real name, that is
a string of the form
{propertyName1='propertyValue1'
propertyName2='propertyValue2'
...
propertyNameN='propertyValueN'}.
Given a name and an
objectOrName, this function returns the
name unchanged if the name uniquely identifies an
application object. Otherwise it returns name
with an additional property (occurrence) whose value is an
integer such that the name is unique. The purpose of this function is to
create a name that uniquely identifies the given
objectOrName.
This extension is enabled by specifying the location of the JavaScript file that implements it. When Squish hooks into the Web browser, it will evaluate the JavaScript in the extension file inside the browser.
Inside the JavaScript extension file it is possible to use Squish's programming interface to hook into the object recognition, name generation, and other functionality provided by the framework. Also, by implementing certain JavaScript hook-functions, it is possible to expose the APIs of the framework's custom widgets to make them accessible to test scripts.
To specify a JavaScript extension file (and assuming for the sake of
example, that the file is called
C:\squishext\myextension.js), add a line such as
this to the squish.ini file located in your
Squish installation's etc subdirectory:
Wrappers/Web/ExtensionScripts="C:\\squishext\\myextension.js"
If you do distributed testing, this only needs to be done on the machine where squishrunner or the Squish IDE are used.
The API which can be used to implement the extensions is documented in the Squish Object (Section 14.10.22.1)—this object provides methods that support Squish's JavaScript extension. The following sections explain the object's API, and show some examples of its use.
To avoid recording superfluous mouse clicks, Squish only records
clicks on DOM elements which are known to respond to clicks. To decide
whether an element responds to clicks, Squish checks to see if the
element has a mouse event handler set (such as an onClick
function), or if the element is a known clickable widget—such
as a form input element, a link, and so on.
If your JavaScript library comes with custom clickable widgets such as
custom buttons, you can tell Squish about them using the Squish.registerWidget JavaScript function. This
function expects a named argument list (i.e., an object) which specifies
the DOM class of the element and the type of events that should be
recorded.
For example, let's assume that you have a special button implementation which is represented in the DOM as:
<span class='ajaxbutton'>Click Me</span>
To make Squish record mouse click events for this type of widget, add the following line to your extension JavaScript file:
Squish.registerWidget({Class: "ajaxbutton", Event: "click"});
Now, when you record a script and click this button, Squish will
record mouseClick statements.
To identify widgets when replaying a test, Squish defaults to using
its own built-in name generation algorithm. In this specific example the
innerText will be used since no id or
name is set, and this is sufficient in this case. So,
the generated real name for this object will be, {tagName='SPAN'
innerText='Click Me'}
.
It is possible to supplement Squish's name generator with your own name generation algorithm—this is particularly useful if you want to make use of custom properties from a web framework's custom elements when names are generated. This is covered in the next section.
To produce a name for a widget, Squish generates a list of property
pairs identifying the object. Squish uses a set of pre-defined
properties such as tagName, id,
name, title, innerText, and a few
others.
If the properties do not uniquely identify the object, an
occurrence property is added to the name which specifies
which of the objects matching the other properties is supposed to be
selected.
With the exception of tagName—which is the one
mandatory property that all names must have—
the properties are optional and can be chosen freely.
In some cases it might be desirable to use custom properties in the names of certain types of objects. To do this, it is possible to specify your own hook function which will then be called to generate names for your own widgets. And if necessary, a hook function that performs the property matching that is done when objects are searched for can also be installed.
To show how to implement a custom name generator, we will start with an example menu element:
<SPAN class='menu' id='fileMenu'>
<SPAN class='menuItem' menuID='fileOpen'>Open</SPAN>
<SPAN class='menuItem' menuID='fileQuit'>Quit</SPAN>
</SPAN class='menu'>
First, we must register the menu items as clickable widgets using
the Squish.registerWidget function:
Squish.registerWidget({Class: "menuItem", Event: "click"});
(We already saw an example of using this function earlier: How to set up Support for Simple Widgets (Section 14.10.22.3).)
In this example we are going to use the menuID attribute,
along with the DOM class, and the parent element's ID, to give our menu
elements (i.e., each menuItem <span>
tag), their unique identifying names.
var myUiExtension = new Object;
myUiExtension.nameOf = function(obj) {
if (obj.tagName == "SPAN" &&
Squish.hasClassName(obj, "menuItem")) {
var name = '{' +
Squish.propertiesToName(obj, ["tagName", "menuID"]) +
" parentID='" + obj.parentNode.id + "'" +
" className='menuItem'" +
"}";
return escape(Squish.uniquifyName(name, obj));
}
return undefined;
}
We have added this function as a property of a custom
myUiExtension object. In the implementation we check if the
object is an object of the type we want to handle, that is,
menuItem <span> tag. If the type is
right we use custom code to create a unique name for it; otherwise we
return undefined—this isn't a valid name value, so
Squish will try each of the other registered name generation hook
functions (if any), and if all of them return undefined (or
if there aren't any), Squish will fall back to using its own default
name generator.
To determine if the element is one of those we want to handle, we check to
see if its tag name is SPAN and if its DOM class is
menuItem. For this second check we use the Squish.hasClassName helper function, which
returns a true value if any of the DOM object's DOM classes has the same
name as the given class name.
If the element is of the right type we create a name for it using our
own custom name generation algorithm. A real (multi-property) name
consists of one or more property name–value pairs, all contained
in braces. Here we start by using the Squish.propertiesToName function to create a
name string containing the given property names and values; then we add
two additional property pairs, one for the parent ID and another for the
class name. Finally, we use the Squish.uniquifyName function to ensure that we
produce a unique name. This function accepts a real (multi-property)
name as a string and the object the name is supposed to identify, and
will return the name unchanged if possible, or will return it with the
addition of an occurrence property if it is necessary to
distingish the name further to ensure its uniqueness.
So, given the example shown above, if the object was the
fileOpen menu item, the
Squish.propertiesToName function would give
us the string "tagName='SPAN' menuID='fileOpen'", and with
the addition of the parent ID and class name, the final name we would
end up with is "{tagName='SPAN' menuID='fileOpen'
parentID='fileMenu' className='menuItem'}".
We could not use the Squish.propertiesToName function for either the
parent ID or for the class name properties. In the case of the parent ID
this is because the parentID is not a regular property, but
rather a pseudo-property, so we must handle it ourselves. Once part of a
real name though, Squish will be able to work with it like any other
property. In the case of the class name the only reason we cannot use
the Squish.propertiesToName function is
because the DOM property name is class while Squish uses
the JavaScript className name. Also, a DOM class may
contain multiple values while we only want to specify
one—menuItem.
At the end we make sure that any special characters are escaped
properly—for this we use the standard JavaScript
escape function. And then we return the result.
Once our name generator function is ready, we must inform Squish of its existence so that it is used when names are needed. This is done by registering it as a hook function:
Squish.addNameOfHook(myUiExtension.nameOf);
Here we have used the Squish.addNameOfHook
function to register the myUiExtension.nameOf function
as a name generator function. From now on Squish will use this
function whenever it needs to generate a real name, and will fall back
to using any other generator function (and its own built-in default name
generator function as a last resort), if the function returns
undefined.
When searching for an object by name, Squish iterates over all objects in the DOM tree and queries the specified object properties to see if their values match those of the name.
Using a custom name matcher hook makes it possible to consider a
name's pseudo-properties (such as the parentID we saw
earlier), when searching for a matching object. Since Squish has no
knowledge about any pseudo-properties we have created, we must implement
a custom function to perform the lookup and name matching and that
accounts for our pseudo-properties.
myUiExtension.matchObject = function(obj, property, valueObject) {
if (property == "parentID")
return Squish.matchProperty(valueObject, obj.parentNode.id);
return undefined;
}
Again, we have implemented this function as a property of our custom
myUiExtension object. Squish will pass the object, the
property name and the expected value as specified in the name to this
function.
If the given property is our pseudo-property, we use Squish's built-in
Squish.matchProperty function to determine
if there is a match. Otherwise we return undefined; in such
cases Squish will try all the other match objects that are registered
(if any), and if none of these gives a definitive true or false (or if
there aren't any), it falls back on its own internal name matching
function. Note that the valueObject is not simply a string
but rather an object which contains a string value and a flag denoting
whether the matching should be based on a literal string comparison,
wildcard matching, or regular expression matching.
(See also Improving Object Identification (Section 15.8).)
In this example we have chosen to handle the parentID
pseudo-property ourselves; and by returning undefined for
any other property we pass on the matching work to Squish for anything
other than the pseudo-property we are interested in.
The custom name matching setup is completed by installing the hook:
Squish.addMatchObjectHook(myUiExtension.matchObject);
The Squish.addMatchObjectHook function can
be used to register as many name matching functions as we want.
Using the extension mechanism it is also possible to add dedicated support for complex widgets—that is, widgets which contain items—such as tree widgets, tables, menus, calendar controls, and other item-based widgets. (For example, trees contain nodes, tables contain cells, menus contain items, and calendars contain date cells.) We will generally refer to such complex widgets as “item views”, and will often refer to their nodes, cells, and items, simply as “items”.
To make high-level interactions with such widgets possible, user actions such as mouse clicks on cells or items, and expanding and collapsing tree nodes, must be recognized and replayed—and in a way that is independent of the underlying HTML representation. In addition, certain states and properties, such as the current selection, ought to be queryable from test scripts, to allow for robust and automatic verifications.
Using the item and item view abstractions and the necessary JavaScript hooks and APIs, Squish supports the addition of any custom item view DHTML/AJAX/JS widget so that test scripts can access the widget's and its items' states, properties and functions.
This section explains how to implement such dedicated item view support so that Squish will correctly be able to record test scripts using custom item views and accurately replay such tests. This is done by using Squish's JavaScript extension API.
We will illustrate the explanation by using an example AJAX widget—the tree control from Google's Web Toolkit (GWT). We will implement all the necessary support to properly record and replay clicks on items and item handles, to identify the tree and items independent of the DOM, and to allow querying the tree's selection.
Once the necessary hooks are implemented, calls to the clickItem function and to the clickTreeHandle function will be recorded
when interacting with the supported item view widget. In addition, using
the HTML_CustomItemView Class (Section 14.10.8) and HTML_CustomItem Class (Section 14.10.7) abstraction API, the test scripts
will be able to access the widget and work with its items, states, and
properties.
Before we can start implementing the necessary support, we need to look at the widget's DOM structure since our custom support will use the Web application's DOM internally to provide the abstraction and encapsulation that test scripts will rely on.
Below is a screenshot of the GWT Tree widget as it appears in a Web browser:

The DOM hierarchy that GWT uses to represent this tree widget has the following structure (with irrelevant details, and most of the data, omitted):
<DIV class="gwt-Tree">
<TABLE>
<TR>
<TD>
<IMG src="tree_open.gif"/>
</TD>
<TD>
<SPAN class="gwt-TreeItem">Beethoven</SPAN>
</TD>
</TR>
</TABLE>
<SPAN>
<DIV>
<TABLE>
<TR>
<TD>
<IMG src="tree_closed.gif"/>
</TD>
<TD>
<SPAN
class="gwt-TreeItem gwt-TreeItem-selected">Concertos</SPAN>
</TD>
</TR>
</TBODY>
</TABLE>
</DIV>
<DIV>
<TABLE>
<TR>
<TD>
<IMG src="tree_closed.gif"/>
</TD>
<TD>
<SPAN class="gwt-TreeItem">Quartets</SPAN>
</TD>
</TR>
</TBODY>
</TABLE>
</DIV>
</SPAN>
...
</DIV>
So we can see that a tree widget is represented using a DIV
element with the class name of gwt-Tree. The tree itself is
contained inside this DIV element, in a TABLE.
Each tree item is held in a SPAN element that has a class
of gwt-TreeItem. The item's text is the element's inner
text, and selected items have an additional class of
gwt-TreeItem-selected.
Item handles (typically shown as + or
- symbols to indicate that the item can
be expanded or is already expanded), are represented by an
IMG element in the TD element above the
item—specifically, the item's parent's previous sibling's first
child. The IMG's src property can be used to
determine if the item is expanded (src="tree_open.gif") or
collapsed src="tree_closed.gif").
The relationship between the items (i.e., the actual tree structure),
is modeled using nested SPAN elements which contain a
set of siblings relative to their parent.
This information is sufficient for us to be able to detect a GWT Tree element, the tree's item elements, and the items' handles, in the web page's DOM structure. Armed with this knowledge we can create a high-level API that our test scripts can use to interact with a GWT Tree and its items, using Squish's uniform “item view” API.
Note that all the code used in the following subsections is taken from
the file lib/extensions/web/jshook_gwt.js.
![]() | Functions to implement in the toolkit's extension object |
|---|---|
The first step is to implement the JavaScript hooks for recording
high-level GUI operations on the GWT Tree. This means, if the user
clicks an item, a function call should be recorded.
Similarly, a click on a tree item's handle should be recorded as
clickItem(treeName,
itemName).
clickTreeHandle(treeName,
itemName)
To achieve this, we must implement three different hooks:
Event object hook: A function that returns the DOM element that is the source of an event.
Type of object hook: A function that returns a DOM object's high-level type name (as a string).
Name of object hook: A function that returns a DOM object's Squish object name (as a string).
Once these functions are implemented, they must be registered with Squish so that they are called by Squish's event recorder. When Squish calls them, it will pass the event's DOM source object as an argument, and based on this we can decide whether we will respond or not. (We can safely ignore events we don't want to handle and leave them for Squish to deal with.)
For the GWT Tree when we implement these functions we must handle three different high-level objects:
Tree objects
Tree items
Tree item handles
So for all three functions we need a way to determine which type of
object we are dealing with. To do this we will start by defining a
gwtExtension object to contain all the GWT Tree-related
code we write. Then we'll define some constants, and then we will create
a getType function.
var gwtExtension = new Object; gwtExtension.Tree = 0; gwtExtension.TreeItem = 1; gwtExtension.TreeItemHandle = 2;
We will use these constants to distinguish between the objects we are interested in handling. Now we need a function that can match DOM class names to these constantts:
gwtExtension.getType = function(obj)
{
if (Squish.hasClassName(obj, 'gwt-TreeItem'))
return gwtExtension.TreeItem;
else if (obj.tagName == 'IMG' &&
(obj.src.indexOf('tree_open') != -1 ||
obj.src.indexOf('tree_closed') != -1) &&
Squish.hasClassName(gwttreeExtension.itemOfHandle(obj),
'gwt-TreeItem'))
return gwtExtension.TreeItemHandle;
else if (Squish.hasClassName(obj, 'gwt-Tree'))
return gwtExtension.Tree;
return undefined;
}
The custom getType function uses Squish's Squish.hasClassName function to see if the
element is a tree item, and if it is, the appropriate constant is
returned. Similar code is used to handle trees themselves, but for tree
handles we must check that the tag is IMG and that it has
one of the appropriate images and that the element associated with the
image is an item with the correct class (gwt-TreeItem).
We will see the creation of the gwttreeExtension object and
of the gwttreeExtension.itemOfHandle function shortly.
If the element is not one of those we are interested in, we
return undefined which indicates to Squish that it should
try whatever type functions it hasn't yet tried, or to fall back on its
own built-in functionality.
Now that we have a suitable getType function, it is quite
easy to implement the three hook functions that are needed:
gwtExtension.eventObject = function(obj)
{
if (!obj)
return undefined;
switch (gwtExtension.getType(obj)) {
case gwtExtension.TreeItem: // fallthrough
case gwtExtension.TreeItemHandle:
return obj;
}
return undefined;
}
If the high-level object type is a tree item or a tree item's handle, we
return this object. This tells Squish that the object is one we want
to record events on, and so should not be ignored by the event recorder.
As usual, if we don't recognize the object, we return
undefined which tells Squish to handle it for us.
If Squish encounters an object for which events should be recorded, it will need know the object's type. For this we must implement a suitable hook function:
gwtExtension.typeOf = function(obj)
{
switch (gwtExtension.getType(obj)) {
case gwtExtension.TreeItem:
return 'custom_item_gwttree';
case gwtExtension.TreeItemHandle:
return 'custom_itemhandle_gwttree';
case gwtExtension.Tree:
return 'custom_itemview_gwttree';
}
return undefined;
}
The type names returned from this function follow a convention that must be followed! Squish provides a common item view abstraction, and for it to work correctly, we must return type names of the correct form.
The three main components used by the item view API for custom trees,
and that correspond to components that the DOM object represents, are
items, handles, and views—a view is a list or table or tree
widget. The naming convention we must follow for custom type names is
very simple: Item type names must begin with custom_item_;
Item handle type names must begin with custom_itemhandle_;
and view type names must begin with custom_itemview_.
The rest of the name must identify our custom view (so in this example,
each type name ends with _gwttree).
The third hook function that we must implement returns the name of a specific high-level object:
gwtExtension.nameOf = function(obj)
{
switch (gwtExtension.getType(obj)) {
case gwtExtension.TreeItem:
return escape(gwtExtension.nameOfTreeItem(obj));
case gwtExtension.TreeItemHandle:
return escape(gwtExtension.nameOfTreeItem(
gwttreeExtension.itemOfHandle(obj)));
case gwtExtension.Tree:
return Squish.uniquifyName(gwtExtension.nameOfTree(obj), obj);
}
return undefined;
}
As usual, we tell Squish to handle any objects that we are not
interested in by returning undefined.
This function makes use of two other functions,
gwtExtension.nameOfTree and
gwtExtension.nameOfTreeItem to create suitable real
(multi-property) names for the custom objects. Here are their
implementations:
gwtExtension.nameOfTree = function(obj)
{
return '{' + Squish.propertiesToName(obj,
["tagName", "id", "name"]) + " className='gwt-Tree'}";
}
This function creates a unique name for each GWT Tree object that Squish encounters. (See How to Implement a Custom Name Generator (Section 14.10.22.4.1) for more information about creating names.)
Here is the function which generates a name for a tree item:
gwtExtension.nameOfTreeItem = function(obj)
{
var tree = obj;
while (tree && (!Squish.hasClassName(tree, 'gwt-Tree')))
tree = tree.parentNode;
var treeName = Squish.nameOf(tree);
var item = obj;
return Squish.createItemName(treeName, item.innerText);
}
An item's name consists of the name of the item view containing the item (the tree widget) and the actual name of the item (usually the item's text—i.e., its innerText—is used).
First we find the tree widget that the item belongs to. This is done by
going to the item's parent, and if that isn't the tree, the parent's
parent, and so on until we get an object of class gwt-Tree.
Once we have located the tree object, we can call the Squish.nameOf function to get its real
(multi-property) name, and then use the Squish.createItemName function to generate a
unique real name for the item; essentially, the same name as the tree's
but with an additional property containing the item's text (which we get
from the item's innerText).
Now that we have implemented all the necessary hook functions we must register them to make them take effect:
Squish.addNameOfHook(gwtExtension.nameOf); Squish.addTypeOfHook(gwtExtension.typeOf); Squish.addEventObjectHook(gwtExtension.eventObject);
With these hooks in place, if we now record events on a GWT Tree, the expected high-level operations will be correctly recorded.
![]() | Functions to implement in the view's extension object |
|---|---|
Once the recording hooks are implemented and recording works, the next step is to implement the hooks to enable Squish to recognize and correctly replay the recorded GUI operations.
To support replaying clicks on items (clickItem), only one additional function
needs to be implemented. This function has to search for an item by name
in the tree, and should return a reference to the DOM object representing
the item. Squish will use this function to get the item to send click
events to.
The name of this function has to follow a certain naming convention. In
particular, it must be called
findItem and it must exist as a
function property of an object called
typenameExtension where
typename is exactly the same name as
we appended to the type names of the objects in our
typeOf hook function.
For the GWT Tree example we have typenames
custom_item_gwttree and so on, so the name we must use is
gwttree. This means that we have to create an object called
gwttreeExtension and give it a findItem
function, as the following code illustrates:
var gwttreeExtension = new Object;
gwttreeExtension.findItem = function(tree, itemText)
{
var node = tree.firstChild;
while (node) {
if (node.firstChild) {
var child = gwttreeExtension.findItem(node, itemText);
if (child)
return child;
}
if (node.className &&
Squish.hasClassName(node, 'gwt-TreeItem') &&
Squish.cleanString(node.innerText) == itemText) {
return node;
}
node = node.nextSibling;
}
return undefined;
}
The tree is a reference to the tree DOM element and the
itemText is the item's text (actually its
innerText).
The function iterates through all child elements of the tree until it
finds an element of class gwt-TreeItem whose
innerText matches the requested item text.
For list and table widgets it is sufficient to provide a
findItem function, but for tree widgets an additional
function is required to deal with item handles.
For this purpose an itemHandle function must be
implemented in the same object that returns the handle belonging to the
given item. Here is an implementation of the function that works for GWT
Tree items:
gwttreeExtension.itemHandle = function(node)
{
return node.parentNode.previousSibling.firstChild;
}
This function returns the GWT Tree element that corresponds to an item
handle (an IMG element in the TD element above
the item—i.e., the item's parent's previous sibling's first
child.)
The implementation of these two functions is all that's needed to enable the replaying of high-level operations on items and item handles.
![]() | Functions to implement in the view's extension object |
|---|---|
|
For Squish to be able to detect an item view and its items, and be able to record and replay high-level GUI operations involving them, what we have done so far is sufficient.
But Squish's item view abstraction also provides the tester with APIs to iterate through the items and to query and set the selection and other properties. To support such functionality, various additional functions need to be implemented—all of which we will cover here, again providing examples based on the GWT Tree example.
Squish's test script item-view API allows us to retrieve a tree item
(e.g., using tree.findItem(...)), and to query the item's
text property.
By default, Squish returns the item's innerText, but if
this is inappropriate for the items you are working with you can
implement your own itemText(item) function in the view's
extension object, and which will then be called instead of Squish's
default function for your items:
gwttreeExtension.itemText = function(item)
{
return item.innerText;
}
If the typenameExtension has an
itemText function property, Squish will call this
function and pass a reference to the DOM object representing the
relevant item. This principle applies to the other functions too: if we
provide the function it is used for our extension types; otherwise
Squish falls back to its own built-in functionality.
In this particular case (i.e., for GWT Tree items) there is no need to
implement this function because Squish's built-in version returns the
innerText anyway.
Squish's test script item-view API allows us to retrieve a tree item
(e.g., using tree.findItem(...)), and to query the item's
selected property.
To support the querying of an item's selection state, we must provide an
isItemSelected function in the
view's extension object. Here is an example that works for GWT Trees:
gwttreeExtension.isItemSelected = function(item)
{
return Squish.hasClassName(item, "gwt-TreeItem-selected");
}
If the typenameExtension has an
isItemSelected function property, Squish will call this
function and pass a reference to the DOM object representing the
relevant item.
To check if the item is selected we simply return true or
false depending on whether one of the item's class names is
gwt-TreeItem-selected.
Squish's item-view API also supports the changing of an item's
selection state. This can be achieved by implementing a
setItemSelected(item, selected) function in the same
extension object. The item is a reference to the item's DOM
object and selected is a Boolean value, with
true meaning that the item should be selected and
false meaning that it should be unselected.
Squish's test script item-view API allows us to access a tree item's
handle and query it to see if the item is expanded (its children are
visible) or collapsed (its children are hidden). The handle's state is
held in the opened property, and to support this property
we must implement an isItemOpened function in the tree's
extension object. (Note that this functionality doesn't make sense for
list or table views.)
Here is an example implementation for the GWT Tree:
gwttreeExtension.isItemOpen = function(item)
{
return gwttreeExtension.itemHandle(item).src.indexOf(
'tree_open') != -1;
}
If the typenameExtension has an
isItemOpen function property, Squish will call this
function and pass a reference to the DOM object representing the
relevant item.
Here, we simply retrieve the item's handle and return a Boolean that reflects whether it has the opened image.
Squish's item-view API also supports the changing of an item's
expanded/collapsed state. This can be achieved by implementing a
setItemOpen(item, expand) function in the same extension
object. The item is a reference to the item's DOM object
and expand is a Boolean value, with true
meaning that the item should be expanded (opened) and false
meaning that it should be collapsed (closed).
The item view API also includes functions for traversing items in a tree
view. The traveral functions are: childItem(treeOrItem),
nextSibling(item), and parentItem(item). There
is also an itemView(item) function; this returns the view
that the given item is in.
Using these APIs it is possible to iterate over the items in a tree, and using the functions shown earlier, it is then possible to retrieve items' texts, select or unselect items, or expand or collapse items.
If we want our custom view to provide traversal then we must implement
our own versions of these four functions as properties of our custom
view's extension object. And, just the same as for the functions we have
already discussed, if we create our own versions of these functions,
Squish will call them and pass a reference to the DOM object
representing the relevant item. Note that exceptionally, in the case of
the childItem function, Squish might call it with
either a tree or an item.
Here are implementations of these function for the GWT tree:
gwttreeExtension.childItem = function(node)
{
if (Squish.hasClassName(node, "gwt-Tree")) {
return getElementByClassName(node, 'gwt-TreeItem', 'SPAN');
} else {
while (node && node.tagName != 'TABLE')
node = node.parentNode;
if (!node || !node.nextSibling)
return undefined;
node = node.nextSibling;
return getElementByClassName(node, 'gwt-TreeItem', 'SPAN');
}
}
gwttreeExtension.nextSibling = function(node)
{
while (node && node.tagName != 'DIV')
node = node.parentNode;
if (!node || !node.nextSibling)
return undefined;
node = node.nextSibling;
return getElementByClassName(node, 'gwt-TreeItem', 'SPAN');
}
gwttreeExtension.parentItem = function(node)
{
while (node && node.tagName != 'DIV')
node = node.parentNode;
if (!node || !node.parentNode || !node.parentNode.previousSibling)
return undefined;
node = node.parentNode.previousSibling;
return getElementByClassName(node, 'gwt-TreeItem', 'SPAN');
}
gwttreeExtension.itemView = function(node)
{
while (node && !hasClassName(node, 'gwt-Tree'))
node = node.parentNode;
return node;
}
The implementations are quite self-explanatory, especially if you look at the DOM structure that the GWT Tree uses.
If the item view supports multiple columns, the functions
columnCaption(view, column) and
numColumns(view) can be implemented in the view's extension
object to allow the test script to query the column information using
the API calls with the same names through the item view API.