Promise::3138 {[[PromiseStatus]]: "pending"} : 不能 return 数字

Promise::3138 {[[PromiseStatus]]: "pending"} : can't return number

我尝试在量角器中使用 IndexOf 方法。而且我不能 return 数字值而不是 Promise。

  PsGrid.prototype.getQuickFilterByName = function(name) {
       var num;
       num = this.all(by.xpath(".//tr[contains(@class,'n-grid__head-row')]/th[contains(@class,'n-grid__title')]//div[contains(@class,'n-grid__text')]")).getText().then(function(textArray){
       return textArray.indexOf(name) + 2;
       });

    expect(num).toEqual(8);  // num == 2
    console.log("sdf" + num); // num == Promise::3138 {[[PromiseStatus]]: "pending"} 
    return this.element(by.xpath('.//tr[2]/td[' + num + ']//input')); //protractor can't find element
};

table 的完整 HTML 代码:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<table class="n-grid">
      <colgroup>
        <col ng-repeat="column in $view.columns track by column.$id" ps-link-element="column.elements.col" ng-attr-width="{{column.settings.width}}" class="ng-scope" width=""><col ng-repeat="column in $view.columns track by column.$id" ps-link-element="column.elements.col" ng-attr-width="{{column.settings.width}}" class="ng-scope" width="185">
        <col ng-if="$view.fillerColumn.needVisible()" ng-attr-width="{{$view.fillerColumn.width}}" class="ng-scope" width="*">
      </colgroup>
      <thead class="n-grid__head" ps-event="{ mousedown: [
                         {exp: 'onMouseDown($event,column,internalOptions.states.preMoveColumn)', selector: 'div.n-grid__event'},
                         {exp: 'onMouseDown($event,column,internalOptions.states.resizeColumn)',  selector: 'div.n-grid-col-resize'}]
                       }">
        <tr class="n-grid__head-row" ng-show="$view.hasHeader">
          <th class="n-grid__title ng-scope ng-isolate-scope n-grid__status" ng-class="column.design.classes.title" ng-repeat="column in $view.columns track by column.$id" ps-link-element="column.elements.head" on-link-element="onLinkHead(column, $last)" ps-context-menu="menuOptions.show(column, $event)" ps-grid-bind-element="column.elements.title"><span ng-if="psGrid.isMultiSelect()" class="n-grid__select-all ng-scope"></span></th><th class="n-grid__title ng-scope ng-isolate-scope" ng-class="column.design.classes.title" ng-repeat="column in $view.columns track by column.$id" ps-link-element="column.elements.head" on-link-element="onLinkHead(column, $last)" ps-context-menu="menuOptions.show(column, $event)" ps-grid-bind-element="column.elements.title">
            <div class="n-grid-title-in" ng-style="{'z-index': $view.columns.length - $index}" style="z-index: 2;">
              <div class="n-grid__event n-grid__event_sort" ng-class="{'n-grid__event_sort': column.sortable}">
                <div class="n-grid__text ng-binding" ng-attr-title="{{column.title()}}" ng-bind="column.caption()" title="Имя клиента">Имя клиента</div>
                <span class="n-grid__sort-icon"></span>
              </div>
              <div ng-if="column.resizable" class="n-grid-col-resize ng-scope" ng-dblclick="menuOptions.onColumnAutoSize(column)"></div>
            </div>
          </th><th class="n-grid__title ng-scope ng-isolate-scope n-grid__title_sortable" ng-class="column.design.classes.title" ng-repeat="column in $view.columns track by column.$id" ps-link-element="column.elements.head" on-link-element="onLinkHead(column, $last)" ps-context-menu="menuOptions.show(column, $event)" ps-grid-bind-element="column.elements.title">
            <div class="n-grid-title-in" ng-style="{'z-index': $view.columns.length - $index}" style="z-index: 1;">
              <div class="n-grid__event n-grid__event_sort" ng-class="{'n-grid__event_sort': column.sortable}">
                <div class="n-grid__text ng-binding" ng-attr-title="{{column.title()}}" ng-bind="column.caption()" title="Номер">Номер</div>
                <span class="n-grid__sort-icon"></span>
              </div>
              <div ng-if="column.resizable" class="n-grid-col-resize ng-scope" ng-dblclick="menuOptions.onColumnAutoSize(column)"></div>
            </div>
          </th>
          <th ng-if="$view.fillerColumn.needVisible()" class="n-grid__title ng-scope ng-isolate-scope" ps-context-menu="">
            <div class="n-grid-title-in">&nbsp;</div>
          </th>
        </tr>

        <tr ng-if="$view.hasVisibleFilters" class="n-grid__head-row ng-scope" ps-event="{ 'keydown': {exp: '$event.keyCode === 13 &amp;&amp; $currentScope.onFilterApply()', selector: '.inp-text', apply: true},
                        'apply.value.component': {exp: '$currentScope.onFilterApply()', apply: true}}">
          <td ng-class="column.design.classes.filter" ng-repeat="column in $view.columns track by column.$id" ps-grid-bind-element="column.elements.filter || column.elements.filter_empty" class="ng-scope n-grid__title n-grid__status"><a ng-if="$view.hasVisibleFilters" ng-click="onFilterClear()" class="n-grid__cancel-filter ng-scope" ng-attr-title="{{locale.psGrid.clearFilter}}" title="Очистить фильтр"><span class="n-grid__filter-icon"></span></a></td><td ng-class="column.design.classes.filter" ng-repeat="column in $view.columns track by column.$id" ps-grid-bind-element="column.elements.filter || column.elements.filter_empty" class="ng-scope n-grid__filter">
          <input class="inp-text ng-scope ng-pristine ng-valid" ng-mousedown="in.filter.dirty.customer.filterMethod=4" ng-model="in.filter.dirty.customer.name" maxlength="64">
        </td><td ng-class="column.design.classes.filter" ng-repeat="column in $view.columns track by column.$id" ps-grid-bind-element="column.elements.filter || column.elements.filter_empty" class="ng-scope n-grid__filter">
          <input class="inp-text ng-scope ng-pristine ng-valid" ng-model="in.filter.dirty.inquiry.ids" ps-input-allow="/^[\s,;0-9]*$/">
        </td>
          <td ng-if="$view.fillerColumn.needVisible()" class="n-grid__filter ng-scope">
            <span class="n-grid__empty-placeholder">&nbsp;</span>
          </td>
        </tr>
      </thead>
    </table>

栏目名称 - “Номер”。

我尝试编写 addLocator 方法,但我认为我在那里有一些误解。

是的,num是一个承诺。所以如果你想用它做任何事情,它需要进入一个 then 回调;而你的功能只能 return 另一个承诺。

PsGrid.prototype.getQuickFilterByName = function(name) {
    return this.all(by.xpath(".//tr[contains(@class,'n-grid__head-row')]/th[contains(@class,'n-grid__title')]//div[contains(@class,'n-grid__text')]")).getText().then(function(textArray){
        return textArray.indexOf(name) + 2;
    }).then(function(index) {
        expect(index).toEqual(8);
        console.log("sdf" + index);
        return this.element(by.xpath('.//tr[2]/td[' + index + ']//input'));
    });
};

您可以使用相当复杂的XPath 表达式一次性将元素定位到所需的列中。这个想法是获取所需的 header 单元格的位置,并使用该位置来定位所需的 "data" 单元格。为了便于阅读,分成多行:

.//tr[2]/td[
    count(//preceding::tr[contains(@class,'n-grid__head-row')]/th[
        contains(@class,'n-grid__title') and .//div/@title = 'Номер'
    ]/preceding-sibling::th) + 3
]//input

其中 Номер 是 header 名称的示例。为什么 + 3? - 1 需要定义 header 的位置(我们计算前面的 th 元素来计算 header 位置),另一个 2 是来自您提供的代码:return textArray.indexOf(name) + 2;.

希望大家清楚我在这里要做什么。