takeaway() is called in Tabulator, but is not shown in Tabulator. Tabulator throws a "[object promise]" message instead of showing the number of the variable number. How can this code be changed to show the number in Tabulator instead of the "[object promise]"? Tabulator of Olifolkerd. Tabulator probably only accepts sync (not async).
function Restaurant() {
return fetchOrders("/orders/" + orderID()").then(result => {
menuNumber = result.data["menuNumber"];
console.log("menuNumber = ", menuNumber);
});
}
async function takeaway() {
let number = await Restaurant();
console.log("number = ", number);
return number;
}
Related
I am using BDD/Cucumber with Cypress. I want to calculate the sum of some rows of table.
This is my step definition:
And("I add up all the total on hand",()=>{
const sumOnHand = itemListPage.totalOnHandAmsterdam()+itemListPage.totalOnHandDelft()
cy.log(sumOnHand)
})
And this is my js page:
totalOnHandAmsterdam() {
cy.get(':nth-child(2) > .dx-grandtotal > span').invoke('text').then(text =>{
const ttOnHandAmst = text
return ttOnHandAmst;
})
}
totalOnHandDelft() {
cy.get(':nth-child(11) > .dx-grandtotal > span').invoke('text').then(text =>{
const ttOnHandDelft = text
return ttOnHandDelft;
})
}
But this is the output of the calculation:
Any ideas on how can I sum up this value is appreciated.
You can't use the results of totalOnHandAmsterdam() and totalOnHandDelft() directly in a summation because
they don't return anything (the return inside .then(text => does not return the value from the function).
Cypress commands don't return values, they add the values to the command queue
You can do it like this
totalOnHandAmsterdam() {
return cy.get(':nth-child(2) > .dx-grandtotal > span')
.invoke('text').then(parseInt)
}
totalOnHandDelft() {
return cy.get(':nth-child(11) > .dx-grandtotal > span')
.invoke('text').then(parseInt)
}
And("I add up all the total on hand", () => {
itemListPage.totalOnHandAmsterdam().then(ams => // get value on command queue
itemListPage.totalOnHandDelft().then(delft => // get other value
const sumOnHand = ams + delft;
cy.log(sumOnHand)
})
})
})
The key to accessing command return values is using .then() after the command.
It's annoying but necessary because Cypress ensures that the web page has received data from the server before evaluating the element text.
Since the test runs faster than web page fetches data, it can easily evaluate the text before the page is fully populated.
You have to convert your texts to numbers and then add it. You can simply add + in front of the number to convert them into Integers. Also I have added trim() in case your strings have any unwanted spaces.
And('I add up all the total on hand', () => {
const sumOnHand =
+itemListPage.totalOnHandAmsterdam().trim() + +itemListPage.totalOnHandDelft().trim()
cy.log(sumOnHand)
})
You could set the function results as aliases.
Since the code is asynchronous, access it within cy.then().
totalOnHandAmsterdam() {
cy.get(':nth-child(2) > .dx-grandtotal > span')
.invoke('text')
.then(parseInt)
.as('amsterdamTotal') // alias will set this.amsterdamTotal
}
totalOnHandDelft() {
return cy.get(':nth-child(11) > .dx-grandtotal > span')
.invoke('text')
.then(parseInt)
.as('defltTotal') // alias will set this.delftTotal
}
And("I add up all the total on hand", function() { // use function() to access "this"
po.totalOnHandAmsterdam()
po.totalOnHandDelft()
cy.then(() => {
const sumOnHand = this.amsterdamTotal + this.defltTotal;
cy.log(sumOnHand)
})
})
below is one piece of code where i have to compare one object stored value (i.e 'resort') with the value compare that value what i am getting from the JSON file .
code -
resort = _.find(this.resorts.entries, (o) => {
return o.gqe_name === resort;
})
;
i have tried to get the value but the it is displaying as [Object,Object ] , tried with console .log('resort'+ resort) and log.info ('resort'+ resort).
is there any way i can view the return value ?
how i can print json stored value 'o.gqe_name' ?
JSON.stringify can help
const object = { test: { test2: 'value' } }
const result = JSON.stringify(object)
const result2 = JSON.stringify(object, null, 2)
console.log(result)
console.log(result2)
My scenario is to add a section in a page and perform an action on it.But as there are elements with the same xpath already, webdriver is clicking on first element and the script is failing.So, I want to fetch the existing number of elements having the same xpath and then increase the count by 1 so as to click on the newly added section. Please find the below code and correct me where it is going wrong.(Or) Suggest me any other approach.
Also, please let me know will line no. 9 works if getting the number of elements issue is resolved. Thanks!
Method :
this.getElementCount=async function(locator) {
try {
console.info('Verifying count for element ' + locator);
let noOfElements = await element.all(locator).count();
await console.info('There are ' + noOfElements + 'elements in UI');
return noOfElements;
} catch(err) {
throw err;
}
}
Calling method :
var compLocator = element(by.xpath("//div[#title='Test']"));
this.clickOnComp=async function(){
var elementsCount=getElementCount(compLocator);
console.info("No. of elements : "+elementsCount);
if(elementsCount>1){
var currentEle=elementsCount+1;
var currentCompLocator=compLocator[currentEle]; // line no.9
console.info("comp locator :" +currentCompLocator);
await clickElement(currentCompLocator);
console.info("Clicked : "+currentCompLocator);
}
else{
await clickElement(compLocator);
}
}
Output :
Verifying count for element [object Object]
No. of elements : [object Promise]
(node:13915) UnhandledPromiseRejectionWarning: TypeError: Invalid locator
Start with resolving promise with await
var compLocator = element(by.xpath("//div[#title='Test']"));
this.clickOnComp=async function(){
var elementsCount=await getElementCount(compLocator); // <-----------------
console.info("No. of elements : "+elementsCount);
if(elementsCount>1){
var currentEle=elementsCount+1;
var currentCompLocator=compLocator[currentEle]; // line no.9
console.info("comp locator :" +currentCompLocator);
await clickElement(currentCompLocator);
console.info("Clicked : "+currentCompLocator);
}
else{
await clickElement(compLocator);
}
}
There are two issues in your code:
getElementCount() expects a locator argument by you give a element
(Line 9) compLocator is an element not an xpath or an element array, you can't use compLocator[currentEle]
var compXPath = "//div[#title='Test']"
var compLocator = by.xpath(compXPath);
this.clickOnComp=async function(){
var elementsCount = await getElementCount(compLocator);
console.info("No. of elements : "+elementsCount);
if(elementsCount > 1){
var currentEle = elementsCount+1;
var currentCompXPath = compXPath + "/["+ currentEle +"]" // line no.9
console.info("current Comp xpath :" +currentCompXPath);
var currentCompLocator = by.xpath(currentCompXPath)
await clickElement(currentCompLocator);
console.info("Clicked : "+currentCompLocator);
}
else{
await clickElement(compLocator);
}
}
static async getInitialProps() {
const campaigns = await factory.methods.getDeployedCampaigns().call();
const campaign = Campaign(campaigns[0]);//call the contract to be able to use the methods inside the campaign
const summary = await campaign.methods.getSummary().call();
return { campaigns,summary };//campaigns is given to campaignIndex as an object
}
renderCampaigns() {
const items = this.props.campaigns.map(address => {
return {
header: this.props.summary[7] ,
description:(
<Segment >
<Progress percent={this.props.summary[1]/this.props.summary[6]} attached='bottom' success/>
<Card.Content description = {'balance: '+ web3.utils.fromWei(this.props.summary[1], 'ether') + ' ' + 'ether'} textAlign='right'/>
</Segment>
),
extra:(
<Link route={`/campaigns/${address}`}>
<a>View Campaign</a>
</Link>
),
fluid: true,//card takes width of the container
//percentage goal of the event),
link: true,
meta:(
<Segment>
<Card.Content header ={'Description: '+ this.props.summary[5]} textAlign='left'/>
<Card.Content description = {'Goal: '+ this.props.summary[6] +' wei'} textAlign='left'/>
</Segment>
)
};
});
So my problem is that I want to go through an array of string provided by campaigns and pass each string to my function campaign and just after that be able to call the methods found in the class campaign through summary. Since summary is an await function my loop needs to be an async loop.I have tried to
create an array of objects in which in the mapping of the string I push all the data from my summary array in it but I get an out of scope error from which it says that my mapping is not async.Snippet of my actual code I just want to get an idea how to create an async function in which I can map all the strings from campaigns in it get my data from summary and return an array of data to render below
Having trouble debugging an issue that mockgoose has for populating a property with fields set. Yads mockgoose http://github.com/yads/Mockgoose fork solved the bug of making the populate option work, but if you specify fields it returns a null for the populated property. I tried looking through the source code and stepping through with the debugger but not sure where to look. I can see in the debugger that the populate option triggers a call to get the child element - and I see the call made returns the right child result with the correct fields, but when the parent element finally comes back it has the property to the child element set to null.
The query:
Posts.findById(foo).populate('createdBy', {fname:1, lname:1});
Incorrectly returns a post with post.createdBy = null. Omitting the fields parameter of fame, lname, somehow makes it work again with post.createdBy returning the full object.
Following are some excerpts from the code - though I'm not sure those are the right places to look.
collections.js
this.find = function (conditions, options, callback) {
var results;
var models = db[name];
if (!_.isEmpty(conditions)) {
results = utils.findModelQuery(models, conditions);
} else {
results = utils.objectToArray(utils.cloneItems(models));
}
results = filter.applyOptions(options, results);
if (results.name === 'MongoError') {
callback(results);
} else {
var result = {
toArray: function (callback) {
callback(null, results);
}
};
callback(null, result);
}
};
util.js
function cloneItems(items) {
var clones = {};
for (var item in items) {
clones[item] = cloneItem(items[item]);
}
return clones;
}
function cloneItem(item) {
return _.cloneDeep(item, function(value) {
// Do not clone items that are ObjectId objects as _.clone mangles them
if (value instanceof ObjectId) {
return new ObjectId(value.toString());
}
});
}
And here's a conversation about the issue
https://github.com/mccormicka/Mockgoose/pull/90