From 1527e49eb31725dda31ebc96d5f626cb12626a8a Mon Sep 17 00:00:00 2001
From: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
Date: Mon, 9 Sep 2019 13:30:18 +0100
Subject: [PATCH] Make InputDateInteractsWithEditContext_NullableDateTimeOffset
 more reliable (#13648)

---
 .../ServerExecutionTests/GlobalizationTest.cs | 21 ++++++-------------
 .../test/E2ETest/Tests/FormsTest.cs           | 14 ++++++-------
 src/Shared/E2ETesting/WebElementExtensions.cs | 17 +++++++++++++++
 3 files changed, 29 insertions(+), 23 deletions(-)
 create mode 100644 src/Shared/E2ETesting/WebElementExtensions.cs

diff --git a/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs b/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs
index af0ef6980e5..c9dfe0fba6b 100644
--- a/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs
+++ b/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs
@@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
             display = Browser.FindElement(By.Id("input_type_text_datetime_value"));
             Browser.Equal(new DateTime(1985, 3, 4).ToString(cultureInfo), () => display.Text);
 
-            ReplaceText(input, new DateTime(2000, 1, 2).ToString(cultureInfo));
+            input.ReplaceText(new DateTime(2000, 1, 2).ToString(cultureInfo));
             input.SendKeys("\t");
             Browser.Equal(new DateTime(2000, 1, 2).ToString(cultureInfo), () => display.Text);
 
@@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
             display = Browser.FindElement(By.Id("input_type_text_datetimeoffset_value"));
             Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4)).ToString(cultureInfo), () => display.Text);
 
-            ReplaceText(input, new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo));
+            input.ReplaceText(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo));
             input.SendKeys("\t");
             Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo), () => display.Text);
         }
@@ -137,7 +137,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
             Browser.Equal(new DateTime(1985, 3, 4).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTime(1985, 3, 4).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
 
-            ReplaceText(extraInput, new DateTime(2000, 1, 2).ToString(cultureInfo));
+            extraInput.ReplaceText(new DateTime(2000, 1, 2).ToString(cultureInfo));
             extraInput.SendKeys("\t");
             Browser.Equal(new DateTime(2000, 1, 2).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTime(2000, 1, 2).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
@@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
             Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4)).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4)).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
 
-            ReplaceText(extraInput, new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo));
+            extraInput.ReplaceText(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo));
             extraInput.SendKeys("\t");
             Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
@@ -194,7 +194,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
             Browser.Equal(new DateTime(1985, 3, 4).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTime(1985, 3, 4).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
 
-            ReplaceText(extraInput, new DateTime(2000, 1, 2).ToString(cultureInfo));
+            extraInput.ReplaceText(new DateTime(2000, 1, 2).ToString(cultureInfo));
             extraInput.SendKeys("\t");
             Browser.Equal(new DateTime(2000, 1, 2).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTime(2000, 1, 2).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
@@ -206,21 +206,12 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
             Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4)).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4)).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
 
-            ReplaceText(extraInput, new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo));
+            extraInput.ReplaceText(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo));
             extraInput.SendKeys("\t");
             Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString(cultureInfo), () => display.Text);
             Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2)).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
         }
 
-        // see: https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/214
-        //
-        // Calling Clear() can trigger onchange, which will revert the value to its default.
-        private static void ReplaceText(IWebElement element, string text)
-        {
-            element.SendKeys(Keys.Control + "a");
-            element.SendKeys(text);
-        }
-
         private void SetCulture(string culture)
         {
             var selector = new SelectElement(Browser.FindElement(By.Id("culture-selector")));
diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs
index f0a2a7b4363..3c3ad7ca49d 100644
--- a/src/Components/test/E2ETest/Tests/FormsTest.cs
+++ b/src/Components/test/E2ETest/Tests/FormsTest.cs
@@ -11,7 +11,7 @@ using OpenQA.Selenium;
 using OpenQA.Selenium.Support.UI;
 using System;
 using System.Linq;
-using System.Security.Cryptography;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Xunit;
 using Xunit.Abstractions;
@@ -196,27 +196,26 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
 
             // Validates on edit
             Browser.Equal("valid", () => renewalDateInput.GetAttribute("class"));
-            renewalDateInput.SendKeys("01/01/2000\t");
+            renewalDateInput.ReplaceText("01/01/2000\t");
             Browser.Equal("modified valid", () => renewalDateInput.GetAttribute("class"));
 
             // Can become invalid
-            renewalDateInput.SendKeys("0/0/0");
+            renewalDateInput.ReplaceText("0/0/0");
             Browser.Equal("modified invalid", () => renewalDateInput.GetAttribute("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");
+            renewalDateInput.ReplaceText($"{Keys.Backspace}");
             Browser.Equal("modified invalid", () => renewalDateInput.GetAttribute("class"));
             Browser.Equal(new[] { "The RenewalDate field must be a date." }, messagesAccessor);
 
             // Can become valid
-            renewalDateInput.SendKeys("01/01/01\t");
+            renewalDateInput.ReplaceText("01/01/01");
             Browser.Equal("modified valid", () => renewalDateInput.GetAttribute("class"));
             Browser.Empty(messagesAccessor);
         }
 
         [Fact]
-        [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2511", FlakyOn.All)]
         public void InputDateInteractsWithEditContext_NullableDateTimeOffset()
         {
             var appElement = MountTestComponent<TypicalValidationComponent>();
@@ -229,8 +228,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
             Browser.Equal("modified valid", () => expiryDateInput.GetAttribute("class"));
 
             // Can become invalid
-            expiryDateInput.Clear();
-            expiryDateInput.SendKeys("111111111");
+            expiryDateInput.ReplaceText("111111111");
             Browser.Equal("modified invalid", () => expiryDateInput.GetAttribute("class"));
             Browser.Equal(new[] { "The OptionalExpiryDate field must be a date." }, messagesAccessor);
 
diff --git a/src/Shared/E2ETesting/WebElementExtensions.cs b/src/Shared/E2ETesting/WebElementExtensions.cs
new file mode 100644
index 00000000000..6f08e1ba318
--- /dev/null
+++ b/src/Shared/E2ETesting/WebElementExtensions.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace OpenQA.Selenium
+{
+    public static class WebElementExtensions
+    {
+        // see: https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/214
+        //
+        // Calling Clear() can trigger onchange, which will revert the value to its default.
+        public static void ReplaceText(this IWebElement element, string text)
+        {
+            element.SendKeys(Keys.Control + "a");
+            element.SendKeys(text);
+        }
+    }
+}
-- 
GitLab