I have a small app in VueJs. When you click on a button, it launches the watchPosition function of the Geolocation API, get the user's position and do some calculations with the user's positions.
I would like to test this behaviour in Cypress test.
I've stubbed the watchLocation function like this, in a Cypress command:
Cypress.Commands.add('mockGeolocation', (latitude, longitude) => {
cy.window().then((win) => {
const mockGeolocation = {
watchPosition: (successCallback, errorCallback, options) => {
// Call the successCallback with mock position data
const mockPosition = {
coords: {
latitude: latitude,
longitude: longitude
}
}
successCallback(mockPosition);
// Optionally, you can call the errorCallback or handle options as needed
},
clearWatch: () => {
console.log("hello there")
}
};
// Replace the real geolocation object with the stub
cy.stub(win.navigator, 'geolocation').value(mockGeolocation);
});
});
And then I call it in my test:
it('My awesome test', () => {
cy.visit('/')
cy.mockGeolocation(1, 2)
cy.get('[data-testid="start-button-game"]').click()
})
It works but it works once.
I would like to call cy.mockGeolocation again with different latitude and longitude to check if my app reacts as expected to a brand new position. And repeat the process several times in the same test.
How can I achieve that ?
The reason is,
watchPositionis a watcher that is usually set once and responds to events from the navigator object in a push pattern.The mock you have set up is for a function where data is fetched each time in a pull pattern.
I feel there must be a way to mock a watcher/listener, but it escapes me at the moment.
Instead, I recommend switching
watchPositiontogetCurrentPositionwhich seems more appropriate for something initiated by a button click.Tested with this app