问题
I want to use one variable in two different functions. More precisely I want to get a number (as a string) of a label and set it into an input field. Afterwards I check another label for the right (resulted) text.
I have written two functions that are working correctly (executed separately) but I want to use the value (stored in a variable) of the first function within the second function.
So I have tried to put the functions together but then cypress doesn't find the given csspath '#sQuantity' because cypress points to (an other scope) the element within the table and my element doesn't belong to the table. The given value of the variable 'txtAmountColumn' of the first function is used in the second function for some calculations.
let txtAmountColumn
let txtPackPriceColumn
let txtDiscountColumn
it('get some values', function() {
//go to page
cy.loadpage(txtUrl)
//find product box
cy.get('.ProductSelectionBox table').within(($scaleTable) => {
//find table of scaled discount
cy.get('tbody > tr').eq(1).within((rowTable) => {
//get second row of table
let txtRowTable = rowTable.text()
//get first column (amount) of row
cy.get('td').eq(0).then((lineOfTable) => {
let txtValueOfFirstColumn = lineOfTable.text()
txtAmountColumn = txtValueOfFirstColumn.match(/\d{1,}/)[0]
cy.log(txtAmountColumn)
})
//get second column (price of pack price) of row
cy.get('td').eq(1).then((lineOfTable) => {
let txtValueOfSecondColumn = lineOfTable.text()
txtPackPriceColumn = txtValueOfSecondColumn.match(/[0-9]*,[0-9]*/)[0]
cy.log(txtPackPriceColumn)
})
//get third column (discount in percentage) of row
cy.get('td').eq(2).then((lineOfTable) => {
let txtValueOfThirdColumn = lineOfTable.text()
txtDiscountColumn = txtValueOfThirdColumn.match(/\d{1,}/)[0]
cy.log(txtDiscountColumn)
})
})
})
})
// ToDo: integrate this function within previous function because I need a dynamic value for txtAmount
it('calculate the price', function() {
let txtAmount = 10 //replace this hardcoded value with the determined value of txtAmountColumn
let txtPackPriceColumn = 9.99
//go to the sale
cy.loadpage(txtUrl)
//set amount of products
cy.get('#sQuantity').type(txtAmount).then(() =>{
cy.get('.MainProductCalculatedPriceOverview').then((labelPrice) => {
let txtPrice = labelPrice.text()
//calculate expected price
let calculatedPrice = txtAmount * txtPackPriceColumn
//calculate expected VAT
let calculatedVat = Math.round((calculatedPrice * 1.19)*100)/100
})
})
})
If I put them together
<p>CypressError: cy.type() can only accept a String or Number. You passed in: 'undefined'</p>
How can I use 'txtAmounColumn' for my calculation(in both functions)?
回答1:
State can be easily passed between test cases (it blocks) because the callbacks are invoked serially, one at a time. Thus, a variable set in the first test case will be defined by the time the second test case runs:
let value;
describe('test', () => {
it('one', () => {
cy.document().then(doc => {
doc.body.innerHTML = '<div class="test">42</div>';
});
cy.get('.test').invoke('text').then( val => {
value = val;
});
});
it('two', () => {
cy.document().then(doc => {
doc.body.innerHTML = '<input class="test">';
});
cy.get('.test').type(value)
.invoke('val').should('eq', '42');
});
});
If, on the other hand, you're trying to reuse a variable within a single test case, then you can do so like this:
describe('test', () => {
it('test', () => {
cy.document().then(doc => {
doc.body.innerHTML = `
<div class="test1">42</div>
<input class="test2">
`;
});
let value;
cy.get('.test1').invoke('text').then( val => {
value = val;
});
cy.then(() => {
// note that these commands could have been nested into the `then`
// callback above, directly, without needing to cache the variable
// at all
cy.get('.test2').type(value)
.invoke('val').should('eq', '42');
});
});
});
See my older answer elaborating on this pattern.
来源:https://stackoverflow.com/questions/58627067/cypress-use-a-variable-in-several-functions