diff --git a/packages/angular-cli/plugins/karma.js b/packages/angular-cli/plugins/karma.js index 1448b2bb4408..0131b660264e 100644 --- a/packages/angular-cli/plugins/karma.js +++ b/packages/angular-cli/plugins/karma.js @@ -1,4 +1,6 @@ const path = require('path'); +const fs = require('fs'); + const getWebpackTestConfig = require('../models/webpack-build-test').getWebpackTestConfig; const CliConfig = require('../models/config').CliConfig; @@ -17,6 +19,27 @@ const init = (config) => { progress: config.angularCli.progress } + // add assets + if (appConfig.assets) { + const assets = typeof appConfig.assets === 'string' ? [appConfig.assets] : appConfig.assets; + config.proxies = config.proxies || {}; + assets.forEach(asset => { + const fullAssetPath = path.join(config.basePath, appConfig.root, asset); + const isDirectory = fs.lstatSync(fullAssetPath).isDirectory(); + const filePattern = isDirectory ? fullAssetPath + '/**' : fullAssetPath; + const proxyPath = isDirectory ? asset + '/' : asset; + config.files.push({ + pattern: filePattern, + included: false, + served: true, + watched: true + }); + // The `files` entry serves the file from `/base/{appConfig.root}/{asset}` + // so, we need to add a URL rewrite that exposes the asset as `/{asset}` only + config.proxies['/' + proxyPath] = '/base/' + appConfig.root + '/' + proxyPath; + }); + } + // add webpack config const webpackConfig = getWebpackTestConfig(config.basePath, environment, appConfig, testConfig); const webpackMiddlewareConfig = { diff --git a/tests/e2e/tests/test/test.ts b/tests/e2e/tests/test/test.ts index c64a17088ada..89859a4caef9 100644 --- a/tests/e2e/tests/test/test.ts +++ b/tests/e2e/tests/test/test.ts @@ -1,8 +1,65 @@ -import {ng} from '../../utils/process'; +import { writeMultipleFiles } from '../../utils/fs'; +import { ng } from '../../utils/process'; +import { updateJsonFile } from '../../utils/project'; +import { expectToFail } from '../../utils/utils'; +import { stripIndent } from 'common-tags'; -export default function() { - // make sure both --watch=false and --single-run work +export default function () { + // Each test function returns PromiseLike, + // which would throw normally + // but resolve() normalizes this to from the start + return Promise.resolve() + .then(() => testWatchFalseAndSingleRun()) + .then(() => testAssetsAreServed()); +} + +// Make sure both --watch=false and --single-run work +function testWatchFalseAndSingleRun() { return ng('test', '--single-run') .then(() => ng('test', '--watch=false')); } + +// Make sure asset files are served +function testAssetsAreServed() { + return Promise.resolve() + .then(() => writeMultipleFiles({ + 'src/assets/file.txt': 'assets-folder-content', + 'src/file.txt': 'file-content', + // Not using `async()` in tests as it seemed to swallow `fetch()` errors + 'src/app/app.component.spec.ts': stripIndent` + describe('Test Runner', () => { + const fetch = global['fetch']; + it('should serve files in assets folder', (done) => { + fetch('/assets/file.txt') + .then(response => response.text()) + .then(fileText => { + expect(fileText).toMatch('assets-folder-content'); + done(); + }); + }); + it('should serve files explicitly added to assets array', (done) => { + fetch('/file.txt') + .then(response => response.text()) + .then(fileText => { + expect(fileText).toMatch('file-content'); + done(); + }); + }); + }); + ` + })) + // Test failure condition (no assets in angular-cli.json) + .then(() => updateJsonFile('angular-cli.json', configJson => { + const app = configJson['apps'][0]; + app['assets'] = []; + })) + .then(() => expectToFail(() => ng('test', '--single-run'), + 'Should fail because the assets to serve were not in the angular-cli config')) + // Test passing condition (assets are included) + .then(() => updateJsonFile('angular-cli.json', configJson => { + const app = configJson['apps'][0]; + app['assets'] = ['assets', 'file.txt']; + })) + .then(() => ng('test', '--single-run')); +} diff --git a/tests/e2e/utils/utils.ts b/tests/e2e/utils/utils.ts index f1c92420181b..0e89816b07c1 100644 --- a/tests/e2e/utils/utils.ts +++ b/tests/e2e/utils/utils.ts @@ -1,9 +1,12 @@ -export function expectToFail(fn: () => Promise): Promise { +export function expectToFail(fn: () => Promise, errorMessage?: string): Promise { return fn() .then(() => { - throw new Error(`Function ${fn.source} was expected to fail, but succeeded.`); - }, () => {}); + const functionSource = fn.name || (fn).source || fn.toString(); + const errorDetails = errorMessage ? `\n\tDetails:\n\t${errorMessage}` : ''; + throw new Error( + `Function ${functionSource} was expected to fail, but succeeded.${errorDetails}`); + }, () => { }); } export function isMobileTest() {