diff --git a/.travis.yml b/.travis.yml
index 735b95651ab6..04cc589e5552 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -92,9 +92,6 @@ matrix:
 
 
 before_install:
-  # Use a virtual display.
-  - export DISPLAY=:99.0
-  - sh -e /etc/init.d/xvfb start
   # Install yarn.
   - curl -o- -L https://yarnpkg.com/install.sh | bash
   - export PATH="$HOME/.yarn/bin:$PATH"
diff --git a/tests/e2e/assets/1.0.0-proj/package.json b/tests/e2e/assets/1.0.0-proj/package.json
index decc11c482fc..76f5af43c004 100644
--- a/tests/e2e/assets/1.0.0-proj/package.json
+++ b/tests/e2e/assets/1.0.0-proj/package.json
@@ -33,7 +33,7 @@
     "jasmine-core": "~2.5.2",
     "jasmine-spec-reporter": "~3.2.0",
     "karma": "~1.4.1",
-    "karma-chrome-launcher": "~2.0.0",
+    "karma-chrome-launcher": "~2.1.1",
     "karma-cli": "~1.0.1",
     "karma-jasmine": "~1.1.0",
     "karma-jasmine-html-reporter": "^0.2.2",
diff --git a/tests/e2e/setup/500-create-project.ts b/tests/e2e/setup/500-create-project.ts
index 4d6f546c0304..dbbd35d89a8a 100644
--- a/tests/e2e/setup/500-create-project.ts
+++ b/tests/e2e/setup/500-create-project.ts
@@ -1,7 +1,7 @@
 import {join} from 'path';
 import {git, ng, silentNpm} from '../utils/process';
 import {expectFileToExist, replaceInFile} from '../utils/fs';
-import {updateTsConfig, updateJsonFile, useNg2} from '../utils/project';
+import {updateTsConfig, updateJsonFile, useNg2, useCIChrome} from '../utils/project';
 import {gitClean, gitCommit} from '../utils/git';
 import {getGlobalVariable} from '../utils/env';
 
@@ -36,27 +36,7 @@ export default function() {
         json['dependencies'][pkgName] = packages[pkgName].tar;
       });
     }))
-    // There's a race condition happening in Chrome. Enabling logging in chrome used by
-    // protractor actually fixes it. Logging is piped to a file so it doesn't affect our setup.
-    // --no-sandbox is needed for Circle CI.
-    .then(() => replaceInFile('protractor.conf.js', `'browserName': 'chrome'`,
-      `'browserName': 'chrome',
-        chromeOptions: {
-          args: [
-            "--enable-logging",
-            "--no-sandbox",
-          ]
-        }
-      `))
-    .then(() => replaceInFile('karma.conf.js', `browsers: ['Chrome'],`,
-      `browsers: ['ChromeNoSandbox'],
-      customLaunchers: {
-        ChromeNoSandbox: {
-          base: 'Chrome',
-          flags: ['--no-sandbox']
-        }
-      },
-      `))
+    .then(() => useCIChrome())
     .then(() => argv['ng2'] ? useNg2() : Promise.resolve())
     .then(() => {
       if (argv['nightly'] || argv['ng-sha']) {
diff --git a/tests/e2e/tests/misc/breaking-change.ts b/tests/e2e/tests/misc/breaking-change.ts
index b63fa90af62d..e087e959cf84 100644
--- a/tests/e2e/tests/misc/breaking-change.ts
+++ b/tests/e2e/tests/misc/breaking-change.ts
@@ -1,4 +1,5 @@
 import { createProjectFromAsset } from '../../utils/assets';
+import { replaceInFile } from '../../utils/fs';
 import { ng } from '../../utils/process';
 
 // This test ensures a project generated with 1.0.0 will still work.
@@ -7,6 +8,26 @@ import { ng } from '../../utils/process';
 export default function () {
   return Promise.resolve()
     .then(() => createProjectFromAsset('1.0.0-proj'))
+    // Update chrome configs.
+    .then(() => replaceInFile('protractor.conf.js', `'browserName': 'chrome'`,
+      `'browserName': 'chrome',
+        chromeOptions: {
+          args: [
+            "--enable-logging",
+            "--no-sandbox",
+            ${process.env['TRAVIS'] ? '"--headless", "--disable-gpu"' : ''}
+          ]
+        }
+      `))
+    .then(() => replaceInFile('karma.conf.js', `browsers: ['Chrome'],`,
+      `browsers: ['ChromeCI'],
+      customLaunchers: {
+        ChromeCI: {
+          base: '${process.env['TRAVIS'] ? 'ChromeHeadless' : 'Chrome'}',
+          flags: ['--no-sandbox']
+        }
+      },
+      `))
     .then(() => ng('generate', 'component', 'my-comp'))
     .then(() => ng('lint'))
     .then(() => ng('test', '--single-run'))
diff --git a/tests/e2e/utils/project.ts b/tests/e2e/utils/project.ts
index a3c017b865d8..3a8f514509ef 100644
--- a/tests/e2e/utils/project.ts
+++ b/tests/e2e/utils/project.ts
@@ -1,6 +1,6 @@
-import {readFile, writeFile} from './fs';
-import {execAndWaitForOutputToMatch, silentNpm, ng} from './process';
-import {getGlobalVariable} from './env';
+import { readFile, writeFile, replaceInFile } from './fs';
+import { execAndWaitForOutputToMatch, silentNpm, ng } from './process';
+import { getGlobalVariable } from './env';
 
 const packages = require('../../../lib/packages').packages;
 
@@ -43,6 +43,7 @@ export function createProject(name: string, ...args: string[]) {
         json['dependencies'][pkgName] = packages[pkgName].dist;
       });
     }))
+    .then(() => useCIChrome())
     .then(() => argv['ng2'] ? useNg2() : Promise.resolve())
     .then(() => {
       if (argv.nightly || argv['ng-sha']) {
@@ -77,6 +78,36 @@ export function createProject(name: string, ...args: string[]) {
     .then(() => silentNpm('install'));
 }
 
+export function useCIChrome() {
+  // There's a race condition happening in Chrome. Enabling logging in chrome used by
+  // protractor actually fixes it. Logging is piped to a file so it doesn't affect our setup.
+  // --no-sandbox is needed for Circle CI.
+  // Travis can use headless chrome, but not appveyor.
+  return Promise.resolve()
+    .then(() => replaceInFile('protractor.conf.js', `'browserName': 'chrome'`,
+      `'browserName': 'chrome',
+        chromeOptions: {
+          args: [
+            "--enable-logging",
+            "--no-sandbox",
+            ${process.env['TRAVIS'] ? '"--headless", "--disable-gpu"' : ''}
+          ]
+        }
+    `))
+    // Not a problem if the file can't be found.
+    .catch(() => null)
+    .then(() => replaceInFile('karma.conf.js', `browsers: ['Chrome'],`,
+      `browsers: ['ChromeCI'],
+      customLaunchers: {
+        ChromeCI: {
+          base: '${process.env['TRAVIS'] ? 'ChromeHeadless' : 'Chrome'}',
+          flags: ['--no-sandbox']
+        }
+      },
+    `))
+    .catch(() => null);
+}
+
 // Convert a Angular 4 project to Angular 2.
 export function useNg2() {
   const ng2Deps: any = {