如何根据 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,然后 运行 一组特定的检查,反之亦然?
测试说明:
条件是 selectedIssueKind
是 Product
或 Equipment
。下一页将有 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])
}
})
})
我有一个检查页面上 table 的柏树测试,但是有两个不同的 table 可以呈现,具体取决于 table 类型条件。如果 table 的类型是 product
,将呈现一个 table,如果类型是 equipment
,将呈现另一个 table。
我如何编写这个 cypress 测试来检查页面上是否有特定的 table,然后 运行 一组特定的检查,反之亦然?
测试说明:
条件是 selectedIssueKind
是 Product
或 Equipment
。下一页将有 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])
}
})
})