如何使用 C# 在 Safari 上使用 Selenium 为 iPhone 执行拖放操作?

How do you perform Drag and Drop using Selenium on Safari for iPhone using C#?

我一直在兜圈子,找不到适合我的答案。这是我的情况。

  1. 我正在使用 Visual Studio 和 C# 在 Safari 上针对 iPhone
  2. 自动测试网页
  3. Actions 和 ITouchActions 失败,因为它一直给我一条错误消息,说不受支持,而且我在其他网站上看到 iPhone 上的 Actions 不受支持。我不知道为什么 ITouchActions 会失败。

我看到很多人建议使用 JavaScriptExectuor,但我找不到一个好的例子。 到目前为止,我可以使用 JSE 来单击页面元素,但我不知道如何使用它来拖放。 要单击我正在使用的 Web 元素,它可以工作。

IJavaScritpExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("document.querySelector('#nextButton').click()");

所以我有 2 个问题

  1. JavaScriptExecutor 是将 Web 元素拖放到 iPhone 上的唯一方法吗?
  2. 如果是这样,用 C# 执行此操作的代码是什么?
  3. JSE 代码是否仅适用于 CSSelecetrs 而不适用于 Xpath?

提前谢谢大家

Appium 可能会建议您使用他们的 dragAndDrop 方法,但我从未成功过——我不得不使用 PressMoveTo 编写自己的自定义操作,和 Release.

以下代码在 Android 上对我有用——在 iOS 上可能值得一试:

using OpenQA.Selenium.Appium.Android;
using OpenQA.Selenium.Appium.Interfaces;
using OpenQA.Selenium.Appium.MultiTouch;
using OpenQA.Selenium.Support.UI;


// need to wrap this in IPerformsTouchActions driver, not regular AndroidDriver
public void DragAndDrop(this IPerformsTouchActions driver, int startX, int startY, int endX, int endY)
{
    new TouchAction(driver).Press(startX, startY).MoveTo(endX, endY).Release().Perform();
}

我们可以这样调用这个方法:

var fromElement = driver.FindElement(someLocator);
var toElement = driver.FindElement(someOtherLocator);

driver.DragAndDrop(fromElement.Coordinates.LocationOnScreen.X, fromElement.Coordinates.LocationOnScreen.Y, toElement.Coordinates.LocationOnScreen.X, toElement.Coordinates.LocationOnScreen.Y);

这应该会让您充满希望地开始。您可以将 Press 替换为 LongPress,或使用 Press().Wait(500)(毫秒)。您可能需要尝试几个不同的选项才能满足您的需求。

我找到了使用 C#、iOS 和 Safar 滚动的解决方案,我已经在下面发布了代码,希望它能帮助其他 运行 解决这个问题的人。

我使用 IJavaScriptExecutor 接口创建了一个变量 "js" 我创建 web 元素来保存要拖动的元素,以及要将其拖动到的元素。 然后我找到每个项目的中心并将它们保存在一些整数中 然后我创建了一个字典,其中包含脚本要遵循的各个命令,您可以在 Appium 页面 here

上找到更多相关信息

最后我将这个字典和我希望执行的脚本的名称传递给 js 变量并让它执行。

    public bool DragAndDropJavascript(string dragElement, string dropElement)
    {
        try
        {  
            IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
            // The element to drag
            // The element to drop on
            IWebElement dragFrom = driver.FindElement(By.XPath(dragElement));
            IWebElement dragTo = driver.FindElement(By.XPath(dropElement));

            // The top left corner of the drag element
            int fromX = dragFrom.Location.X;
            int fromY = dragFrom.Location.Y;

            // Add half the height and half the width
            // to find the centre of the drag element
            int fromCentreX = fromX + dragFrom.Size.Width / 2;
            int fromCentreY = fromY + dragFrom.Size.Height / 2;

            // The top left corner of the drop element
            int toX = dragTo.Location.X;
            int toY = dragTo.Location.Y;

            // Add half the height and half the width
            // to find the centre of the drop to element
            int toCentreX = toX + dragTo.Size.Width / 2;
            int toCentreY = toY + dragTo.Size.Height / 2;

            Dictionary<string, object> dragNDrop = new Dictionary<string, object>();
            dragNDrop.Add("duration", 1.0);
            dragNDrop.Add("fromX", fromCentreX);
            dragNDrop.Add("fromY", fromCentreY + 50); // 50 compensates for Safari header
            dragNDrop.Add("toX", toCentreX);
            dragNDrop.Add("toY", toCentreY + 50);


            js.ExecuteScript("mobile:dragFromToForDuration", dragNDrop);
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }