[C#][Selenium] 如何拖放元素

[C#][Selenium] How to drag-hover-drop an element([C#][Selenium] 如何拖放元素)
本文介绍了[C#][Selenium] 如何拖放元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我运行它的网站位于内部服务器上,所以我无法提供链接,但我可以发布一些相关代码,当您单击显示元素"时会显示这些代码

有 5 个元素与此相关:

  • 组 1
  • 学生
  • 移动1
  • 组 2
  • 移动2

此页面显示学生组,并允许用户在组之间拖动学生.每个组都有一个移动元素.棘手的部分是任何给定组的移动按钮仅在用户将学生元素拖到该组上时才会显示,并且该学生不属于该组.

目标是将学生转移到一个新小组,然后再回到原来的小组.

注意事项:学生更改组时 XPath 更改我无法确认,但我相信移动按钮的 XPath 在隐藏时与可见时不同

我当前的代码:

IWebDriver driver = (IWebDriver)FeatureContext.Current["Driver"];动作生成器 = 新动作(驱动程序);IWebElement originalstudent = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[3]/a[1]/div[1]/div"));IWebElement originalClass = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[1]"));IWebElement newClass = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[3]/div[1]/div[1]"));IWebElement originalMove = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[2]/div[1]/div"));IWebElement newMove = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[3]/div[1]/div[2]/div[1]/div"));builder.ClickAndHold(originalstudent);builder.MoveToElement(newClass);builder.Release(newMove);builder.Build().Perform();IWebElement save = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[1]/div/div/button[2]"));builder.Click(保存);builder.Build().Perform();//断言 group2 有 1 个学生, group 1 有 3 个学生IWebElement newstudent = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[3]/div/div[3]/a/div[1]/div"));builder.ClickAndHold(newstudent);builder.MoveToElement(originalClass);builder.Release(originalMove);builder.Click(保存);builder.Build().Perform();

此代码不会移动任何元素,并且在尝试查找保存时失败,因为没有任何更改(这是预期的,因为没有任何移动).

页面相关代码:

 <div class="column small-5 filter"><div class="行组-标题"><!-- ngIf: !model.configData.groupingMode.autoRegroup --><div ng-if="!model.configData.groupingMode.autoRegroup" class="column small-8 ng-scope"></div><!-- 结束 ngIf: !model.configData.groupingMode.autoRegroup --><!-- ngIf: model.configData.groupingMode.autoRegroup --><div class="column small-4 left-delimiter no-regroup" ng-class="{'no-regroup' : !model.configData.groupingMode.autoRegroup}"><button type="button" class="light" ng-click="model.addGroup()" ng-disabled="!model.canAddGroup()">添加组</按钮></div></div><!-- ngRepeat: group in model.groupingData --><div class="group ng-scope" ng-repeat="group in model.groupingData">******<div index="1" class="drop-outer" ui-on-drop="model.onDrop(group)" ui-drag-enter="model.dragOver(group)" ui-drag-leave="model.dragLeave(组)"><div class="button radius group-btn" ng-style="{'background-color': group.color}" ng-click="model.toggleState(group)" ui-on-drop="model.onMoveDrop(组)"ui-drag-enter="moveActive = true;model.autoScroll(el);"ui-drag-leave="moveActive = false;"style="背景色:rgb(0, 155, 159);"><div class="left group-label ng-binding">第 1 组 |4<span ng-show="group.students.length !== 1" class="">学生</span><span ng-show="group.students.length === 1" class="ng-hide">学生</span></div><div class="right group-collapser" ng-hide="group.students.length == 0"><!-- ngIf: group.collapsed --><!-- ngIf: !group.collapsed --><span class="glyph-chevron-collapsed ng-scope" ng-if="!group.collapsed"></span><!-- 结束 ngIf: !group.collapsed --></div></div><div ng-show="group.showAddContainers" class="row drop-container ng-hide"><div ui-on-drop="model.onMoveDrop(group)" class="column" ng-class="{'active':moveActive}">**********<div class="移动">移动</div></div><div ui-on-drop="model.onCopyDrop(group)" class="column"><div class="复制">复制</div></div></div><!-- ngIf: !group.collapsed -->******<div class="行学生幻灯片动画拖动元素 ng-scope" ng-if="!group.collapsed"><!-- ngRepeat: group.students 中的学生 --><a no-chrome-href="" title="AM2Paper S" alt="AM2Paper S" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students"ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged"on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style=""><div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);">************<div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AM2Paper S" style="font-size: 9px;">AM2Paper S</div></div><div class="dots 点线"></div></a><!-- end ngRepeat: student in group.students --><a no-chrome-href="" title="AMTest A" alt="AMTest A" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students"ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged"on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style=""><div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);"><div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AMTest A" style="font-size: 11px;">AMTest A</div></div><div class="dots 点线"></div></a><!-- end ngRepeat: student in group.students --><a no-chrome-href="" title="AMTestPaper A" alt="AMTestPaper A" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students"ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged"on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style=""><div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);"><div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AMTestPaper A" style="font-size: 9px;">AMTestPaper...</div></div><div class="dots 点线"></div></a><!-- end ngRepeat: student in group.students --><a no-chrome-href="" title="AM2Online S" alt="AM2Online S" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students"ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged"on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style=""><div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);"><div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AM2Online S" style="font-size: 9px;">AM2Online S</div></div><div class="dots 点线"></div></a><!-- end ngRepeat: student in group.students --></div><!-- 结束 ngIf: !group.collapsed --><div ng-show="group.showRemoveContainers" class="row drop-container ng-hide"><div class="column remove" ui-on-drop="model.onRemoveDrop(group)"><div class="remove ng-binding">从组 1 中删除</div></div></div></div><!-- ngIf: group.students.length == 0 --></div><!-- end ngRepeat: group in model.groupingData --><div class="group ng-scope" ng-repeat="group in model.groupingData">******<div index="2" class="drop-outer" ui-on-drop="model.onDrop(group)" ui-drag-enter="model.dragOver(group)" ui-drag-leave="model.dragLeave(组)"><div class="button radius group-btn" ng-style="{'background-color': group.color}" ng-click="model.toggleState(group)" ui-on-drop="model.onMoveDrop(组)"ui-drag-enter="moveActive = true;model.autoScroll(el);"ui-drag-leave="moveActive = false;"style="背景色: rgb(109, 48, 146);"><div class="left group-label ng-binding">第 2 组 |0<span ng-show="group.students.length !== 1" class="">学生</span><span ng-show="group.students.length === 1" class="ng-hide">学生</span></div><div class="正确的group-collapser ng-hide" ng-hide="group.students.length == 0"><!-- ngIf: group.collapsed --><!-- ngIf: !group.collapsed --><span class="glyph-chevron-collapsed ng-scope" ng-if="!group.collapsed"></span><!-- 结束 ngIf: !group.collapsed --></div></div><div ng-show="group.showAddContainers" class="row drop-container ng-hide"><div ui-on-drop="model.onMoveDrop(group)" class="column" ng-class="{'active':moveActive}">************

<div class="row 学生幻灯片动画拖动元素 ng-scope" ng-if="!group.collapsed" style=""><!-- ngRepeat: group.students 中的学生 --></div><!-- 结束 ngIf: !group.collapsed --><div ng-show="group.showRemoveContainers" class="row drop-container ng-hide"><div class="column remove" ui-on-drop="model.onRemoveDrop(group)"><div class="remove ng-binding">从组 2 中删除</div></div></div></div><!-- ngIf: group.students.length == 0 --><div class="empty-group-label ng-scope" ng-if="group.students.length == 0"><span class="left">将学生图标拖入该组</span><a href="" class="right" ng-click="model.removeGroup($index)">删除这个组</a></div><!-- 结束 ngIf: group.students.length == 0 --></div><!-- end ngRepeat: group in model.groupingData --></div>

星号标记相关元素.让我知道您是否需要了解上下文的其他信息.

解决方案

Selenium 的拖放操作在 HTML5 中表现不佳,所以我求助于使用 jquery 来拖动元素.

我将这些用作参考:https://gist.github.com/rcorreia/2362544http://elementalselenium.com/tips/39-drag-and-drop

结果如下:

public void WhenASTudentIsMovedToANewGroup(string action, string student, string group){等待角();IWebDriver driver = (IWebDriver)FeatureContext.Current["Driver"];/** 加载我们可以访问的 jQuery 版本*/driver.Manage().Timeouts().SetScriptTimeout(TimeSpan.FromSeconds(10));IJavaScriptExecutor js = (IJavaScriptExecutor)驱动程序;js.ExecuteAsyncScript(loadJQuery, jQueryUrl);string dragEntity = string.Format("[title="{0}"]", student);string target = string.Format("[ui-on-drop="model.onMoveDrop(group)"]:contains({0}) ~ div > div .{1}", group, action);string javaScriptString = string.Format("{0}$('{1}').simulateDragDrop({{ dropTarget: '{2}'}});", dragAndDropHelper, dragEntity, target);//对HTML5执行拖放js.ExecuteScript(javaScriptString);}常量字符串 dragAndDropHelper = @"(function( $ ) {$.fn.simulateDragDrop = 功能(选项){返回 this.each(function() {新的 $.simulateDragDrop(this, options);});};$.simulateDragDrop = 函数(元素,选项){this.options = 选项;this.simulateEvent(elem, options);};$.extend($.simulateDragDrop.prototype, {模拟事件:函数(元素,选项){/*模拟拖动开始*/var type = 'dragstart';var event = this.createEvent(type);this.dispatchEvent(elem, type, event);/*模拟掉落*/类型 = '下降';var dropEvent = this.createEvent(type, {});dropEvent.dataTransfer = event.dataTransfer;this.dispatchEvent($(options.dropTarget)[0], type, dropEvent);/*模拟拖动结束*/类型 = 'dragend';var dragEndEvent = this.createEvent(type, {});dragEndEvent.dataTransfer = event.dataTransfer;this.dispatchEvent(elem, type, dragEndEvent);},创建事件:函数(类型){var event = document.createEvent(""CustomEvent"");event.initCustomEvent(type, true, true, null);event.dataTransfer = {数据: {},setData:函数(类型,val){this.data[类型] = val;},获取数据:函数(类型){返回 this.data[类型];}};返回事件;},调度事件:函数(元素,类型,事件){如果(elem.dispatchEvent){elem.dispatchEvent(事件);}否则如果(elem.fireEvent){elem.fireEvent(""on""+type, event);}}});})(jQuery);";const string loadJQuery = @"(function(jqueryUrl, callback) {if (typeof jqueryUrl != 'string') {jqueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';}if (typeof jQuery == 'undefined') {var script = document.createElement('script');var head = document.getElementsByTagName('head')[0];var 完成 = 假;script.onload = script.onreadystatechange = (function() {if (!done && (!this.readyState || this.readyState == 'loaded'||this.readyState == '完成')) {完成=真;script.onload = script.onreadystatechange = null;head.removeChild(脚本);打回来();}});script.src = jqueryUrl;head.appendChild(脚本);}别的 {打回来();}})(arguments[0], arguments[arguments.length - 1]);";

The website I am running this against is on an internal server so I can't give a link but I can post some of the relevant code that is shown when you click "show element"

There are 5 elements that are relevant to this:

  • Group1
  • student
  • move1
  • Group2
  • move2

This page shows groups of students and allows the user to drag students between groups. There is a move element for each group. The tricky part is that the move button for any given group only shows up while the user is dragging a student element over that group, and the student was not from that group.

The goal is to move a student to a new group and then back to the original group.

notes: The students XPath changes when they change groups I can't confirm but I believe the XPath for the move buttons are different while hidden than while visible

My Current code:

IWebDriver driver = (IWebDriver)FeatureContext.Current["Driver"];
        Actions builder = new Actions(driver);
        IWebElement originalstudent = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[3]/a[1]/div[1]/div"));
        IWebElement originalClass = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[1]"));
        IWebElement newClass = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[3]/div[1]/div[1]"));
        IWebElement originalMove = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[2]/div[1]/div"));
        IWebElement newMove = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[3]/div[1]/div[2]/div[1]/div"));
        builder.ClickAndHold(originalstudent);
        builder.MoveToElement(newClass);
        builder.Release(newMove);
        builder.Build().Perform();
        IWebElement save = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[1]/div/div/button[2]"));
        builder.Click(save);
        builder.Build().Perform();
        //assert group2 has 1 student and group 1 has 3 students
        IWebElement newstudent = driver.FindElement(By.XPath("//*[@id="AMTeacherApp"]/div/div/div[1]/div/div[3]/div/div/div[2]/div[2]/div[3]/div/div[3]/a/div[1]/div"));
        builder.ClickAndHold(newstudent);
        builder.MoveToElement(originalClass);
        builder.Release(originalMove);
        builder.Click(save);
        builder.Build().Perform();

This code doesn't move any elements and fails when trying to find save because nothing was changed(which is expected given that nothing moves).

Relevant code from the page:

  <div class="column  small-5 filter">
     <div class="row groups-header">
        <!-- ngIf: !model.configData.groupingMode.autoRegroup -->
        <div ng-if="!model.configData.groupingMode.autoRegroup" class="column small-8 ng-scope">
        </div>
        <!-- end ngIf: !model.configData.groupingMode.autoRegroup -->
        <!-- ngIf: model.configData.groupingMode.autoRegroup -->
        <div class="column small-4 left-delimiter no-regroup" ng-class="{'no-regroup' : !model.configData.groupingMode.autoRegroup}">
           <button type="button" class="light" ng-click="model.addGroup()" ng-disabled="!model.canAddGroup()">Add group
           </button>
        </div>
     </div>
     <!-- ngRepeat: group in model.groupingData -->
     <div class="group ng-scope" ng-repeat="group in model.groupingData">
******<div index="1" class="drop-outer" ui-on-drop="model.onDrop(group)" ui-drag-enter="model.dragOver(group)" ui-drag-leave="model.dragLeave(group)">
           <div class="button radius group-btn" ng-style="{'background-color': group.color}" ng-click="model.toggleState(group)" ui-on-drop="model.onMoveDrop(group)" 
           ui-drag-enter="moveActive = true;model.autoScroll(el);" ui-drag-leave="moveActive = false;" style="background-color: rgb(0, 155, 159);">
           <div class="left group-label ng-binding">Group 1 | 4  
              <span ng-show="group.students.length !== 1" class="">Students
              </span>
              <span ng-show="group.students.length === 1" class="ng-hide">Student
              </span>
           </div>
           <div class="right group-collapser" ng-hide="group.students.length == 0">
              <!-- ngIf: group.collapsed --> 
              <!-- ngIf: !group.collapsed -->
              <span class="glyph-chevron-collapsed ng-scope" ng-if="!group.collapsed">
              </span>
              <!-- end ngIf: !group.collapsed -->
           </div>
        </div>
        <div ng-show="group.showAddContainers" class="row drop-container ng-hide">
           <div ui-on-drop="model.onMoveDrop(group)" class="column" ng-class="{'active':moveActive}">
**********<div class="move">Move
              </div>
           </div>
           <div ui-on-drop="model.onCopyDrop(group)" class="column">
              <div class="copy">Copy
              </div>
           </div>
        </div>
        <!-- ngIf: !group.collapsed -->
******<div class="row students slide-animation drag-elements ng-scope" ng-if="!group.collapsed">
           <!-- ngRepeat: student in group.students -->
           <a no-chrome-href="" title="AM2Paper S" alt="AM2Paper S" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students" 
           ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged" 
           on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style="">
              <div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);">
************<div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AM2Paper S" style="font-size: 9px;">AM2Paper S
                 </div>
              </div>
              <div class="dots dots-line">
              </div>
           </a>
           <!-- end ngRepeat: student in group.students -->
           <a no-chrome-href="" title="AMTest A" alt="AMTest A" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students" 
           ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged" 
           on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style="">
              <div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);">
                 <div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AMTest A" style="font-size: 11px;">AMTest A
                 </div>
              </div>
              <div class="dots dots-line">
              </div>
           </a>
           <!-- end ngRepeat: student in group.students -->
           <a no-chrome-href="" title="AMTestPaper A" alt="AMTestPaper A" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students" 
           ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged" 
           on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style="">
              <div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);">
                 <div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AMTestPaper A" style="font-size: 9px;">AMTestPaper...
                 </div>
              </div>
              <div class="dots dots-line">
              </div>
           </a>
           <!-- end ngRepeat: student in group.students -->
           <a no-chrome-href="" title="AM2Online S" alt="AM2Online S" class="student-btn-cont fade-animation ng-scope" ng-repeat="student in group.students" 
           ui-draggable="true" on-drag-begin="model.dragStart(student, group)" drag="student" drag-class="student-btn-cont student-btn-cont-dragged" 
           on-drop-success="model.dropSuccessHandler($index,group)" draggable="true" style="">
              <div ng-style="{'background-color': group.color}" class="radius column student-btn" style="background-color: rgb(0, 155, 159);">
                 <div class="left student-label ng-isolate-scope" rl-display-name="" long-name="AM2Online S" style="font-size: 9px;">AM2Online S
                 </div>
              </div>
              <div class="dots dots-line">
              </div>
           </a>
           <!-- end ngRepeat: student in group.students -->
        </div>
        <!-- end ngIf: !group.collapsed -->
        <div ng-show="group.showRemoveContainers" class="row drop-container ng-hide">
           <div class="column remove" ui-on-drop="model.onRemoveDrop(group)">
              <div class="remove ng-binding">Remove from Group 1
              </div>
           </div>
        </div>
     </div>
     <!-- ngIf: group.students.length == 0 -->
     </div>
     <!-- end ngRepeat: group in model.groupingData -->
     <div class="group ng-scope" ng-repeat="group in model.groupingData">
******<div index="2" class="drop-outer" ui-on-drop="model.onDrop(group)" ui-drag-enter="model.dragOver(group)" ui-drag-leave="model.dragLeave(group)">
           <div class="button radius group-btn" ng-style="{'background-color': group.color}" ng-click="model.toggleState(group)" ui-on-drop="model.onMoveDrop(group)" 
           ui-drag-enter="moveActive = true;model.autoScroll(el);" ui-drag-leave="moveActive = false;" style="background-color: rgb(109, 48, 146);">
              <div class="left group-label ng-binding">Group 2 | 0  
                 <span ng-show="group.students.length !== 1" class="">Students
                 </span>
                 <span ng-show="group.students.length === 1" class="ng-hide">Student
                 </span>
              </div>
              <div class="right group-collapser ng-hide" ng-hide="group.students.length == 0">
                 <!-- ngIf: group.collapsed --> 
                 <!-- ngIf: !group.collapsed -->
                 <span class="glyph-chevron-collapsed ng-scope" ng-if="!group.collapsed">
                 </span>
                 <!-- end ngIf: !group.collapsed -->
              </div>
           </div>
           <div ng-show="group.showAddContainers" class="row drop-container ng-hide">
              <div ui-on-drop="model.onMoveDrop(group)" class="column" ng-class="{'active':moveActive}">
************<div class="move">Move
                 </div>
              </div>
              <div ui-on-drop="model.onCopyDrop(group)" class="column">
                 <div class="copy">Copy
                 </div>
              </div>
           </div>
           <!-- ngIf: !group.collapsed -->
           <div class="row students slide-animation drag-elements ng-scope" ng-if="!group.collapsed" style="">
              <!-- ngRepeat: student in group.students -->
           </div>
           <!-- end ngIf: !group.collapsed -->
           <div ng-show="group.showRemoveContainers" class="row drop-container ng-hide">
              <div class="column remove" ui-on-drop="model.onRemoveDrop(group)">
                 <div class="remove ng-binding">Remove from Group 2
                 </div>
              </div>
           </div>
        </div>
        <!-- ngIf: group.students.length == 0 -->
        <div class="empty-group-label ng-scope" ng-if="group.students.length == 0">
           <span class="left">Drag student icons into this Group
           </span> 
           <a href="" class="right" ng-click="model.removeGroup($index)">Delete this group
           </a>
        </div>
        <!-- end ngIf: group.students.length == 0 -->
     </div>
     <!-- end ngRepeat: group in model.groupingData -->
  </div>

Stars mark the relevant elements. Let me know if there is other information that you may need for context.

解决方案

Selenium's actions for drag and drop do not play nice with HTML5 so I resorted to using jquery to drag the element.

I used these as references: https://gist.github.com/rcorreia/2362544 http://elementalselenium.com/tips/39-drag-and-drop

And this is the result:

public void WhenAStudentIsMovedToANewGroup(string action, string student, string group)
    {
        WaitForAngular();
        IWebDriver driver = (IWebDriver)FeatureContext.Current["Driver"];

        /*
         * Load a version of jQuery that we can access
         */
        driver.Manage().Timeouts().SetScriptTimeout(TimeSpan.FromSeconds(10));
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        js.ExecuteAsyncScript(loadJQuery, jQueryUrl);

        string dragEntity = string.Format("[title="{0}"]", student);
        string target = string.Format("[ui-on-drop="model.onMoveDrop(group)"]:contains({0})  ~ div > div .{1}", group, action);


        string javaScriptString = string.Format("{0}$('{1}').simulateDragDrop({{ dropTarget: '{2}'}});", dragAndDropHelper, dragEntity, target);

        //Execute the drag and drop against the HTML5
        js.ExecuteScript(javaScriptString);

    }

    const string dragAndDropHelper = @"(function( $ ) {
    $.fn.simulateDragDrop = function(options) {
            return this.each(function() {
                    new $.simulateDragDrop(this, options);
            });
    };
    $.simulateDragDrop = function(elem, options) {
            this.options = options;
            this.simulateEvent(elem, options);
    };
    $.extend($.simulateDragDrop.prototype, {
            simulateEvent: function(elem, options) {
                    /*Simulating drag start*/
                    var type = 'dragstart';
                    var event = this.createEvent(type);
                    this.dispatchEvent(elem, type, event);

                    /*Simulating drop*/
                    type = 'drop';
                    var dropEvent = this.createEvent(type, {});
                    dropEvent.dataTransfer = event.dataTransfer;
                    this.dispatchEvent($(options.dropTarget)[0], type, dropEvent);

                    /*Simulating drag end*/
                    type = 'dragend';
                    var dragEndEvent = this.createEvent(type, {});
                    dragEndEvent.dataTransfer = event.dataTransfer;
                    this.dispatchEvent(elem, type, dragEndEvent);
            },
            createEvent: function(type) {
                    var event = document.createEvent(""CustomEvent"");
                    event.initCustomEvent(type, true, true, null);
                    event.dataTransfer = {
                            data: {
                            },
                            setData: function(type, val){
                                    this.data[type] = val;
                            },
                            getData: function(type){
                                    return this.data[type];
                            }
                    };
                    return event;
            },
            dispatchEvent: function(elem, type, event) {
                    if(elem.dispatchEvent) {
                            elem.dispatchEvent(event);
                    }else if( elem.fireEvent ) {
                            elem.fireEvent(""on""+type, event);
                    }
            }
    });
})(jQuery);";



    const string loadJQuery = @"(function(jqueryUrl, callback) {
if (typeof jqueryUrl != 'string') {
    jqueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
}
if (typeof jQuery == 'undefined') {
    var script = document.createElement('script');
    var head = document.getElementsByTagName('head')[0];
    var done = false;
    script.onload = script.onreadystatechange = (function() {
        if (!done && (!this.readyState || this.readyState == 'loaded' 
                || this.readyState == 'complete')) {
            done = true;
            script.onload = script.onreadystatechange = null;
            head.removeChild(script);
            callback();
        }
    });
    script.src = jqueryUrl;
    head.appendChild(script);
}
else {
    callback();
}
})(arguments[0], arguments[arguments.length - 1]);";

这篇关于[C#][Selenium] 如何拖放元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Force JsonConvert.SerializeXmlNode to serialize node value as an Integer or a Boolean(强制 JsonConvert.SerializeXmlNode 将节点值序列化为整数或布尔值)
Using JSON to Serialize/Deserialize TimeSpan(使用 JSON 序列化/反序列化 TimeSpan)
Could not determine JSON object type for type quot;Classquot;(无法确定类型“Class的 JSON 对象类型.)
How to deserialize a JSONP response (preferably with JsonTextReader and not a string)?(如何反序列化 JSONP 响应(最好使用 JsonTextReader 而不是字符串)?)
how to de-serialize JSON data in which Timestamp it-self contains fields?(如何反序列化时间戳本身包含字段的JSON数据?)
JSON.Net custom contract serialization and Collections(JSON.Net 自定义合约序列化和集合)