You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follows up on #17852, which added the integer/number primitive checks this loosens.
💥 What does this PR do?
An integer BiDi field now accepts a whole-valued float like 5.0 in addition to 5, inbound and outbound. A fractional value like 1.5 is still a mismatch and still raises.
🔧 Implementation Notes
PRIMITIVE_TYPES (a map of Ruby classes) becomes PRIMITIVE_CHECKS (a map of lambdas), so a schema primitive is defined by JSON kind rather than by Ruby class. JS has no int/float split, so a browser is free to spell an integer either way.
Inbound coerces a whole float to Integer so the parsed value matches the declared type; the conversion is exact. Outbound passes the value through unchanged.
🤖 AI assistance
AI assisted (complete below)
Tool(s): Claude Code (Opus 5)
What was generated: this description
I reviewed all AI output and can explain the change
➖ Conflicts with the intent of the BiDi schema and prior primitive enforcement work.
Recommendation: The chosen approach (predicate-based PRIMITIVE_CHECKS + inbound coercion of whole floats to Integer) is the best balance: it keeps the schema’s integer semantics, matches JS/JSON realities, and centralizes the rule so scalar unions, inbound parsing, and outbound validation stay consistent. The new specs cover both the acceptance case (5.0) and the rejection case (5.5/1.5), reducing regression risk.
Files changed (2) +36 / -20
Bug fix (1) +24 / -18
record.rbAccept whole-valued floats for integer primitives via predicate checks+24/-18
Accept whole-valued floats for integer primitives via predicate checks
• Replaces PRIMITIVE_TYPES (Ruby class lists) with PRIMITIVE_CHECKS (predicate lambdas) to validate primitives by JSON kind. Updates scalar-union and outbound primitive validation to use these checks. Inbound reading now coerces whole-valued floats for integer fields into Integer while still rejecting fractional floats.
serialization_spec.rbAdd coverage for whole-float integer acceptance and integer coercion+12/-2
Add coverage for whole-float integer acceptance and integer coercion
• Updates the outbound integer primitive test to reject fractional floats and adds a new test allowing whole-valued floats for integer fields. Adds an inbound test asserting whole-valued floats are accepted for integer-typed fields and coerced to Integer.
WHOLE_FLOAT uses Float modulo to decide integrality, which can treat very large fractional values as
“whole” after Float rounding, allowing a non-integer wire value to pass integer validation and be
coerced to Integer. This violates the intent that fractional values always raise and can silently
change values in extreme numeric ranges.
The PR introduces WHOLE_FLOAT’s modulo-based integrality test and then uses it to accept Float
values for the integer primitive; inbound, accepted floats are coerced to Integer via to_i.
Because Float rounding can erase fractional parts at large magnitudes, this pathway can accept and
coerce values that were not true integers on the wire.
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution
### Issue description
`WHOLE_FLOAT` currently checks integrality via `(value % 1).zero?`. For sufficiently large magnitudes, IEEE-754 Float cannot represent fractional increments (the parsed Float may already be rounded to an integer), so a wire value that was fractional can be accepted as an `integer` and then coerced via `to_i`.
### Issue Context
This PR intentionally accepts whole-valued floats for `integer` primitives and coerces inbound floats to `Integer`.
### Fix Focus Areas
- rb/lib/selenium/webdriver/bidi/serialization/record.rb[269-279]
- rb/lib/selenium/webdriver/bidi/serialization/record.rb[238-243]
### What to change
- Strengthen the definition of an “acceptable integer float” by additionally requiring it be within JS safe-integer bounds (since the sender is a browser JS Number) and/or explicitly documenting and enforcing the intended exactness constraint.
- For example:
- Define a `SAFE_INTEGER = 9_007_199_254_740_991` constant.
- Update `WHOLE_FLOAT` to require `value.abs <= SAFE_INTEGER` in addition to current checks.
- Keep coercion (`to_i`) only after the strengthened check.
### Acceptance criteria
- A value like `5.0` is accepted.
- A value like `5.5` is rejected.
- A very large float with potential precision loss (e.g., magnitude > 2**53) is rejected for `integer` primitives when expressed as Float, preventing silent rounding/acceptance.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
B-devtoolsIncludes everything BiDi or Chrome DevTools relatedC-rbRuby Bindings
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Related Issues
Follows up on #17852, which added the integer/number primitive checks this loosens.
💥 What does this PR do?
An
integerBiDi field now accepts a whole-valued float like5.0in addition to5, inbound and outbound. A fractional value like1.5is still a mismatch and still raises.🔧 Implementation Notes
PRIMITIVE_TYPES(a map of Ruby classes) becomesPRIMITIVE_CHECKS(a map of lambdas), so a schema primitive is defined by JSON kind rather than by Ruby class. JS has no int/float split, so a browser is free to spell an integer either way.Integerso the parsed value matches the declared type; the conversion is exact. Outbound passes the value through unchanged.🤖 AI assistance
🔄 Types of changes