@@ -602,25 +602,40 @@ public function dragAndDrop($source, $target, $xOffset = null, $yOffset = null)
602
602
if ($ xOffset === null && $ yOffset === null ) {
603
603
parent ::dragAndDrop ($ source , $ target );
604
604
} else {
605
+ // Call dragAndDropBy() first
605
606
$ sNode = $ this ->matchFirstOrFail ($ this ->baseElement , $ source );
606
607
$ tNode = $ this ->matchFirstOrFail ($ this ->baseElement , $ target );
607
-
608
- $ sHeight = $ sNode ->getSize ()->getHeight ();
609
- $ sWidth = $ sNode ->getSize ()->getWidth ();
610
-
611
- $ travelX = intval ($ tNode ->getLocation ()->getX () - $ sNode ->getLocation ()->getX () + $ xOffset );
612
- $ travelY = intval ($ tNode ->getLocation ()->getY () - $ sNode ->getLocation ()->getY () + $ yOffset );
613
-
608
+ $ travelX1 = intval ($ tNode ->getLocation ()->getX ()-$ sNode ->getLocation ()->getX ()+$ xOffset );
609
+ $ travelY1 = intval ($ tNode ->getLocation ()->getY ()-$ sNode ->getLocation ()->getY ()+$ yOffset );
614
610
$ action = new WebDriverActions ($ this ->webDriver );
615
- if ($ travelX >0 && $ travelY >0 && $ travelX < $ sWidth && $ travelY < $ sHeight ) {
616
- // Perform separate action steps when dragging and dropping inside the source element boundary
617
- $ action ->moveToElement ($ sNode )->perform ();
618
- $ action ->clickAndHold ($ sNode )->perform ();
619
- $ action ->moveByOffset ($ travelX , $ travelY )->perform ();
620
- $ action ->release ()->perform ();
621
- } else {
622
- // Call dragAndDropBy otherwise
623
- $ action ->dragAndDropBy ($ sNode , $ travelX , $ travelY )->perform ();
611
+ $ action ->dragAndDropBy ($ sNode , $ travelX1 , $ travelY1 )->perform ();
612
+ $ this ->waitForPageLoad (20 );
613
+
614
+ try {
615
+ // Try drag and drop in steps if source and target elements didn't change at all
616
+ $ sNode2 = $ this ->matchFirstOrFail ($ this ->baseElement , $ source );
617
+ $ tNode2 = $ this ->matchFirstOrFail ($ this ->baseElement , $ target );
618
+ if ($ sNode2 == $ sNode && $ tNode2 == $ tNode ) {
619
+ $ sHeight = $ sNode2 ->getSize ()->getHeight ();
620
+ $ sWidth = $ sNode2 ->getSize ()->getWidth ();
621
+ // Because we will move to the middle of source element to perform drag & drop, we need to deduct
622
+ // an additional half of source element's width for X, and half of source element's height for Y
623
+ // when calculating the travel distance.
624
+ $ travelX2 = intval (
625
+ $ tNode2 ->getLocation ()->getX () - $ sNode2 ->getLocation ()->getX () - $ sWidth /2 + $ xOffset
626
+ );
627
+ $ travelY2 = intval (
628
+ $ tNode2 ->getLocation ()->getY () - $ sNode2 ->getLocation ()->getY () - $ sHeight /2 + $ yOffset
629
+ );
630
+ $ action = new WebDriverActions ($ this ->webDriver );
631
+ // Move to the middle of source element
632
+ $ action ->moveToElement ($ sNode2 )->perform ();
633
+ $ action ->clickAndHold ($ sNode2 )->perform ();
634
+ $ action ->moveByOffset ($ travelX2 , $ travelY2 )->perform ();
635
+ $ action ->release ()->perform ();
636
+ }
637
+ } catch (\Exception $ e ) {
638
+ // dragAndDropBy() is probably succeeded
624
639
}
625
640
}
626
641
}
0 commit comments