title: How to run E2E tests using headless chrome with WebGL support
body: <p>I am trying to run E2E tests with WebGL support inside a CI environment.</p>
  
  <p>From reading up on the topic it seems that I need to run a 'real' browser using Xvfb. Xvfb is "the display system used by Linux. It provides a fake display buffer for graphical programs to write to, thus allowing any program to run headlessly." ~ <a href="http://tobyho.com/2015/01/09/headless-browser-testing-xvfb/" rel="nofollow noreferrer">Headless Browser Testing With Xvfb</a></p>
  
  <p>I am using this docker image: <a href="https://github.com/jciolek/docker-protractor-headless" rel="nofollow noreferrer">docker-protractor-headless</a> which includes Xvfb. I have a JS snippet that will detect WebGL support in the browser, it will result in an html element that is true or false. When I run the JS snippet in a dev environment it is true (as expected). However the test fails.</p>
  
  <p>Question: How can I run E2E tests with WebGL support?</p>
  
  <p><strong>My protractor.config:</strong></p>
  
  <pre><code>'use strict';
  
  var config = {
    debug: true,
    logLevel: 'DEBUG',
    allScriptsTimeout: 110000,
    baseUrl: 'http://localhost:' + (process.env.PORT || '9000'),
    specs: [
      'e2e/**/*.spec.js'
    ],
    capabilities: {
      'browserName': 'chrome',
      chromeOptions: {
        args: ['--headless', '--window-size=1200x800']
        // args: ['--headless', '--window-size=1200x800', '--no-sandbox'] // also tried with the no-sandbox flag
      }
    }
  };
  
  config.params.baseUrl = config.baseUrl;
  exports.config = config;
  </code></pre>
  
  <p><strong>The E2E tests:</strong></p>
  
  <pre><code>describe("check for webgl", function() {
  
      it("browser should support webgl", function() {
  
        browser.get("#/login").then(function() {
  
        }).then(function(title) {
          browser.waitForAngular();
          browser.sleep(6000);
  
          var foo = element(by.model('vm.foo'));
  
          foo.evaluate('vm.foo').then(function (value) {
            expect(value).toBe(true);
          });
        });
      });
  });
  </code></pre>
  
  <p><strong>Failing Test result:</strong></p>
  
  <pre><code>Failures:
  1) check for webgl browser should support webgl
    Message:
      Expected false to be true.
  </code></pre>
  
  <p><strong>Javascript checking for WebGL:</strong></p>
  
  <pre><code>function webgl_detect(return_context) {
        if (!!window.WebGLRenderingContext) {
            var canvas = document.createElement("canvas"),
                 names = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"],
               context = false;
  
            for(var i=0;i&lt;4;i++) {
                try {
                    context = canvas.getContext(names[i]);
                    if (context &amp;&amp; typeof context.getParameter == "function") {
                        // WebGL is enabled
                        if (return_context) {
                            // return WebGL object if the function's argument is present
                            return {name:names[i], gl:context};
                        }
                        // else, return just true
                        return true;
                    }
                } catch(e) {}
            }
  
            // WebGL is supported, but disabled
            return false;
        }
  
        // WebGL not supported
        return false;
      }
  
  
      this.foo = webgl_detect();
  </code></pre>
  
  <p><strong>Test browser capabilities (via modernizr):</strong></p>
  
  <pre><code>Capabilities {
    'applicationCacheEnabled' =&gt; false,
    'rotatable' =&gt; false,
    'mobileEmulationEnabled' =&gt; false,
    'networkConnectionEnabled' =&gt; false,
    'chrome' =&gt; { chromedriverVersion: '2.32.498513 (2c63aa53b2c658de596ed550eb5267ec5967b351)',
    userDataDir: '/tmp/.org.chromium.Chromium.0sDOso' },
    'takesHeapSnapshot' =&gt; true,
    'pageLoadStrategy' =&gt; 'normal',
    'databaseEnabled' =&gt; false,
    'handlesAlerts' =&gt; true,
    'hasTouchScreen' =&gt; false,
    'version' =&gt; '59.0.3071.115',
    'platform' =&gt; 'LINUX',
    'browserConnectionEnabled' =&gt; false,
    'nativeEvents' =&gt; true,
    'acceptSslCerts' =&gt; true,
    'webdriver.remote.sessionid' =&gt; '66060cd4-68fc-4142-a524-a348bbf44de2',
    'locationContextEnabled' =&gt; true,
    'webStorageEnabled' =&gt; true,
    'browserName' =&gt; 'chrome',
    'takesScreenshot' =&gt; true,
    'javascriptEnabled' =&gt; true,
    'cssSelectorsEnabled' =&gt; true,
    'setWindowRect' =&gt; true,
    'unexpectedAlertBehaviour' =&gt; '' }
  </code></pre>