使用量角器编写端到端测试相对较新。在兑现承诺方面也相对缺乏经验。
我正在写一个测试,在某些情况下,我需要遍历代码b / c,我选择的记录不符合某些条件。在这些情况下,我想返回上一步并尝试另一条记录(并继续这样做,直到找到合适的记录)。我无法通过测试进入我的循环。
我可以使用Protractor编写常规的e2e测试,但是解决此循环问题非常困难。我知道一定是因为我正在处理Promises,但未正确处理它们。尽管我看到了循环量角器代码的示例,但它们通常涉及需要对列表中的每个项目执行的单个方法。在这里,我需要执行多个步骤才能到达可以找到并设置我的值以突破循环的地步。
以下是我尝试解决的一些线程:
我当前的代码:
it('should select a customer who has a valid serial number', () => {
const products = new HomePage();
let serialIsValid: boolean = false;
let selectedElement, serialNumber, product, recordCount, recordList;
recordList = element.all(by.css(`mat-list.desco-list`));
recordList.then((records) => {
recordCount = records.length;
console.log('records', records.length, 'recordCount', recordCount);
}
);
for (let i = 0; i < recordCount; i++) {
if (serialIsValid === false) {
const j = i + 1;
products.btnFormsSelector.click();
products.formSelectorRepossession.click();
browser.wait(EC.visibilityOf(products.itemSearch));
products.itemSearch.element(by.tagName('input')).sendKeys(browser.params.search_string);
products.itemSearch.element(by.id('btnSearch')).click();
browser.wait(EC.visibilityOf(products.itemSearch.element(by.id('list-container'))));
selectedElement = element(by.tagName(`#itemSearch mat-list:nth-child(${{j}})`));
selectedElement.click();
browser.wait(EC.visibilityOf(products.doStuffForm));
browser.sleep(1000);
element(by.css('#successful mat-radio-button:nth-child(1) label')).click();
browser.sleep(1000);
expect(element(by.css('.itemDetailsContainer'))).toBeTruthy();
product = products.productIDNumber.getText();
product.then((item) => {
serialNumber = item;
if (item !== 'Unknown') {
expect(serialNumber).not.toContain('Unknown');
serialIsValid = true;
} else {
i++
}
})
} else {
console.log('serial is valid: ' + serialIsValid);
expect(serialNumber).not.toContain('Unknown');
break;
}
}
console.log('serial number validity: ', serialIsValid);
})
我已经多次重写和重组我的代码,包括尝试将我的代码分解为将相关步骤组合在一起的函数(如上述线程之一所建议,然后尝试将它们链接在一起,如下所示:< / p>
findValidCustomer() {
const gotoProductSearch = (function () {...})
const searchForRecord = (function () {...})
const populateForm = (function (j) {...})
for (let i = 0; i < recordCount; i++) {
const j = i + 1;
if (serialIsValid === false) {
gotoProductSearch
.then(searchForRecord)
.then(populateForm(j))
.then(findValidSerial(i))
} else {
console.log('serial number validity' + serialIsValid);
expect(serialIsValid).not.toContain('Unknown');
break;
}
}
console.log('serial number validity' + serialIsValid);
}
当我尝试像这样将它们链接时,我收到此错误 -TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'
如果我在这样做时出错了,请从我的实际测试和道歉中编辑我的代码。总的来说,将不胜感激关于如何执行此操作的评论或解释,b / c我知道我没有正确执行此操作。提前致谢。
答案 0 :(得分:0)
我建议调查异步/等待并迁移此测试。为什么要迁移?量角器6和前进将需要异步/等待。为此,您需要在配置中加入SELENIUM_PROMISE_MANAGER: false
并等待诺言。在下面的答案中,我将使用async / await。
下面是我尝试将其重写为async / await。还可以在需要时尝试定义ElementFinder,数字和其他内容,以便将它们定义为const。
it('should select a customer who has a valid serial number', async () => {
const products = new HomePage();
let serialIsValid = false; // Setting the value to false is enough
// and :boolean is not needed
const recordList = element.all(by.css(`mat-list.desco-list`));
const recordCount = await recordList.count();
console.log(`recordCount ${recordCount}`);
// This could be rewritten with .each
// See https://github.com/angular/protractor/blob/master/lib/element.ts#L575
// await recordList.each(async (el: WebElement, index: number) => {
for (let i = 0; i < recordCount; i++) {
if (serialIsValid === false) {
const j = index + 1; // Not sure what j is being used for...
await products.btnFormsSelector.click();
await products.formSelectorRepossession.click();
await browser.wait(EC.visibilityOf(products.itemSearch));
await products.itemSearch.element(by.tagName('input'))
.sendKeys(browser.params.search_string);
await products.itemSearch.element(by.id('btnSearch')).click();
await browser.wait(
EC.visibilityOf(await products.itemSearch.element(
by.id('list-container')))); // Maybe use a boolean check?
const selectedElement = element(by.tagName(
`#itemSearch mat-list:nth-child(${{j}})`));
await selectedElement.click();
// not sure what doStuffForm is but I'm guessing it returns a promise.
await browser.wait(EC.visibilityOf(await products.doStuffForm));
await browser.sleep(1000); // I would avoid sleeps since this might
// cause errors (if ran on a slower machine)
// or just cause your test to run slow
await element(by.css(
'#successful mat-radio-button:nth-child(1) label')).click();
await browser.sleep(1000);
expect(await element(by.css('.itemDetailsContainer'))).toBeTruthy();
const serialNumber = await products.productIDNumber.getText();
if (item !== 'Unknown') {
expect(serialNumber).not.toContain('Unknown');
serialIsValid = true;
}
// The else statement if you were using i in a for loop, it is not
// a good idea to increment it twice.
} else {
// So according to this, if the last item is invalid, you will not break
// and not log this. This will not fail the test. It might be a good idea
// to not have this in an else statement.
console.log(`serial is valid: ${serialIsValid}`);
expect(serialNumber).not.toContain('Unknown');
break;
}
}
console.log('serial number validity: ', serialIsValid);
});
答案 1 :(得分:0)
按照代码段更新代码后,您可以再次检查计数吗?
element.all(by.css(`mat-list.desco-list`)).then(function(records) => {
recordCount = records.length;
console.log(recordCount);
});
OR
ElementArrayFinder类中有count()函数,可返回带有定位符计数的promise
element.all(by.css(`mat-list.desco-list`)).then(function(records) => {
records.count().then(number => {
console.log(number); })
});