【问题标题】:Element does not move within canvas元素不在画布内移动
【发布时间】:2019-01-24 06:34:33
【问题描述】:

我很想在画布内移动元素,但不知何故它没有发生。

我试过的代码:

        Actions actions = new Actions(driver);
        actions.moveToElement(flowCanvas, 434, 177);
        actions.clickAndHold();
        actions.moveToElement(flowCanvas, 592 , 373);
        actions.release();
        actions.perform();

我的 xpath :

   @FindBy(xpath = "//div[@id='diagramDiv']//canvas")
    protected WebElement flowCanvas;

我正在尝试的网址:https://gojs.net/latest/samples/panelLayout.html

我正在使用 selenium webdriver 和 Java。我在上面的代码中没有收到任何错误,但它也没有移动元素。

试图移动以下元素:

【问题讨论】:

  • 这些数字(offsetX 和 offsetY)应该在什么坐标系中?您使用的 X 值对于操作图中四个节点的左上角节点似乎太大了。
  • @WalterNorthwoods - 你能告诉我如何获得我想要移动的那个控件的精确坐标吗?
  • gojs.net/latest/intro/viewport.html 描述了 GoJS 图表中的坐标系。 myDiagram.nodes.first().location 在文档坐标中; myDiagram.transformDocToView(myDiagram.nodes.first().location) 在视口坐标中生成一个点。

标签: java selenium-webdriver gojs


【解决方案1】:

基本上,问题在于您使用的坐标和您正在使用的 Bowser / Web 驱动程序实现。 W3C specification 声明 Action 命令的偏移量是从元素的中心开始的。但并非所有的 Web 驱动程序实现都遵循这一点。所以基本上壁虎驱动程序 (Firefox) 的 moveToElement x 和 y 偏移量是从画布中心的元素中心计算的,但对于 Chrome 驱动程序 (Google Chrome),坐标是从左上角计算的.因此,如果您想要跨浏览器支持拖放,您将需要这样的东西。

WebDriver driver = getDriver();

driver.get("https://gojs.net/latest/samples/panelLayout.html");
WebElement flowCanvas = driver.findElement(By.xpath("//div[@id='myDiagramDiv']//canvas"));

if(isGoogleChrome()){
    new Actions(driver)
   .moveToElement(flowCanvas, 100, 125).clickAndHold()
   .moveToElement(flowCanvas, 150, 175).release()
   .perform();
} else if (isFireFox()){
    new Actions(driver)
    .moveToElement(flowCanvas, -50, -50).clickAndHold()
    .moveToElement(flowCanvas, 100, 100).release()
    .perform();
}

正如您所见,对于 Firefox,您必须使用负值将鼠标从中心移动到画布中的左上角元素,而对于 chrome,您需要向下和向右移动鼠标。

【讨论】:

  • 嘿,非常感谢您的回答。你能告诉我你是如何得到元素坐标的吗?我在 chrome 中为 x 和 y 安装了一些扩展,但它显示了其他坐标,请检查:prnt.sc/mf52jk
  • 毫无疑问,该工具的坐标不正确,因为工作 div 被定义为 400 像素上的 400 像素,因此无法将 502 作为任何坐标。我正在使用 Firefox 开发工具中的标尺。但是您可以通过执行myDiagram.transformDocToView(myDiagram.nodes.first().location) 来获取 chrome 的坐标,这将返回第一个节点的左上角坐标,因此您可以在执行单击操作之前添加 5 或 10 px 以确保单击节点。
  • @Babl - 我正在尝试在具有 2 个画布的页面上进行拖放操作,从一个画布到另一个画布,并且无法将元素移出第一个画布。有什么想法/建议吗?
  • @misha 需要一个你在做什么的例子,没有代码例子就帮不上忙
【解决方案2】:

尝试操作和操作组合

Actions builder = new Actions(driver);
Action moveAction = builder.moveToElement(flowCanvas,434,177)  
                 .click()
                 .moveByOffset(592, 373) 
                 .doubleClick()
                 .build();
moveAction.perform();

【讨论】:

  • 它不动哥们。
【解决方案3】:

我尝试用 Sikuli 移动那个物体,效果很好。请检查下面的sn-p。

    Pattern p = new Pattern("Win/AboutScreen/Move.PNG");
    Region r1 = screen.exists(p);
    r1.hover();
    r1.mouseDown(Button.LEFT);
    r1.mouseMove(50, 50);
    r1.mouseUp(Button.LEFT); 

您需要在某个位置保存屏幕截图并提及路径。 hover(); 方法将找到屏幕并将鼠标悬停在其上。 mouseDown(Button.LEFT) 将按住左键单击,最后一个 mouserMove(50,50) 将移动元素到坐标。

如果您使用的是 Maven 项目,安装 Sikuli 非常容易,只需添加一个简单的依赖项即可。

希望得到帮助:)

【讨论】:

  • 谢谢朋友,但我的画布有 500 多个控件,我无法截取 500 个屏幕截图来移动每个控件
猜你喜欢
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2011-06-09
  • 1970-01-01
相关资源
最近更新 更多