I found the error: setValue is not a function when I was trying to set value for an element.
But I came up with a solution like using the async function
describe("Interaction with web elements", function () {
it("Enter Value in a field", async function () {
await browser.url('/');
const Search = await $('#twotabsearchtextbox')
await Search.setValue('MacBook');
})
});
Will there be any other alternative way to fix them?
it not working because you have not added async and await
describe("interaction with web elements",()=>{
it("enter value in a field", async() => {
await browser.url('/');
const search = await browser.$('#twotabsearchtextbox');
search.setValue('mac');
await browser.pause(500);
})
})
this should work
Related
I have three API calls which should be dependent on one another. The second API call should trigger only when the first succeeds.
With my current implementation, I'm getting a CORS error when the first API call is made and was able to catch the error in the catch block. However, I'm seeing that the second and third APIs calls are made irrespective of the error that got caught in the first API call.
Could anyone please advise?
const firstApiCall = async() => {
try {
await axios.post(
process.env.FIRST_API,
payload
);
]
} catch (err) {
console.log(`err`, err);
}
};
const secondApiCall = async() => {
try {
await axios.post(
process.env.SECOND_API,
payload
}
} catch (err) {
console.log(`err`, err);
}
};
const thirdApiCall = async() => {
try {
await axiosInstance.patch(
process.env.THIRD_API,
payload
);
} catch (err) {
console.log('err', err);
}
};
firstApiCall();
secondApiCall();
thirdApiCall();
You're calling the functions synchronously when you need to do it asynchronously:
async function performTasks() {
await firstApiCall();
await secondApiCall();
await thirdApiCall();
}
performTasks();
You can use the ES6 Promise implementation approacg. Therefore you should take a look to this ressource : [Promise][1]
With the promise approach you can react at each step / each API call.
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
async await functions work only in their local scope.
For example:
const myFunc = async() => {
try{
//...
await foo();
//All the code below will be blocked till
//the promise return by foo function is resolved
}
catch{
//...
}
}
const main = () => {
myFunc();
otherFunc();
//Other function calls
//Regardless of using async await in myFunc,
//the code bellow myFunc will be executed as
//async await will work only in myFunc block scope
}
main()
What you can do is, use async await inside the main function, so that the functions would be called in an order
const main = async () => {
await myFunc();
await otherFunc();
}
i am a beginner in javascript async await function. I have tried to make a asynchronous request in my backend and i want it to initialized in my variable but when I tried to log my variable, it gives me a promise and not a value. When i also tried to put an await. It gives me error.
Here is what I've done:
const getActivityContestApi = async () => {
try {
const response = await fetch(
`${getDjangoApiHost()}/api/events/event_activity_contests/`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
return data;
} catch(error) {
console.log(error)
}
}
The function above is my asynchronous function, I want this to be stored in a variable like this:
const test_variable = getActivityContestApi();
console.log(test_variable);
this code gives me a promise. I want the actual variable so I tried to put await like this:
const test_variable = await getActivityContestApi();
console.log(test_variable);
this gives me error in react. please help.
await is only allowed inside async function.
const test_variable = await getActivityContestApi();
you can only use this statement inside another async function.
asyncFunction will return a promise. So if you just want get result, maybe you can use then
getActivityContestApi().then((resolve,reject)=>{
let test_variable = resolve;
console.log(test_variable);
})
await can't exist outside of async function. Here is what you need to do:
;(async () => {
const test_variable = await getActivityContestApi();
console.log(test_veriable);
})()
I'm creating tests using jest puppeteer for my react website. Each test passes when run individually however they do not pass when all run together.
import './testFunctions'
import {
cleanSmokeTest,
testErrorsPage1,
testErrorsPages2,
} from '. /testFunctions'
describe('app', () => {
beforeEach(async () => {
jest.setTimeout(120000)
await page.goto('http://localhost:3000')
})
it('should for through all pages with no issue', async () => {
await cleanSmokeTest()
})
it('test errors on page 1', async () => {
await testErrorsPage1()
})
it('test errors on page 2', async () => {
await testErrorsPage2()
})
My best guess for a solution involves clearing the session storage or opening the browser in a new page (as no errors will occur if the page has already passed once)
The following will not open the webpage url so I'm stuck on how to solve this issue
import './testFunctions'
import {
cleanSmokeTest,
testErrorsPage1,
testErrorsPages2,
} from '. /testFunctions'
describe('app', () => {
beforeEach(async () => {
jest.setTimeout(120000)
const puppeteer = require('puppeteer')
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('http://localhost:3000')
})
it('should for through all pages with no issue', async () => {
await cleanSmokeTest()
})
it('test errors on page 1', async () => {
await testErrorsPage1()
})
it('test errors on page 2', async () => {
await testErrorsPage2()
})
Using the line:
sessionStorage.clear()
produces the error
ReferenceError: sessionStorage is not defined
and:
window.sessionStorage.clear()
produces the error
ReferenceError: window is not defined
Found my solution
await page.goto('http://localhost:3000')
await page.evaluate(() => {
sessionStorage.clear()
})
await page.goto('http://localhost:3000')
The reason for this was because sessionStorage is not defined unless the page is reached. Once it has cleared the page needs a refresh because redux has kept it in memory.
I think you are running sessionStorage.clear() function in nodejs environment. sessionStorage is defined in client javascript context. The code below is executing the function in the page context.
const html = await page.evaluate(() => {sessionStorage.clear() });
I'm writing an async test that expects the async function to throw like this:
it("expects to have failed", async () => {
let getBadResults = async () => {
await failingAsyncTest()
}
expect(await getBadResults()).toThrow()
})
But jest is just failing instead of passing the test:
FAIL src/failing-test.spec.js
● expects to have failed
Failed: I should fail!
If I rewrite the test to looks like this:
expect(async () => {
await failingAsyncTest()
}).toThrow()
I get this error instead of a passing test:
expect(function).toThrow(undefined)
Expected the function to throw an error.
But it didn't throw anything.
You can test your async function like this:
it('should test async errors', async () => {
await expect(failingAsyncTest())
.rejects
.toThrow('I should fail');
});
'I should fail' string will match any part of the error thrown.
I'd like to just add on to this and say that the function you're testing must throw an actual Error object throw new Error(...). Jest does not seem to recognize if you just throw an expression like throw 'An error occurred!'.
await expect(async () => {
await someAsyncFunction(someParams);
}).rejects.toThrowError("Some error message");
We must wrap the code in a function to catch the error. Here we are expecting the Error message thrown from someAsyncFunction should be equal to "Some error message". We can call the exception handler also
await expect(async () => {
await someAsyncFunction(someParams);
}).rejects.toThrowError(new InvalidArgumentError("Some error message"));
Read more https://jestjs.io/docs/expect#tothrowerror
Custom Error Class
The use of rejects.toThrow will not work for you. Instead, you can combine the rejects method with the toBeInstanceOf matcher to match the custom error that has been thrown.
Example
it("should test async errors", async () => {
await expect(asyncFunctionWithCustomError()).rejects.toBeInstanceOf(
CustomError
)
})
To be able to make many tests conditions without having to resolve the promise every time, this will also work:
it('throws an error when it is not possible to create an user', async () => {
const throwingFunction = () => createUser(createUserPayload)
// This is what prevents the test to succeed when the promise is resolved and not rejected
expect.assertions(3)
await throwingFunction().catch(error => {
expect(error).toBeInstanceOf(Error)
expect(error.message).toMatch(new RegExp('Could not create user'))
expect(error).toMatchObject({
details: new RegExp('Invalid payload provided'),
})
})
})
I've been testing for Firebase cloud functions and this is what I came up with:
test("It should test async on failing cloud functions calls", async () => {
await expect(async ()=> {
await failingCloudFunction(params)
})
.rejects
.toThrow("Invalid type"); // This is the value for my specific error
});
This is built on top of lisandro's answer.
If you want to test that an async function does NOT throw:
it('async function does not throw', async () => {
await expect(hopefullyDoesntThrow()).resolves.not.toThrow();
});
The above test will pass regardless of the value returned, even if undefined.
Keep in mind that if an async function throws an Error, its really coming back as a Promise Rejection in Node, not an error (thats why if you don't have try/catch blocks you will get an UnhandledPromiseRejectionWarning, slightly different than an error). So, like others have said, that is why you use either:
.rejects and .resolves methods, or a
try/catch block within your tests.
Reference:
https://jestjs.io/docs/asynchronous#asyncawait
This worked for me
it("expects to have failed", async () => {
let getBadResults = async () => {
await failingAsyncTest()
}
expect(getBadResults()).reject.toMatch('foo')
// or in my case
expect(getBadResults()).reject.toMatchObject({ message: 'foo' })
})
You can do like below if you want to use the try/catch method inside the test case.
test("some test case name with success", async () => {
let response = null;
let failure = null;
// Before calling the method, make sure someAsyncFunction should be succeeded
try {
response = await someAsyncFunction();
} catch(err) {
error = err;
}
expect(response).toEqual(SOME_MOCK_RESPONSE)
expect(error).toBeNull();
})
test("some test case name with failure", async () => {
let response = null;
let error = null;
// Before calling the method, make sure someAsyncFunction should throw some error by mocking in proper way
try {
response = await someAsyncFunction();
} catch(err) {
error = err;
}
expect(response).toBeNull();
expect(error).toEqual(YOUR_MOCK_ERROR)
})
Edit:
As my given solution is not taking the advantage of inbuilt jest tests with the throwing feature, please do follow the other solution suggested by #Lisandro https://stackoverflow.com/a/47887098/8988448
it('should test async errors', async () => {
await expect(failingAsyncTest())
.rejects
.toThrow('I should fail');
});
test("It should test async on failing cloud functions calls", async () => {
failingCloudFunction(params).catch(e => {
expect(e.message).toBe('Invalid type')
})
});
i'm struggling with promises in a service worker while using async/await syntax.
Following situation: I got a push notification and want to handle the click event. If i use the "old" syntax with then and catch i can iteratore over the list of clients and do something with it. If i use my prefered way with async/await it wouldn't do anything.
self.addEventListener("notificationclick", event => {
// is working
event.waitUntil(self.clients.matchAll().then(clientList => {
console.log(clientList);
}));
// is not working
event.waitUntil(async () => {
const clientList = await self.clients.matchAll();
console.log(clientList);
});
});
Thanks to #Crice and #Keith,
waitUntil need a promise as argument instead of a function. So this is the working example in async/await style:
self.addEventListener("notificationclick", event =>
{
event.waitUntil(getClients());
});
async function getClients()
{
const clientList = await self.clients.matchAll();
console.log(clientList);
}
You can modify your original code to make an async IIFE as
// should be working now
event.waitUntil( (async () => {
const clientList = await self.clients.matchAll();
console.log(clientList);
})() );
The added ( ), will immediately invokes the async function hence the name async IIFE