Giter Site home page Giter Site logo

polymer-rtc-testing's Introduction

polymer-rtc-testing

Guide on unit-testing OpenTok WebRTC Polymer 1.0 elements.

Overview

Testing WebRTC-enabled components is a special case when doing unit-testing.

We need 2 (or more) parallel test instances in order to simulate multi-party calls and we also need to suppress browser-level "Share your mic/camera"-type of dialog boxes, otherwise the tests will fail.

This guide focuses on unit-testing OpenTok Polymer 1.0 elements, where the element needs to be tested using 2 WCT instances running in parallel.

While it focuses on OpenTok's Web SDK, it's general concepts should be applicable to standard/vendorless WebRTC implementations.

View the sample <rtc-element>

Build Status rtc-element

There's a sample Polymer element in /rtc-element with unit-tests which are run with the strategy illustrated in this guide.

Add your own TokBox account credentials in the credentials property of rtc-element/rtc-element.html, like so:

credentials: {
  type: Object,
  value: function() {
    return {
      // Replace with your actual TokBox account credentials.
      api_key: 1234,
      token: 'foo-token',
      session_id: 'foo-session-id'
    }
  },
  observer: '_initSession'
}

and then:

$ cd rtc-element
$ npm install -g polymer-cli mocha
$ npm install && bower install
$ npm test

Guide

Add important WCT configuration

Add the following wct.conf.json in your element's directory.

{
  "expanded": true,
  "suites": ["test/*.html"],
  "plugins": {
    "local": {
      "browsers": [
        "chrome"
      ],
      "browserOptions": {
        "chrome": [
          "auto-select-desktop-capture-source='Entire screen'",
          "use-fake-device-for-media-stream",
          "use-fake-ui-for-media-stream"
        ]
      }
    }
  }
}

This tells WCT to:

  • Ignore .js files in test/ since we are going to add a MochaJS test script there.
  • Prevent pop-up of "Do you want to share your mic/camera?" dialogs.

Run tests using Mocha instead of the polymer-cli

You should still write the actual unit-tests as test-1.html, test-2.html etc in tests/, but instead of running them all with $ polymer test we are going to use a Mocha script which executes $ polymer test test runs of them, in-parallel.

In your element:

# Specify `$ mocha test/run.js` when prompted for a test script.
$ npm init
$ npm install --save-dev mocha

The following script spawns 2 WCT instances, running in-parallel.

test/run.js:

'use strict'

const spawn = require('child_process').spawn

// @NOTE
// Helper function that spawns N `$ polymer test` instances and returns
// a Promise which resolves if all instances have exited with 0,
// rejects otherwise.
const spawnPolymerTest = ({ times = 2 }) => {
  const tasks = Array.from({ length: times }, () => ['polymer', ['test']])
    .map(args => {
      return new Promise(resolve => {
        spawn(args[0], args[1], { stdio: 'inherit' }).on('exit', resolve)
      })
    })

  return Promise.all(tasks)
    .then(exitCodes => {
      if (!exitCodes.every(result => result === 0))
        throw new Error('Some tests have failed')

      return
    })
}

describe('Test Suite', () => {
  it ('Runs OK under normal network conditions', function() {
    this.timeout(60000)

    return spawnPolymerTest({ times: 2 })
  })

  // ... add more tests as you see fit.
})

Then run:

$ mocha test/run.js

to run your tests.

Sample unit-test

A sample unit-test that tests a video call between 2 parties:

suite('rtc-element', function() {
  test('Starts a call', function(done) {
    // @NOTE Allow ample timeout as calls might take a while to connect,
    // esp. under bad network conditions.
    this.timeout(10000)

    const element = fixture('basic')

    element.session.on('streamCreated', e => {
      element.session.getSubscribersForStream(e.stream)
        .forEach(subscriber => {
          subscriber.on('videoElementCreated', e => {
            // @NOTE
            // Opentok.js swallows errors in event handlers (eventing.js),
            // so we have to call `done(err)` ourselves, using `try/catch`.
            try {
              const publisherVideoElem = Polymer.dom(element.root)
                .querySelector('#publisher')
                .querySelectorAll('.OT_root')

              const subscriberVideoElem = Polymer.dom(element.root)
                .querySelector('#subscriber')
                .querySelectorAll('.OT_root')

              assert.lengthOf(Array.from(publisherVideoElem), 2)
              assert.lengthOf(Array.from(subscriberVideoElem), 1)

              // @NOTE
              // Wait for the other client to create his video element
              // and run his tests before moving on.
              setTimeout(() => done(), 3000)
            } catch (err) {
              done(err)
            }
          })
        })
    })

    element.startCall().catch(done)
  })
})

Simulating bad network conditions

You should aim to test how your element fares under bad network conditions.

The sitespeedio/throttle package is a tool that allows system-wide throttling of network connections. It can also be used as a Node.js module so you can easily include it in test/run.js to run tests under (simulated) bad network conditions.

However it needs sudo permissions before it runs, runs only on Linux/MacOS and requires that you explicitly stop it when the tests are done.

Building on TravisCI

Sample .travis.yml file:

language: node_js
sudo: required
before_script:
  - npm install -g bower polymer-cli mocha
  - sudo mv /usr/bin/google-chrome /usr/bin/google-chrome-old
  - sudo mv /usr/bin/google-chrome-beta /usr/bin/google-chrome
node_js: stable
addons:
  firefox: latest
  apt:
    sources:
      - google-chrome
    packages:
      - google-chrome-beta
script:
  - npm install
  - bower install
  - xvfb-run npm test
dist: trusty

Todos

See: https://github.com/nicholaswmin/polymer-rtc-testing/issues/1.

Resources

Authors

polymer-rtc-testing's People

Contributors

nicholaswmin avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.