[dotnet] [bidi] Make cookie expiry as TimeSpan by nvborisenko · Pull Request #16204 · SeleniumHQ/selenium
User description
Finally Firefox and Chromium are aligned.
💥 What does this PR do?
Expiry means how long cookie lives in milliseconds.
🔧 Implementation Notes
Added new TimeSpan converter.
🔄 Types of changes
- Bug fix (backwards compatible)
- Breaking change (fix or feature that would cause existing functionality to change)
PR Type
Bug fix, Enhancement
Description
-
Change cookie expiry from DateTimeOffset to TimeSpan
-
Add TimeSpan JSON converter for BiDi communication
-
Align Firefox and Chromium cookie handling
Diagram Walkthrough
flowchart LR
A["Cookie.Expiry Property"] --> B["DateTimeOffset → TimeSpan"]
B --> C["TimeSpanConverter"]
C --> D["Broker Registration"]
D --> E["Aligned Browser Support"]
File Walkthrough
| Relevant files | |||
|---|---|---|---|
| Configuration changes |
| ||
| Enhancement |
| ||
| Bug fix |
|
PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
| ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪ |
| 🧪 No relevant tests |
| 🔒 No security concerns identified |
⚡ Recommended focus areas for reviewPrecision Loss
|
PR Code Suggestions ✨
Explore these optional code suggestions:
| Category | Suggestion | Impact |
| High-level |
Clarify TimeSpan units/precisionThe new TimeSpanConverter assumes expiry is milliseconds, but silently converts Examples:dotnet/src/webdriver/BiDi/Communication/Json/Converters/TimeSpanConverter.cs [28-38]public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TryGetInt64(out long milliseconds) is false) { var doubleValue = reader.GetDouble(); milliseconds = Convert.ToInt64(doubleValue); } return TimeSpan.FromMilliseconds(milliseconds); ... (clipped 1 lines) Solution Walkthrough:Before:public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TryGetInt64(out long milliseconds) is false) { var doubleValue = reader.GetDouble(); milliseconds = Convert.ToInt64(doubleValue); } return TimeSpan.FromMilliseconds(milliseconds); } After:public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // Per spec, expiry is in whole milliseconds. Rejecting floating-point // values prevents silent precision loss and potential unit confusion. if (reader.TryGetInt64(out long milliseconds)) { return TimeSpan.FromMilliseconds(milliseconds); } throw new JsonException("Expected cookie expiry to be an integer representing milliseconds."); } Suggestion importance[1-10]: 8__ Why: This suggestion correctly identifies a critical issue where silent truncation of floating-point values in | Medium |
| Possible issue |
Validate JSON token typesGuard against unexpected token types to avoid throwing when the JSON value is dotnet/src/webdriver/BiDi/Communication/Json/Converters/TimeSpanConverter.cs [28-38] public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
- if (reader.TryGetInt64(out long milliseconds) is false)
+ if (reader.TokenType == JsonTokenType.Number)
{
- var doubleValue = reader.GetDouble();
+ if (reader.TryGetInt64(out long milliseconds))
+ {
+ return TimeSpan.FromMilliseconds(milliseconds);
+ }
- milliseconds = Convert.ToInt64(doubleValue);
+ if (reader.TryGetDouble(out double doubleValue))
+ {
+ return TimeSpan.FromMilliseconds(doubleValue);
+ }
}
- return TimeSpan.FromMilliseconds(milliseconds);
+ throw new JsonException($"Invalid JSON token for TimeSpan: expected number, got {reader.TokenType}.");
}
Suggestion importance[1-10]: 7__ Why: The suggestion correctly identifies that the | Medium |
| General |
Normalize milliseconds precisionEnsure consistent numeric precision by writing integral milliseconds when the dotnet/src/webdriver/BiDi/Communication/Json/Converters/TimeSpanConverter.cs [40-43] public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
{
- writer.WriteNumberValue(value.TotalMilliseconds);
+ double totalMs = value.TotalMilliseconds;
+ if (Math.Abs(totalMs % 1) < double.Epsilon)
+ {
+ writer.WriteNumberValue((long)totalMs);
+ }
+ else
+ {
+ writer.WriteNumberValue(totalMs);
+ }
}
Suggestion importance[1-10]: 6__ Why: The suggestion correctly points out that serializing whole-number milliseconds as integers instead of doubles can improve consistency with protocols that might expect an integer. This is a good practice for ensuring predictable JSON output, making the implementation more robust. | Low |
| ||
This was referenced
Oct 2, 2025This was referenced
Oct 27, 2025This was referenced
Dec 9, 2025This was referenced
Dec 16, 2025This was referenced
Jan 19, 2026This was referenced
Feb 16, 2026This was referenced
Feb 23, 2026This 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