Canoo Webtest WebTest Canoo

Extension Step expectDialog

Description

Provides the ability to set expectations in relation to user responses to JavaScript Dialog boxes (Alert, Confirm and Prompt dialogs).

This step is used prior to clicking on a link or button which invokes some JavaScript that uses dialogs (Alert, Confirm or Prompt dialogs). If you don't use this step, Canoo WebTest simply clicks 'OK' on every dialog silently. This is OK if you don't care about the Dialogs, but if you do care, you have no way of telling if anything was actually clicked or what messages were displayed in the dialogs.

You may be wondering why you need to set up expectations prior to clicking on a link or button. This is mostly due to implementation issues with the way Canoo WebTest works and the way it calls HtmlUnit . It turns out to be easier at the moment to create a list of dialog expectations. As interactions with your application cause JavaScript to invoke dialogs, we simply look at the next dialog expectation on the list, check that it meets expectations (or optionally save away the dialog message text) and then remove it from the list. For tricky JavaScript there may be multiple interactions from the user. We simply list all the expected dialog interactions in the order we expect them to occur by repeating this step as many times as required. (Alternatively, consider using the newer expectDialogs step which allows more concise expression of dialog sequences.)

Often you will use the verifyNoDialogs step in conjunction with this step to ensure that your expectations for dialogs were met. The verifyNoDialogs step is used after clicking on your link or button - it checks that the list of expected dialogs is now empty, i.e. by the time you have finished interacting with your application all the dialogs you were expecting to need clicking were actually clicked.

Parameters

description
Required? no
The description of this test step.
dialogType
Required? no, default is alert
One of "alert", "confirm" or "prompt".
response
Required? no, default is true
simulate user response: ignored for alerts, converted to boolean for confirms - "OK" (true) or "Cancel" (false), contains typed text for prompts.
saveProperty
Required? no
The name of the property in which to store the dialog text for later checking with "verifyProperty".
savePropertyType
Required? no, default is the "defaultPropertyType" as specified in the "config" element is used.
The type of the property in which to store the dialog text for later checking. Either "ant" or "dynamic".

Details

Normally only one <expectDialog> step will be required but if you have complex JavaScript, it may require the user to respond to multiple dialogs associated with one form or link click. If this is the case (as in the complex example below) you should use multiple <expectDialog> steps in the same order that the user would respond to them in or consider using the enhanced expectDialogs step. If you want to check that no dialogs were in fact used, you must use the expectDialogs step. Only one verifyNoDialogs is ever required after the click event to check that everything worked as planned.

If you were expecting the JavaScript to invoke 2 dialog but only one was in fact invoked, the verifyNoDialogs step will fail with an appropriate error message. Similarly, if you expected only one dialog interaction but more occurred, the intervening click request step will fail.

Simple Example

Consider the following HTML form:

If the user leaves fields blank, we want to pop up an alert as follows:

The HTML might look something like:

Simple dialog example HTML
<HTML>
<HEAD><TITLE>Simple Dialog Example</TITLE>
<SCRIPT LANGUAGE='JAVASCRIPT'>
function isEmpty(thefield) {
    var re = /^\s{1,}$/g; //match white space i.e. space, tab, form-feed, etc.
    if ((thefield.value.length==0) || (thefield.value==null)
            || ((thefield.value.search(re)) > -1)) {
        return true;
    }
    return false;
}
function validate(theForm) {
    var message="Validation errors in form:\n";
    var errorFound = false;
    if (isEmpty(theForm.name)) {
        message += "Username field must not be blank!\n";
        theForm.name.focus();
        errorFound = true;
    }
    if (isEmpty(theForm.password)) {
        message += "Password field must not be blank!\n";
        if (!errorFound) {
            theForm.password.focus();
            errorFound = true;
        }
    }
    if (errorFound) {
        alert(message);
        return false;
    }
    return true;
}
</SCRIPT>
</HEAD>
<BODY>
<FORM name='myForm' action='' method='post'>
   Username: <INPUT type='text' NAME='name' value='' SIZE='30'><br>
   Password: <INPUT type='password' NAME='password' value='' SIZE='30'><br>
   <INPUT type='button' name='submit' value=' Login '
        onClick='return validate(myForm);'>
   <INPUT type='reset' name='reset' value=' Clear '>
</FORM>
</BODY>
</HTML>

The test might look something like:

Simple dialog example Test
<webtest name="verifyDialogs: test simple dialog form validation example">
    <config .../>
    <steps>
        <invoke description="Load Pageurl="/simpleDialogExample.html"/>
        <verifyTitle description="Confirm pagetext="Simple Dialog Example"/>

        <-- try with both fields blank -->
        <expectDialog dialogType="alertsaveProperty="simpleDialog" />
        <clickButton description="Click Login buttonname="submit" />
        <verifyProperty name="simpleDialogregex="true"
            text=".*Username field must not be blank.*"/>
        <verifyProperty name="simpleDialogregex="true"
            text=".*Password field must not be blank.*"/>
        <verifyNoDialogs description="Check all dialogs were used" />

        <-- try with just password field blank -->
        <expectDialog dialogType="alertsaveProperty="simpleDialog" />
        <setInputField name="namevalue="some username" />
        <clickButton description="Click Login buttonname="submit" />
        <not>
            <verifyProperty name="simpleDialogregex="true"
                text=".*Username field must not be blank.*"/>
        </not>
        <verifyProperty name="simpleDialogregex="true"
            text=".*Password field must not be blank.*"/>
        <verifyNoDialogs description="Check all dialogs were used" />

        <-- try with just username field blank -->
        <expectDialog dialogType="alertsaveProperty="simpleDialog" />
        <setInputField name="namevalue="" />
        <setInputField name="passwordvalue="some password" />
        <clickButton description="Click Login buttonname="submit" />
        <verifyProperty name="simpleDialogregex="true"
            text=".*Username field must not be blank.*"/>
        <not>
            <verifyProperty name="simpleDialogregex="true"
                text=".*Password field must not be blank.*"/>
        </not>
        <verifyNoDialogs description="Check all dialogs were used" />

        <-- try with valid fields -->
        <setInputField name="namevalue="some username" />
        <clickButton description="Click Login buttonname="submit" />
        <-- would normally check we are on a new page here -->
    </steps>
</webtest>

Complex Example

Consider an application which performs some disk administration (the samples below don't actual do anything but show the kind of JavaScript messages that such an application would need to use).

When the user clicks the clean button they receive a JavaScript confirm dialog:

If the user selects "Cancel" they receive the following alert:

If the user selects "OK" they receive the following prompt dialog as a precaution:

If the user then clicks "Cancel" or enters incorrect text, e.g. "No" in the prompt, they receive the following alert dialog:

If the user enters the correct "YES" text and clicks "OK", they receive the following alert dialog (NOTE: nothing happens despite the message - this is just a hypothetical demo):

Here is the relevant part of the build.xml:

Complex example test
<webtest name="testHardDiskErase">
  <config .../>
  <steps>
    <invoke description="Load Initial Pageurl="/diskadmin.jsp"/>
    <verifytitle description="Should be disk admin pagetext="Disk Admin Page"/>
    <-- check for initial cancel -->
    <expectDialog description="Save first JavaScript Response"
        dialogType="confirmresponse="falsesaveProperty="initialDialog" />
    <expectDialog description="Save second JavaScript Response"
        dialogType="alertsaveProperty="resultDialog" />
    <clickbutton description="Click Clean buttonname="CleanButton" />
    <verifyProperty description="Check text from first JavaScript Dialog"
        property="initialDialogtext="Are you sure?" />
    <verifyProperty description="Check text from second JavaScript Dialog"
        property="resultDialogtext="Operation cancelled!" />
    <verifyNoDialogs description="Check all dialogs were used" />

    <-- check for initial OK but then cancel instead of confirm -->
    <expectDialog description="Save first JavaScript Response"
        dialogType="confirmresponse="truesaveProperty="initialDialog" />
    <expectDialog description="Save second JavaScript Response"
        dialogType="promptresponse="falsesaveProperty="confirmDialog" />
    <expectDialog description="Save third JavaScript Response"
        dialogType="alertsaveProperty="resultDialog" />
    <clickbutton description="Click Clean buttonname="CleanButton" />
    <verifyProperty description="Check text from first JavaScript Dialog"
        property="initialDialogtext="Are you sure?" />
    <verifyProperty description="Check text from second JavaScript Dialog"
        property="confirmDialogregex="truetext=".*very sure.*YES.*" />
    <verifyProperty description="Check text from third JavaScript Dialog"
        property="resultDialogtext="Operation aborted!" />
    <verifyNoDialogs description="Check all dialogs were used" />

    <-- check for initial OK followed by confirm -->
    <expectDialog description="Save first JavaScript Response"
        dialogType="confirmresponse="truesaveProperty="initialDialog" />
    <expectDialog description="Save second JavaScript Response"
        dialogType="promptresponse="YESsaveProperty="confirmDialog" />
    <expectDialog description="Save third JavaScript Response"
        dialogType="alertsaveProperty="resultDialog" />
    <clickbutton description="Click Clean buttonname="CleanButton" />
    <verifyProperty description="Check text from first JavaScript Dialog"
        property="initialDialogtext="Are you sure?" />
    <verifyProperty description="Check text from second JavaScript Dialog"
        property="confirmDialogregex="truetext=".*very sure.*YES.*" />
    <verifyProperty description="Check text from third JavaScript Dialog"
        property="resultDialogtext="Hard disk erased!" />
    <verifyNoDialogs description="Check all dialogs were used" />
  </steps>
</webtest>

This assumes you have some HTML containing a form and some JavaScript something like the following:

Complex example HTML/JavaScript
<html>
<title>Disk Admin Page</title>
<body>
<script>
function doubleCheck() {
var x=confirm("Are you sure?")
if (x) {
    var y=prompt("Are you very sure? Type 'YES' to confirm")
    if (y=="YES")
       alert("Hard disk erased!")
    else
       alert("Operation aborted!")
} else
    alert("Operation cancelled!")
}
</script>
<h3>Clean Disk?</h3>
<form method="POST">
<p><input type="buttonname="CleanButtonvalue="OKonclick="doubleCheck()"></p>
</form>
</body>
</html>

news

Latest build: development
Posted: 19-Jul-2016 17:36

WebTest 3.0 released, featuring upgrades to Java 5, Groovy 1.6, and HtmlUnit 2.4.
The release includes support for maven integration, IDE-integration like for unit tests, capturing of background JavaScript errors, new steps for mouseOver and mouseOut events, better parallel execution of tests and - as usual - lots of handling improvements.
Posted: 5 March 2009

WebTest @ JavaOne
Dierk König presented "Functional testing of web applications: scaling with Java" on Wed May 7, 13:30 at JavaOne 2008 in the Tools and Scripting Languages track.
Posted: 8 May 2008

New WebTest screencast available:
Data Driven WebTest
Posted: 13 November 2007

First WebTest screencast available:
Creating a first Webtest Project

Extend WebTest with Groovy! Groovy in Action is available in every good bookstore.
Groovy in Action
Posted: 29 January 2007