I use the standardized Broadcast Channel API (https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) for messaging between multiple tabs when a session timeout occurs in our react app.
On all tested browsers, this works just fine. But when I run our jest tests I get the following error message: "ReferenceError: BroadcastChannel is not defined"
I define a BroadcastChannel instance outside of our hook like this:
const sessionTimeoutChannel = new BroadcastChannel("session_timeout_channel");
export default function useSessionTimeout() {...}
Has anybody any idea why the tests seemingly dont know of the BroadcastChannel API? Or knows of a workaround so that the tests run again?
No experience here, but it could be that your tests are run in nodejs... so not actually having browser support. I found this on npm, maybe it needs to be added to your tests project? https://www.npmjs.com/package/broadcast-channel
Related
I can run my test script on the Cypress interface with npx cypress open. In this case test runs pass. But when I run the same test script headless, it fails. What can be the cause of this issue?
I run the tests always behind OpenVPN both when running headless or on Cypress interface. This is required due to authentication API.
I wanted to mention that, not always the same tests are failed. While testing headless than my tests fails randomly. But when I run these tests on the Cypress interface everything passes without any error.
OpenVPN is connected.
This is the HTML element:
Every test creates new work order via API. So for every test work order title changes with a new workorder-title one, I leave DOM here to show DOM the design.
<div class="workorder-title">21-270073 / EM / -</div>
I found the problem. First of all everything, there were two different issues to solve about my Stackoverflow issue.
1- my API request came as unauthorized.
I was getting authorization tokens like this--> anyVariable=localStorage.getItem('autToken')
This was work without a problem while I using npx Cypress open because Cypress works extremely quickly on the interface and anyVariable fully filled by token and works without any problem.
But while using headless mode then cypress gets slower so that's why Cypress sent API req before anyVariable fully filled by token and responses as unauthorized.
I read some issues and articles about Cypress and Getting item by LocalStorage. People said that this usage "anyVariable=localStorage.getItem('autToken')" to get item local storage works as async So that's why I used cy. command to solve my problem and my attempt completely solved my problem.
I solved the problem by using the chainable cypress method.
cy.window()
.then((window) => {
return window.localStorage.getItem('anyVariable')
})
.then((token) => {
setAnyVariable(token)
})
2- The second problem was caused by one of our frontend component which refreshes the newly created item list to be newly created items visible. It was strange because that component was works stable when I run my tests with npx cypress open.
Why I explained that if you face with similar issue then you can try to check your frontend components.
I working on a solution to that problem right now.
When I used to program with python I could run a python app and then execute methods and access variables of the app from within terminal. This was a great way to test things around.
Working on my JS app I often use console.log to try things out but I am looking for a way to try things without having to rerun the app each time. I want to be able to call any method / variable of my React app (including imported classes etc) from within console "at run-time".
Is this possible? If yes, how?
If not, what is the best alternative to switching between code and browser back-and-force to see the effect of certain changes console.log ?
I am developing a JavaScript library (https://github.com/yvesgurcan/web-midi-player) to enable MIDI playback in a web application. The library relies on the Web Audio API to create a way to play these MIDI files (https://github.com/yvesgurcan/web-midi-player/blob/test/src/MidiPlayer.js#L50). However, I am having trouble creating meaningful unit tests with Jest (https://github.com/yvesgurcan/web-midi-player/blob/test/tests/midiPlayer.js) because these tests don't have access to the window object and more particularly to window.AudioContext. As a consequence, running my application code which relies on AudioContext throws errors related to the fact that this object does not exist and I can't actually test very much things in the library.
I've tried the following packages to solve my problem: jsdom, jsdom-global, and also web-audio-test-api but none of these seem to inject AudioContext in the environment.
I am thinking that the solution here would be to stub/mock AudioContext but that does not sound like a good solution for solid unit tests.
What do you folks suggest to test the Web Audio API? Is stubbing the only viable solution here?
I think it depends a bit on what you want to test. Since you're using Jest I imagine you're just interested in testing the correctness of your own code. In that case I would recommend to fully mock the Web Audio API. It's not part of your responsibility and you can assume it works the way it should. The only thing you have to test is if your code is making the expected calls.
Mocking globally available variables like the AudioContext constructor is always a bit tricky but you could allow an AudioContext to be passed into your MidiPlayer class as an optional argument. It would make testing a little easier and it would also allow users of your library to bring their own AudioContext.
I think of something like this:
class MidiPlayer {
constructor({
// ... the other options ...
context = new AudioContext()
}) {
// ...
}
}
Inside a test you could then simply instantiate the MidiPlayer with a fake AudioContext.
const fakeAudioContext = {
currentTime: 3,
// ... and all the other things your code uses ...
};
const midiPlayer = new MidiPlayer({ context: fakeAudioContext });
I recently answered a similar question related to Tone.js which might be helpful. The basic idea is the same.
In case you want to test if your library works nicely with the Web Audio API in a browser I would recommend to use a test runner like Karma. It executes the tests in a real browser and therefore can use all the browser APIs.
I'm trying to figure out how to call an Electron method from my frontend application javascript. Either the main or renderer process would do fine for starters, presumably I can work through the rest from there.
In all the examples I can find, the renderer code attaches to the frontend element and adds an event listener:
document.querySelector('#btn').addEventListener(() => { // doElectronStuff });
This is not quite what I'm after though... it seems like a rather severe coupling to have this "server side" code reaching into my DOM.
Using an Angular2 frontend, I found what appears to be a nice package called ngx-electron which exposes the electron interface as an injectable complete with typescript mappings, etc.
So now I have an Angular service that I want to call an Electron method for (to grab some database stuff, or whatever else):
constructor(private _electron:ElectronService) {}
getAll(): Entity[] {
var results = this._electron.ipcRenderer.?????
}
I really have no idea how to make the angular service make that call to the electron method. I've tried running emit() and have tried using send() and such against the ipcRenderer, the remote.ipcMain, but receive various errors and all and all can't seem to make the connection.
Hopefully I missing something simple? What's the combination of electron-side syntax and angular-side syntax that's required to match these up? Thanks
(I'm not particularly stuck on ngx-electron, but it did seem a nice lib and I'm assuming it works well, once I get past my own block...)
Found it. As usual, an oversight on my end.
// in the angular service
this._electron.ipcRenderer.send('event-aka-channel-name1', args);
// in the electron main.js
ipc.on('event-aka-channel-name1', (event, args) => { // doStuff });
My issue was apparently a misspelling of an import which I caught via various logs. Once that was fixed the rest works as intended (or at least enough for me to move forward)
Sorry I don't know if this is a stupid question or not but I cannot find the answer.
I have a pure function in javascript which check if the argument is a correct URL
isValidUrl(url) {
const protocol = new URL(url).protocol;
...
}
The code runs fine in browser. But I would like to write a test using mocha for it. And mocha complains "ReferenceError: URL is not defined". So does that mean server side JS does not have URL class? Do I need to use something like headless browser to test it?
Thanks a lot.
Node and friends, where your tests are likely running, implement the ECMAScript (JS) spec. The URL class is from this WhatWG spec. The JS spec does not have any reference to a URL class, which explains your immediate problem.
Node also implements its own CommonJS-based modules, one of which is a URL module. It doesn't appear to have the same interface, however.
Using Mocha with Karma to run tests in a headless browser, like PhantomJS, is probably a better solution. You'll get an accurate, if slightly out of date, version of chromium to test within. You can also set Karma up to use other browsers, if they are available on the test machine.