You need this when you want to test a form the way a user fills it in: type values, choose options, press a button, and see the result. FormTester does that for one form on the page that WicketTester last rendered. Test pages and components covers setting up the tester.
Fill in and submit a form
Ask the tester for a FormTester with the path of the form, set the values with the ids of the fields relative to the form, and submit:
SignUpPageTest.java
@Test
void signsUp() {
tester.startPage(SignUpPage.class);
FormTester form = tester.newFormTester("form");
form.setValue("name", "Ada Lovelace");
form.setValue("email", "ada@example.com");
form.setValue("terms", true);
form.submit();
tester.assertNoErrorMessage();
tester.assertRenderedPage(WelcomePage.class);
}
A new FormTester starts with the values the fields show, as a browser would send them. Text fields without a value are sent as empty strings; newFormTester("form", false) leaves them out of the request instead. Invisible and disabled fields are never sent.
Each FormTester submits once. Create a new one for the next submit.
FormTester sends the request directly, so the browser’s own checks of required and pattern attributes do not run. A test that submits an empty required field therefore reaches Wicket’s server-side validation, which is what you want to test.
Since Wicket 11, text fields write
requiredwhen they are required,placeholderfrom their label (setLabel), andpatternfor aPatternValidator. Tests that compare rendered markup with an expected file, or check the attributes of an<input>withTagTester, see these attributes on Wicket 11 and not on Wicket 10.
Set each kind of field
| Field | Method |
|---|---|
TextField, TextArea, PasswordTextField, hidden fields |
setValue("id", "text") |
CheckBox |
setValue("id", true) |
DropDownChoice, RadioChoice, RadioGroup, ListChoice
|
select("id", index) |
ListMultipleChoice, CheckBoxMultipleChoice, CheckGroup
|
selectMultiple("id", new int[] {0, 2}) |
FileUploadField |
setFile("id", file, "application/pdf") |
select takes the position of the option in the list of choices, starting at 0. selectMultiple adds to the current selection; selectMultiple("id", indexes, true) replaces it. setValue also takes the component instead of its id.
Press a specific button
submit() submits the form without naming a button, so no button’s onSubmit runs. To press a button, name it:
form.submit("save");
For an AjaxButton or AjaxSubmitLink, submit("id") fires the Ajax event, so you can check the Ajax response afterwards:
form.submit("saveAjax");
tester.assertComponentOnAjaxResponse("feedback");
A SubmitLink, inside or outside the form, is pressed with submitLink(path, pageRelative): with true the path starts at the page, with false at the form.
Check the feedback messages
form.setValue("email", "not an address");
form.submit();
tester.assertErrorMessages("The value of 'email' is not a valid email address.");
tester.assertModelValue("form:email", null);
| Method | Checks |
|---|---|
assertErrorMessages(String...) |
Exactly these error messages, in any order |
assertInfoMessages(String...) |
Exactly these info messages |
assertNoErrorMessage(), assertNoInfoMessage()
|
No such messages |
assertFeedback(path, String...) |
What a FeedbackPanel at that path renders |
assertComponentFeedbackMessage(component, key, model, filter) |
A message from a resource key for one component |
The tester keeps all messages until the next request, and the FormTester clears them before it submits.
Check the model after submitting
Read the model of a field with assertModelValue, or check the object behind the form directly:
form.setValue("name", "Grace Hopper");
form.submit("save");
Person saved = (Person) tester.getComponentFromLastRenderedPage("form")
.getDefaultModelObject();
assertEquals("Grace Hopper", saved.getName());
Fire an Ajax event on a field
A field with an AjaxFormComponentUpdatingBehavior only processes its value when the event fires. Set the value with a FormTester, then fire the event:
FormTester form = tester.newFormTester("form");
form.setValue("country", "NL");
tester.executeAjaxEvent("form:country", "change");
tester.assertComponentOnAjaxResponse("form:province");
If the application uses ResourceIsolationRequestCycleListener, add the Sec-Fetch-Site header before each submit; see Test pages and components.