[Proposal] Refactor browser/device detection by adding EnvDetector
concept
#1620
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
tl;dr
Go from:
to:
To facilitate both tests writing/mocking and the suggestion/discoverability of browsers/devices for RxPlayer developers.
Overview
I wanted to add tests recently for environment-specific workarounds (e.g. on the PlayStation 5, we have to reload as soon as an unusable decryption key is detected to avoid issues).
Yet our integration tests are currently running on desktop browsers (Chrome and Firefox), so the environment detected by the RxPlayer when it plays a content always correspond to that desktop machine. Running those tests directly on all devices is not easily doable for us either.
I thus propose here a mean to force the environment detected by the RxPlayer, through special
mockEnvironment
andresetEnvironment
functions. I also refactored the ways with which we categorize environments by putting more emphasis into the browser/device duality ("browser" is a name for the web browser such as "Chrome", "Firefox","SafariMobile" etc., "device" is a string categorizing the device/OS that browser runs on like "WebOs2022", "PlayStation5" etc.).
Then tests can just directly call
mockEnvironment
to make the RxPlayer "believe" that it is running on another environment, allowing to trigger its device-specific or browser-specific behavior.This update also broke unit tests, which I've updated. While doing that, I refactored those tests in what seems to be a more idiomatic way.
Coincidentally, it also makes them much less verbose and they work better with TypeScript. It also makes them pass in
vitest
's browser mode (which allows to run unit tests in the browser, those for now sadly run in Node.js today), as that mode has subtle differences when relying on thevi.doMock
function like we did previously.Note about tests with a mocked environment
There's however a relatively big detail for which I'm not sure how I'll advance: a browser actually relied on for a test now may be different than the browser "announced" during that test: Let's say that I'm running integration tests on Firefox which has some decoding issues with the current content but I'm currently forcing a Chrome environment to check for Chrome-specific workarounds - there, Firefox workarounds won't be applied though we actually need them considering that's the actual real browser we run on).
One solution for that last problem could be to completely rely on a controlled environment for tests, like running tests in Node.js with
jsdom
, like our unit tests today, but I do prefer running tests on actual web browsers as that's much more representative of what we'll run on.Another solution could be to be careful and consider any such issues manually in integration tests, for example by patching some API when mocking the environment. That's the solution I chose for now.