I am trying to mock SSEs in cypress. There are a few questions on SO, and a few issues on GitHub about this, but nothing definitive, or particularly relevant to my setup. I feel like this could be simple, if I can "fake" a message on an EventSource.
My Setup
I have an EventSource that connects to an SSE endpoint on our server:
const eventSrc = new EventSource(`/api/sseEndpoint`, options);
This gets fed to a subscription function within a redux-saga:
const chan = yield call(subscribe, eventSrc);
const message = yield take(chan)
// pass message to further action/reducer processing:
yield handleMessage(message)
Where the subscribe funcrion is pretty simple:
export function subscribe(eventSrc: EventSource): EventChannel<unknown> {
const subscriptions: Subscribe<unknown> = emitter => {
eventSrc.onmessage = (msg): void => {
emitter(msg);
};
eventSrc.onerror = fn,
eventSrc.onopen = fn;
return (): void => {
eventSrc.close();
};
};
return eventChannel(subscriptions);
}
Where eventChannel is part of the redux-saga channel api.
In need to be able to spoof a message to this EventSource from within cypress. I am trying to figure out what I can attach to the cypress window in the following fashion:
if (window.Cypress) {
window.eventSrc = eventSrc;
}
Such that from within cypress commands, I can create a command to hijack that window.eventSrc to dispatch a message:
Cypress.Commands.add("sendSSE", sse => {
cy.window()
.its("eventSrc")
.then(eventSrc => {
eventSrc.dispatchEvent({
data: JSON.stringify(sse),
lastEventId: "",
origin: "http://localhost:3000",
type: "message"
});
});
});
Dispatching / spoofing an event?
As you can see, I've tried using the dispatchEvent function which is on the prototype of an EventSource. Unfortunately, I get the error message from within the cypress test:
Saga or channel was provided with an undefined action
Hints:
- check that your Action Creator returns a non-undefined value
- if the Saga was started using runSaga, check that your subscribe source provides the action to its listeners
I must not be undertanding the dispatchEvent function. Is there a way to use the EventSource that I've attached to the window object to send an event programmatically from within cypress, such that the eventSrc.onMessage = (msg) => { ... } function will fire?