blob: f72813dd02493e1d6aa8c3996fe3c482be59f7f5 [file] [log] [blame]
Wicket provides utility class FormTester that is expressly designed to test Wicket forms. A new FormTester is returned by @WicketTester@'s method @newFormTester(String, boolean)@ which takes in input the page-relative path of the form we want to test and a boolean flag indicating if its form components must be filled with a blank string:
{code}
//...
//create a new form tester without filling its form components with a blank string
FormTester formTester = tester.newFormTester("form", false);
//...
{code}
@FormTester@ can simulate form submission with method submit which takes in input as optional parameter the submitting component to use instead of the default one:
{code}
//...
//create a new form tester without filling its form components with a blank string
FormTester formTester = tester.newFormTester("form", false);
//submit form with default submitter
formTester.submit();
//...
//submit form using inner component 'button' as alternate button
formTester.submit("button");
{code}
If we want to submit a form with an external link component we can use method @submitLink(String path, boolean pageRelative)@ specifying the path to the link.
In the next paragraphs we will see how to use @WicketTester@ and @FormTester@ to interact with a form and with its children components.
h3. Setting form components input
The purpose of a HTML form is to collect user input. @FormTester@ comes with the following set of methods that simulate input insertion into form's fields:
* *setValue(String path, String value)*: inserts the given textual value into the specified component. It can be used with components @TextField@ and @TextArea@. A version of this method that accepts a component instance instead of its path is also available.
* *setValue(String checkboxId, boolean value)*: sets the value of a given @CheckBox@ component.
* *setFile(String formComponentId, File file, String contentType)*: sets a @File@ object on a @FileUploadField@ component.
* *select(String formComponentId, int index)*: selects an option among a list of possible options owned by a component. It supports components that are subclasses of @AbstractChoice@ along with @RadioGroup@ and @CheckGroup@.
* *selectMultiple(String formComponentId, int[] indexes)*: selects all the options corresponding to the given array of indexes. It can be used with multiple-choice components like @CheckGroup@ or @ListMultipleChoice@.
@setValue@ is used inside method @insertUsernamePassword@ to set the username and password fields of the form used in project @StatelessLoginForm@:
{code}
protected void insertUsernamePassword(String username, String password) {
//start and render the test page
tester.startPage(HomePage.class);
FormTester formTester = tester.newFormTester("form");
//set credentials
formTester.setValue("username", username);
formTester.setValue("password", password);
//submit form
formTester.submit();
}
{code}
h3. Testing feedback messages
To check if a page contains one or more expected feedback messages we can use the following methods provided by @WicketTester@:
* *assertFeedback(String path, String... messages)*: asserts that a given panel contains the specified messages
* *assertInfoMessages(String... expectedInfoMessages)*: asserts that the expected info messages are rendered in the page.
* *assertErrorMessages(String... expectedErrorMessages)*: asserts that the expected error messages are rendered in the page.
@assertInfoMessages@ and @assertErrorMessages@ are used in the test case from project @StatelessLoginForm@ to check that form generates a feedback message in accordance with the login result:
{code}
@Test
public void testMessageForSuccessfulLogin(){
inserUsernamePassword("user", "user");
tester.assertInfoMessages("Username and password are correct!");
}
@Test
public void testMessageForFailedLogin (){
inserUsernamePassword("wrongCredential", "wrongCredential");
tester.assertErrorMessages("Wrong username or password");
}
{code}
h3. Testing models
Component model can be tested as well. With method @assertModelValue@ we can test if a specific component has the expected data object inside its model.
This method has been used in the test case of project @ModelChainingExample@ to check if the form and the drop-down menu share the same data object:
{code}
@Test
public void testFormSelectSameModelObject(){
PersonListDetails personListDetails = new PersonListDetails();
DropDownChoice dropDownChoice = (DropDownChoice) personListDetails.get("persons");
List choices = dropDownChoice.getChoices();
//select the second option of the drop-down menu
dropDownChoice.setModelObject(choices.get(1));
//start and render the test page
tester.startPage(personListDetails);
//assert that form has the same data object used by drop-down menu
tester.assertModelValue("form", dropDownChoice.getModelObject());
}
{code}