这个问题烦恼了快2天,网上的回答很混乱,那些乱七八糟的回答往往让人误入歧途,终于在这个找到了问题明确的原因和解决方案,请参照下面的网站
Selenium Drag and Drop Bug Workaround
您是否遇到过众所周知的 Selenium问题,即 拖放手势在某些情况下不适用于 Selenium ?这个错误已经存在多年。
介绍
拖放 是当一个元素被拖到某个其他元素或位置之上时的一个动作。Selenium有一个错误,使该操作无法进行,并且已经存在多年。
问:是什么导致拖放问题?
答案:此手势包含 3 个动作:单击并按住、将鼠标移动到其他元素/位置、释放鼠标。问题都与最后一个动作(释放鼠标)有关。当 Selenium 向 webdriver API 发送请求以释放鼠标时,在某些情况下它会一直按住鼠标。
解决方法
通过 webdriver API向浏览器发送JavaScript代码。因此代码使用JavaScript模拟拖放操作,而不是 webdriver 方法。
问:为什么不将修复程序包含在Selenium包中?
答:拖放 错误是一个webdriver问题, 因此您在Selenium方面所能做的就是简单地执行与我相同的解决方法。我与David Burnes(Selenium 核心提交者)讨论了将该变通办法推入Selenium的问题,但他说在Selenium 本身中提供任何变通办法并不是一个好主意。这就是为什么我必须创建一个单独的包来帮助测试自动化社区解决这个问题。
py程序在这里
Selenium - HTML5 drag and drop · GitHub
把上面的js改编成groovy(java)如下 ,并加上了对elementUI的特殊对应
WebElement From = driver.findElement(By.xpath("//table[@class='el-table__body']//tr[1]"));
WebElement To = driver.findElement(By.xpath("//div[@class='el-tree-node__content' and descendant::span[text()='未分類']]"));
new Actions(driver)
.clickAndHold(From)
.perform();
final String java_script = """
var args = arguments,
callback = args[args.length - 1],
source = args[0],
target = args[1],
offsetX = (args.length > 2 && args[2]) || 0,
offsetY = (args.length > 3 && args[3]) || 0,
delay = (args.length > 4 && args[4]) || 1;
if (!source.draggable) throw new Error('Source element is not draggable.');
var doc = source.ownerDocument,
win = doc.defaultView,
rect1 = source.getBoundingClientRect(),
rect2 = target ? target.getBoundingClientRect() : rect1,
x = rect1.left + (rect1.width >> 1),
y = rect1.top + (rect1.height >> 1),
x2 = rect2.left + (rect2.width >> 1) + offsetX,
y2 = rect2.top + (rect2.height >> 1) + offsetY,
dataTransfer = Object.create(Object.prototype, {
_items: { value: { } },
effectAllowed: { value: 'all', writable: true },
dropEffect: { value: 'move', writable: true },
files: { get: function () { return undefined } },
types: { get: function () { return Object.keys(this._items) } },
setData: { value: function (format, data) { this._items[format] = data } },
getData: { value: function (format) { return this._items[format] } },
clearData: { value: function (format) { delete this._items[format] } },
setDragImage: { value: function () { } }
});
target = doc.elementFromPoint(x2, y2);
if(!target) throw new Error('The target element is not interactable and need to be scrolled into the view.');
rect2 = target.getBoundingClientRect();
emit(source, 'dragstart', delay, function () {
var rect3 = target.getBoundingClientRect();
x = rect3.left + x2 - rect2.left;
y = rect3.top + y2 - rect2.top;
emit(target, 'dragenter', 1, function () {
emit(target, 'dragover', delay, function () {
target = doc.elementFromPoint(x, y);
emit(target, 'drop', 1, function () {
emit(source, 'dragend', 1, callback);
});});});});
function emit(element, type, delay, callback) {
var event = doc.createEvent('DragEvent');
event.initMouseEvent(type, true, true, win, 0, 0, 0, x, y, false, false, false, false, 0, null);
Object.defineProperty(event, 'dataTransfer', { get: function () { return dataTransfer } });
element.dispatchEvent(event);
win.setTimeout(callback, delay);
}
"""
((JavascriptExecutor)driver).executeScript(java_script, From, To, null, null, 101);
下面这段代码的意思是在拖动前先clickAndHold这个元素,在elementui中,拖放前draggable属性才会从"false"变成"true",clickAndHold的目的就是让draggable属性变成"true",否则js会出错。
new Actions(driver)
.clickAndHold(From)
.perform(); 文章来源:https://www.toymoban.com/news/detail-618675.html
文章来源地址https://www.toymoban.com/news/detail-618675.html
到了这里,关于如何解决selenium的dragAndDrop失效的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!