diff --git a/packages/angular_devkit/architect/testing/run-target-spec.ts b/packages/angular_devkit/architect/testing/run-target-spec.ts
index e06a80487d..1224589e4e 100644
--- a/packages/angular_devkit/architect/testing/run-target-spec.ts
+++ b/packages/angular_devkit/architect/testing/run-target-spec.ts
@@ -6,25 +6,47 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { Path, experimental, logging, normalize } from '@angular-devkit/core';
-import { Observable } from 'rxjs';
-import { concatMap } from 'rxjs/operators';
+import { experimental, logging, normalize } from '@angular-devkit/core';
+import { Observable, merge, throwError, timer } from 'rxjs';
+import { concatMap, concatMapTo, finalize, takeUntil } from 'rxjs/operators';
 import { Architect, BuildEvent, TargetSpecifier } from '../src';
 import { TestProjectHost } from './test-project-host';
 
+export const DefaultTimeout = 45000;
 
 export function runTargetSpec(
   host: TestProjectHost,
   targetSpec: TargetSpecifier,
   overrides = {},
+  timeout = DefaultTimeout,
   logger: logging.Logger = new logging.NullLogger(),
 ): Observable<BuildEvent> {
   targetSpec = { ...targetSpec, overrides };
   const workspaceFile = normalize('angular.json');
   const workspace = new experimental.workspace.Workspace(host.root(), host);
 
-  return workspace.loadWorkspaceFromHost(workspaceFile).pipe(
+  // Emit when runArchitect$ completes or errors.
+  // TODO: There must be a better way of doing this...
+  let finalizeCB = () => { };
+  const runArchitectFinalize$ = new Observable(obs => {
+    finalizeCB = () => obs.next();
+  });
+
+  // Load the workspace from the root of the host, then run a target.
+  const runArchitect$ = workspace.loadWorkspaceFromHost(workspaceFile).pipe(
     concatMap(ws => new Architect(ws).loadArchitect()),
     concatMap(arch => arch.run(arch.getBuilderConfiguration(targetSpec), { logger })),
+    finalize(() => finalizeCB()),
+  );
+
+  // Error out after the timeout if runArchitect$ hasn't finalized.
+  const timeout$ = timer(timeout).pipe(
+    takeUntil(runArchitectFinalize$),
+    concatMapTo(throwError(`runTargetSpec timeout (${timeout}) reached.`)),
+  );
+
+  return merge(
+    timeout$,
+    runArchitect$,
   );
 }
diff --git a/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts b/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts
index 26527a7607..0618c7a7f6 100644
--- a/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts
@@ -5,10 +5,10 @@
  * Use of this source code is governed by an MIT-style license that can be
  * found in the LICENSE file at https://angular.io/license
  */
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, host } from '../utils';
+import { host } from '../utils';
 
 
 describe('AppShell Builder', () => {
@@ -38,7 +38,7 @@ describe('AppShell Builder', () => {
       `,
     });
 
-    runTargetSpec(host, { project: 'app', target: 'app-shell' }).pipe(
+    runTargetSpec(host, { project: 'app', target: 'app-shell' }, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         const fileName = 'dist/index.html';
@@ -46,6 +46,5 @@ describe('AppShell Builder', () => {
         expect(content).toMatch(/Welcome to app!/);
       }),
     ).toPromise().then(done, done.fail);
-
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/allow-js_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/allow-js_spec_large.ts
index 02a4f0bab3..6f2abef286 100644
--- a/packages/angular_devkit/build_angular/test/browser/allow-js_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/allow-js_spec_large.ts
@@ -8,7 +8,7 @@
 
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder allow js', () => {
@@ -27,7 +27,7 @@ describe('Browser Builder allow js', () => {
     runTargetSpec(host, browserTargetSpec).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('works with aot', (done) => {
     host.writeMultipleFiles({
@@ -40,5 +40,5 @@ describe('Browser Builder allow js', () => {
     runTargetSpec(host, browserTargetSpec, overrides).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/aot_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/aot_spec_large.ts
index 68c43a6655..86259541d3 100644
--- a/packages/angular_devkit/build_angular/test/browser/aot_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/aot_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder AOT', () => {
@@ -29,5 +29,5 @@ describe('Browser Builder AOT', () => {
         expect(content).toMatch(/platformBrowser.*bootstrapModuleFactory.*AppModuleNgFactory/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Standard);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts
index f8002095b8..703e44a730 100644
--- a/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { normalize, virtualFs } from '@angular-devkit/core';
 import { tap, toArray } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder assets', () => {
@@ -57,7 +57,7 @@ describe('Browser Builder assets', () => {
         expect(host.scopedSync().exists(normalize('./dist/folder/.gitkeep'))).toBe(false);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('fails with non-absolute output path', (done) => {
     const assets: { [path: string]: string } = {
@@ -76,7 +76,7 @@ describe('Browser Builder assets', () => {
     // The node_modules folder must be deleted, otherwise code that tries to find the
     // node_modules folder will hit this one and can fail.
     host.scopedSync().delete(normalize('./node_modules'));
-  }, Timeout.Basic);
+  });
 
   it('fails with non-source root input path', (done) => {
     const assets: { [path: string]: string } = {
@@ -93,7 +93,7 @@ describe('Browser Builder assets', () => {
     // The node_modules folder must be deleted, otherwise code that tries to find the
     // node_modules folder will hit this one and can fail.
     host.scopedSync().delete(normalize('./node_modules'));
-  }, Timeout.Basic);
+  });
 
   it('still builds with empty asset array', (done) => {
     const overrides = {
@@ -104,5 +104,5 @@ describe('Browser Builder assets', () => {
       toArray(),
       tap((buildEvents) => expect(buildEvents.length).toBe(1)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/base-href_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/base-href_spec_large.ts
index 25bd1bc815..c70912e862 100644
--- a/packages/angular_devkit/build_angular/test/browser/base-href_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/base-href_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder base href', () => {
@@ -34,5 +34,5 @@ describe('Browser Builder base href', () => {
         expect(content).toMatch(/<base href="\/myUrl">/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/build-optimizer_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/build-optimizer_spec_large.ts
index 6dae12121a..4e0c11220f 100644
--- a/packages/angular_devkit/build_angular/test/browser/build-optimizer_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/build-optimizer_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder build optimizer', () => {
@@ -28,5 +28,5 @@ describe('Browser Builder build optimizer', () => {
         expect(content).not.toMatch(/\.decorators =/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/bundle-budgets_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/bundle-budgets_spec_large.ts
index b797da6d6b..918e691ba7 100644
--- a/packages/angular_devkit/build_angular/test/browser/bundle-budgets_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/bundle-budgets_spec_large.ts
@@ -6,9 +6,9 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder bundle budgets', () => {
@@ -24,11 +24,11 @@ describe('Browser Builder bundle budgets', () => {
 
     const logger = new TestLogger('rebuild-type-errors');
 
-    runTargetSpec(host, browserTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2, logger).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(logger.includes('WARNING')).toBe(false)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
   it('shows errors', (done) => {
     const overrides = {
@@ -36,10 +36,10 @@ describe('Browser Builder bundle budgets', () => {
       budgets: [{ type: 'all', maximumError: '100b' }],
     };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(false)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
   it('shows warnings', (done) => {
     const overrides = {
@@ -49,9 +49,9 @@ describe('Browser Builder bundle budgets', () => {
 
     const logger = new TestLogger('rebuild-type-errors');
 
-    runTargetSpec(host, browserTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2, logger).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(logger.includes('WARNING')).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/circular-dependency_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/circular-dependency_spec_large.ts
index ab817a7cff..7b93b85b7f 100644
--- a/packages/angular_devkit/build_angular/test/browser/circular-dependency_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/circular-dependency_spec_large.ts
@@ -6,9 +6,9 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder circular dependency detection', () => {
@@ -22,9 +22,9 @@ describe('Browser Builder circular dependency detection', () => {
     const overrides = { baseHref: '/myUrl' };
     const logger = new TestLogger('circular-dependencies');
 
-    runTargetSpec(host, browserTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout, logger).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(logger.includes('Circular dependency detected')).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/deploy-url_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/deploy-url_spec_large.ts
index 9ce163d7f0..f24dd02475 100644
--- a/packages/angular_devkit/build_angular/test/browser/deploy-url_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/deploy-url_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { concatMap, tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder deploy url', () => {
@@ -37,7 +37,7 @@ describe('Browser Builder deploy url', () => {
         expect(content).toContain('http://example.com/some/path/main.js');
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('uses deploy url for in webpack runtime', (done) => {
     const overrides = { deployUrl: 'deployUrl/' };
@@ -50,6 +50,6 @@ describe('Browser Builder deploy url', () => {
         expect(content).toContain('deployUrl/');
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/errors_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/errors_spec_large.ts
index 7f3a521c7b..f5093885ee 100644
--- a/packages/angular_devkit/build_angular/test/browser/errors_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/errors_spec_large.ts
@@ -6,9 +6,9 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder errors', () => {
@@ -22,36 +22,36 @@ describe('Browser Builder errors', () => {
     `);
     const logger = new TestLogger('errors-compilation');
 
-    runTargetSpec(host, browserTargetSpec, undefined, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, {}, DefaultTimeout, logger).pipe(
       tap((buildEvent) => {
         expect(buildEvent.success).toBe(false);
         expect(logger.includes('polyfills.ts is missing from the TypeScript')).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('shows TS syntax errors', (done) => {
     host.appendToFile('src/app/app.component.ts', ']]]');
     const logger = new TestLogger('errors-syntax');
 
-    runTargetSpec(host, browserTargetSpec, undefined, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, {}, DefaultTimeout, logger).pipe(
       tap((buildEvent) => {
         expect(buildEvent.success).toBe(false);
         expect(logger.includes('Declaration or statement expected.')).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('shows static analysis errors', (done) => {
     host.replaceInFile('src/app/app.component.ts', `'app-root'`, `(() => 'app-root')()`);
     const logger = new TestLogger('errors-static');
 
-    runTargetSpec(host, browserTargetSpec, { aot: true }, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, { aot: true }, DefaultTimeout, logger).pipe(
       tap((buildEvent) => {
         expect(buildEvent.success).toBe(false);
         expect(logger.includes('Function expressions are not supported in')).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/i18n_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/i18n_spec_large.ts
index a74c737615..ee8e6f1271 100644
--- a/packages/angular_devkit/build_angular/test/browser/i18n_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/i18n_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder i18n', () => {
@@ -62,7 +62,7 @@ describe('Browser Builder i18n', () => {
         expect(content).toMatch(/Bonjour i18n!/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('ignores missing translations', (done) => {
     const overrides = {
@@ -84,7 +84,7 @@ describe('Browser Builder i18n', () => {
         expect(content).toMatch(/Other content/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('reports errors for missing translations', (done) => {
     const overrides = {
@@ -101,7 +101,7 @@ describe('Browser Builder i18n', () => {
     runTargetSpec(host, browserTargetSpec, overrides).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(false)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('register locales', (done) => {
     const overrides = { aot: true, i18nLocale: 'fr_FR' };
@@ -115,5 +115,5 @@ describe('Browser Builder i18n', () => {
         expect(content).toMatch(/angular_common_locales_fr/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/index_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/index_spec_large.ts
index 71b9f92870..7d2a8eb856 100644
--- a/packages/angular_devkit/build_angular/test/browser/index_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/index_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, tags, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder works with BOM index.html', () => {
@@ -34,7 +34,7 @@ describe('Browser Builder works with BOM index.html', () => {
         expect(content).toBe(`<html><head><base href="/"></head><body><app-root></app-root><script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body></html>`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('works with UTF16 LE BOM', (done) => {
     host.writeMultipleFiles({
@@ -52,7 +52,7 @@ describe('Browser Builder works with BOM index.html', () => {
         expect(content).toBe(`<html><head><base href="/"></head><body><app-root></app-root><script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body></html>`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('keeps escaped charaters', (done) => {
     host.writeMultipleFiles({
@@ -71,7 +71,7 @@ describe('Browser Builder works with BOM index.html', () => {
         expect(content).toBe(`<html><head><title>&iacute;</title><base href="/"></head> <body><app-root></app-root><script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body></html>`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('keeps custom template charaters', (done) => {
     host.writeMultipleFiles({
@@ -90,5 +90,5 @@ describe('Browser Builder works with BOM index.html', () => {
         expect(content).toBe(`<html><head><base href="/"><%= csrf_meta_tags %></head> <body><app-root></app-root><script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body></html>`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts
index 65a30a2a81..2177de3863 100644
--- a/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts
@@ -6,11 +6,11 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
 import { BrowserBuilderSchema } from '../../src';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 export const lazyModuleFiles: { [path: string]: string } = {
@@ -87,7 +87,7 @@ describe('Browser Builder lazy modules', () => {
         expect(host.scopedSync().exists(join(outputPath, 'lazy-lazy-module.js'))).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('supports lazy bundle for lazy routes with AOT', (done) => {
     host.writeMultipleFiles(lazyModuleFiles);
@@ -100,7 +100,7 @@ describe('Browser Builder lazy modules', () => {
           .exists(join(outputPath, 'lazy-lazy-module-ngfactory.js'))).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports lazy bundle for import() calls`, (done) => {
     host.writeMultipleFiles({
@@ -114,7 +114,7 @@ describe('Browser Builder lazy modules', () => {
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(host.scopedSync().exists(join(outputPath, '0.js'))).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports lazy bundle for dynamic import() calls`, (done) => {
     host.writeMultipleFiles({
@@ -130,7 +130,7 @@ describe('Browser Builder lazy modules', () => {
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(host.scopedSync().exists(join(outputPath, 'lazy-module.js'))).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports lazy bundle for System.import() calls`, (done) => {
     host.writeMultipleFiles({
@@ -142,7 +142,7 @@ describe('Browser Builder lazy modules', () => {
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(host.scopedSync().exists(join(outputPath, '0.js'))).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports hiding lazy bundle module name`, (done) => {
     host.writeMultipleFiles({
@@ -157,7 +157,7 @@ describe('Browser Builder lazy modules', () => {
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(host.scopedSync().exists(join(outputPath, '0.js'))).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports making a common bundle for shared lazy modules`, (done) => {
     host.writeMultipleFiles({
@@ -174,7 +174,7 @@ describe('Browser Builder lazy modules', () => {
       // TODO: the chunk with common modules used to be called `common`, see why that changed.
       tap(() => expect(host.scopedSync().exists(join(outputPath, '2.js'))).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports disabling the common bundle`, (done) => {
     host.writeMultipleFiles({
@@ -192,7 +192,7 @@ describe('Browser Builder lazy modules', () => {
       tap(() => expect(host.scopedSync().exists(join(outputPath, '1.js'))).toBe(true)),
       tap(() => expect(host.scopedSync().exists(join(outputPath, '2.js'))).toBe(false)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports extra lazy modules array in JIT`, (done) => {
     host.writeMultipleFiles(lazyModuleFiles);
@@ -223,7 +223,7 @@ describe('Browser Builder lazy modules', () => {
       tap(() => expect(host.scopedSync().exists(join(outputPath, 'src-app-lazy-lazy-module.js')))
         .toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports extra lazy modules array in AOT`, (done) => {
     host.writeMultipleFiles(lazyModuleFiles);
@@ -253,11 +253,11 @@ describe('Browser Builder lazy modules', () => {
       optimization: true,
     };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => expect(host.scopedSync()
         .exists(join(outputPath, 'src-app-lazy-lazy-module-ngfactory.js')))
         .toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/license-extraction_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/license-extraction_spec_large.ts
index d80b3ff81e..3dbea255bf 100644
--- a/packages/angular_devkit/build_angular/test/browser/license-extraction_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/license-extraction_spec_large.ts
@@ -6,10 +6,10 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder license extraction', () => {
@@ -24,12 +24,12 @@ describe('Browser Builder license extraction', () => {
     // TODO: make license extraction independent from optimization level.
     const overrides = { extractLicenses: true, optimization: true };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         const fileName = join(outputPath, '3rdpartylicenses.txt');
         expect(host.scopedSync().exists(fileName)).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/no-entry-module_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/no-entry-module_spec_large.ts
index 4bb2963f62..2046bf6e8e 100644
--- a/packages/angular_devkit/build_angular/test/browser/no-entry-module_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/no-entry-module_spec_large.ts
@@ -8,7 +8,7 @@
 
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder no entry module', () => {
@@ -25,5 +25,5 @@ describe('Browser Builder no entry module', () => {
     runTargetSpec(host, browserTargetSpec, overrides).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/optimization-level_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/optimization-level_spec_large.ts
index e1af671f2d..932ae0928b 100644
--- a/packages/angular_devkit/build_angular/test/browser/optimization-level_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/optimization-level_spec_large.ts
@@ -6,10 +6,10 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder optimization level', () => {
@@ -21,7 +21,7 @@ describe('Browser Builder optimization level', () => {
   it('works', (done) => {
     const overrides = { optimization: true };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         const fileName = join(outputPath, 'main.js');
@@ -30,14 +30,14 @@ describe('Browser Builder optimization level', () => {
         expect(content).not.toContain('AppComponent');
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
   it('tsconfig target changes optimizations to use ES2015', (done) => {
     host.replaceInFile('tsconfig.json', '"target": "es5"', '"target": "es2015"');
 
     const overrides = { optimization: true };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         const fileName = join(outputPath, 'vendor.js');
@@ -45,5 +45,5 @@ describe('Browser Builder optimization level', () => {
         expect(content).toMatch(/class \w{constructor\(\){/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/output-hashing_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/output-hashing_spec_large.ts
index d2e18ebb49..999e843c5d 100644
--- a/packages/angular_devkit/build_angular/test/browser/output-hashing_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/output-hashing_spec_large.ts
@@ -6,10 +6,10 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { normalize } from '@angular-devkit/core';
 import { concatMap, tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 import { lazyModuleFiles, lazyModuleImport } from './lazy-module_spec_large';
 
 
@@ -61,7 +61,7 @@ describe('Browser Builder output hashing', () => {
 
     // We must do several builds instead of a single one in watch mode, so that the output
     // path is deleted on each run and only contains the most recent files.
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3).pipe(
       tap(() => {
         // Save the current hashes.
         oldHashes = generateFileHashMap();
@@ -107,17 +107,19 @@ describe('Browser Builder output hashing', () => {
         validateHashes(oldHashes, newHashes, []);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Massive);
+  });
 
   it('supports options', (done) => {
     host.writeMultipleFiles({ 'src/styles.css': `h1 { background: url('./spectrum.png')}` });
     host.writeMultipleFiles(lazyModuleFiles);
     host.writeMultipleFiles(lazyModuleImport);
 
+    const overrides = { outputHashing: 'all', extractCss: true };
+
     // We must do several builds instead of a single one in watch mode, so that the output
     // path is deleted on each run and only contains the most recent files.
     // 'all' should hash everything.
-    runTargetSpec(host, browserTargetSpec, { outputHashing: 'all', extractCss: true }).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap(() => {
         expect(host.fileMatchExists('dist', /runtime\.[0-9a-f]{20}\.js/)).toBeTruthy();
         expect(host.fileMatchExists('dist', /main\.[0-9a-f]{20}\.js/)).toBeTruthy();
@@ -160,5 +162,5 @@ describe('Browser Builder output hashing', () => {
         expect(host.fileMatchExists('dist', /spectrum\.[0-9a-f]{20}\.png/)).toBeFalsy();
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/output-path_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/output-path_spec_large.ts
index c4db03b065..61fff72011 100644
--- a/packages/angular_devkit/build_angular/test/browser/output-path_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/output-path_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder output path', () => {
@@ -33,12 +33,12 @@ describe('Browser Builder output path', () => {
         expect(host.scopedSync().exists(outputPath)).toBe(false);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('does not allow output path to be project root', (done) => {
     const overrides = { outputPath: './' };
 
     runTargetSpec(host, browserTargetSpec, overrides)
       .subscribe(undefined, () => done(), done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/poll_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/poll_spec_large.ts
index 53ca623fa9..cada0a0663 100644
--- a/packages/angular_devkit/build_angular/test/browser/poll_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/poll_spec_large.ts
@@ -8,7 +8,7 @@
 
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { debounceTime, take, tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder poll', () => {
@@ -39,5 +39,5 @@ describe('Browser Builder poll', () => {
       expect(msAvg).toBeLessThan(2750);
       done();
     });
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts
index ec730fbc2c..ed534fded5 100644
--- a/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts
@@ -6,10 +6,10 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { debounceTime, take, tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 import { lazyModuleFiles, lazyModuleImport } from './lazy-module_spec_large';
 
 
@@ -66,7 +66,7 @@ describe('Browser Builder rebuilds', () => {
 
     let buildNumber = 0;
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3).pipe(
       // We must debounce on watch mode because file watchers are not very accurate.
       // Changes from just before a process runs can be picked up and cause rebuilds.
       // In this case, cleanup from the test right before this one causes a few rebuilds.
@@ -109,18 +109,18 @@ describe('Browser Builder rebuilds', () => {
       }),
       take(3),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Massive);
+  });
 
   it('rebuilds on CSS changes', (done) => {
     const overrides = { watch: true };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3).pipe(
       debounceTime(500),
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => host.appendToFile('src/app/app.component.css', ':host { color: blue; }')),
       take(2),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Massive);
+  });
 
   it('type checks on rebuilds', (done) => {
     host.writeMultipleFiles({
@@ -137,7 +137,7 @@ describe('Browser Builder rebuilds', () => {
     const typeError = `is not assignable to parameter of type 'number'`;
     let buildNumber = 0;
 
-    runTargetSpec(host, browserTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3, logger).pipe(
       debounceTime(1000),
       tap((buildEvent) => {
         buildNumber += 1;
@@ -179,7 +179,7 @@ describe('Browser Builder rebuilds', () => {
       }),
       take(4),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Massive);
+  });
 
   it('rebuilds on type changes', (done) => {
     host.writeMultipleFiles({ 'src/type.ts': `export type MyType = number;` });
@@ -187,13 +187,13 @@ describe('Browser Builder rebuilds', () => {
 
     const overrides = { watch: true };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3).pipe(
       debounceTime(1000),
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => host.writeMultipleFiles({ 'src/type.ts': `export type MyType = string;` })),
       take(2),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
 
   it('rebuilds after errors in AOT', (done) => {
@@ -209,7 +209,7 @@ describe('Browser Builder rebuilds', () => {
     const syntaxError = 'Declaration or statement expected.';
     let buildNumber = 0;
 
-    runTargetSpec(host, browserTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3, logger).pipe(
       debounceTime(1000),
       tap((buildEvent) => {
         buildNumber += 1;
@@ -255,7 +255,7 @@ describe('Browser Builder rebuilds', () => {
       }),
       take(5),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
 
   it('rebuilds AOT factories', (done) => {
@@ -271,7 +271,7 @@ describe('Browser Builder rebuilds', () => {
     const overrides = { watch: true, aot: true, forkTypeChecker: false };
     let buildNumber = 0;
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 3).pipe(
       debounceTime(1000),
       tap((buildEvent) => {
         buildNumber += 1;
@@ -334,5 +334,5 @@ describe('Browser Builder rebuilds', () => {
       }),
       take(7),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/replacements_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/replacements_spec_large.ts
index 75851924fa..f96ac4a10a 100644
--- a/packages/angular_devkit/build_angular/test/browser/replacements_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/replacements_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder file replacements', () => {
@@ -49,7 +49,7 @@ describe('Browser Builder file replacements', () => {
           .not.toMatch(/meaning\s*=\s*10/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`allows file replacements with deprecated format`, (done) => {
     const overrides = {
@@ -71,7 +71,7 @@ describe('Browser Builder file replacements', () => {
           .not.toMatch(/meaning\s*=\s*10/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`fails compilation with missing 'replace' file`, (done) => {
     const overrides = {
@@ -85,7 +85,7 @@ describe('Browser Builder file replacements', () => {
 
     runTargetSpec(host, browserTargetSpec, overrides)
       .subscribe(undefined, () => done(), done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`fails compilation with missing 'with' file`, (done) => {
     const overrides = {
@@ -99,5 +99,5 @@ describe('Browser Builder file replacements', () => {
 
     runTargetSpec(host, browserTargetSpec, overrides)
       .subscribe(undefined, () => done(), done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/scripts-array_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/scripts-array_spec_large.ts
index 3aa5928b78..40ab2b5fa8 100644
--- a/packages/angular_devkit/build_angular/test/browser/scripts-array_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/scripts-array_spec_large.ts
@@ -6,10 +6,10 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { PathFragment, join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder scripts array', () => {
@@ -74,7 +74,7 @@ describe('Browser Builder scripts array', () => {
         expect(content).toMatch(matches[fileName]);
       })),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('uglifies, uses sourcemaps, and adds hashes', (done) => {
     host.writeMultipleFiles(scripts);
@@ -86,7 +86,7 @@ describe('Browser Builder scripts array', () => {
       scripts: getScriptsOption(),
     };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         const scriptsBundle = host.fileMatchExists(outputPath, /scripts\.[0-9a-f]{20}\.js/);
@@ -108,7 +108,7 @@ describe('Browser Builder scripts array', () => {
           .toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
   it('preserves script order', (done) => {
     host.writeMultipleFiles(scripts);
@@ -132,5 +132,5 @@ describe('Browser Builder scripts array', () => {
         expect(content).toMatch(re);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/service-worker_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/service-worker_spec_large.ts
index cfaabd684a..0ec60ea749 100644
--- a/packages/angular_devkit/build_angular/test/browser/service-worker_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/service-worker_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder service worker', () => {
@@ -49,7 +49,7 @@ describe('Browser Builder service worker', () => {
       .subscribe(event => {
         expect(event.success).toBe(false);
       }, () => done(), done.fail);
-  }, Timeout.Basic);
+  });
 
   it('works with service worker', (done) => {
     host.writeMultipleFiles({
@@ -104,7 +104,7 @@ describe('Browser Builder service worker', () => {
         });
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('works with service worker and baseHref', (done) => {
     host.writeMultipleFiles({
@@ -159,5 +159,5 @@ describe('Browser Builder service worker', () => {
         });
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/source-map_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/source-map_spec_large.ts
index df08df1348..4708376f1f 100644
--- a/packages/angular_devkit/build_angular/test/browser/source-map_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/source-map_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder source map', () => {
@@ -28,7 +28,7 @@ describe('Browser Builder source map', () => {
         expect(host.scopedSync().exists(fileName)).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('does not output source map when disabled', (done) => {
     const overrides = { sourceMap: false };
@@ -40,7 +40,7 @@ describe('Browser Builder source map', () => {
         expect(host.scopedSync().exists(fileName)).toBe(false);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('supports eval source map', (done) => {
     const overrides = { sourceMap: true, evalSourceMap: true };
@@ -54,5 +54,5 @@ describe('Browser Builder source map', () => {
         expect(content).toContain('eval("function webpackEmptyAsyncContext');
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/stats-json_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/stats-json_spec_large.ts
index 550bb542ca..c34556ad0f 100644
--- a/packages/angular_devkit/build_angular/test/browser/stats-json_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/stats-json_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder stats json', () => {
@@ -28,5 +28,5 @@ describe('Browser Builder stats json', () => {
         expect(host.scopedSync().exists(fileName)).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/styles_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/styles_spec_large.ts
index ff9c92318e..bd8be4b7ce 100644
--- a/packages/angular_devkit/build_angular/test/browser/styles_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/styles_spec_large.ts
@@ -6,10 +6,10 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, runTargetSpec } from '@angular-devkit/architect/testing';
 import { normalize, tags, virtualFs } from '@angular-devkit/core';
 import { concatMap, tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder styles', () => {
@@ -104,7 +104,7 @@ describe('Browser Builder styles', () => {
         expect(content).toMatch(jsIndexMatches[fileName]);
       })),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('supports empty styleUrls in components', (done) => {
     host.writeMultipleFiles({
@@ -127,7 +127,7 @@ describe('Browser Builder styles', () => {
     runTargetSpec(host, browserTargetSpec, overrides).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   extensionsWithImportSupport.forEach(ext => {
     it(`supports imports in ${ext} files`, (done) => {
@@ -180,7 +180,7 @@ describe('Browser Builder styles', () => {
           expect(content).toMatch(matches[fileName]);
         })),
       ).toPromise().then(done, done.fail);
-    }, Timeout.Basic);
+    });
   });
 
   extensionsWithImportSupport.forEach(ext => {
@@ -206,7 +206,7 @@ describe('Browser Builder styles', () => {
       runTargetSpec(host, browserTargetSpec, overrides).pipe(
         tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       ).toPromise().then(done, done.fail);
-    }, Timeout.Basic);
+    });
   });
 
   it(`supports material icons`, (done) => {
@@ -218,10 +218,10 @@ describe('Browser Builder styles', () => {
       ],
     };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
   extensionsWithVariableSupport.forEach(ext => {
     it(`supports ${ext} includePaths`, (done) => {
@@ -274,7 +274,7 @@ describe('Browser Builder styles', () => {
           expect(content).toMatch(matches[fileName]);
         })),
       ).toPromise().then(done, done.fail);
-    }, Timeout.Standard);
+    });
   });
 
   it('inlines resources', (done) => {
@@ -331,7 +331,7 @@ describe('Browser Builder styles', () => {
       //   throw new Error('Expected no postcss-url file read warnings.');
       // }
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`supports font-awesome imports`, (done) => {
     host.writeMultipleFiles({
@@ -369,7 +369,7 @@ describe('Browser Builder styles', () => {
           div { -ms-flex: 1; flex: 1 }`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it(`minimizes css`, (done) => {
     host.writeMultipleFiles({
@@ -381,7 +381,7 @@ describe('Browser Builder styles', () => {
 
     const overrides = { extractCss: true, optimization: true };
 
-    runTargetSpec(host, browserTargetSpec, overrides).pipe(
+    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         const fileName = 'dist/styles.css';
@@ -390,7 +390,7 @@ describe('Browser Builder styles', () => {
           '/*! important-comment */div{-ms-flex:1;flex:1}');
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Complex);
+  });
 
   // TODO: consider making this a unit test in the url processing plugins.
   it(`supports baseHref and deployUrl in resource urls`, (done) => {
@@ -527,5 +527,5 @@ describe('Browser Builder styles', () => {
     runTargetSpec(host, browserTargetSpec, overrides).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/subresource-integrity_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/subresource-integrity_spec_large.ts
index 7cfd848122..83c31d5870 100644
--- a/packages/angular_devkit/build_angular/test/browser/subresource-integrity_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/subresource-integrity_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder subresource integrity', () => {
@@ -34,5 +34,5 @@ describe('Browser Builder subresource integrity', () => {
         expect(content).toMatch(/integrity="\w+-[A-Za-z0-9\/\+=]+"/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/tsconfig-paths_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/tsconfig-paths_spec_large.ts
index db87d7f398..a37a5d3877 100644
--- a/packages/angular_devkit/build_angular/test/browser/tsconfig-paths_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/tsconfig-paths_spec_large.ts
@@ -8,7 +8,7 @@
 
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder tsconfig paths', () => {
@@ -29,7 +29,7 @@ describe('Browser Builder tsconfig paths', () => {
     runTargetSpec(host, browserTargetSpec).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('works', (done) => {
     host.writeMultipleFiles({
@@ -71,5 +71,5 @@ describe('Browser Builder tsconfig paths', () => {
     runTargetSpec(host, browserTargetSpec).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/vendor-chunk_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/vendor-chunk_spec_large.ts
index b93a30d1cc..7c0fc24801 100644
--- a/packages/angular_devkit/build_angular/test/browser/vendor-chunk_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/vendor-chunk_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder vendor chunk', () => {
@@ -28,5 +28,5 @@ describe('Browser Builder vendor chunk', () => {
         expect(host.scopedSync().exists(fileName)).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts
index 1dde6a577f..45bc619140 100644
--- a/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts
@@ -10,7 +10,7 @@ import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import * as path from 'path';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 describe('Browser Builder external source map', () => {
   const outputPath = normalize('dist');
@@ -32,7 +32,7 @@ describe('Browser Builder external source map', () => {
         expect(path.extname(sourcePath)).toBe('.ts', `${sourcePath} extention should be '.ts'`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('does not map sourcemaps from external library when disabled', (done) => {
     const overrides = { sourceMap: true, vendorSourceMap: false };
@@ -48,6 +48,6 @@ describe('Browser Builder external source map', () => {
         expect(path.extname(sourcePath)).toBe('.js', `${sourcePath} extention should be '.js'`);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
 });
diff --git a/packages/angular_devkit/build_angular/test/browser/works_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/works_spec_large.ts
index f6f3f52645..aeeefccf3f 100644
--- a/packages/angular_devkit/build_angular/test/browser/works_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/works_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
-import { Timeout, browserTargetSpec, host } from '../utils';
+import { browserTargetSpec, host } from '../utils';
 
 
 describe('Browser Builder basic test', () => {
@@ -32,5 +32,5 @@ describe('Browser Builder basic test', () => {
         expect(host.scopedSync().exists(join(outputPath, 'index.html'))).toBe(true);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/extract-i18n/works_spec_large.ts b/packages/angular_devkit/build_angular/test/extract-i18n/works_spec_large.ts
index 4b7477a1f4..2c69b92dd2 100644
--- a/packages/angular_devkit/build_angular/test/extract-i18n/works_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/extract-i18n/works_spec_large.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
 import { extractI18nTargetSpec, host } from '../utils';
@@ -36,7 +36,7 @@ describe('Extract i18n Target', () => {
     host.appendToFile('src/app/app.component.html',
       '<p i18n>Hello world <span i18n>inner</span></p>');
 
-    runTargetSpec(host, extractI18nTargetSpec, {}, logger).pipe(
+    runTargetSpec(host, extractI18nTargetSpec, {}, DefaultTimeout, logger).pipe(
       tap((buildEvent) => {
         expect(buildEvent.success).toBe(false);
         const msg = 'Could not mark an element as translatable inside a translatable section';
diff --git a/packages/angular_devkit/build_angular/test/server/base_spec_large.ts b/packages/angular_devkit/build_angular/test/server/base_spec_large.ts
index beff84f3e0..845666bf5e 100644
--- a/packages/angular_devkit/build_angular/test/server/base_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/server/base_spec_large.ts
@@ -9,7 +9,7 @@
 import { runTargetSpec } from '@angular-devkit/architect/testing';
 import { join, normalize, virtualFs } from '@angular-devkit/core';
 import { take, tap } from 'rxjs/operators';
-import { Timeout, host } from '../utils';
+import { host } from '../utils';
 
 
 describe('Server Builder', () => {
@@ -30,7 +30,7 @@ describe('Server Builder', () => {
         expect(content).toMatch(/AppServerModuleNgFactory/);
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Standard);
+  });
 
   it('supports sourcemaps', (done) => {
     const overrides = { sourceMap: true };
@@ -45,7 +45,7 @@ describe('Server Builder', () => {
         expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBeTruthy();
       }),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Standard);
+  });
 
   it('runs watch mode', (done) => {
     const overrides = { watch: true };
@@ -60,5 +60,5 @@ describe('Server Builder', () => {
       }),
       take(1),
     ).subscribe(undefined, done.fail, done);
-  }, Timeout.Standard);
+  });
 });
diff --git a/packages/angular_devkit/build_angular/test/tslint/works_spec_large.ts b/packages/angular_devkit/build_angular/test/tslint/works_spec_large.ts
index 9a652f76aa..bd14b52247 100644
--- a/packages/angular_devkit/build_angular/test/tslint/works_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/tslint/works_spec_large.ts
@@ -6,7 +6,7 @@
  * found in the LICENSE file at https://angular.io/license
  */
 
-import { TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
+import { DefaultTimeout, TestLogger, runTargetSpec } from '@angular-devkit/architect/testing';
 import { normalize, virtualFs } from '@angular-devkit/core';
 import { tap } from 'rxjs/operators';
 import { TslintBuilderOptions } from '../../src';
@@ -53,7 +53,7 @@ describe('Tslint Target', () => {
     const logger = new TestLogger('lint-force');
     const overrides: Partial<TslintBuilderOptions> = { force: true };
 
-    runTargetSpec(host, tslintTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, tslintTargetSpec, overrides, DefaultTimeout, logger).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
       tap(() => {
         expect(logger.includes(`" should be '`)).toBe(true);
@@ -67,7 +67,7 @@ describe('Tslint Target', () => {
     const logger = new TestLogger('lint-format');
     const overrides: Partial<TslintBuilderOptions> = { format: 'stylish' };
 
-    runTargetSpec(host, tslintTargetSpec, overrides, logger).pipe(
+    runTargetSpec(host, tslintTargetSpec, overrides, DefaultTimeout, logger).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(false)),
       tap(() => {
         expect(logger.includes(`quotemark`)).toBe(true);
diff --git a/packages/angular_devkit/build_angular/test/utils.ts b/packages/angular_devkit/build_angular/test/utils.ts
index 3eaa672bf6..dd4a2df08a 100644
--- a/packages/angular_devkit/build_angular/test/utils.ts
+++ b/packages/angular_devkit/build_angular/test/utils.ts
@@ -21,10 +21,3 @@ export const extractI18nTargetSpec = { project: 'app', target: 'extract-i18n' };
 export const karmaTargetSpec = { project: 'app', target: 'test' };
 export const tslintTargetSpec = { project: 'app', target: 'lint' };
 export const protractorTargetSpec = { project: 'app-e2e', target: 'e2e' };
-
-export enum Timeout {
-  Basic = 30000,
-  Standard = Basic * 1.5,
-  Complex = Basic * 2,
-  Massive = Basic * 4,
-}
diff --git a/packages/angular_devkit/build_ng_packagr/src/build/index_spec_large.ts b/packages/angular_devkit/build_ng_packagr/src/build/index_spec_large.ts
index a0882db0d5..f2d66cc774 100644
--- a/packages/angular_devkit/build_ng_packagr/src/build/index_spec_large.ts
+++ b/packages/angular_devkit/build_ng_packagr/src/build/index_spec_large.ts
@@ -16,11 +16,6 @@ const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-lin
 const workspaceRoot = join(devkitRoot, 'tests/@angular_devkit/build_ng_packagr/ng-packaged/');
 export const host = new TestProjectHost(workspaceRoot);
 
-export enum Timeout {
-  Basic = 30000,
-  Standard = Basic * 1.5,
-}
-
 describe('NgPackagr Builder', () => {
   beforeEach(done => host.initialize().toPromise().then(done, done.fail));
   afterEach(done => host.restore().toPromise().then(done, done.fail));
@@ -31,7 +26,7 @@ describe('NgPackagr Builder', () => {
     runTargetSpec(host, targetSpec).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 
   it('tests works', (done) => {
     const targetSpec: TargetSpecifier = { project: 'lib', target: 'test' };
@@ -39,7 +34,7 @@ describe('NgPackagr Builder', () => {
     runTargetSpec(host, targetSpec).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Standard);
+  });
 
   it('lint works', (done) => {
     const targetSpec: TargetSpecifier = { project: 'lib', target: 'lint' };
@@ -47,5 +42,5 @@ describe('NgPackagr Builder', () => {
     runTargetSpec(host, targetSpec).pipe(
       tap((buildEvent) => expect(buildEvent.success).toBe(true)),
     ).toPromise().then(done, done.fail);
-  }, Timeout.Basic);
+  });
 });
diff --git a/packages/angular_devkit/build_webpack/src/webpack/index_spec_large.ts b/packages/angular_devkit/build_webpack/src/webpack/index_spec_large.ts
index e5b5749f77..a9e130aa2a 100644
--- a/packages/angular_devkit/build_webpack/src/webpack/index_spec_large.ts
+++ b/packages/angular_devkit/build_webpack/src/webpack/index_spec_large.ts
@@ -27,7 +27,7 @@ describe('Webpack Builder basic test', () => {
           expect(basicHost.scopedSync().exists(join(outputPath, 'bundle.js'))).toBe(true);
         }),
       ).toPromise().then(done, done.fail);
-    }, 30000);
+    });
   });
 
   describe('Angular app', () => {
@@ -45,6 +45,6 @@ describe('Webpack Builder basic test', () => {
           expect(angularHost.scopedSync().exists(join(outputPath, 'polyfills.js'))).toBe(true);
         }),
       ).toPromise().then(done, done.fail);
-    }, 30000);
+    });
   });
 });
diff --git a/scripts/test.ts b/scripts/test.ts
index 3685490c34..26de76f4cf 100644
--- a/scripts/test.ts
+++ b/scripts/test.ts
@@ -171,6 +171,11 @@ export default function (args: ParsedArgs, logger: logging.Logger) {
     runner.env.addReporter(new IstanbulReporter());
   }
 
+  if (args.large) {
+    // Default timeout for large specs is 2.5 minutes.
+    jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000;
+  }
+
   // Run the tests.
   const allTests =
     glob.sync(regex)