Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ffdad0a
Added the fix for date time value resetting to null.
NanthiniMahalingam Jun 17, 2026
6a413ff
Added the test cases.
NanthiniMahalingam Jun 18, 2026
8b26fcb
Merge branch 'dotnet:main' into fix-40660
NanthiniMahalingam Jun 19, 2026
03f2bb7
Resolved the flaky failed test case.
NanthiniMahalingam Jun 29, 2026
0cc0e6d
Merge branch 'main' of https://github.com/NanthiniMahalingam/aspnetco…
NanthiniMahalingam Jun 29, 2026
94078c1
Merge branch 'main' of https://github.com/NanthiniMahalingam/aspnetco…
NanthiniMahalingam Jun 30, 2026
c03de67
Updated the fix and test case.
NanthiniMahalingam Jun 30, 2026
d4aaaf4
Removed unwanted comment lines.
NanthiniMahalingam Jul 1, 2026
f3c4e66
Merge branch 'main' of https://github.com/NanthiniMahalingam/aspnetco…
NanthiniMahalingam Jul 1, 2026
cf144f7
Updated the test case.
NanthiniMahalingam Jul 6, 2026
23ab2ad
Merge branch 'main' of https://github.com/NanthiniMahalingam/aspnetco…
NanthiniMahalingam Jul 6, 2026
6d7845b
Updated the comment.
NanthiniMahalingam Jul 8, 2026
b9eb2c1
Merge branch 'main' of https://github.com/NanthiniMahalingam/aspnetco…
NanthiniMahalingam Jul 8, 2026
ce962fc
Merge branch 'fix-40660' of https://github.com/NanthiniMahalingam/asp…
NanthiniMahalingam Jul 8, 2026
62aab9f
Reverted the unwanted code changes.
NanthiniMahalingam Jul 8, 2026
9483744
Merge branch 'main' into flakytest-67243
NanthiniMahalingam Jul 15, 2026
2c3f4bf
Merge branch 'dotnet:main' into flakytest-67243
NanthiniMahalingam Jul 29, 2026
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
68 changes: 37 additions & 31 deletions src/Components/test/E2ETest/Tests/FormsInputDateTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,21 @@ public void InputDateInteractsWithEditContext_NonNullableDateTime()

// Validates on edit
Browser.Equal("valid", () => renewalDateInput.GetDomAttribute("class"));
renewalDateInput.SendKeys($"{Keys.Backspace}\t{Keys.Backspace}\t{Keys.Backspace}\t");
renewalDateInput.SendKeys("01/01/2000\t");
SetDateInputValue(renewalDateInput, "2000-01-01");
Browser.Equal("modified valid", () => renewalDateInput.GetDomAttribute("class"));

// Can become invalid
renewalDateInput.SendKeys("11-11-11111\t");
// Can become invalid (year is out of range for DateTime)
SetDateInputValue(renewalDateInput, "11111-11-11");
Browser.Equal("modified invalid", () => renewalDateInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The RenewalDate field must be a date." }, messagesAccessor);

// Empty is invalid, because it's not nullable
renewalDateInput.SendKeys($"{Keys.Backspace}\t{Keys.Backspace}\t{Keys.Backspace}\t");
SetDateInputValue(renewalDateInput, "");
Browser.Equal("modified invalid", () => renewalDateInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The RenewalDate field must be a date." }, messagesAccessor);

// Can become valid
renewalDateInput.SendKeys("01/01/01\t");
SetDateInputValue(renewalDateInput, "2001-01-01");
Browser.Equal("modified valid", () => renewalDateInput.GetDomAttribute("class"));
Browser.Empty(messagesAccessor);
}
Expand All @@ -74,16 +73,16 @@ public void InputDateInteractsWithEditContext_NullableDateTimeOffset()

// Validates on edit
Browser.Equal("valid", () => expiryDateInput.GetDomAttribute("class"));
expiryDateInput.SendKeys("01-01-2000\t");
SetDateInputValue(expiryDateInput, "2000-01-01");
Browser.Equal("modified valid", () => expiryDateInput.GetDomAttribute("class"));

// Can become invalid
expiryDateInput.SendKeys("11-11-11111\t");
// Can become invalid (year is out of range for DateTimeOffset)
SetDateInputValue(expiryDateInput, "11111-11-11");
Browser.Equal("modified invalid", () => expiryDateInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The OptionalExpiryDate field must be a date." }, messagesAccessor);

// Empty is valid, because it's nullable
expiryDateInput.SendKeys($"{Keys.Backspace}\t{Keys.Backspace}\t{Keys.Backspace}\t");
SetDateInputValue(expiryDateInput, "");
Browser.Equal("modified valid", () => expiryDateInput.GetDomAttribute("class"));
Browser.Empty(messagesAccessor);
}
Expand All @@ -104,13 +103,13 @@ public void InputDateInteractsWithEditContext_TimeInput()

// Validates on edit
Browser.Equal("valid", () => departureTimeInput.GetDomAttribute("class"));
departureTimeInput.SendKeys("06:43\t");
SetDateInputValue(departureTimeInput, "06:43");
Browser.Equal("modified valid", () => departureTimeInput.GetDomAttribute("class"));

// Can become invalid
// Stricly speaking the following is equivalent to the empty state, because that's how incomplete input is represented
// Strictly speaking the following is equivalent to the empty state, because that's how incomplete input is represented
// We don't know of any way to produce a different (non-empty-equivalent) state using UI gestures, so there's nothing else to test
departureTimeInput.SendKeys($"20{Keys.Backspace}\t");
SetDateInputValue(departureTimeInput, "");
Comment on lines 109 to +112
Browser.Equal("modified invalid", () => departureTimeInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The DepartureTime field must be a time." }, messagesAccessor);
}
Expand All @@ -131,13 +130,12 @@ public void InputDateInteractsWithEditContext_TimeInput_Step()

// Input works with seconds value of zero and has the expected final value
Browser.Equal("valid", () => departureTimeInput.GetDomAttribute("class"));
departureTimeInput.SendKeys("111111");
SetDateInputValue(departureTimeInput, "11:11:11");
Browser.Equal("modified valid", () => departureTimeInput.GetDomAttribute("class"));
Browser.Equal("11:11:11", () => departureTimeInput.GetDomProperty("value"));

// Input works with non-zero seconds value
// Move to the beginning of the input and put the new time
departureTimeInput.SendKeys(string.Concat(Enumerable.Repeat(Keys.ArrowLeft, 3)) + "101010");
SetDateInputValue(departureTimeInput, "10:10:10");
Browser.Equal("modified valid", () => departureTimeInput.GetDomAttribute("class"));
Browser.Equal("10:10:10", () => departureTimeInput.GetDomProperty("value"));
}
Expand All @@ -151,22 +149,21 @@ public void InputDateInteractsWithEditContext_MonthInput()

// Validates on edit
Browser.Equal("valid", () => visitMonthInput.GetDomAttribute("class"));
visitMonthInput.SendKeys($"03{Keys.ArrowRight}2005\t");
SetDateInputValue(visitMonthInput, "2005-03");
Browser.Equal("modified valid", () => visitMonthInput.GetDomAttribute("class"));

// Empty is invalid because it's not nullable
visitMonthInput.Clear();
SetDateInputValue(visitMonthInput, "");
Browser.Equal("modified invalid", () => visitMonthInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The VisitMonth field must be a year and month." }, messagesAccessor);

// Invalid year (11111)
visitMonthInput.SendKeys($"11{Keys.ArrowRight}11111\t");
// Invalid year (11111, out of range for DateTime)
SetDateInputValue(visitMonthInput, "11111-11");
Browser.Equal("modified invalid", () => visitMonthInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The VisitMonth field must be a year and month." }, messagesAccessor);

// Can become valid again
visitMonthInput.Clear();
visitMonthInput.SendKeys($"11{Keys.ArrowRight}1111\t");
SetDateInputValue(visitMonthInput, "1111-11");
Browser.Equal("modified valid", () => visitMonthInput.GetDomAttribute("class"));
Browser.Empty(messagesAccessor);
}
Expand All @@ -187,22 +184,21 @@ public void InputDateInteractsWithEditContext_DateTimeLocalInput()

// Validates on edit and has the expected value
Browser.Equal("valid", () => appointmentInput.GetDomAttribute("class"));
appointmentInput.SendKeys($"01011970{Keys.ArrowRight}05421");
SetDateInputValue(appointmentInput, "1970-01-01T05:42");
Browser.Equal("modified valid", () => appointmentInput.GetDomAttribute("class"));

// Empty is invalid because it's not nullable
appointmentInput.Clear();
SetDateInputValue(appointmentInput, "");
Browser.Equal("modified invalid", () => appointmentInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The AppointmentDateAndTime field must be a date and time." }, messagesAccessor);

// Invalid year (11111)
appointmentInput.SendKeys($"111111111{Keys.ArrowRight}11111");
// Invalid year (11111, out of range for DateTime)
SetDateInputValue(appointmentInput, "11111-11-11T11:11");
Browser.Equal("modified invalid", () => appointmentInput.GetDomAttribute("class"));
Browser.Equal(new[] { "The AppointmentDateAndTime field must be a date and time." }, messagesAccessor);

// Can become valid again
appointmentInput.Clear();
appointmentInput.SendKeys($"11111111{Keys.ArrowRight}11111");
SetDateInputValue(appointmentInput, "1111-11-11T11:11");
Browser.Equal("modified valid", () => appointmentInput.GetDomAttribute("class"));
Browser.Empty(messagesAccessor);
}
Expand All @@ -223,13 +219,12 @@ public void InputDateInteractsWithEditContext_DateTimeLocalInput_Step()

// Input works with seconds value of zero (as in, starting from a zero value, which is the default) and has the expected final value
Browser.Equal("valid", () => appointmentInput.GetDomAttribute("class"));
appointmentInput.SendKeys($"11111970{Keys.ArrowRight}114216");
SetDateInputValue(appointmentInput, "1970-11-11T11:42:16");
Browser.Equal("modified valid", () => appointmentInput.GetDomAttribute("class"));
Browser.Equal("1970-11-11T11:42:16", () => appointmentInput.GetDomProperty("value"));

// Input works when starting with a non-zero seconds value
// Move to the beginning of the input and put the new value
appointmentInput.SendKeys(string.Concat(Enumerable.Repeat(Keys.ArrowLeft, 6)) + $"10101970{Keys.ArrowRight}105321");
SetDateInputValue(appointmentInput, "1970-10-10T10:53:21");
Browser.Equal("modified valid", () => appointmentInput.GetDomAttribute("class"));
Browser.Equal("1970-10-10T10:53:21", () => appointmentInput.GetDomProperty("value"));
}
Expand All @@ -242,4 +237,15 @@ private Func<string[]> CreateValidationMessagesAccessor(IWebElement appElement)
.OrderBy(x => x)
.ToArray();
}

// Sets the value of a native date/time input directly and raises the "change" event that
// InputDate binds to. This avoids the well-known flakiness of driving the browser's native
// date-picker segments via simulated keystrokes (see the class-level comment above), while
// still exercising the real value-parsing and EditContext validation path.
private void SetDateInputValue(IWebElement input, string value)
=> ((IJavaScriptExecutor)Browser).ExecuteScript(
"arguments[0].value = arguments[1];" +
"arguments[0].dispatchEvent(new Event('change', { bubbles: true }));",
input,
value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<!-- Project supports more than one language -->
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>

<StaticWebAssetSpaFallbackEnabled>true</StaticWebAssetSpaFallbackEnabled>

<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>

<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.Extensions.Validation.Generated</InterceptorsNamespaces>
Expand Down
Loading