【问题标题】:How do I get rows from a list(table) in a protractor e2e test?如何在量角器 e2e 测试中从列表(表)中获取行?
【发布时间】:2018-08-06 20:02:02
【问题描述】:

有问题的列表是由没有特定 ID 的反应角度形式生成的表。以下代码用于生成角度部分的列表:

<p-table id='paragraphList' *ngIf="paragraphsObs | async; else loading"
         [value]="paragraphsObs | async"
         selectionMode="single" (onRowSelect)="select($event)"
         scrollable="true">
  <ng-template pTemplate="header">
    <tr> ...header... </tr>
  </ng-template>
  <ng-template pTemplate="body" let-paragraph let-rowData>
    <tr [pSelectableRow]="rowData">
      <td width="15%">{{paragraph.cell1}}</td>
      <td width="10%">{{paragraph.cell2}}</td>
      <td width="31%">{{paragraph.cell3}}</td>
      <td width="11%">{{paragraph.cell4 | dateTransform: helperService.MM_DD_YYYY_HH_MM_A_Z_DATE_PATTERN}}
      </td>
      <td width="11%">{{paragraph.cell5}}</td>
      <td width="11%">{{paragraph.cell6 | dateTransform: helperService.MM_DD_YYYY_HH_MM_A_Z_DATE_PATTERN}}
      </td>
      <td width="11%">{{paragraph.cell7}}</td>
    </tr>
  </ng-template>
</p-table>

前端生成的对应表有如下html源码:

<p-table _ngcontent-c6="" id="paragraphList" scrollable="true" selectionmode="single" ng-reflect-selection-mode="single" ng-reflect-scrollable="true" class="ng-star-inserted" ng-reflect-value="[object Object],[object Object">
  <div class="ui-table ui-widget ui-table-hoverable-rows" ng-reflect-ng-class="[object Object]">
    <div class="ui-table-scrollable-wrapper ng-star-inserted">  
      <div class="ui-table-scrollable-view" ng-reflect-frozen="false">
        <div class="ui-table-scrollable-header ui-widget-header">...header...</div>
        <div class="ui-table-scrollable-body">
          <table class="ui-table-scrollable-body-table" ng-reflect-klass="ui-table-scrollable-body-table" ng-reflect-ng-class="[object Object]">               
            <tbody class="ui-table-tbody" ng-reflect-template="[object Object]">
              <tr _ngcontent-c6="" ng-reflect-data="[object Object]" class="ng-star-inserted">...</tr>
              <tr _ngcontent-c6="" ng-reflect-data="[object Object]" class="ng-star-inserted">...</tr>
               ...
            </tbody>
          </table>
          <div class="ui-table-virtual-scroller"></div>
        </div>
      </div>
    </div>
  </div>
</p-table>

我想触及那些内部元素并将它们作为一个列表。我尝试将类名与元素和所有定位器一起使用,以获取元素但无济于事。然后我尝试使用标签名称来访问这些元素,但这似乎也不起作用。

下面这个小 sn-p 为我尝试从列表中获取的元素计数返回 0。

element(by.id('paragraphList')).element(by.css('.ui-table-scrollable-body-table'))
  .all(by.tagName('tr')).count().then(function (result) {
  console.log(result);
});

任何帮助将不胜感激。谢谢

【问题讨论】:

  • 你想要什么列表???行??
  • 这样的格式适合你吗?一个数组数组,其中每个数组都是单元格的内容??
  • 是的,我想要列表中的行。只要我有单独的行要测试,任何集合都可以。

标签: html angular testing protractor e2e-testing


【解决方案1】:

考虑到上面是您完整呈现的 HTML.. 下面的代码将给出一个数组数组,其中每个数组将包含一行中所有单元格的文本。

说明: 该代码具有三个功能, populateData() - 是我们传递rows 的解析列表的驱动函数。

然后_populateRows()_populateCells() 递归运行以从单元格中收集文本。这也可以通过循环来实现(因为量角器本身将承诺排队),但我喜欢在我的最后保持清晰。 _populateRows() 在行上重复,_populateCells() 在每行的单元格上重复。 (更多内容见 cmets)

注意在实施之前您应该做的第一件事是:检查element.all(by.css('#paragraphList table tbody tr'))count()(或resolvedRows.length)。因为基本上这是你最初的问题,我相信。现在,如果您有计数,那么您可以使用此解决方案或任何您需要的套件。

let allRows = element.all(by.css(`#paragraphList table tbody tr`)); //will have all the rows.
allRows.then((rowsResolved) => {
    // now have all the rows
    PO.populateData(rowsResolved).then((allData) => {console.log(allData)})  // should be an Array od arrays, each array would be containing texts from all the cells. 
    // Considering you have a Page Object and added the functions below in the Page Object.
    // Page Object is nothing but another class where we keep our utility methods
})


//    driving function
populateData(rowsResolved) {
    let data = [];
    return this._populateRows(0, rowsResolved, data);
}

// calls itself recursively to loop over the rows
private _populateRows(index, rowsResolved, data) {
    if (index >= rowsResolved.length) {
        let defer = protractor.promise.defer();
        defer.fulfill(data);
        return defer.promise;   // so that it is chainable even if I don't have any rows
    }

    let cells = element.all(by.css(`#paragraphList table tbody tr:nth-child(${index + 1}) td`));
    cells.then((cellsResolved) => {
        let cellData = [];
        if (cellsResolved.length) {
            data.push(cellData);
        }
        this._populateCells(0, cellsResolved, cellData);
        return this._populateRows(index + 1, rowsResolved, data);
    })
}

// calls itself recursively to loop over all the cells ofeach row.
private _populateCells(index, cellsResolved, cellData) {
    if (index >= cellsResolved.length) {
        let defer = protractor.promise.defer();
        defer.fulfill(cellData);
        return defer.promise;  // so that it is chainable even if I don't have any cells(that would be an incorrect structure though, if a row exists then cells have to exist )
    }

    cellsResolved[index].getText().then((cellValue) => {
        cellData.push(cellValue)
    });
    return this._populateCells(index + 1, cellsResolved, cellData);
}

【讨论】:

  • css 选择器仍然不起作用。它给了我 0 的行数。
  • @AmritanshuJoshi:在您的浏览器中,转到您要在应用程序中测试的页面,打开检查元素并执行:console.log(document.querySelectorAll('#paragraphList table tbody tr'))。你看到了什么?如果你看到空,那么你没有在问题中提供确切的 DOM 结构,实际上你不需要,这是你自己可以弄清楚的。
  • 终于成功了。事实证明选择器一直都是正确的,但是列表需要一些时间来加载页面,然后测试才能访问它。我放入了 browser.wait() 以使页面正确加载,现在我得到了正确的计数和列表项。我会将此标记为正确答案。谢谢。
  • 列表长度没问题。但是当我尝试记录所有元素时,代码仍然出错。错误:- 失败:无法读取未定义的属性 'then' 在行:this.populateData(rowsResolved).then((allData) =&gt; {console.log(allData)})
猜你喜欢
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 2021-04-26
相关资源
最近更新 更多