CI/CD - Continuous Integration & Deployment Example - StreamApp Tests

During the sprint, you ensured the new header for the StreamApp application resulted in UI improvements. After launching the application in production, you were asked to double-check some of the configs that affected the playback of several users. You found another component that affected your new deployed improvement, and the team had to roll back to the previous application version until a fix.

Well, I would like to say that’s an uncommon scenario. But, as engineers, managers, stakeholders, etc., we all know this scenario is expected due to countless circumstances. Therefore, applying unit tests is a common approach, which in conjunction with CI - Continuous Integration & CD - Continuous Deployment techniques, it plans for successful releases of the application.

The goal of this post (divided into two) is to describe how a CI/CD integration can be performed on an OTT platform using the Bitmovin Player, running tests to assure the quality of the releases.

The idea behind CI/CD is to continuously build, test, and deploy iterative code changes in an automated way. The CI (Continuous Integration) takes responsibility for every change being built and tested automatically & constantly. The tests ensure the application is behaving as expected after improvements/fixes. CD (Continuous Deployment) verifies every change that passes the tests/pipeline to be released to the customers. If there’s one issue, the CD process will fail. CD - Continuous Delivery is another term used, intending to deploy all code changes to a testing/production environment respecting the release pipeline. Let’s continue with the CD - Continuous Deployment definition for this post. CI/CD is a broad subject and is not intended to be discussed in detail in this post. However, if you were asked to apply CI/CD techniques on an OTT application or you were asked if Bitmovin supports it, you are in the right place.

First, let’s start with the requirements for the whole integration process.


1st - StreamApp & Tests Post:

  • Node.js & npm.
  • HTTP (or HTTPS) Server.
  • WebdriverIO: a progressive automation framework built to automate modern web and mobile applications.
  • Browser Testing: Chrome Browser.
    – (Optional) : BrowserStack - framework to enable cross-browser testing. An account will be needed to execute it.

2nd - StreamApp & CI/CD Post:

  • Jenkins: an open-source automation server enabling building, testing, and deploying software.
  • Cloud Storage: S3, GCP, Azure Blob, etc.

Let’s go to the first part of the integration:


StreamApp 51.0.0 application is a simple video platform where subscribers can log in and watch VOD content. But, first, make sure you cloned the player-ci-cd-routines project.

git clone

Main Page:

Player Page:

Load the HTML pages on your preferred HTTP (or HTTPS) Server. For example, let's assume the server runs at, and you can access the index page by writing If you are able to log in and play back, the application behaves as expected. Next, you can move to the StreamApp Tests topic.

Ps: at the player.html code, a Bitmovin Player Key is required. Go to and start a trial account if you still don’t have a license. :slight_smile:

StreamApp Tests

You want to ensure that every playback/pause is successful across releases. This is achievable using WebdriverIO by creating a BDD Mocha script with the instructions to log in, playback and pause the content, validating each step automatically. First, clone the following project with the test instructions (I added the test scripts into the player-ci-cd-routines just to separate the application from the & CI&CD routines. The tests could have been added to the player-ci-cd-app project without issues).

git clone

Mocha tests:

describe('StreamApp Test', () => {
    it('Login into the application with credentials', async () => {
        await browser.url(`index.html`);
        const userInput = await $('#user');
        await userInput.setValue('');
        const passwordInput = await $('#password');
        await passwordInput.setValue('pass');
        await browser.pause(2000)
        const login = await $('#login');;

    it('Should playback and pause content', async () => {
        await browser.pause(2000)
        await expect(browser).toHaveUrlContaining('player')
        const playButton = await browser.$('.bmpui-ui-playbacktogglebutton')
        await browser.pause(5000)
        var isPlaying = await browser.execute((isPlaying) => {
        return player.isPlaying()
        await expect(isPlaying).toBe(true)
        await browser.pause(3000)
        const pauseButton = await browser.$('.bmpui-ui-playbacktogglebutton')
        await browser.pause(2000)
        isPlaying = await browser.execute((isPlaying) => {
        return player.isPlaying()
        await expect(isPlaying).toBe(false)
        await browser.saveScreenshot('./screenshot.png')

As you can note, the instructions are clear. It accesses index.html, writes the credentials and clicks on the Login button (the first test finished). If there’s a player, click on the play button. Wait for 5 seconds. Calling the Bitmovin Player API isPlaying() returns true if it’s playing. As it’s expected to be true, it clicks the pause button. Calls Bitmovin Player API isPlaying() returns false. It’s expected to be false.

This simple test can be translated to multiple use-cases, from the simple ones to the most advanced. When the tests are created, it’s time to run them. There are two options for the project:

How to run & test the StreamApp on a local Chrome:

  1. Run a local server with the deployed StreamApp, i.e.
  2. Access the player-ci-cd-routines root folder.
  3. At the console, define the BASE_URL:
    export BASE_URL= ""
  4. Execute: npx wdio run wdio_local.conf.js

How to run & test StreamApp on Browserstack:

  1. Access the player-ci-cd-routines root folder.
  2. At the console, define the BASE_URL:
    export BASE_URL= "" or the URL to page.
  3. Define the Browserstack credentials:
  4. Execute:
    npx wdio run wdio_browserstack.conf.js


[chrome 102 mac os x #0-0] » /test/specs/example.e2e.js
[chrome 102 mac os x #0-0] StreamApp Test
[chrome 102 mac os x #0-0]    ✓ Login into the application with credentials
[chrome 102 mac os x #0-0]    ✓ Should playback and pause content
[chrome 102 mac os x #0-0]
[chrome 102 mac os x #0-0] 2 passing (16.6s)
Spec Files:	 1 passed, 1 total (100% completed) in 00:00:18

After starting the script, you can follow the whole instructions being executed on your browser automatically. However, the part that interests the entire CI/CD integration process is the final result, whether the tests pass or fail. If it fails, the logs will provide the information for troubleshooting and fixing the issue. In this case, as we can observe, it passed.

Next Steps

The tests are a fundamental part of the CI/CD integration process. With the tests up & running, I’ll show you how to set up a CI/CD routine using Jenkins to just click on the deploy button to run the tests & deploy/publish the application.

Thanks! CI/CD routines on the upcoming post :slight_smile: