Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions articles/building-apps/forms-data/add-form/fields-and-binding.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,35 @@ When using a JavaBean as an FDO, `Binder` can operate in *buffered* or *write-th
* *Buffered mode*: Changes remain in the form until explicitly saved. This prevents side effects but may affect validation behavior.
* *Write-through mode*: Updates the FDO immediately as the user edits the form. Business logic in setter methods is triggered immediately. However, invalid states can occur where the form contains errors, but the FDO remains valid.

==== Choosing a Mode

Prefer buffered mode for most forms: it lets you implement a *Cancel* action without tracking state manually, and it defers writing until the data is valid. Reach for write-through mode when every change should take effect immediately.

[cols="2,1,3"]
|===
|Scenario |Mode |Why

|Form with [guibutton]`Save`/[guibutton]`Cancel` buttons
|Buffered
|The user can discard changes; nothing is written until validation passes.

|Multi-step wizard
|Buffered
|Validate each step before advancing.

|Inline row editing in a Grid
|Buffered
|Save or cancel per row.

|Settings panel
|Write-through
|Each change should apply immediately.

|Search or filter bar
|Write-through
|Filtering should update live as the user types.
|===

Form validation is covered in the <<validation#,Form Validation>> guide.


Expand Down
3 changes: 3 additions & 0 deletions articles/flow/binding-data/components-binder-beans.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ binder.forField(gender)
.bind(Person::getGender, Person::setGender);
----

[TIP]
Prefer explicit [methodname]`forField().bind()` binding with getter and setter method references for anything beyond the simplest forms. It's more readable, is checked at compile time, and doesn't rely on field and property names matching. Automatic [methodname]`bindInstanceFields()` binding is convenient for simple forms, but its reliance on naming conventions and its use of `@PropertyId` and [methodname]`forMemberField()` to handle mismatches make it harder to maintain as a form grows. Binding by string property name is best reserved for record FDOs, whose component accessors can't be referenced as method references.


=== Specifying Property Names

Expand Down
14 changes: 14 additions & 0 deletions articles/flow/testing/end-to-end/reliable-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ As with any code, it's important to write tests so that the reader understands t
If the test is full of low-level details about how you locate the parts of the application with which you want to interact, it becomes overwhelming to try to decode what the test is actually trying to verify. By using page/view objects, you can abstract away the low-level details about how the view is built and what exact components are used. You can also use <<bdd#,Behavior-Driven-Development>> (BDD) to describe your test scenarios using normal English sentences.


== Keeping Tests Focused and Independent

End-to-end tests are expensive to run compared to <<{articles}/flow/testing/browserless#,browserless tests>>, so use them deliberately. Cover each critical user journey -- such as logging in, or completing a checkout -- with one focused test rather than trying to exercise every edge case through the browser. Push comprehensive coverage of component logic, validation, and view behavior down to faster browserless tests, and keep the end-to-end suite for the paths that genuinely need a real browser.

Make each test independent: it should set up the state it needs and not rely on another test having run first. Independent tests can run in any order or in parallel, and a failure points to a single scenario instead of a broken chain.


== Guarding against Application Changes

If your application never changes, you can test it manually once and know that it works. However, applications are usually developed forward and you will need to maintain the tests as the application evolves.
Expand All @@ -45,6 +52,13 @@ Use `ids` which describe the action that occurs when the button is pressed, not,
If your `id` is tied to the hierarchy, you indirectly depend on the hierarchy and lose many benefits of using `ids`.


== Waiting for Asynchronous Updates

Views often update asynchronously -- after navigation, a server round-trip, or lazy data loading -- so an element you want to interact with may not be present the moment a test looks for it. Don't paper over this with fixed pauses such as `Thread.sleep()`: a sleep that's long enough on a fast machine is often too short on a loaded CI server, and any sleep that's reliable is slower than it needs to be.

Instead, wait for the condition you actually care about. Use [methodname]`waitForFirst()` on an [classname]`ElementQuery` to wait until a matching element appears, or [methodname]`waitUntil()` to wait for an arbitrary condition. Explicit waits return as soon as the condition is met, so they are both faster and more reliable than fixed delays.


== Dealing with Test Environment Problems

When dealing with browser-based tests, you need to take into account that the environment isn't always as stable as you would want it to be.
Expand Down
Loading