当目标元素和目标元素在不同的帧中时,如何使用 selenium-webdriver 执行拖放?
Posted
技术标签:
【中文标题】当目标元素和目标元素在不同的帧中时,如何使用 selenium-webdriver 执行拖放?【英文标题】:How to perform drag and drop using selenium-webdriver when target and destination element are in different frames? 【发布时间】:2012-08-07 12:04:31 【问题描述】:我必须将图像拖放到 CQ5 组件中。图像和组件在不同的框架中。
这是在目标框架处于活动状态时无法作为 webelement destination
工作的代码。
new Actions(driver).dragAndDrop(target, destination).perform();
我也尝试在动作之间切换帧:
Actions builder = new Actions(driver);
Actions action = builder.clickAndHold(target);
driver.switchTo().frame("newFrame"); //switching frames
builder.moveToElement(destination);
builder.release(destination);
builder.build();
action.perform();
这也不起作用。然后,我尝试通过偏移量移动图像
new Actions(driver).dragAndDropBy(target, x, y).perform(); // x and y
这移动了图像但组件没有捕获它,可能是因为动作太快了。有什么办法可以做到这样的拖放吗?
提前致谢。
【问题讨论】:
不打算添加作为答案,因为它不能解决你的问题,但我在尝试让 Selenium 在 CQ 中工作时遇到了同样的麻烦。我发现在 CQ 中有时您可以双击而不是尝试使用拖放。例如,在添加组件时,双击 parsys 将带您进入可以添加的组件列表(在同一框架内)。在此处选择一个组件将直接带您进入该新组件的编辑对话框。内容查找器也可以这样做吗? 【参考方案1】:你需要把它分成两部分。
// grab your element
Actions builder = new Actions(driver);
Actions action = builder.clickAndHold(target);
builder.build();
action.perform();
// switch to the frame (you havent told webdriver to un-grab
driver.switchTo().frame("newFrame"); //switching frames
// move and drop
Actions builder = new Actions(driver);
Actions action = builder.moveToElement(destination);
builder.release(destination);
builder.build();
action.perform();
【讨论】:
你真的试过这段代码吗?如何在两个不同的操作之间共享一个元素?【参考方案2】:似乎 selenium / webdriver 拖放存在一些问题。我已经向 selenium 的人提交了一个缺陷,http://code.google.com/p/selenium/issues/detail?id=4420
希望我们能得到一些积极的回应。
【讨论】:
【参考方案3】:我和你有同样的prb。我不能将两个元素从一帧拖放到花药。 ansers 鞋面是正确的,但从 selenium 3 开始,这个解决方案不再有效。 工作箭头是将源元素(在 clickAndHol 之后)移动到位置 0,0,然后将其移动到第二帧下。例如 150,150。
Actions builder = new Actions(driver);
// switsh to the source frame
driver.switchTo().frame("sourceFrame");
// take the element with mouse
builder.clickAndHold(sourceElt).build().perfom();
// move mouse to the top of the source frame
builder.moveToElement(sourceElt, 0, 0 ).build().perfom();
// move the mouse under the target frame (specific to your case)
builder.moveToElement(sourceElt, 150,200).build().perfom();
// switsh to the target frame
driver.switchTo().frame("targetFrame");
builder.moveToElement(targetElt).build().perform();
builder.release(target).build().perform();
希望我也能帮助你。
【讨论】:
【参考方案4】:有人找到 Adobe CQ 5.5 的解决方案吗?
我在使用 adobe CQ 5.5 时遇到了同样的问题,我尝试了多种不同的方法,我可以将图像放到拖放区,但是一旦出现,图像似乎仍然不活跃并且丢弃它没有意义。我发现这是因为鼠标指针没有随着图像移动,这就是为什么丢弃没有意义。我添加了将鼠标移动到放置区域的代码,但看起来命令是单独工作的,所以仍然无法放置,请提供任何建议。
这是我的代码(不适用于 CQ 5.5)
String handle = driver.getWindowHandle(); // for main window
// 切换到窗口可以选择图像
driver.switchTo().window(handle);
WebElement dragble = driver.findElement(By.xpath("//xpath"));
Actions builder = new Actions(driver);
builder.clickAndHold(dragble);
Action action2 = builder.build();
action2.perform();
// 然后,切换到 iframe
driver.switchTo().frame("cq-cf-frame");
WebElement droppable = driver.findElement(By.cssSelector("#cssSelector of droppable"));
// 机器人将鼠标指向可放置区域
Point coordinates = driver.findElement(By.cssSelector("#cssSelector of droppable")).getLocation();
Robot robot = new Robot();
// 查找可放置元素的位置
int x = driver.findElement(By.cssSelector("#ext-comp-1271")).getLocation().getX();
int y = driver.findElement(By.cssSelector("#ext-comp-1271")).getLocation().getY();
// 将可拖动移动到可放置
builder = new Actions(driver);
builder.moveByOffset(x,y).perform().
builder.build();
builder.release();
robot.mouseMove(coordinates.getX(),coordinates.getY()+120);
builder.release(droppable).perform();
【讨论】:
【参考方案5】:以上发布的解决方案在 CQ 5.5 和 CQ 5.6 下对我不起作用
这行得通:
Actions builder = new Actions(driver);
builder.clickAndHold(sideKickComponent);
Action action = builder.build();
action.perform();
driver.switchTo().frame("cq-cf-frame");
builder = new Actions(driver);
builder.moveToElement(destination).perform();
builder.build();
builder.release();
builder.release(destination).perform();
这种方法可以方便地放置组件:
public void addComponentByDragAndDrop(String sideKickComponentName, WebElement destination)
driver.switchTo().defaultContent();
WebElement sidekick = driver.findElement(By.id("cq-sk"));
List<WebElement> components =sidekick.findElements(By.tagName("button"));
WebElement sideKickComponent = null;
for (WebElement webElement : components)
if (webElement.getText().equals(sideKickComponentName))
sideKickComponent = webElement;
break;
if (sideKickComponent == null)
fail("SideKick component with the name: "+sideKickComponentName + " was not found.");
Actions builder = new Actions(driver);
builder.clickAndHold(sideKickComponent);
Action action = builder.build();
action.perform();
driver.switchTo().frame(Consts.CQ_MAIN_FRAME);
builder = new Actions(driver);
builder.moveToElement(destination).perform();
builder.build();
builder.release();
builder.release(destination).perform();
【讨论】:
【参考方案6】:以下代码有效,希望对您有所帮助:
WebElement dragElement = (WebElement) elements.get(sourceElement);
Actions builder = new Actions(driver);
Actions action = builder.clickAndHold(dragElement);
action.build().perform();
driver.switchTo().frame("cq-cf-frame");
WebElement dropElement = driver.findElement(By.id("ext-comp-1411"));
builder.moveToElement(dropElement).build().perform();
//click the destination
builder.click(dropElement).build().perform();
//back to main page to release the hold mouse
driver.switchTo().defaultContent();
builder.release(dragElement).build().perform();
【讨论】:
【参考方案7】:要从一个 iframe 拖放到另一个 iframe,您需要在源 Web 元素的 iframe 中引用您的所有操作。为此,您应该获取目标 iframe 的父级并使用它进行操作,即 CqFrameParent,它是具有目标 iframe 的 div。
由于源和目标属于单个 iframe,因此无需进行 iframe 的切换即可。
builder.moveElement(CqFrameParent(), targetX, targetY).build().perform();
builder.release().build().perform();
【讨论】:
【参考方案8】:创建动作类的对象
Actions act=new Actions(driver);
找到我们需要拖动的元素xpath
WebElement drag=driver.findElement(By.xpath("put x path"));
找到我们需要放置的元素xpath
WebElement drop=driver.findElement(By.xpath("put x path"));
将元素拖到目的地
act.dragAndDrop(drag, drop).build().perform();
要在 CQ 中使用拖放功能,请先使用双击功能并放置任何组件,然后尝试上述方法。
【讨论】:
【参考方案9】:此代码适用于 CQ 5.5
driver.switchTo().defaultContent();
Actions builder = new Actions(driver);
builder.clickAndHold(target);
Action action = builder.build();
action.perform();
driver.switchTo().frame("cq-cf-frame");
builder.moveToElement(destination);
builder.release(destination);
action = builder.build();
action.perform();
【讨论】:
【参考方案10】:String source = "xpath_of_source";
String destination = "xpath_of_destination";
// grab your element
Actions builder = new Actions(driver);
Actions action = builder.clickAndHold(driver.findElement(By.xpath(source)));
builder.build();
action.perform();
// switch to the frame
driver.switchTo().frame("newFrame"); //switching frames
// move and drop
builder = new Actions(driver);
action = builder.moveToElement(driver.findElement(By.xpath(destination)));
builder.release(driver.findElement(By.xpath(destination)));
builder.build();
action.perform();
【讨论】:
【参考方案11】:Selenium webdriver 提供拖放功能。试试这个
WebElement element = driver.findElement(By.name("source"));
WebElement target = driver.findElement(By.name("target"));
(new Actions(driver)).dragAndDrop(element, target).perform();
【讨论】:
以上是关于当目标元素和目标元素在不同的帧中时,如何使用 selenium-webdriver 执行拖放?的主要内容,如果未能解决你的问题,请参考以下文章
仅在 xcode 中启动 iPhone 目标,而不是 OSwatch 目标,当两者都存在于项目中时
当 UICollectionView 位于 iOS 中的自定义 TableViewCell 中时,如何为 UICollectionView 实现委托和数据源方法,目标 C