Hello Everyone,
I have a case where I am unable to use async in the step definitions.
I have a simple scenario where in am logging in through the api interface of my application to fetch auth token
My feature file is:
Feature: Login
Scenario: Login using api
Given I login to my account with my username and password
Then I should get an authorization token
|username|password|
|[email protected]|dev|
my steps are :
defineSupportCode(({ Given, Then, setDefaultTimeout }) => {
const timeOut = 30000;
const baseSteps: BaseSteps = new BaseSteps();
setDefaultTimeout(timeOut);
// tslint:disable-next-line:only-arrow-functions
Given(/^I login to my account with my username and password$/, async (table: TableDefinition) => {
const userData = table.hashes();
const loginResponse = await baseSteps.loginUser(userData[0].username, userData[0].password);
console.log('Login response is ', loginResponse);
const statusCode = 302;
expect(await loginResponse.status).to.equal(statusCode);
});
Then(/^I should get an authorization token$/, async () => {
const authorizationHeader = await baseSteps.getAuthorizationHeader();
console.log('Auth Header', authorizationHeader);
expect(authorizationHeader).to.not.equal(null);
const orders = await fetch('url',
{
method: 'GET', headers: {
authorization: authorizationHeader
}
});
// tslint:disable-next-line:no-console
console.log(await orders.json());
});
});
And my helper functions in the BaseSteps.ts are as follows:
async loginUser(userName: string, password: string): Promise<Response> {
const getSignInFormResponse = await fetch(this.getInitialRequestUrl(),
{
method: 'GET'
});
const form = <some-form-data>;
const loginResponse = await fetch(getSignInFormResponse.url,
{
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
body: form,
redirect: 'manual'
});
return loginResponse;
}
async getAuthorizationHeader() {
const tokenResponse = await fetch(this.getInitialRequestUrl(),
{
method: 'GET',
redirect: 'manual'
});
const tokenInfo = qs.parse(tokenResponse.headers.get('location'));
const authorizationHeader = `${tokenInfo.token_type} ${tokenInfo.access_token}`;
return authorizationHeader;
}
When i run my scenario it fails with the following error:
Error: function uses multiple asynchronous interfaces: callback and promise
on the line where my Given starts
Please help me fix this error.
Your Given
step definition has a table
argument while in your feature file, it does not have a table. Cucumber-js determines if you are using the callback
interface based on the number of arguments in your step definition. If the number is one more than the number of arguments that are passed in, then it assumes you are using the callback interface. Since you are also returning a promise, it determines you are using the promise interface. Only one interface at a time can be used.
Thoughts on updating the error message to include something about the fact that the callback interface is assumed because the step definition has X number of arguments?
@charlierudolph Hey mate thanks for your reply, but I didnt quite understand why you said that my feature file does not have a table in it?
Given I login to my account with my username and password
Then I should get an authorization token
|username|password|
|[email protected]|dev|
isnt how we pass the table in the feature file?
Took inspiration from here https://github.com/cucumber/cucumber-js/blob/master/features/data_tables.feature
Yeah the error message could be a bit more clearer..
Thanks again.
I meant that in your feature file, your Then
step has a table but your Given
step does not.
Uhh damn.. Yeah you are right.. I mistook table to be an example
sorry for the confusion. I guess it would be alright now. If the problem persists i shall come back to ask questions again.
Closing the issue as @charlierudolph helped me figure out my own coding error in the feature file.
Glad its working for you. I'll open a separate issue for updating the error message to hopefully make this easier to figure out in the future
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Your
Given
step definition has atable
argument while in your feature file, it does not have a table. Cucumber-js determines if you are using thecallback
interface based on the number of arguments in your step definition. If the number is one more than the number of arguments that are passed in, then it assumes you are using the callback interface. Since you are also returning a promise, it determines you are using the promise interface. Only one interface at a time can be used.Thoughts on updating the error message to include something about the fact that the callback interface is assumed because the step definition has X number of arguments?