_COMPUTER-AIDED SOFTWARE TESTING_ by Birger Baksaas [Listing One] void APPstoreMainID(Widget W, /* I: Widget of MainWindow */ char *ProcessName) /* I: Name of the property */ { /* Code to initialization the test system within the application. Stores the Main Widget window ID as a property in the X server */ Atom atom; Display *display; Window window; display = XtDisplay(W); window = XtWindow(W); /* Atoms are the addressing mechanism for properties */ atom = XInternAtom(display, ProcessName, 0); /* Adding property for ProcessName. The property is associated with the root window */ XChangeProperty(display, DefaultRootWindow(display), atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&window, 1); } [Listing Two] int GENsendEvent(Widget FromW, /* Widget the event is sent from, used to get the display ID. */ XEvent *Event, /* Event to be sent */ char *ProcessName) /* Destination process name */ /* Description: General routine to send an event, here used to send events from the test process to the applications. */ { int ret, format; unsigned long nitems, left; Display *display=NULL; Window window, *retData=NULL; Atom atom, type; long eventMask = 0; display = XtDisplay(FromW); /* Get propery identifier. */ atom = XInternAtom(display, ProcessName, 1); /* Get the receiving window ID, stored as a property in the server. */ ret = XGetWindowProperty(display, DefaultRootWindow(display), atom, 0, 4, False, XA_WINDOW, &type, &format, &nitems, &left, (unsigned char **)&retData); /* Check ret: Success value is special for XGetWindowProperty, see Ref Man.*/ if (retData != NULL) { window = *retData; eventMask |= ButtonPressMask; eventMask |= ButtonReleaseMask; eventMask |= NoEventMask; Event->xany.window = window; Event->xany.display = display; ret = XSendEvent(display, window, TRUE, eventMask, Event); } XFree((caddr_t)retData); } [Listing Three] int TESTsendButtonEvent(int Down, /* I: TRUE if ButtonPress */ int WidgetIndex, /* I: Destination widget number converted from the name read from the test script via a table */ char *ProcName, /* I: Name of application read from test script*/ Widget FromWidget) /* I: Main widget of test driver */ /* Declares and sends events from the Test Driver to the applications */ { int eventType; XClientMessageEvent event; if (Down) eventType = ButtonPress; else eventType = ButtonRelease; event.type = ClientMessage; event.format = 32; event.data.l[0] = eventType; event.data.l[1] = WidgetIndex; GENsendEvent(FromWidget, (XEvent *)&event, ProcName); /* GENsendEvent is shown in Listing Two */ } [Listing Four] #include void APPdistributeEvent(Widget W, XtPointer ClientData, XClientMessageEvent *Event, Boolean *ContToDispatch) /* Receives events from the test driver and passes the events to individual widgets based on the message received by the test driver. This is a standard callback routine. Therefore the parameters are not explained. */ { int ret, format, widgetIndex, eventType, keyCode; Display *display; Window window; long eventMask = 0; XButtonEvent newEvent; /* Used both for button and key events. The structures are identical, except for the button/code field. */ eventType = (int)Event->data.l[0]; widgetIndex = (int)Event->data.l[1]; if ((eventType == KeyPress) || (eventType == KeyRelease)) { keyCode = (int)Event->data.l[2]; } /* Checks should be performed to ensure that widget index is within legal range, skipped in this listing */ if (XtIsWidget(WidgetTable[widgetIndex])) { display = XtDisplay(WidgetTable[widgetIndex]); window = XtWindow(WidgetTable[widgetIndex]); /* Position is set inside the window */ newEvent.x = 4; newEvent.y = 4; } else { /* gadgets */ display = XtDisplay(((XmGadget)WidgetTable[widgetIndex])->object.parent); window = XtWindow(((XmGadget)WidgetTable[widgetIndex])->object.parent); /* Gadgets are part of their parent widget's window. Below is code to find where gadget is positioned inside parent. Event is sent to parent in the case of gadgets. */ newEvent.x = ((XmGadget)WidgetTable[widgetIndex])->rectangle.x + 4; newEvent.y = ((XmGadget)WidgetTable[widgetIndex])->rectangle.y + 4; } newEvent.window = window; newEvent.display = display; newEvent.subwindow = 0; newEvent.root = XRootWindowOfScreen(XtScreenOfObject(W)); newEvent.type = eventType; newEvent.time = CurrentTime; newEvent.state = 0; if ((eventType == KeyPress) || (eventType == KeyRelease)) { /* The field below is the only difference between the event types used. */ newEvent.button = keyCode; } else { newEvent.button = Button1; } ret = XSendEvent(display, window, TRUE, eventMask, (XEvent *)&newEvent); /* Error checks should be done on ret */ } [Listing Five] Listing Five /* Application include file which defines widget names used as index into WidgetTable */ #define file-cascade 1 #define open-button 2 #define open-file-field 3 #define open-ok-button 4 [Listing Six] /* Table used to find widget indexes of application App1 in test driver */ TEST_ITEM App1TestTable[] = { {"file-cascade", 1}, {"open-button", 2}, {"open-file-field", 3}, {"open-ok-button", 4} }; int App1TableSize = (sizeof App1TestTable / sizeof App1TestTable[0]); [Listing Seven] /* Definition of the TEST_ITEM structure */ typedef struct { char *WidgetName; int WidgetIndex; } TEST_ITEM; Example 1: Typical test script B[uttonPress] K[eyPress] Example 2: Sample test Script Syntax ButtonPress myapp file-cascade ButtonPress myapp open-button KeyPress myapp open-file-field n KeyPress myapp open-file-field e KeyPress myapp open-file-field w KeyPress myapp open-file-field . KeyPress myapp open-file-field t KeyPress myapp open-file-field x KeyPress myapp open-file-field t ButtonPress myapp open-ok-button