]> source.dussan.org Git - vaadin-framework.git/commitdiff
Test for #4103 and #4107 (validation error indicators for empty fields)
authorHenri Sara <henri.sara@itmill.com>
Thu, 28 Jan 2010 12:10:05 +0000 (12:10 +0000)
committerHenri Sara <henri.sara@itmill.com>
Thu, 28 Jan 2010 12:10:05 +0000 (12:10 +0000)
svn changeset:11036/svn branch:6.3

tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.html [new file with mode: 0644]
tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.java [new file with mode: 0644]

diff --git a/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.html b/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.html
new file mode 100644 (file)
index 0000000..3d5f70f
--- /dev/null
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8080/run/com.vaadin.tests.validation.EmptyFieldErrorIndicators?restartApplication" />
+<title>EmptyFieldErrorIndicators</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">EmptyFieldErrorIndicators</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.validation.EmptyFieldErrorIndicators?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>initial</td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]/domChild[4]</td>
+       <td>168</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>emptyValidated</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td>
+       <td>22,15</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>enterCharacter</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td>
+       <td>a</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[0]/domChild[1]</td>
+       <td>15,10</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[3]</td>
+       <td>312</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span</td>
+       <td>12,8</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]</td>
+       <td>5980</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>17,11</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]/domChild[6]</td>
+       <td>6496</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[1]/domChild[1]</td>
+       <td>11,12</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[3]</td>
+       <td>364</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span</td>
+       <td>19,9</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]</td>
+       <td>9919</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VFilterSelect[1]/domChild[1]</td>
+       <td>11,11</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td</td>
+       <td>55,0</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[0]/domChild[0]/domChild[0]</td>
+       <td>9,3</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[1]/domChild[0]/domChild[0]</td>
+       <td>11,7</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td>
+       <td>32,14</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>enterCharacter</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td>
+       <td>a</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[0]/domChild[1]</td>
+       <td>12,9</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[3]</td>
+       <td>520</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span</td>
+       <td>12,12</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]</td>
+       <td>689</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>19,15</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]/domChild[6]</td>
+       <td>798</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[1]/domChild[1]</td>
+       <td>11,15</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[2]</td>
+       <td>91</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span</td>
+       <td>22,12</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>scroll</td>
+       <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]</td>
+       <td>4303</td>
+</tr>
+<tr>
+       <td>pause</td>
+       <td>300</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VFilterSelect[1]/domChild[1]</td>
+       <td>9,13</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td/span</td>
+       <td>23,9</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[0]/domChild[0]/domChild[0]</td>
+       <td>5,6</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[1]/domChild[0]/domChild[0]</td>
+       <td>7,7</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>filledValidated</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.java b/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.java
new file mode 100644 (file)
index 0000000..9ea28f6
--- /dev/null
@@ -0,0 +1,136 @@
+package com.vaadin.tests.validation;\r
+\r
+import com.vaadin.data.Validator.InvalidValueException;\r
+import com.vaadin.data.validator.AbstractValidator;\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.ComponentContainer;\r
+import com.vaadin.ui.DateField;\r
+import com.vaadin.ui.Field;\r
+import com.vaadin.ui.Form;\r
+import com.vaadin.ui.HorizontalLayout;\r
+import com.vaadin.ui.InlineDateField;\r
+import com.vaadin.ui.NativeSelect;\r
+import com.vaadin.ui.OptionGroup;\r
+import com.vaadin.ui.Panel;\r
+import com.vaadin.ui.PopupDateField;\r
+import com.vaadin.ui.Select;\r
+import com.vaadin.ui.TextField;\r
+import com.vaadin.ui.VerticalLayout;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.Button.ClickListener;\r
+\r
+public class EmptyFieldErrorIndicators extends TestBase {\r
+\r
+    @Override\r
+    protected void setup() {\r
+        getLayout().setSizeFull();\r
+\r
+        HorizontalLayout hl = new HorizontalLayout();\r
+        hl.setSizeFull();\r
+        hl.setSpacing(true);\r
+\r
+        ComponentContainer part1 = createPart(\r
+                "Empty required fields validation", true, false);\r
+        part1.setDebugId("emptyFieldPart");\r
+        hl.addComponent(part1);\r
+\r
+        ComponentContainer part2 = createPart(\r
+                "Empty required fields with failing validator", true, true);\r
+        part1.setDebugId("validatedFieldPart");\r
+        hl.addComponent(part2);\r
+\r
+        Panel panel = new Panel();\r
+        panel.setSizeFull();\r
+        panel.setStyleName(Panel.STYLE_LIGHT);\r
+        panel.addComponent(hl);\r
+        panel.setScrollable(true);\r
+        addComponent(panel);\r
+    }\r
+\r
+    private ComponentContainer createPart(String caption, boolean required,\r
+            boolean failValidator) {\r
+        VerticalLayout part = new VerticalLayout();\r
+        part.setMargin(true);\r
+\r
+        final Form form = createForm(required, failValidator);\r
+        part.addComponent(form);\r
+\r
+        Button validate = new Button("Validate fields");\r
+        validate.addListener(new ClickListener() {\r
+            public void buttonClick(ClickEvent event) {\r
+                try {\r
+                    form.validate();\r
+                } catch (InvalidValueException e) {\r
+                }\r
+            }\r
+        });\r
+        part.addComponent(validate);\r
+\r
+        Panel panel = new Panel(caption, part);\r
+        panel.setHeight("100%");\r
+        return panel;\r
+    }\r
+\r
+    private Form createForm(final boolean required, final boolean failValidator) {\r
+        // hand-crafted form, not using form field factory\r
+        Form form = new Form() {\r
+            @Override\r
+            public void addField(Object propertyId, Field field) {\r
+                super.addField(propertyId, field);\r
+                field.setRequired(required);\r
+                field.setRequiredError("Missing required value!");\r
+                if (failValidator) {\r
+                    field\r
+                            .addValidator(new AbstractValidator(\r
+                                    "Validation error") {\r
+                                public boolean isValid(Object value) {\r
+                                    return false;\r
+                                }\r
+                            });\r
+                }\r
+            }\r
+        };\r
+        \r
+        form.addField("Field", new TextField("Text"));\r
+        form.addField("Date", new DateField("Date"));\r
+        form.addField("Inline Date", new InlineDateField("Date"));\r
+        form.addField("Popup Date", new PopupDateField("Date"));\r
+\r
+        form.addField("Native Select", new NativeSelect("NativeSelect"));\r
+\r
+        // in #4103, the Select component was behaving differently from others\r
+        form.addField("Select", new Select("Select"));\r
+\r
+        Select select2 = new Select("Select 2");\r
+        select2.addItem("Value 1");\r
+        form.addField("Select 2", select2);\r
+\r
+        OptionGroup optionGroup = new OptionGroup("OptionGroup");\r
+        optionGroup.setMultiSelect(false);\r
+        optionGroup.addItem("Option 1");\r
+        optionGroup.addItem("Option 2");\r
+        form.addField("Option Group 1", optionGroup);\r
+\r
+        OptionGroup optionGroup2 = new OptionGroup("OptionGroup");\r
+        optionGroup2.setMultiSelect(true);\r
+        optionGroup2.addItem("Option 1");\r
+        optionGroup2.addItem("Option 2");\r
+        form.addField("Option Group 2", optionGroup2);\r
+\r
+        // TODO could add more different fields\r
+\r
+        return form;\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "Fields on a form should not show the error indicator if required and empty";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 4013;\r
+    }\r
+\r
+}\r