vaadin / vaadin/browserless-test
CustomField calling setPresentationValue even though trigger came from client-side
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1
- Forks
- 3
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 51
Description
Using version 1.1.2.
I have a widget that is a subclass of CustomField and wraps a TextField. (Specifically, it edits an Integer with significant digits and rounding, but this is not relevant to the problem.)
My implementation handles events manually by implementing TextField.addValueChangeListener on the wrapped TextField. It does not listen to changes on the CustomField.
The problem is that the browserless-test framework is calling CustomField.setPresentationValue in response to changes from the user. The sequence is:
-
Test code simulates the user inputting a value by calling
ComponentTester.setValueAsUser(value)on the CustomField. -
This calls
CustomField.getFieldSupport().setValue(value, false, true); -
Because
fromInternal=false, this callsAbstractFieldSupport.applyValue(value); -
That calls
setPresentationValue.accept(value)on the CustomField.
The documentation at https://vaadin.com/docs/latest/components/custom-field reads:
Custom Field triggers [setPresentationValue] to update child component values when its value changes programmatically on the server-side.
But it DIDN'T come from the server-side; it came from the client. In step2, fromClient=true.
-
My implementation of
CustomField.setPresentationValueassumes the change is coming from the server. It updates the TextField. This triggers a TextField event which the CustomField ignores because it is server-side. (This step is not relevant to the problem; I am just explaining it for completeness.) -
The
AbstractFieldSupport.setValuemethod fires an event for the CustomField with the correct value offromClient=true. However, I am not listening to it.
I suppose I could fix this one case by listening to the CustomField instead of the TextField. However, I have many other cases where the CustomField contains more than just a TextField: Code that listens to each widget individually is cleaner and easier to follow.
Another option is to alter my custom ComponentTester to set the value on the TextField rather than the CustomField. I plan to try this next.
My concern is that my code has to handle an unnecessary setPresentationValue. Is this a "real issue" or is it a "false artifact"? Meaning, specifically, will the actual browser ever update the value directly on the CustomField, which is what I am simulating?
A. If the browser never updates the value directly on the CustomField, this is a non-issue.
B. If the browser updates the value directly on the TextField, my listener will work correctly. And the correct implementation of my ComponentTester is to update the TextField and not the CustomField.
Prior to further testing, I suspect "A" is the answer, because I have parallel testing in place with playwright, where it does work correctly.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ComponentTester.setValueAsUser(value), CustomField.getFieldSupport().setValue, AbstractFieldSupport.setValue, and the setPresentationValue call described in the report. Compare this path with how an actual browser updates the wrapped TextField, then determine whether the tester should target the child component or whether CustomField should avoid the call for client-originated changes. Done means the browser and browserless-test behavior are consistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100