【问题标题】:How to simulate a drag and drop action in protractor?如何在量角器中模拟拖放动作?
【发布时间】:2014-09-04 11:39:48
【问题描述】:

我有一个双滑块,我想测试它是否可操作并返回正确的数据。滑块有一个最小值和一个最大值处理程序,它还有一些“我可以挂钩的断点”。

我要模拟的是

  • “.handler-max”元素的 touchStart
  • 拇指在类“.step-3”的元素上移动
  • “.handler-max”元素的 touchEnd

虽然我发现了如何触发 touchStart 和 touchEnd 事件。我不知道如何模拟拇指的移动

browser.executeScript('angular.element(arguments[0]).triggerHandler("touchstart");', filterHandler);
// <--- move event????
browser.executeScript('angular.element(arguments[0]).triggerHandler("touchend");', filterHandler);

附:这个问题的范围是一个集成测试,它测试当用户与双滑块指令交互时应用程序发生的情况是否是理想的结果。

【问题讨论】:

    标签: angularjs testing protractor angularjs-e2e


    【解决方案1】:

    elem = 要移动的元素;

    target = 要放置 elem 的元素;

    对于 WebdriverJS:-

    browser.driver.actions().dragAndDrop(elem,target).mouseUp().perform();
    

    对于量角器:-

    browser.actions().dragAndDrop(elem,target).mouseUp().perform();
    

    【讨论】:

    • 我猜(Protractor) 是一个错字!
    【解决方案2】:

    现在这很简单:

    browser.actions().dragAndDrop(elem, target).perform();
    

    其中dragAndDrop behind the scenesmouseDown + mouseMove + mouseUp

    /**
     * Convenience function for performing a "drag and drop" manuever. The target
     * element may be moved to the location of another element, or by an offset (in
     * pixels).
     * @param {!webdriver.WebElement} element The element to drag.
     * @param {(!webdriver.WebElement|{x: number, y: number})} location The
     *     location to drag to, either as another WebElement or an offset in pixels.
     * @return {!webdriver.ActionSequence} A self reference.
     */
    webdriver.ActionSequence.prototype.dragAndDrop = function(element, location) {
      return this.mouseDown(element).mouseMove(location).mouseUp();
    };
    

    【讨论】:

    • 太棒了,如果有人验证,我会投票。对我来说很难,因为我不再在前端工作,而且我没有设置 selenium atm
    • @AlexandrosSpyropoulos 当然,我可以验证它对我有用:)
    【解决方案3】:

    好吧,我发现我有更好的方法。可能我之前查看的资源已经过时了。以下脚本将非常干净和简单地完成这个技巧......

    it( 'step : 6 : select star rating min === 1 and max === 2' , function (done) {
    
        driver.actions()
            .mouseDown(element(by.css('.filter-editorial-rating .ngrs-handle-max')))
            .mouseMove(element(by.css('.filter-editorial-rating .step-2')))
            .mouseUp()
            .perform();
    
    
    element( by.css( '.results-indicator' ) ).getText()
        .then( function ( text ) {
            resultsB = parseInt (text.split(" ")[0]);
            expect( resultsB ).toBeLessThan( resultsA );                            
            done();
        });
    });
    

    你可以得到这样的驱动程序...

    browser.get(url);
    var driver = browser.driver;
    

    干杯

    【讨论】:

      【解决方案4】:
              var plot0 = ptor.element(protractor.By.id(''));
      
              ptor.driver.actions()
      
              .dragAndDrop(plot0, {x: 200, y: 100})
      
              .mouseMove(plot0, {x: 200, y: 100}) // 200px from left, 200 px from top of plot0
      
              .mouseDown()
      
              .mouseMove({x: 600, y: 0}) // 600px to the right of current location
      
              .perform();
      

      这对我有用。我的场景是拖动一个没有目标元素的弹出对话框。

      【讨论】:

      • 谢谢!像魅力一样工作!
      【解决方案5】:

      我正在将自动化项目从使用 SELENIUM_PROMISE_MANAGER 转换为使用 JS 原生 async/await。以前,我一直在使用 user3800138 ^ 描述的方式,但是它不再适用于我以及此处描述的所有其他方法。对我有用的是通过then 这样的方法链接每一个操作

      dragAndDrop: ( $element, $destination ) =>
          browser
              .actions()
              .mouseMove( $element )
              .perform()
              .then( () => browser
                  .actions()
                  .mouseDown( $element )
                  .perform() )
              .then( () => browser
                  .actions()
                  .mouseMove( $destination )
                  .perform() )
              .then( () => browser
                  .actions()
                  .mouseUp()
                  .perform())
      

      然后像这样调用它await dragAndDrop($leftSlider, $lastDateTitle);

      或者同样使用await 会是这样的

      dragAndDrop: async( $element, $destination ) => {
          await browser.actions().mouseMove( $element ).perform();
          await browser.actions().mouseDown( $element ).perform();
          await browser.actions().mouseMove( $destination ).perform();
          await browser.actions().mouseUp().perform();
      }
      

      我知道它有点笨重,但我找不到更好的选择

      【讨论】:

        【解决方案6】:

        正如有人已经提到的(但有点过时),您也可以通过提供 x,y 坐标将滑块移动到任何方向:

        browser.actions().dragAndDrop(sliderElement, {x: 10}).perform()
        
        browser.actions().dragAndDrop(sliderElement, {x: -10}).perform()
        
        browser.actions().dragAndDrop(modalElement, {x: 100, y:100}).perform()
        

        【讨论】:

          【解决方案7】:
          import {code as dragAndDrop} from 'html-dnd';
          
          it("dragAndDropInCanvas",function(){
             var xy= (element(by.className('row ng-star-inserted')),{x: 300, y: 300});
             var source_1 = element(by.xpath('//*[@id="sidebarnav"]/li[3]/ul/li[1]'))
             var target = element(by.id('mainCanvas'));
             browser.sleep(1000);
             browser.executeScript(dragAndDrop, source_1, target);
             browser.sleep(2000);
             element(by.className('col-4 ng-star-inserted')).click()
             browser.sleep(5000)
            })
          

          【讨论】:

            【解决方案8】:

            对于这样的问题,我将业务代码(实际上对拖放事件做了一些有用的事情)与 UI 隔离开来。这样,我可以确保拖放开始代码将正确填写数据结构,并且我可以确保放置处理代码将做正确的事情实际上不必让某些东西发送真正的拖放事件。

            那样,真正的事件处理代码只有 1-2 行,所以它在那里中断的可能性非常非常小。此外,没有理由测试您的浏览器或操作系统的拖放代码;这段代码应该可以工作。

            【讨论】:

            • 我的问题似乎正是这个 github.com/angular/protractor/issues/160 。我的意思是我正在尝试测试滑块指令和实际更新任何数据的搜索模块之间的集成。我要测试的是 .我是用户与滑块指令交互的。它真的会触发用户体验所期望的事件序列吗?
            • @AlexandrosSpyropoulos:你的评论对我来说没有意义。
            • 我的意思是我正在尝试测试滑块指令和实际处理事件的搜索模块之间的集成。我要测试的是 .如果用户与滑块指令交互。它是否真的触发了用户体验所期望的事件序列?我希望这对你有意义。事实上,我测试了一个更改最小值/最大值的滑块和一些向服务发出请求并显示数据列表的模块。
            • 您希望从执行数十万行代码中学到什么?您的问题不是真的意味着“我不知道滑块是如何工作的以及它会触发哪些事件”吗?我不认为事件经常发生变化。因此,只需 一次 找出您可以期待哪些事件以及以何种顺序进行就足够了。然后编写单元测试以确保您的代码可以处理它们。如果应用程序的这一部分发生故障,请再次检查触发了哪些事件,看看发生了什么变化。
            • 对不起,我可能没有解释清楚。我不是在写单元测试。这已经完成并且单元测试满足他们自己的测试。我现在正在做的是 E2E 测试。正如您所说,事实是,测试对应用程序的内部一无所知。所以我不关心关于这个测试的应用程序内部。我只关心用户体验的 UI(实际上用户正在使用滑块过滤器获取有效的结果列表)。所以看不到我如何在不模拟移动动作的情况下模拟用户的动作。恐怕您的回答与我的问题无关。
            猜你喜欢
            • 2018-09-21
            • 1970-01-01
            • 2020-01-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多