Javascript Cypress:Cypress自定义命令';s的返回值在测试文件中实际返回null
我创建了一个Cypress自定义命令,该命令使用console.log显示值(因此我知道它可以工作)。但是,当我在Cypress测试文件中调用自定义命令时,它返回blank/null support/commands.js:Javascript Cypress:Cypress自定义命令';s的返回值在测试文件中实际返回null,javascript,amazon-dynamodb,cypress,aws-sdk-js,Javascript,Amazon Dynamodb,Cypress,Aws Sdk Js,我创建了一个Cypress自定义命令,该命令使用console.log显示值(因此我知道它可以工作)。但是,当我在Cypress测试文件中调用自定义命令时,它返回blank/null support/commands.js: Cypress.Commands.add('scanAWSDb', (siteId) => { let siteName = null //default it to null ... some AWS SDK function which scans the D
Cypress.Commands.add('scanAWSDb', (siteId) => {
let siteName = null //default it to null
... some AWS SDK function which scans the DB and check for corresponding Name of the ID: 12345 ...
siteName = <new value>
console.log("Value returned is: " + siteName //This displays the value in the web console for the corresponding ID: 12345, let's say name is Taylor
return siteName //Expected to return "Taylor" in the test file
})
describe('Display value from the Custom command that scanned the AWS DB', ()=> {
it('Display value from the Custom command that scanned the AWS DB', () => {
const siteId = "12345"
cy.scanAWSDb(siteId)
.then((returned_value) => {
cy.log(returned_value) //This displays a null value so it is not picking up the return value from the custom command which is supposedly Taylor
})
})
})
const tableName = 'table1';
let recordId = '';
cy.scanDB(tableName, recordId, $returnValue => {
cy.log($returnValue) //<-- THIS DISPLAYS THE OBJECT BUT I NEED TO CONVERT IT TO STRING SO I CAN DO ASSERTION like this:
//expect($returnValue).to.eq(recordId)
})
const AWS = require('aws-sdk')
const region = Cypress.env('aws_region')
const accessKeyId = Cypress.env('aws_access_key_id')
const secretAccessKey = Cypress.env('aws_secret_access_key')
const sessionToken = Cypress.env('aws_session_token')
let scannedRecordId = ''
AWS.config.update({region: region})
AWS.config.credentials = new AWS.Credentials(accessKeyId, secretAccessKey, sessionToken)
const docClient = new AWS.DynamoDB.DocumentClient();
export const scanTable = async (tableName, recordId) => {
const params = {
TableName: tableName,
FilterExpression: '#Id = :RecordId',
ExpressionAttributeNames: {
'#Id': 'RecordId',
},
ExpressionAttributeValues: {
':RecordId': recordId // Check if Id is stored in DB
}
};
let scanResults = [];
let items
let index = 0
do{
items = await docClient.scan(params).promise()
items.Items.forEach((item) => scanResults.push(item))
params.ExclusiveStartKey = items.LastEvaluatedKey
scannedRecordId = JSON.stringify(items.Items[index].Id)
cy.log('Record successfully found in table: ' + scannedRecordId)
index += 1 // This may not be required as the assumption is that only a unique record is found
}while(typeof items.LastEvaluatedKey != "undefined")
return scannedRecordId;
};
Cypress.Commands.add('scanDB', (tableName, recordId, cb) => {
const record = scanTable(tableName, recordId)
cb(record) // Callback function
// const record = scanTable(tableName, recordId).then(record => { cb(record) }) //This does not work and returns a console error
})
const tableName = 'random-dynamodb-table'
let myId = '12345'
it('Verify if ID is stored in AWS DynamoDB', () => {
cy.scanDB(tableName, myId, $returnValue => {
cy.log($returnValue)
cy.log(`Record ID: ${myId} is found in table: ` + $returnValue)
expect($returnValue).to.deep.eq(myId) //This asserts that the Id is found
})
})
===
更新:
Cypress.Commands.add('scanAWSDb', (siteId) => {
let siteName = null //default it to null
... some AWS SDK function which scans the DB and check for corresponding Name of the ID: 12345 ...
siteName = <new value>
console.log("Value returned is: " + siteName //This displays the value in the web console for the corresponding ID: 12345, let's say name is Taylor
return siteName //Expected to return "Taylor" in the test file
})
describe('Display value from the Custom command that scanned the AWS DB', ()=> {
it('Display value from the Custom command that scanned the AWS DB', () => {
const siteId = "12345"
cy.scanAWSDb(siteId)
.then((returned_value) => {
cy.log(returned_value) //This displays a null value so it is not picking up the return value from the custom command which is supposedly Taylor
})
})
})
const tableName = 'table1';
let recordId = '';
cy.scanDB(tableName, recordId, $returnValue => {
cy.log($returnValue) //<-- THIS DISPLAYS THE OBJECT BUT I NEED TO CONVERT IT TO STRING SO I CAN DO ASSERTION like this:
//expect($returnValue).to.eq(recordId)
})
const AWS = require('aws-sdk')
const region = Cypress.env('aws_region')
const accessKeyId = Cypress.env('aws_access_key_id')
const secretAccessKey = Cypress.env('aws_secret_access_key')
const sessionToken = Cypress.env('aws_session_token')
let scannedRecordId = ''
AWS.config.update({region: region})
AWS.config.credentials = new AWS.Credentials(accessKeyId, secretAccessKey, sessionToken)
const docClient = new AWS.DynamoDB.DocumentClient();
export const scanTable = async (tableName, recordId) => {
const params = {
TableName: tableName,
FilterExpression: '#Id = :RecordId',
ExpressionAttributeNames: {
'#Id': 'RecordId',
},
ExpressionAttributeValues: {
':RecordId': recordId // Check if Id is stored in DB
}
};
let scanResults = [];
let items
let index = 0
do{
items = await docClient.scan(params).promise()
items.Items.forEach((item) => scanResults.push(item))
params.ExclusiveStartKey = items.LastEvaluatedKey
scannedRecordId = JSON.stringify(items.Items[index].Id)
cy.log('Record successfully found in table: ' + scannedRecordId)
index += 1 // This may not be required as the assumption is that only a unique record is found
}while(typeof items.LastEvaluatedKey != "undefined")
return scannedRecordId;
};
Cypress.Commands.add('scanDB', (tableName, recordId, cb) => {
const record = scanTable(tableName, recordId)
cb(record) // Callback function
// const record = scanTable(tableName, recordId).then(record => { cb(record) }) //This does not work and returns a console error
})
const tableName = 'random-dynamodb-table'
let myId = '12345'
it('Verify if ID is stored in AWS DynamoDB', () => {
cy.scanDB(tableName, myId, $returnValue => {
cy.log($returnValue)
cy.log(`Record ID: ${myId} is found in table: ` + $returnValue)
expect($returnValue).to.deep.eq(myId) //This asserts that the Id is found
})
})
这是有效的,但当尝试执行断言时,它不起作用,因为我无法将对象承诺转换为字符串
测试文件:
Cypress.Commands.add('scanAWSDb', (siteId) => {
let siteName = null //default it to null
... some AWS SDK function which scans the DB and check for corresponding Name of the ID: 12345 ...
siteName = <new value>
console.log("Value returned is: " + siteName //This displays the value in the web console for the corresponding ID: 12345, let's say name is Taylor
return siteName //Expected to return "Taylor" in the test file
})
describe('Display value from the Custom command that scanned the AWS DB', ()=> {
it('Display value from the Custom command that scanned the AWS DB', () => {
const siteId = "12345"
cy.scanAWSDb(siteId)
.then((returned_value) => {
cy.log(returned_value) //This displays a null value so it is not picking up the return value from the custom command which is supposedly Taylor
})
})
})
const tableName = 'table1';
let recordId = '';
cy.scanDB(tableName, recordId, $returnValue => {
cy.log($returnValue) //<-- THIS DISPLAYS THE OBJECT BUT I NEED TO CONVERT IT TO STRING SO I CAN DO ASSERTION like this:
//expect($returnValue).to.eq(recordId)
})
const AWS = require('aws-sdk')
const region = Cypress.env('aws_region')
const accessKeyId = Cypress.env('aws_access_key_id')
const secretAccessKey = Cypress.env('aws_secret_access_key')
const sessionToken = Cypress.env('aws_session_token')
let scannedRecordId = ''
AWS.config.update({region: region})
AWS.config.credentials = new AWS.Credentials(accessKeyId, secretAccessKey, sessionToken)
const docClient = new AWS.DynamoDB.DocumentClient();
export const scanTable = async (tableName, recordId) => {
const params = {
TableName: tableName,
FilterExpression: '#Id = :RecordId',
ExpressionAttributeNames: {
'#Id': 'RecordId',
},
ExpressionAttributeValues: {
':RecordId': recordId // Check if Id is stored in DB
}
};
let scanResults = [];
let items
let index = 0
do{
items = await docClient.scan(params).promise()
items.Items.forEach((item) => scanResults.push(item))
params.ExclusiveStartKey = items.LastEvaluatedKey
scannedRecordId = JSON.stringify(items.Items[index].Id)
cy.log('Record successfully found in table: ' + scannedRecordId)
index += 1 // This may not be required as the assumption is that only a unique record is found
}while(typeof items.LastEvaluatedKey != "undefined")
return scannedRecordId;
};
Cypress.Commands.add('scanDB', (tableName, recordId, cb) => {
const record = scanTable(tableName, recordId)
cb(record) // Callback function
// const record = scanTable(tableName, recordId).then(record => { cb(record) }) //This does not work and returns a console error
})
const tableName = 'random-dynamodb-table'
let myId = '12345'
it('Verify if ID is stored in AWS DynamoDB', () => {
cy.scanDB(tableName, myId, $returnValue => {
cy.log($returnValue)
cy.log(`Record ID: ${myId} is found in table: ` + $returnValue)
expect($returnValue).to.deep.eq(myId) //This asserts that the Id is found
})
})
awsTest.js文件:
Cypress.Commands.add('scanAWSDb', (siteId) => {
let siteName = null //default it to null
... some AWS SDK function which scans the DB and check for corresponding Name of the ID: 12345 ...
siteName = <new value>
console.log("Value returned is: " + siteName //This displays the value in the web console for the corresponding ID: 12345, let's say name is Taylor
return siteName //Expected to return "Taylor" in the test file
})
describe('Display value from the Custom command that scanned the AWS DB', ()=> {
it('Display value from the Custom command that scanned the AWS DB', () => {
const siteId = "12345"
cy.scanAWSDb(siteId)
.then((returned_value) => {
cy.log(returned_value) //This displays a null value so it is not picking up the return value from the custom command which is supposedly Taylor
})
})
})
const tableName = 'table1';
let recordId = '';
cy.scanDB(tableName, recordId, $returnValue => {
cy.log($returnValue) //<-- THIS DISPLAYS THE OBJECT BUT I NEED TO CONVERT IT TO STRING SO I CAN DO ASSERTION like this:
//expect($returnValue).to.eq(recordId)
})
const AWS = require('aws-sdk')
const region = Cypress.env('aws_region')
const accessKeyId = Cypress.env('aws_access_key_id')
const secretAccessKey = Cypress.env('aws_secret_access_key')
const sessionToken = Cypress.env('aws_session_token')
let scannedRecordId = ''
AWS.config.update({region: region})
AWS.config.credentials = new AWS.Credentials(accessKeyId, secretAccessKey, sessionToken)
const docClient = new AWS.DynamoDB.DocumentClient();
export const scanTable = async (tableName, recordId) => {
const params = {
TableName: tableName,
FilterExpression: '#Id = :RecordId',
ExpressionAttributeNames: {
'#Id': 'RecordId',
},
ExpressionAttributeValues: {
':RecordId': recordId // Check if Id is stored in DB
}
};
let scanResults = [];
let items
let index = 0
do{
items = await docClient.scan(params).promise()
items.Items.forEach((item) => scanResults.push(item))
params.ExclusiveStartKey = items.LastEvaluatedKey
scannedRecordId = JSON.stringify(items.Items[index].Id)
cy.log('Record successfully found in table: ' + scannedRecordId)
index += 1 // This may not be required as the assumption is that only a unique record is found
}while(typeof items.LastEvaluatedKey != "undefined")
return scannedRecordId;
};
Cypress.Commands.add('scanDB', (tableName, recordId, cb) => {
const record = scanTable(tableName, recordId)
cb(record) // Callback function
// const record = scanTable(tableName, recordId).then(record => { cb(record) }) //This does not work and returns a console error
})
const tableName = 'random-dynamodb-table'
let myId = '12345'
it('Verify if ID is stored in AWS DynamoDB', () => {
cy.scanDB(tableName, myId, $returnValue => {
cy.log($returnValue)
cy.log(`Record ID: ${myId} is found in table: ` + $returnValue)
expect($returnValue).to.deep.eq(myId) //This asserts that the Id is found
})
})
如果此
AWS
函数是异步的,您应该像promise那样处理它,因此:
let siteName = null //default it to null
... some AWS SDK function which scans the DB and check for corresponding Name of the ID: 12345 ...
siteName = <new value>
此外,如果在测试中您只需要读取该值,您可以使用回调而不是承诺:例如
Cypress.Commands.add('scanAWSDb', (siteId, cb) => {
AWSFunction().then((newValue) => {
cb(newValue);
})
})
// test
cy.scanAWSDb(siteId, (returned_value) => {
cy.log(returned_value)
});
- 更新:
wrap
和invoke
cypress方法:
scan
函数是异步的,所以您必须这样调用它:
Cypress.Commands.add('scanDB', (tableName, recordId, cb) => {
const record = scanTable(tableName, recordId).then(record => { cb(record) };
})
这个AWS函数是同步的还是异步的?它基于AWS Javascript SDK,所以我假设它是异步的。无论如何,Cypress团队也提供了一个基于此的示例。谢谢你。但是我不能让它工作。我得到未定义的“无法读取属性项”。基本上,我正在尝试调用DynamoDB并使用这里的解决方案返回一个值:。我在我的帖子上提供了一个更新(请参阅更新部分),但我觉得我所做的代码过于结构化。如果你能看一看,那就太好了。我无法在Cypress测试中将对象承诺转换为字符串。由于某些原因,我无法让
等待
或。然后
工作我添加了更新部分,请让我知道这是否有帮助感谢您在这方面花费的时间。但是,上面的const-record=scanTable(tableName,recordId)。然后(record=>{cb(record)
不起作用。我在控制台上得到错误:Uncaught(in-promise)TypeError:无法读取在_callee$
处未定义的属性'recordId',不尝试使用勺子,但我在Cypress上尝试了各种可能性。按照文档进行承诺、包装和调用,但此异步正在进行中。我需要更多详细信息来解决此问题,完整堆栈跟踪将非常有用。