I am new to Cypress (and naive to JS). I would like to write a JS library as a wrapper to 3rd party APIs. I write the API wrapper as an individual file (instead of using Cypress Custom functions) because I believe I can share the library with teams NOT using Cypress E2E tool.
The problem I am facing is “I cannot let my code to be executed sequentially in order”
From the result, I can see:
- the data didn’t return successfully
- it looks like the “getTestPlanIdByName:20974” were executed last, but I expect it should be executed before “line 01b testPlanId:{}”
I need to help to know the correct way to handle the flow sequentially in Cypress/Javascript, thanks.
API Library(api-util.js)
let axios = require('axios'); const proxy = "http://10.8.8.8:8080/"; const apiPatToken = 'OmdrvbvvvvvvvvWZqa2E=' let proxyAgentHttps = require('https-proxy-agent'); let proxyAgentHttp = require('http-proxy-agent'); let agentHttps = new proxyAgentHttps(proxy); let agentHttp = new proxyAgentHttp(proxy); let config = { baseURL: 'https://dev.3rdparty.com/mycompany/myaccount/_apis', url: 'DUMMY_INJECTED_LATER', httpsAgent: agentHttps, httpAgent: agentHttp, proxy:false, headers: { 'Authorization': `Basic ${apiPatToken}` } } export async function getTestPlanIdByName(testplan_name){ config.url = '/test/plans?api-version=5.0' let found = '' axios.request(config).then( resp => { found = resp.data.value.find(function(item, index, array){ return item.name === testplan_name }) }) .then(() => { console.log("getTestPlanIdByName:"+found.id) return found.id }) .catch(err => console.log(err)) }
My Cypress code
import * as UTIL from 'api-util.js' describe('CI-', () => { let testPlanId = 'none' it('01 Get TestPlanID', () => { //use cy.log() get a Promise for flow control cy.log() .then(() => { new Cypress.Promise((resolve, reject) => { console.log("01a testPlanId:"+JSON.stringify(testPlanId)) testPlanId = UTIL.getTestPlanIdByName("TESTPLAN-Regression") console.log("01b testPlanId:"+JSON.stringify(testPlanId)) }) }) .then(() => { console.log("01c testPlanId:"+JSON.stringify(testPlanId)) }) }); it('02 Get TestSuitesList', () => { console.log("02 testPlanId:"+testPlanId) // UTIL.getTestSuitesIdList(testPlanId) }); });
Advertisement
Answer
Thank you all. Cypress flow isn’t 100% compatible with standard JS Promise (Wait for an own function (which returns a promise) before tests are executed). After relentless testings, I decided to use a Cypress Custom Command wrapper to wrap my in-house JS library. Though adding an extra layer may seem a little cumbersome. But I am satisfied with the result. Share my code here in case anyone might need it. 🙂
Cypress Code
before('Prepare TestPlanId', () => { cy.getTestPlanIdByName(testPlanName) .then((result) => { testPlanId = result console.log("#01_SDET_testplan:Prepare TestPlanId# "+testPlanId) }) });
Cypress Custom Command
Cypress.Commands.add('getTestPlanIdByName', (wk_testplan_name) => { return new Cypress.Promise((resolve, reject) => { TESTPLAN_API.getTestPlanIdByName(wk_testplan_name) .then(function (data) { resolve(data); }) }); })
In-house JS library
export async function getTestPlanIdByName(wk_testplan_name){ return new Promise((resolve, reject) => { config.method = 'get' config.url = '/test/plans?api-version=5.0' let found = '' axios.request(config).then( resp => { found = resp.data.value.find(function(item, index, array){ return item.name === wk_testplan_name }) }) .then(() => { resolve(found.id) }) .catch(err => console.log(err)) }) }