@@ -522,49 +522,67 @@ private List<WebElement> getSelectedListItems(String fieldLabel)
522522 */
523523 public FieldSelectionDialog repositionField (FieldKey fieldToMove , FieldKey targetField , boolean beforeTarget )
524524 {
525- WebElement elementToMove = elementCache ().findSelectedField (fieldToMove );
526- WebElement elementTarget = elementCache ().findSelectedField (targetField );
525+ List <String > order = selectedFieldKeys ();
526+ int from = indexOfFieldKey (order , fieldToMove );
527+ int target = indexOfFieldKey (order , targetField );
528+ int to = beforeTarget ? (from < target ? target - 1 : target ) : (from < target ? target : target + 1 );
527529
528- int yBefore = elementToMove . getRect (). getY ( );
530+ keyboardReorder ( elementCache (). findDragHandle ( fieldToMove ), to - from );
529531
530- int offset ;
532+ WebDriverWrapper .waitFor (() -> {
533+ List <String > now = selectedFieldKeys ();
534+ return indexOfFieldKey (now , fieldToMove ) - indexOfFieldKey (now , targetField ) == (beforeTarget ? -1 : 1 );
535+ }, "Field '" + fieldToMove + "' was not repositioned as expected" , 5_000 );
531536
532- if (beforeTarget )
533- {
534- if (elementTarget .getRect ().getY () < elementToMove .getRect ().getY ())
535- {
536- // If the target is above the field being moved.
537- offset = -1 * elementTarget .getSize ().getHeight ();
538- }
539- else
540- {
541- // If the target is below the field being moved.
542- offset = -1 * elementTarget .getSize ().getHeight () / 2 ;
543- }
544- }
545- else
546- {
547- offset = elementTarget .getSize ().getHeight () / 2 + 10 ;
548- }
549-
550- WebElement dragHandle = Locator .tagWithAttribute ("div" , "role" , "button" ).findWhenNeeded (elementToMove );
551- getWrapper ().mouseOver (dragHandle );
552- new Actions (getDriver ())
553- .clickAndHold (dragHandle )
554- .moveToElement (elementTarget )
555- .moveByOffset (2 , offset )
556- .release ()
557- .perform ();
537+ return this ;
538+ }
558539
559- // Maybe I don't need to wait?
560- WebDriverWrapper .sleep (1_000 );
540+ /**
541+ * Reorder a row via the keyboard controls: focus the handle, Space to lift, one Arrow per
542+ * step, Space to drop. (Mouse drag is unreliable with the library's sensor.)
543+ *
544+ * @param dragHandle The row's drag handle.
545+ * @param steps Positions to move; negative moves up, positive moves down.
546+ */
547+ private void keyboardReorder (WebElement dragHandle , int steps )
548+ {
549+ getWrapper ().scrollIntoView (dragHandle );
550+ getWrapper ().executeScript ("arguments[0].focus();" , dragHandle );
561551
562- int yAfter = elementToMove .getRect ().getY ();
552+ Actions drag = new Actions (getDriver ()).sendKeys (Keys .SPACE ).pause (Duration .ofMillis (400 )); // lift
553+ Keys arrow = steps < 0 ? Keys .ARROW_UP : Keys .ARROW_DOWN ;
554+ for (int i = 0 ; i < Math .abs (steps ); i ++)
555+ drag .sendKeys (arrow ).pause (Duration .ofMillis (300 ));
556+ drag .sendKeys (Keys .SPACE ).perform (); // drop
557+ }
563558
564- WebDriverWrapper .waitFor (()-> yAfter != yBefore , "I don't think I repositioned the field in the list." ,
565- 1_000 );
559+ /**
560+ * Get the 'data-fieldkey' values of the selected fields, in display order.
561+ *
562+ * @return The encoded field keys.
563+ */
564+ private List <String > selectedFieldKeys ()
565+ {
566+ return elementCache ().getListItemElements (elementCache ().selectedFieldsPanel ).stream ()
567+ .map (el -> el .getDomAttribute ("data-fieldkey" ))
568+ .collect (Collectors .toList ());
569+ }
566570
567- return this ;
571+ /**
572+ * Get the index of a field in the given list, matched case-insensitively (as findFieldRow locates rows).
573+ *
574+ * @param fieldKeys Encoded field keys, in display order.
575+ * @param fieldKey Field to locate.
576+ * @return The index, or -1 if not present.
577+ */
578+ private static int indexOfFieldKey (List <String > fieldKeys , FieldKey fieldKey )
579+ {
580+ for (int i = 0 ; i < fieldKeys .size (); i ++)
581+ {
582+ if (fieldKey .toString ().equalsIgnoreCase (fieldKeys .get (i )))
583+ return i ;
584+ }
585+ return -1 ;
568586 }
569587
570588 /**
@@ -662,6 +680,11 @@ protected WebElement findSelectedField(FieldKey fieldKey)
662680 return findFieldRow (fieldKey , selectedFieldsPanel );
663681 }
664682
683+ protected WebElement findDragHandle (FieldKey fieldKey )
684+ {
685+ return Locator .tagWithAttribute ("div" , "role" , "button" ).findElement (findSelectedField (fieldKey ));
686+ }
687+
665688 protected WebElement findAvailableField (FieldKey fieldKey )
666689 {
667690 return findFieldRow (fieldKey , availableFieldsPanel );
0 commit comments