问题描述
我正在尝试使用Codeceptjs中可用的方法来简单地迭代表的行,并基于要迭代的当前行的特定单元格中存在的文本来选择行。
async selectSiteById(siteId) {
I.waitForElement('table');
for (let i = 1; i < 5; i++) {
let val = await I.grabTextFrom(`tbody tr:nth-child(${i}) td:nth-child(2)`);
if (val === siteId) {
I.say('Val' + val + ' -- Site Id ' + siteId)
within(`tbody tr:nth-child(${i + 1}) td:nth-child(1)`,() => {
I.click('input');
});
}
break;
}
},
grabTextFrom会拉回我需要的确切值,并将其存储到val。
如果我传入的参数的值恰好在表的第一行中,则此方法有效。但是,无论我做什么,我的代码似乎都只能排在第一行,我也不知道为什么?
再次,如果第一行具有传入的参数值,那么my方法将触发并检查第一列中的输入框,确切地说是我希望的操作。
因此,我用于识别给定行中所要查找的文本的两段代码(多数情况下)有效,并且单击“该”行中的复选框的代码也有效。
如果有人可以帮助我理解为什么我不能让它遍历表的所有行,我将不胜感激。
而且,我似乎无法让codeceptjs将tbody中tr的总数作为一个简单的数组拉回,因此我可以将其用作循环的长度,因此任何指针都很棒。
为此,我尝试了-let rowCount = await I.grabNumberOfVisibleElements('tbody tr');
,但似乎没有用。
我确实尝试将分手级别提高到一个水平,因为我最初以为是错误的位置。当我这样做时,运行测试会导致以下错误。
沙箱可在其中玩耍-勾选所有 对象:登录 我在页面“ /登录”上 我填写“ #username”,“ user@somewhere.com”字段 我填写“ #password”字段,***** 我点击“登录” 我抓饼干 我单击“ li [id =“ resources.admin.name”]“ 我点击“站点” 我等待元素“表” 我从“ tbody tr:nth-child(1)td:nth-child(2)”中抓取文本√OK在7254ms内
tableFragment: selectSiteById I grab text from "tbody tr:nth-child(2) td:nth-child(2)" I grab text from "tbody tr:nth-child(3) td:nth-child(2)" × "after all" hook: codeceptjs.afterSuite for "Check Box of specific
表行”在4672ms中TypeError:无法读取null的属性“ $$” (节点:24032)UnhandledPromiseRejectionWarning:无法读取属性 '$$'为null(节点:24032)UnhandledPromiseRejectionWarning:未处理 承诺拒绝。该错误是由以下原因引起的: 一个没有catch块的异步函数,或者通过拒绝一个Promise 没有使用.catch()处理。终止节点进程 未处理的承诺被拒绝,请使用CLI标志
--unhandled-rejections=strict
(请参阅 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝ID:7)(节点:24032)[DEP0018] DeprecationWarning:未处理 答应拒绝已弃用。将来,承诺会被拒绝 未处理的将终止Node.js进程 非零退出代码。-故障:
- 可在其中玩耍的沙盒 “毕竟”钩子:codeceptjs.afterSuite用于“特定表行的复选框”: 无法读取null的属性“ $$”
使用--verbose标志运行以查看NodeJS stacktrace
最后,对于与表的基本交互,使用codeceptjs时,您基本上是否需要使用帮助程序,然后使用本机Puppeteer编写代码? (我在项目中使用人偶)
>>>>> 更新
谁能帮助我理解为什么您似乎无法使用CodeceptJS迭代表的行?我必须丢失一些东西。这是我当前来自PageObject类的代码,我不知道第一次迭代成功完成了什么,但是随后失败了。
async test() {
const totalRows = await I.grabAttributeFrom('tbody tr');
I.say('Total Rows: ' + totalRows.length);
for (let i = 1; i < totalRows.length; i++) {
I.say('Current row is: ' + i);
let str = await I.grabTextFrom(
`tbody tr:nth-child(${i}) td:nth-child(2)`,);
I.say('String value from table is: ' + str);
if (str === 'IDR') {
I.say('Match found in row: ' + i);
within(`tbody tr:nth-child(1) td:nth-child(1) span span`,() => {
I.click('input');
});
break;
}
}
// I.say('Hello');
// let scores = [10,15,20,30];
// for (let score of scores) {
// score += 3;
// I.say(score);
// }
},
要在其中使用的沙盒-选中表ALL 对象:登录 我在页面“ /登录”上 我填写“ #username”,“ bob@infdig.com”字段 我填写“ #password”字段,***** 我点击“登录” 我抓饼干 我单击“ li [id =“ resources.admin.name”]“ 我点击“站点” 我从“ tbody tr”中获取属性 我在12226毫秒内等待5√OK
总行数:4当前行是:1 sitesPage:测试 我从“ tbody tr:nth-child(1)td:nth-child(2)”中抓取文本,表中的字符串值为:IDH当前行为:2 我从“ tbody tr:nth-child(2)td:nth-child(2)”ד毕竟”钩子中获取文本:codeceptjs.afterSuite中的“ More goofing around” 4682ms TypeError:无法读取null的属性'$$'(node:7180) UnhandledPromiseRejectionWarning:无法读取null的属性“ $$” (节点:7180)UnhandledPromiseRejectionWarning:未处理的承诺 拒绝。该错误是由抛出异步内部引起的 没有捕获块或拒绝承诺 未使用.catch()处理。终止未处理的节点进程 承诺拒绝,请使用CLI标志
--unhandled-rejections=strict
(请参见https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝ID:7)(节点:7180)[DEP0018] DeprecationWarning:未处理 答应拒绝已弃用。将来,承诺会被拒绝 未处理的将终止Node.js进程 非零退出代码。-故障:
使用--verbose标志运行以查看NodeJS stacktrace
谢谢! 鲍勃
解决方法
我最终走了帮助路线,并建立了一些通用功能来处理表格。我以为我会分享这一点,这对外面的人都有帮助。尝试使用内置的codeceptjs方法执行此操作不可靠。
Puppeteer Helper类
const { Helper } = codeceptjs;
class Table extends Helper {
// before/after hooks
/**
* @protected
*/
_before() {
// remove if not used
}
/**
* @protected
*/
_after() {
// remove if not used
}
// add custom methods here
// If you need to access other helpers
// use: this.helpers['helperName']
/**
* Get the total rows displayed in a table contained within
* the table body (tbody tr)
*/
async getRowCount() {
//const browser = this.helpers['Puppeteer'].browser;
const page = this.helpers['Puppeteer'].page;
page.waitForSelector('tbody');
const tableRows = 'tbody tr';
let rowCount = await page.$$eval(tableRows,rows => rows.length);
return rowCount;
}
/**
* When a table is present on the page,will check the box
* in column 1 of the header row to select all items listed on
* the current table page (could be more than one page full)
*/
async selectAll() {
const page = this.helpers['Puppeteer'].page;
page.waitForSelector('thead tr th:nth-child(1)');
page.click('thead tr th:nth-child(1)');
}
/**
* Checks the box in column 1 for the row containing the value
* passed in (val),where that value exists in column (col)
* @param {string} val The value you are looking for
* @param {number} col Which column the value will be in
*/
async selectRow(val,col) {
const page = this.helpers['Puppeteer'].page;
page.waitForSelector('tbody');
const tableRows = 'tbody tr';
let rowCount = await page.$$eval(tableRows,rows => rows.length);
for (let i = 0; i < rowCount; i++) {
const str = await page.$eval(
`${tableRows}:nth-child(${i + 1}) td:nth-child(${col})`,(e) => e.innerText
)
if (str === val) {
await page.waitForSelector(`${tableRows}:nth-child(${i + 1}) td:nth-child(1)`);
await page.click(`${tableRows}:nth-child(${i + 1}) td:nth-child(1)`);
break;
}
}
}
/**
* Will iterate through all rows displayed in the table and check the box
* in column 1 for each row where the value in colum (col) matches.
* @param {string} val The value passed in to look for
* @param {number} col The column to find the value in
*/
async selectAllRows(val,(e) => e.innerText
)
if (str.includes(val)) {
await page.waitForSelector(`${tableRows}:nth-child(${i + 1}) td:nth-child(1)`);
await page.click(`${tableRows}:nth-child(${i + 1}) td:nth-child(1)`);
continue;
}
}
}
/**
* Locates the row containing the value passed in,in the
* specified column (col)
* @param {string} val Value passed in to look for in each row
* @param {number} col The column to look for the value in
*/
async editRow(val,(e) => e.innerText
)
if (str === val) {
await page.waitForSelector(`${tableRows}:nth-child(${i + 1}) td:nth-child(1)`);
await page.click(`${tableRows}:nth-child(${i + 1}) td:nth-child(${col})`);
break;
}
}
}
}
module.exports = Table;