|
2 | 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
3 | 3 |
|
4 | 4 | using System;
|
| 5 | +using System.Collections.Generic; |
5 | 6 | using System.Linq;
|
| 7 | +using System.Threading.Tasks; |
6 | 8 | using BasicTestApp;
|
7 | 9 | using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
|
8 | 10 | using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
9 | 11 | using Microsoft.AspNetCore.E2ETesting;
|
10 | 12 | using Microsoft.JSInterop;
|
11 | 13 | using OpenQA.Selenium;
|
| 14 | +using OpenQA.Selenium.Interactions; |
12 | 15 | using Xunit;
|
13 | 16 | using Xunit.Abstractions;
|
14 | 17 |
|
@@ -203,6 +206,73 @@ public void CanReorderInsertDeleteAndEdit_WithAndWithoutKeys()
|
203 | 206 | });
|
204 | 207 | }
|
205 | 208 |
|
| 209 | + [Fact] |
| 210 | + public async Task CanRetainFocusWhileMovingTextBox() |
| 211 | + { |
| 212 | + var appElem = MountTestComponent<ReorderingFocusComponent>(); |
| 213 | + Func<IWebElement> textboxFinder = () => appElem.FindElement(By.CssSelector(".incomplete-items .item-1 input[type=text]")); |
| 214 | + var textToType = "Hello this is a long string that should be typed"; |
| 215 | + var expectedTextTyped = ""; |
| 216 | + |
| 217 | + textboxFinder().Clear(); |
| 218 | + |
| 219 | + // On each keystroke, the boxes will be shuffled. The text will only |
| 220 | + // be inserted correctly if focus is retained. |
| 221 | + textboxFinder().Click(); |
| 222 | + while (textToType.Length > 0) |
| 223 | + { |
| 224 | + var nextBlockLength = Math.Min(5, textToType.Length); |
| 225 | + var nextBlock = textToType.Substring(0, nextBlockLength); |
| 226 | + textToType = textToType.Substring(nextBlockLength); |
| 227 | + expectedTextTyped += nextBlock; |
| 228 | + |
| 229 | + // Send keys to whatever has focus |
| 230 | + new Actions(Browser).SendKeys(nextBlock).Perform(); |
| 231 | + Browser.Equal(expectedTextTyped, () => textboxFinder().GetAttribute("value")); |
| 232 | + |
| 233 | + // We delay between typings to ensure the events aren't all collapsed into one. |
| 234 | + await Task.Delay(100); |
| 235 | + } |
| 236 | + |
| 237 | + // Verify that after all this, we can still move the edited item |
| 238 | + // This was broken originally because of unexpected event-handling behavior |
| 239 | + // in Chrome (it raised events recursively) |
| 240 | + appElem.FindElement( |
| 241 | + By.CssSelector(".incomplete-items .item-1 input[type=checkbox]")).Click(); |
| 242 | + Browser.Equal(expectedTextTyped, () => appElem |
| 243 | + .FindElement(By.CssSelector(".complete-items .item-1 input[type=text]")) |
| 244 | + .GetAttribute("value")); |
| 245 | + } |
| 246 | + |
| 247 | + [Fact] |
| 248 | + public void CanUpdateCheckboxStateWhileMovingIt() |
| 249 | + { |
| 250 | + var appElem = MountTestComponent<ReorderingFocusComponent>(); |
| 251 | + Func<IWebElement> checkboxFinder = () => appElem.FindElement(By.CssSelector(".item-2 input[type=checkbox]")); |
| 252 | + Func<IEnumerable<bool>> incompleteItemStates = () => appElem |
| 253 | + .FindElements(By.CssSelector(".incomplete-items input[type=checkbox]")) |
| 254 | + .Select(elem => elem.Selected); |
| 255 | + Func<IEnumerable<bool>> completeItemStates = () => appElem |
| 256 | + .FindElements(By.CssSelector(".complete-items input[type=checkbox]")) |
| 257 | + .Select(elem => elem.Selected); |
| 258 | + |
| 259 | + // Verify initial state |
| 260 | + Browser.Equal(new[] { false, false, false, false, false }, incompleteItemStates); |
| 261 | + Browser.Equal(Array.Empty<bool>(), completeItemStates); |
| 262 | + |
| 263 | + // Check a box; see it moves and becomes the sole checked item |
| 264 | + checkboxFinder().Click(); |
| 265 | + Browser.True(() => checkboxFinder().Selected); |
| 266 | + Browser.Equal(new[] { false, false, false, false }, incompleteItemStates); |
| 267 | + Browser.Equal(new[] { true }, completeItemStates); |
| 268 | + |
| 269 | + // Also uncheck it; see it moves and becomes unchecked |
| 270 | + checkboxFinder().Click(); |
| 271 | + Browser.False(() => checkboxFinder().Selected); |
| 272 | + Browser.Equal(new[] { false, false, false, false, false }, incompleteItemStates); |
| 273 | + Browser.Equal(Array.Empty<bool>(), completeItemStates); |
| 274 | + } |
| 275 | + |
206 | 276 | private void PerformTest(Node[] before, Node[] after)
|
207 | 277 | {
|
208 | 278 | var rootBefore = new Node(null, "root", before);
|
|
0 commit comments