Skip to main content

Citrix Scripting and Replay Tips

On injector machines, Citrix requires an active desktop to host the Citrix sessions.

For remote injectors:

  • Start the injector process from windows Start menu or by launching the StartInjector.bat script in the bin/ folder where you installed the Eggplant Performance Injector software. You can see the live Citrix viewers during a test.


  • Set the injector service to run as a logged on local user.

Debugging Techniques

Use the following techniques when debugging your scripts:

  • Expect some Citrix events and/or screen portions to fail to synchronize as you start to replay and develop the script. Reducing the DefaultTimeout property (set to 1 minute by default) will reduce the time the Virtual User waits when attempting to synchronize,

  • Catch all exceptions and add a long Sleep() in the exception handler to delay the Citrix viewer closing.

    public override void Script()
    // your code
    catch (Exception e)
    Sleep(100000); // delay exit
  • Set RecordScreenshotOnError = true; (This is the initial default). This will record a screenshot whenever the script terminates on an error.

  • Call SaveScreenshotToFile() at suitable points in the script to record the screen.

  • Increase the value of DefaultWorkInterval to slow down the script. This increases the default time interval before each mouse click or typing.

  • Slow down typing by increasing the NextKeyDelay time. You can also increase KeyDownDelay but you will get key repeats, if a key is down for too long.

Create Separate Script Methods for Each Logical Action

The script generator adds all code to the Script() method. Editing your script to create separate methods for actions such as completing a dialog means:

  • The scripts are more readable and easier to maintain.
  • You can comment out or conditionally execute methods, perhaps based on data values or a test of the screen state. During script development you then don't need to run the script from the start every time, you can begin from the current state of the session.
  • You can move methods to your CustomVirtualUserScript class so they can be called from any script in your project. You can then avoid duplicated code in your scripts.
public override void Script()
public void CompleteSearchDialog()
// Script actions for this dialog

public void SelectSearchResult()
// Your code here

public void UpdateSelectedItem()
// Your code here

Image Matching Techniques and Problems

Use the following information to improve the image-matching in your scripts and avoid potential problems:

  • Capture the smallest size that can uniquely match the image to reduce search overhead and improve reliability. Limit the size to the icon, text, or image without the background or adjacent controls and borders if possible. The space between controls or between text and the text box boundary can often change, even by just one pixel causing a failure to match.
  • Ensure the Citrix FontSmoothingType and FontSmoothingTypePref properties are set to 1 (off). You may need to switch off ClearType on the injector and controller machines as Citrix occasionally ignores the FontSmoothingType setting.
  • If you must include a background such as when searching for text, try to select a solid background rather than a graduated background such as some title bars where the graduation can be dynamic.
  • Set the Citrix server to use a simple style such as Windows Classic to improve reliability. Dynamically changing windows elements such as semi-transparent areas or dynamic color graduations and backgrounds can make image matching unreliable.
  • Use the Spy Tool for Images to check that your images can be found as expected and re-capture if not. You can also use this tool to show (x, y) coordinates.
  • You can search for multiple images using the CheckForImages method. This can be useful if you need to search for alternate versions of an image such as in the enabled or disabled state.

Use the Shared Data Server for Passing Data

The Shared Data Server is particularly useful when working with Citrix as the Client Simulation API provides no way of scraping textual information from the screen. Rather than having to identify an entity by a text label another Virtual User group could be used to generate test entities. The entity details can then be passed to the Virtual User group responsible to operating on these entities.

Usually the Shared Data Server is launched from the Eggplant Performance Studio on the controller PC. If any of the Test Virtual User groups are deployed on remote injectors make sure the address of the Shared Data Server is either conditional (on injector name) or use the external address of the controller PC (providing the network/host setup allows).

The standard dictionary key injectorName (i.e., GetString("injectorName") ) returns the name of the injector that Virtual User is deployed on if the Shared Data Server address is conditional.

Be Conscious of the Effects of System Loading

As system usage increases so does server-side processing, which ultimately means the application and/or Citrix tier will take longer to respond. When setting the DefaultTimeout property is advisable to run a dress rehearsal performance test where a high value is specified. This run will give some indication of a suitable value to be use for subsequent runs used for reporting.

Keep Screen Resolution Settings Consistent

When replaying a Virtual User script on another machine (by exporting the script/workspace) or utilizing setup a remote injector deployment to ensure successful bitmap synchronization, it is important that the client window size (screen resolution) specified in the script is the same as that used for the original recording otherwise screen co-ordinates maybe incorrect during playback.

Compare the clientWidth and clientHeight parameters passed into the StartCitrixClient call with those specified in the Citrix ICA file for the published application.

Note that the ICA file field ScreenPercent takes precedence over DesiredHRES/VRES fields. For testing you should always use fixed sizes and not ScreenPercent.

Other items which need to be consistent between the record and replay machines include Window Colors and System Font. These settings affect the hash value of bitmaps, and inconsistencies may cause synchronisation points to fail.

Avoid Repeatedly Reconnecting

Try to avoid repeatedly connecting and disconnecting from Citrix. In most cases this isn't realistic and will overly stress the Citrix server layer.

Move these calls into scripts found in the initial and final sections of the Virtual User's workflow or your Custom Citrix Virtual User's Pre() or Post() method.

If you need to re-connect on error, you can test the Connected flag, and only connect if this is false e.g.

if (!Connected)
WaitForEvent(new CitrixEvent(CitrixEventType.Connected));

Always Tidy Up the Session

Try to program the Virtual User in such a way that the session is cleaned up at the end of each iteration and/or workflow (prior to gracefully disconnecting).

This effectively resets the screen for that test user ready for the next run. Leaving a single open window in the foreground could be enough to for the Virtual User to lose focus on the main form for the next workflow iteration or test run.

By calling the tidy-up calls at the start, with a check to see it is required, you can reset the application to a known state if the previous iteration or session exited abnormally.

Citrix Changes that Facilitate Performance Testing

You may prefer that Citrix is configured so sessions are closed and reset when the client disconnects. This means you are always starting from a new session on connection rather than where it was left when disconnected.

  • Remove any inactivity warning dialog, or increase it to a long timeout so it does not interrupt test scripts.
  • Disable server pop-up messages that can interfere with the scripts
  • Set the server to use Windows Classic style to increase image matching reliability.