Writing a Visual Studio Web Test for InfoPath Forms Services 2007

To write a Visual Studio web test for InfoPath Forms Services (IPFS), you must first understand some of IPFS’s architecture. Before continuing, read the Forms Services Architecture article on MSDN. Pay close attention to the “Runtime Architecture” and “Rendering and Query Parameters” sections.

InfoPath Forms Services HTTP Traffic

When using an InfoPath form in the browser, a conversation between the browser and server occurs over HTTP. This conversation consists of two kinds of transactions: Invocation and Postback. Invocation occurs once when first opening the form. After the form has been invoked, one or more postbacks to the server can occur.
IPFS HTTP traffic.jpg

Invocation

Invocation is the first transaction that occurs. It loads all the resources that allow you to edit the form in the browser. Invocation is started by making a GET request to FormServer.aspx. (See How to: Use Query Parameters to Invoke Browser-Enabled InfoPath Forms for more information on the format of this request). The response includes the HTML of the form and some javascript for the form. This request also causes requests for other dependent resources. One of these dependent resources is core.js, which defines the core logic for form editing in the browser.
IPFS invocation.jpg

Current Form Data

In the browser, there is javascript running which defines several pieces of data. In particular, there is an array named g_objCurrentFormData. Data in this array will later be used to create a postback request. There are three pieces of dynamic data that will be important when writing the web test:
Data Index of g_objCurrentFormData Description When does it change?
Editing Session Id 3 Identifies your session with the server When invoking a form
Solution Id 4 Uniquely identifies the form template When the form template has been updated
Canary 25 Used for security mitigation With every request/postback

(The indicies above assume you have installed Service Pack 1 on your server. If you are using a pre-SP1 version the Canary will be at index 24.)

Postback

While you are interacting with a form in the browser, you may perform various actions such as typing in a text box or clicking a button. These actions are recorded in an event log, using javascript. When the form is submitted, or when logic must be performed on the server, the browser sends the event log to the server. The server plays back the actions in the event log to recreate the state of the form. Finally, the updated state of the form is returned to the browser and the browser refreshes its view of the data. This transaction is known as a postback. InfoPath has two types of postbacks - partial postback and full page postback. A partial postback is a more efficent transaction because less data is transmitted. However, some actions like view switching must use a full page postback.

Partial Postback

When a partial postback occurs, the event log is sent to the server using a POST request to Postback.FormServer.aspx. The body of the POST request contains the event log. The response from the server contains javascript to evaluate on the browser, which updates its view of the data.
IPFS postback.jpg

Full Page Postback

When a full page postback occurs, the event log, along with some other data, is sent to the server using a POST request to FormServer.aspx. The response from the server contains HTML and javascript to render the updated view of the data.
IPFS full page postback.jpg

Event Log

The event log follows a specific format which is described below in BNF. Note that the location of spaces is important.

<EventLog> ::= <EventLogInfo> ” “ <Events>

<EventLogInfo> ::= <Data0> “;” <PostbackCounter> “;” <EditingSessionId> “;” <SolutionId> “;” <Data4> “;” <Data5> “;” <Data6> “;” <Data7> “;” <Data8> “;” <Data9> “;” <Data10> “;” <Data11> “;” <Data12> “;” <Data13> “;” <Data14> “;” <Data15> “;” <Data16> “;” <Data17> “;” <Canary>

<Events> ::= <Events> “ “ <Event> | <Event> “ “

The event log consists of two main parts: EventLogInfo and Events. EventLogInfo is simply a list of items separated by semicolons. Events is a list of items separated by spaces. Each item of Events represents an action that occurred while interacting with the form.
As you can see, the three important pieces of information from g_objCurrentFormData are used in EventLogInfo.
  1. Editing Session Id is at index 2
  2. Solution Id is at index 3
  3. Canary is at index 18

There is another piece of EventLogInfo to point out. At index 1 is the PostbackCounter. This is an integer that starts at 0 and increments with each postback.

An example event log follows.
Editing Session Id is bolded
Solution Id is italicized
Canary is underlined

8;0;3a41917c-bc1d-409b-904a-32fb82ce565b;I:5fdfe5d2-fe2b-446f-9c70-504a30b3b40f:9285a025-812e-4c2f-a194-39edbec6c50a:633415556920000000;0;;http%3A%2F%2Fmyserver%2Fexample%2FForms%2Ftemplate.xsn;http%3A%2F%2Fmyserver%2Fexample%2FForms%2Ftemplate.xsn;http%3A%2F%2Fmyserver%2Fexample%2F;http%3A%2F%2Fmyserver;http%3A%2F%2Fmyserver%2Fexample%2FForms%2FAllItems.aspx;1;1;0;10;0;633415558731245000;;xKQi13p2GSqnFUzaSU7oMSRrhdC5spPCSnMbGWAd/kp95egDGTpq2vhVf/vz4ASFTrsYvuWQIj4G68gTruRruQ==|633415558731244855 0;V1_I1_T1;0;Type%20some%20text 14;;false;false

Putting the Pieces together in Visual Studio

Now that we have a general idea how IPFS generates HTTP traffic, we can write a web test in Visual Studio. Let’s recap the relevant IPFS architecture information:
  • IPFS has two main transactions when interacting with a form: Invocation and Postback
  • Editing Session Id, Solution Id, and Canary are dynamic. They will need to be extracted from responses.
  • Editing Session Id, Solution Id, and Canary are used in the postback request. Their values will need to be substituted in the postback body.
  • Editing Session Id and Solution Id do not change between postbacks. They will only need to be extracted for the invocation request.
  • Canary changes after every postback. It needs to be extracted for every request.
We have all the required knowledge; we just need to put the pieces together. The basic steps to write a web test for IPFS are:
  1. Capture HTTP requests using Fiddler or Visual Studio
  2. Add the ExtractAndSubstituteDynamicInfoPathData web test plugin. This plugin does all the hard work for us at runtime. It identifies which responses are for InfoPath and extracts Current Form Data to a context parameter. Then it identifies InfoPath postback requests and substitutes the dynamic pieces of data into the postback body.

Capture HTTP requests

  1. Start Visual Studio
  2. Create a new web test
  3. Start capturing using Visual Studios Web Test Recorder
  4. Open an InfoPath form in a web browser open form.jpg
  5. Perform the actions you want to happen in your test perform actions in browser.jpg
  6. Click the stop button in the Web Test Recorder

Add ExtractAndSubstituteDynamicInfoPathData web test plugin

  1. Add an InfoPathExtractionRules reference to the test project. (You can download a dll for InfoPathExtractionRules from the Releases tab of this project. Or you can download the source code for the extraction rules and plugin on the Source Code tab.)
  2. Add ExtractAndSubstituteDynamicInfoPathData web test plugin. For the common usage of InfoPath, just leave the InvocationPath parameter blank. When InvocationPath is blank, the plugin should use _layouts/FormServer.aspx at run time. However, if your InfoPath form is in an XmlFormViewControl, you will need to specify the InvocationPath parameter to identify which requests act as an InfoPath invocation. If a request url contains the InvocationPath string, then it is identified as an InfoPath request.


The original technique for writing a web test with InfoPath involved individual extraction rules and manual steps with context parameters. The instructions for that technique can be found on Using the Individual Extraction Rules.

Last edited Nov 18, 2008 at 11:18 PM by JBooze, version 21