【问题标题】:Protractor e2e tests with MEANJS navigation使用 MEANJS 导航进行量角器 e2e 测试
【发布时间】:2015-06-09 20:11:10
【问题描述】:

大部分时间我仍处于学习模式。

我已经安装了MeanJS,并且正在使用开箱即用的导航。我开始使用ProtractorJasmine 实现端到端测试。

我希望我的量角器测试与导航组件交互。在整页中它很宽。在移动尺寸中,它是一个汉堡包。任何关于编写/考虑测试的好方法的一般信息将不胜感激。

以下是我目前坚持的一些项目:

模拟菜单项选择

我想模拟用户使用量角器单击菜单项。全屏宽度演示的 HTML...

<li data-ng-repeat="item in menu.items | orderBy: 'position'" 
    data-ng-if="item.shouldRender(authentication.user);"  
    ng-switch="item.menuItemType" ui-route="/admin" class="dropdown"  
    ng-class="{active: ($uiRoute)}"  
    dropdown="item.menuItemType === 'dropdown'">  

    <!-- THIS NEEDS TO BE CLICKED TO MAKE THE CHILD LINKS VISIBLE -->
    <a ng-switch-when="dropdown" class="dropdown-toggle ng-scope"  
        dropdown-toggle="" aria-haspopup="true" aria-expanded="false"> 
        <span data-ng-bind="item.title" class="ng-binding">Admin</span> 
        <b class="caret"></b> 
    </a> 
    <ul ng-switch-when="dropdown" class="dropdown-menu ng-scope"> 
        <li data-ng-repeat="subitem in item.items | orderBy: 'position'"  
           data-ng-if="subitem.shouldRender(authentication.user);"  
           ui-route="/admin/users" ng-class="{active: $uiRoute}" class="ng-scope">  

            <!-- THIS IS WHAT I WANT TO CLICK -->
            <a href="/#!/admin/users" data-ng-bind="subitem.title" class="ng-binding"> 
               Administer Users 
            </a> 
        </li> 
    </ul>

我认为我需要做的是模拟单击“管理”链接以显示子菜单(上面的第一条评论指出)。然后模拟点击“Administer Users”链接触发导航

我的具体问题:

  1. 我模拟导航链接点击的策略是否正确?
  2. 我应该使用什么魔法元素(by.?)语句来查找“管理员”链接
  3. 假设我有“管理”链接,找到“管理用户”链接以模拟该点击的最佳方法是什么?

折叠/汉堡模式应该如何处理

在移动布局中导航范式会发生变化。我还没有研究过布局,但是相同的链接需要不同的点击。

这里有哪些最佳做法?关于我可以用来帮助发现做什么的资源的任何建议?

我还要注意...

我确实想找到属于菜单子项的链接...而不是只找到其中​​包含该 URL 的任何链接。

菜单项比显示的要多...为了清楚起见,我只是减少了 html 示例。

【问题讨论】:

    标签: angularjs protractor meanjs


    【解决方案1】:

    又回来了……(自我回答)

    我对量角器、JS 等的了解比刚开始时要多得多。我认为这是一个相当不错的解决方案。这将节省大量时间。希望它可以帮助某人...

    首先,使用Page Object pattern

    接下来,创建一个函数来单击导航栏链接,包括单击展开/显示子项。它需要根据 MEANJS nav 的响应特性智能地工作(例如汉堡包或不汉堡包):

    commonPOs.clickNavBar = function(mainTab, linkUrl) {
      var deferred = protractor.promise.defer();
    
      var hamburger = element(by.id('nav-hamburger'));
    
      hamburger.isDisplayed().then(function(result) {
        if ( result ) {
          hamburger.click().then(function() {
            var navBar = hamburger
              .element(by.xpath('../..'))
              .element(by.id('myapp-navbar'));
              return clickItNow(mainTab, linkUrl, navBar, deferred);
          });
        } else {
          return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')), deferred);
        }
      });
    
      return deferred.promise;
    };
    
    function clickItNow(mainTab, linkUrl, navBar, deferred) {
      var targetLink;
      var linkCssExpression = 'a[href*="' + linkUrl + '"]';
    
      expect(navBar.waitReady()).toBeTruthy();
    
      if(mainTab) {
        // if mainTab was  passed, neet to
        // click the parent first to expose the link
        var parentTabLink;
    
        if (mainTab == 'ACCTADMIN') {
          parentTabLink = navBar.element(by.id('account-admin-menu'));
        }
        else {
          parentTabLink = navBar.element(by.id('main-menu-' + mainTab.split(' ').join('')));
        }
        // expect(parentTabLink.isDisplayed()).toBeTruthy();
        expect(parentTabLink.waitReady()).toBeTruthy();
        parentTabLink.click();
        targetLink = parentTabLink.element(by.xpath('..')).element(by.css(linkCssExpression));
      }
      else {
        targetLink = navBar.element(by.css(linkCssExpression));
      }
    
      expect(targetLink.waitReady()).toBeTruthy();
      targetLink.click().then(function() {
        return deferred.fulfill();
      });
    }
    

    我在上面的代码中引用了 waitReady() 函数。你可以找到here

    上面的导航功能需要修改一些html标记,量角器可以更容易找到导航元素:

    /public/modules/core/views/header.client.view.html 用 ID 标记这些元素:

    • '导航-汉堡包'
    • 'myapp-navbar'
    • 'main-menu-{{item.title.split(' ').join('')}}'
    • '帐户管理菜单'

    /public/modules/core/views/header.client.view.html

    <div class="container" data-ng-controller="HeaderController">
        <div class="navbar-header">
            <button id="nav-hamburger" class="navbar-toggle" type="button" data-ng-click="toggleCollapsibleMenu()">  . . . .
            </button>
        </div>
        <nav id="myapp-navbar" class="collapse navbar-collapse" collapse="!isCollapsed" role="navigation">
            <ul class="nav navbar-nav" data-ng-if="menu.shouldRender(authentication.user);">
                <li data-ng-repeat="item in menu.items | orderBy: 'position'" data-ng-if="item.shouldRender(authentication.user);" ng-switch="item.menuItemType" ui-route="{{item.uiRoute}}" class="{{item.menuItemClass}}" ng-class="{active: ($uiRoute)}" dropdown="item.menuItemType === 'dropdown'">
                    <a id="main-menu-{{item.title.split(' ').join('')}}" ng-switch-when="dropdown" class="dropdown-toggle" dropdown-toggle>
    
            <ul class="nav navbar-nav navbar-right" data-ng-show="authentication.user">
                <li class="dropdown" dropdown>
                    <a id="account-admin-menu" href="#" class="dropdown-toggle" data-toggle="dropdown" dropdown-toggle>
    

    我已经使用通用页面对象命令将导航包装到特定元素:

    commonPOs.navToSigninPage = function() {
      var deferred = protractor.promise.defer();
    
      this.clickNavBar(null, 'signin').then(function() {
        expect(something).toBeTruthy();
        deferred.fulfill(new SigninPage());
      });
    
      return deferred.promise;
    };
    

    最后,像这样在你的规范中使用它:

    commonPOs.navToSigninPage().then(function(signInPage){
      signInPage.loginWithCredentials(username, password);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2016-11-25
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多