Reputation: 21
I am switching over my typescript code in protractor to use async / await and I have a verifyRow method which I cannot seem to get working without .then promises
Tried using await inside browser.wait and also tried adding new Promise inside browser.wait which calls an asycn method
findRowByMultipleCellText is defined as an async method which return a number (ie rowIndex)
async verifyRow(columns: string[], values: string[], shouldFind = true, timeout = 60, refresh = false) {
let results: boolean = false;
const columnValueString: string = this.generateColumnValuesPrintString(columns, values);
// Wait for the row to exist based on shouldFind
// let rowIndex: number;
await this.driver.wait(() => {
return new Promise(resolve => {
this.findRowByMultipleCellText(columns, values).then((rowIndex: number) => {
if (rowIndex >= 0 && shouldFind === true) {
results = true;
logger.debug('Row EXISTS in the grid: \n' + columnValueString);
} else if (rowIndex <= -1 && shouldFind === false) {
results = true;
logger.debug("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
if (refresh === true) {
logger.info('Refreshing the vsphere web client main page');
new VClientMainPage().refreshButton.click();
}
}
});
resolve(results);
});
// return results;
}, timeout * 1000);
if (results === false) {
if (shouldFind === true) {
throw new Error("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
throw new Error('Row EXIST in the grid: \n' + columnValueString);
}
}
}
I a have also tried this but an error exists in await this.find for await can only be called in async functions
await this.driver.wait(() => {
let rowIndex: number = await this.findRowByMultipleCellText(columns, values);
if (rowIndex >= 0 && shouldFind === true) {
results = true;
logger.debug('Row EXISTS in the grid: \n' + columnValueString);
} else if (rowIndex <= -1 && shouldFind === false) {
results = true;
logger.debug("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
if (refresh === true) {
logger.info('Refreshing the vsphere web client main page');
new VClientMainPage().refreshButton.click();
}
}
}, timeout * 1000);
if (results === false) {
if (shouldFind === true) {
throw new Error("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
throw new Error('Row EXIST in the grid: \n' + columnValueString);
}
}
I need findRowByMultipleCellTest to return an number which it does if i call it outside of the wait loop.. IF it's >= 0 we break out of the loop.
Whats happening is when i have the code in new Promise it calls this.find but it never gets to the point where it returns a value .. almost like that code is getting push to the end of the stack so i never break out
Upvotes: 2
Views: 188
Reputation: 13712
Option 1) Use Promise
in browser.wait()
, you should call resolve(results)
inside promise.then()
, rather than outside of it.
async verifyRow(columns: string[], values: string[], shouldFind = true, timeout = 60, refresh = false) {
let results: boolean = false;
const columnValueString: string = this.generateColumnValuesPrintString(columns, values);
// Wait for the row to exist based on shouldFind
// let rowIndex: number;
await this.driver.wait(() => {
return new Promise(resolve => {
this.findRowByMultipleCellText(columns, values).then((rowIndex: number) => {
if (rowIndex >= 0 && shouldFind === true) {
results = true;
logger.debug('Row EXISTS in the grid: \n' + columnValueString);
} else if (rowIndex <= -1 && shouldFind === false) {
results = true;
logger.debug("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
if (refresh === true) {
logger.info('Refreshing the vsphere web client main page');
new VClientMainPage().refreshButton.click();
}
}
resolve(results);
// you should call resolve(..) inside then(),
// otherwise resolve() is executed prior to
// the completion of findRowByMultipleCellText()'s async execution.
});
});
// return results;
}, timeout * 1000);
if (results === false) {
if (shouldFind === true) {
throw new Error("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
throw new Error('Row EXIST in the grid: \n' + columnValueString);
}
}
}
Option 2) Only use async/await
enable code concise.
async verifyRow(columns: string[], values: string[], shouldFind = true, timeout = 60, refresh = false) {
let results: boolean = false;
const columnValueString: string = this.generateColumnValuesPrintString(columns, values);
// Wait for the row to exist based on shouldFind
// let rowIndex: number;
await this.driver.wait(() => {
await rowIndex: number = this.findRowByMultipleCellText(columns, values);
if (rowIndex >= 0 && shouldFind === true) {
results = true;
logger.debug('Row EXISTS in the grid: \n' + columnValueString);
} else if (rowIndex <= -1 && shouldFind === false) {
results = true;
logger.debug("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
if (refresh === true) {
logger.info('Refreshing the vsphere web client main page');
await new VClientMainPage().refreshButton.click();
// Add await ahead of above click() too.
}
}
return results;
}, timeout * 1000);
if (results === false) {
if (shouldFind === true) {
throw new Error("Row DOESN'T exist in the grid: \n" + columnValueString);
} else {
throw new Error('Row EXIST in the grid: \n' + columnValueString);
}
}
}
Upvotes: 0