如何根据 parent 传递的 prop 对页面上呈现的条件表进行两种不同的测试?

How to have two different tests for conditional tables that render on a page based upon the prop passed by parent?

我有一个检查页面上 table 的柏树测试,但是有两个不同的 table 可以呈现,具体取决于 table 类型条件。如果 table 的类型是 product,将呈现一个 table,如果类型是 equipment,将呈现另一个 table。

我如何编写这个 cypress 测试来检查页面上是否有特定的 table,然后 运行 一组特定的检查,反之亦然?

测试说明:

条件是 selectedIssueKindProductEquipment。下一页将有 table 具有不同的列 headers 和信息。

我的想法是让测试检查 data-class,然后对 data-class table 进行测试。所以:

if ('[data-cy=product-issue-tracker-table]') { product table tests} else {equipment table tests}

然而,如果我点击一个设备问题,我会得到一个错误,它找不到 Part ID,但那是因为它试图检查错误的 table(产品),所以我的 if ('[data-cy=product-issue-tracker-table]') 检查,似乎没有用。

如有任何使用条件的提示,我们将不胜感激!如果您需要更多信息,请告诉我!

干杯!

赛普拉斯测试

it.only('Issue Tracker table exists, column headers are correct and there is data', () => {
    if ('[data-cy=product-issue-tracker-table]') {
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'Issue ID')
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'Part ID')
      cy.get('[data-cy=issue-tracker-table] table').contains(
        'th',
        'Station Name'
      )
      cy.get('[data-cy=issue-tracker-table] table').contains(
        'th',
        'Description'
      )
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'SN')
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'Timestamp')
      cy.contains('td', /\w/g).should('be.visible')
    } else {
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'Issue ID')
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'Part')
      cy.get('[data-cy=issue-tracker-table] table').contains(
        'th',
        'Station Name'
      )
      cy.get('[data-cy=issue-tracker-table] table').contains(
        'th',
        'Description'
      )
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'Start Time')
      cy.get('[data-cy=issue-tracker-table] table').contains('th', 'End Time')
      cy.contains('td', /\w/g).should('be.visible')
    }
  })

HTML

<div data-cy="issue-tracker-table">
  <div class="vgt-wrap issue-tracker-table-style cursor-pointer mb-12" data-cy="product-issue-tracker-table" pagination="[object Object]">
    <!--v-if--><div class="vgt-inner-wrap"><!--v-if--><!--v-if--><!--v-if-->
    <div class="vgt-fixed-header"><!--v-if-->
    </div>
    <div class="vgt-responsive">
      <table id="vgt-table" class="vgt-table condensed">
        <colgroup>
          <col id="col-0">
          <col id="col-1">
          <col id="col-2">
          <col id="col-3">
          <col id="col-4">
          <col id="col-5">
          <col id="col-6">
            
       </colgroup>
        <!-- Table header -->
        <thead>
          <tr><!--v-if--><!--v-if-->
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-0" style="min-width: auto; width: auto;">
              <span>Issue ID</span>
              <!--v-if-->
            </th>
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-1" style="min-width: auto; width: auto;">
              <span>Part ID</span>
              <!--v-if-->
            </th>
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-2" style="min-width: auto; width: auto;">
              <span>Station Name</span><!--v-if-->
            </th>
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-3" style="min-width: auto; width: auto;">
              <span>Description</span><!--v-if-->
            </th>
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-4" style="min-width: auto; width: auto;">
              <span>SN</span>
              <!--v-if-->
            </th>
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-5" style="min-width: auto; width: auto;">
              <span>Timestamp</span>
              <!--v-if-->
            </th>
            <th scope="col" class="vgt-left-align" aria-sort="descending" aria-controls="col-6" style="min-width: auto; width: auto;">
              <span></span>
              <!--v-if-->
            </th>
              
            </tr><!--v-if-->
        </thead><!-- Table body starts here -->
        <tbody><!-- if group row header is at the top --><!--v-if--><!-- normal rows here. we loop over all rows -->
          <tr class="">
            <!--v-if--><!--v-if-->
            <td class="vgt-left-align">
              <span>1</span>
                
            </td>
            <td class="vgt-left-align">
              <span></span>
                
            </td>
            <td class="vgt-left-align">
              <span></span>
                
            </td>
            <td class="vgt-left-align">
              <span> Connect to DUT by SSH</span>
                
            </td>
            <td class="vgt-left-align">
              <span></span>
                
            </td>
            <td class="vgt-left-align">
              <span>Mar 28 2022 - 10:01 AM</span>
                
            </td>
            <td class="vgt-left-align"><!--v-if--><!--v-if-->
              <div data-cy="issue-tracker-view-data-button">
                <button class="primary-button">View Data</button>
                  
              </div><!--v-if-->
            </td>
              
            </tr><!-- if group row header is at the bottom --><!--v-if-->
        </tbody><!--v-if-->
      </table>
        
      </div><!--v-if--><!--v-if-->
    </div>
      
    </div><!--v-if--><!-- Issue Data Modals --><!--v-if--><!--v-if--><!-- Issue Data Modals --><!-- Add New Analysis section -->
  <div class="flex">
    <span class="tab font-normal text-card-orange bg-card-orange bg-opacity-20 py-1 px-4 mb-3 mr-9 rounded-full w-max">Analysis Records</span>
    <!--v-if--><!--v-if-->
    <div data-cy="add-new-analysis-button">
      <button class="primary-button">Add New Analysis</button>
        
      </div><!--v-if--></div>
        
 </div>

所以,这种不确定的测试不是很好的做法。理想的情况是 确定 您正在测试一个 table 或另一个。

The conditional is if the selectedIssueKind is Product or Equipment. The next page will have tables with different column headers and info.

根据该描述,我认为我们可以轻松地将其分成两个(或更多)测试。

// pseudo-code
describe('table tests', () => {
  beforeEach(() => {
    // shared setup
  })

  it('tests the product table', () => {
    // in the product test, we'll select the `selectedIssueKind` of product
    // unclear from the HTML/Cypress how you're doing that, so very vague line below
    cy.get('product').click();
    // code to test the product table
  });

  it('tests the equipment table', () => {
    // in the equipment test, we'll select the `selectedIssueKind` of equipment
    // same as above, very vague example
    cy.get('equipment').click();
    // code to test the equipment table
  });
});

此外,如果您规范中的每个测试都需要一个 selectedIssueKind,您可以将该逻辑移至您的 beforeEach(),在您的 it() 中设置一个环境变量,并且不再重复在每个测试中。

// psuedo-code

describe('test', () => {
  beforeEach(() => {
    // other setup
    // grab the cypress environment variable as your selector
    cy.get(Cypress.env('selectedIssueKind')).click();
  })

  it('product test', { env: selectedIssueKind: 'product' } }, () => {
    // code
  });

  it('equipment test', { env: selectedIssueKind: 'equipment' } }, () => {
    // code
  });
});

测试中有一些重复,可以通过获取 table headers.

的数组来减少

您测试的可能不止 headers,但这给了您想法。

const headers = ['Issue ID', ...]  // add all the common headers

cy.get('[data-cy="issue-tracker-table"]')
  .then($table => {
    return $table.find('[data-cy=product-issue-tracker-table]').length > 0
  })
  .then(console.log)              // for checking isProduct value
  .then(isProduct => {
    if (isProduct) {
      return headers.concat(['SN', 'Timestamp'])
    } else {
      return headers.concat(['Start Time', 'End Time'])
    }
  })
  .then(console.log)              // for checking headers array
  .then(headers => {
    // One test here
    cy.get('[data-cy=issue-tracker-table] table thead th')
      .each(($th, index, $list)) => {
        // last header is empty, presume you don't want to test it
        if (index < $list.length -1 ) {       
          expect($th.text()).to.eq(headers[index])
        }
      })
  })

分解步骤也很有用,您可以通过(临时)记录 .then().

的结果来逐步检查每个步骤

我注意到 <!--v-if--> 表明您正在使用 Vue 应用程序。

如果你想变得非常复杂,你可以让应用程序告诉赛普拉斯正在显示哪种 table。这是一个 app-action,它降低了异步加载的风险。

具体代码取决于您的 Vue 组件,但模式是

// in Vue component

if (window.Cypress) {
  window.tableType = tableType
}
// in test

cy.window()
  .then(win => {
    return win.tableType === 'Product'
  })
  .then(console.log)              // for checking isProduct value
  .then(isProduct => {
    ...

正在测试所有 <td> 有内容和可见性

cy.get('[data-cy=issue-tracker-table] table tbody td')
  .each($td => {
    cy.wrap($td)
      .contains(/\w/)
      .should('be.visible')
  })

替代步骤:tableType 而不是 isProduct

cy.get('[data-cy="issue-tracker-table"]')
  .then($table => {
    if ($table.find('[data-cy=product-issue-tracker-table]').length > 0) {
      return 'Product'
    } else {
      return 'Equipment'
    }
  })
  .then(console.log)              // for checking tableType value
  .then(tableType => {
    if (tableType === 'Product') {
      return headers = headers.concat(['SN', 'Timestamp'])
    } else {
      return headers = headers.concat(['Start Time', 'End Time'])
    }
  })
  .then(console.log)              // for checking headers array
  .then(headers => {
    // One test here
    cy.get('[data-cy=issue-tracker-table] table thead th')
      .each(($th, index, $list) => {
        // test header here
        if (index < $list.length -1 ) {
          expect($th.text().trim()).to.eq(headers[index])
        }
      })
  })