Supporting Wrapper Controls
A wrapper control is a container control that groups the controls within it and represents them as a single control. An example of wrapper control is the AwtCalc calculator control.
When UFT One learns a wrapper control, it does not learn the controls within it separately as descendants. If you record a test on a wrapper control, events that occur on the controls within it are recorded as operations on the wrapper control.
Note: Only AWT-based controls can be supported on UFT One as wrapper controls. If the custom control is SWT-based, it is always learned with all of its descendants.
For example, the AwtCalc calculator control contains simple buttons for digits and operators. In a recording session on this control, you might want simple Click operations to be interpreted as more meaningful calculator-oriented operations. You can use Java Add-in Extensibility to instruct UFT One to record clicks on digit buttons as Calculator.SetValue steps, and clicks on operator buttons as Calculator.SetOperator steps.
Understanding How UFT One Handles Wrapper Controls
Wrapper controls must register themselves as wrappers for the types of controls that they wrap.
Before UFT One learns a control as a descendant, UFT One checks if any wrappers are registered for this type of control. If there are registered wrappers, UFT One searches for the one to which this particular control belongs. UFT One performs this search by calling the checkWrappedObject method of each registered wrapper. If UFT One finds a relevant wrapper, UFT One does not learn the descendant control. If no relevant wrapper is found, UFT One learns the descendant control.
When a control is learned separately (by clicking on the specific control), UFT One does not check for wrappers.
Similarly, before UFT One records an operation on a control, UFT One checks if any wrappers are registered for this type of control. If there are registered wrappers, UFT One searches for the one to which this particular control belongs. If UFT One finds a relevant wrapper, UFT One passes the record message to the wrapper control before adding a step to the test. If no relevant wrapper is found, the operation is recorded as is.
When the wrapper receives a record message (triggered by an operation performed on one of its wrapped objects), it can do one of the following:
Discard the message to prevent the recording of the operation.
Modify the message to record a different operation.
Leave the message as is to record the operation without intervention.
The following section describes how this mechanism is implemented, using the AwtCalc wrapper control as an example. After support for the AwtCalc control is implemented, a test recorded on the control could look like this:
Implementing Support for Wrapper Controls
If you want to support a wrapper control, you must implement the com.mercury.ftjadin.infra.abstr.RecordWrapper interface in MicAPI. This interface includes the following methods:
The registerWrapperInspector method is used to register as a wrapper for the relevant types of controls.
For example, the AwtCalcCS support class registers itself as a wrapper of Button:
public void registerWrapperInspector() { MicAPI.registerWrapperInspector(Button.class, this);}
The AwtCalcCS is registered as a wrapper for Button controls only, therefore operations on the AWT Calculator label or on the edit box are recorded without any wrapper intervention. In addition, when the AwtCalc control is learned, the label and edit box are learned as its descendants.
UFT One calls the checkWrappedObject method to check whether a specific object belongs to the custom control. The support class implements this method to return the specific wrapper instance if obj is wrapped by the custom control. Otherwise, it returns null
.
For example, the checkWrappedObject method in AwtCalcCS is implemented, as follows:
public Object checkWrappedObject(Object obj) {
Component comp = (Component)obj;
if (comp.getParent().getClass().getName().equals("org.boutique.toolkit.AwtCalc"))
return comp.getParent();
return null;
}
UFT One calls the wrapperRecordMessage method during a recording session when a wrapped object sends a record message. UFT One passes the record message to the wrapper control before adding a step to the test.
This method returns one of the following:
null, indicating that this message should be ignored and no step should be recorded
a modified record message to be sent instead of the original one
the original record message
For example, in the wrapperRecordMessage method in AwtCalcCS, if the operation to record is on a button, the method replaces it with the appropriate operation to record—Reset, Enter, SetOperator or SetValue (with the appropriate parameters). If the operation in the record message is on a label or text field, AwtCalc does not interfere with the recording.
public RecordMessage wrapperRecordMessage(RecordMessage message, Object wrapper) {
Object subject = message.getSubject();
if (subject instanceof Button) {
// Get the label of the button
String value = ((Button) subject).getLabel().trim();
String operation;
// Select what method to record and with what parameters
if (value.equals("=")) {
return RecordMessage.getRecordMessageInstance(wrapper,"Enter");
}
if (value.equals("C")) {
return RecordMessage.getRecordMessageInstance(wrapper,"Reset");
} else {
if (value.equals("+") || value.equals("-") || value.equals("x")
|| value.equals("/") || value.equals("^")
|| value.equals("sqrt"))
operation = "SetOperator";
else
operation = "SetValue";
}
String params[] = new String[1];
params[0] = value;
RecordMessage res = RecordMessage.getRecordMessageInstance(wrapper, operation, params, AgentRecordMode.NORMAL_RECORD);
return res;
}
// AwtCalc does not interfere if the message is not from a button
return message;
}
When the blockWrappedObjectRecord method returns false, the controls contained in the wrapper generate record messages in response to events as if they were independent controls. UFT One then calls wrapperRecordMessage to pass the record messages it receives from wrapped controls to the wrapper. The wrapper can then decide whether to discard the message, modify it, or record the operation as is.
When the blockWrappedObjectRecord method returns true, it causes all of the controls contained in the wrapper to ignore all events. The wrapped controls do not send any record messages to UFT One, and wrapperRecordMessage is never called.
If blockWrappedObjectRecord returns null, and you want the wrapper to record events that occur on the objects it contains, the wrapper itself must register new event listeners on the wrapped objects. Then it must handle the events to generate the appropriate test steps (using MicAPI.record) during a recording session.
See also: