| |
| |
| 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} |