As the question states, the requiring/importing of the module works fine in these cases:
const Session = require('../session.js').default;
or
import Session from '../session.js');
But I want to replace a module that is required inside session.js, so I tried to do that in a test with Proxyquireify:
const proxyquire = require('proxyquireify')(require);
const someStub = () => { return {}; };
someStub['#noCallThru'] = true;
const Session = proxyquire('../session.js', {
'some': someStub
}).default;
Then I get an error stating that the module '../session.js' cannot be found.
PhantomJS 1.9.8 (Linux 0.0.0) ERROR
Error: Cannot find module '../session.js'
My karma config is this:
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['browserify', 'jasmine'],
files: [
'spec/**/*Spec.js'
],
exclude: [
'spec/**/PlayerSpec.js'
],
preprocessors: {
'spec/**/*Spec.js': ['browserify']
},
browserify: {
debug: true,
transform: ['babelify']
},
reporters: ['progress', 'dots'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false,
concurrency: Infinity
})
};
What could be wrong? Do you need any more information?
Just stumbled onto the same issue.
Noticed that proxyquireify did not inject require calls next to proxyquire ones for some reason, so I just ended up simply doing it myself, at least for now.
Try using something like this:
require('../session.js');
const Session = proxyquire('../session.js', ...);
Related
I have very little experience with configuring Webpack, and I'am a bit overwhelmed by this issue.
I've been working on a Vue2 project built on top of this boilerplate. The project has a folder called public which contains the entry point file index.html. Inside that index.html file I can normally access .env environment variables (e.g. process.env.VUE_APP_PAGE_TITLE).
I've included an HTML fragment inside the public folder, navbar.html, because I want it to be available for other applications via https://example.com/public/navbar.html. However, I cannot seem to get my environment variables working inside ./public/navbar.html even though they work just fine in ./public/index.html. I assume this is a problem with my webpack config.
I know I can edit my Webpack config by editing a file in my project root called vue.config.js. This file contains a configureWebpack object, but I have no idea how to make it enable environment variables inside ./public/navbar.html. Any help would be appreciated.
EDIT:
Here's my vue.config.js:
const HtmlWebpackPlugin = require('html-webpack-plugin');
function resolveClientEnv() {
const env = {};
Object.keys(process.env).forEach((key) => {
env[key] = process.env[key];
});
env.BASE_URL = '/';
return env;
}
module.exports = {
configureWebpack: {
plugins: [
new HtmlWebpackPlugin({
// This is the generated file from the build, which ends up in public/navbar.html
filename: 'navbar.html',
// This is the source file you edit.
template: 'public/navbar.html',
templateParameters: (compilation, assets, pluginOptions) => {
let stats;
return Object.assign({
// make stats lazy as it is expensive
get webpack() {
return stats || (stats = compilation.getStats().toJson());
},
compilation,
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options: pluginOptions,
},
}, resolveClientEnv());
},
}),
],
},
};
This is what my custom HTMLWebpackPlugin adds to the configuration according to vue inspect:
{
options: {
template: 'public/navbar.html',
templateContent: false,
templateParameters: function () { /* omitted long function */ },
filename: 'navbar.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: 'auto',
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: [],
chunksSortMode: 'auto',
meta: {},
base: false,
title: 'Webpack App',
xhtml: false
},
childCompilerHash: undefined,
childCompilationOutputName: undefined,
assetJson: undefined,
hash: undefined,
version: 4
}
Use this standard plugin to generate navbar.html. https://github.com/jantimon/html-webpack-plugin.
If you read the docs, the templateParameters option is what you pass env variables to. Those variables will be available in navbar.html.
This is the same plugin that vue-cli uses for index.html. If you run the vue inspect command, you can see what options they provide to the plugin. You'll need to read the source code for resolveClientEnv() to see how it works.
Example:
/* config.plugin('html-portal') */
new HtmlWebpackPlugin(
{
templateParameters: (compilation, assets, pluginOptions) => {
// enhance html-webpack-plugin's built in template params
let stats
return Object.assign({
// make stats lazy as it is expensive
get webpack () {
return stats || (stats = compilation.getStats().toJson())
},
compilation: compilation,
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options: pluginOptions
}
}, resolveClientEnv(options, true /* raw */))
},
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
collapseBooleanAttributes: true,
removeScriptTypeAttributes: true
},
chunks: [
'chunk-vendors',
'chunk-common',
'portal'
],
template: 'C:\\Users\\Eric\\workspace\\arc-core\\portal\\client\\templates\\portal.html',
filename: 'portal.html',
title: 'Arc Portal'
}
),
That's a bit much, a minimal example would be:
new HtmlWebpackPlugin({
// This is the generated file from the build, which ends up in public/navbar.html
filename: 'navbar.html',
// This is the source file you edit.
template: 'templates/navbar.html',
templateParameters: {
MY_VAR: 'myVar'
}
}),
I'm starting to use webpack-workbox-plugin to inject service worker into application. My project is an ASP.NET Core web application that runs over IIS Express.
This is my development webpack config file:
const MODULE_BUILD_DIR = path.resolve(__dirname, './wwwroot/dist/assets/');
const workboxPlugin = require('workbox-webpack-plugin');
process.env.NODE_ENV = "development";
const config = {
mode: "development",
target: "web",
devtool: "cheap-module-source-map",
context: __dirname, // string (absolute path!)
entry: [
'#babel/polyfill',
'font-awesome/scss/font-awesome.scss',
'./wwwroot/js/main.js',
],
output: {
path: MODULE_BUILD_DIR,
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js',
},
// ...
plugins: [
// ...
new workboxPlugin.GenerateSW({
swDest: 'sw.js',
clientsClaim: true,
skipWaiting: true,
}),
],
devServer: {
contentBase: path.resolve(__dirname, './'),
historyApiFallback: false,
inline: true,
open: false,
port: 9099,
hot: true,
https: true,
},
// ...
}
And this is the function i call over my main.js:
export default function setServiceWorker() {
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then((registration) => {
console.log('SW registered: ', registration);
}).catch((registrationError) => {
console.log('SW registration failed: ', registrationError);
});
});
}
}
But when i run application, client doesn't find sw.js file becuse it's allocated over webpack dev server path, so not in IIS Express app path.
DevTool messages:
A bad HTTP response code (500) was received when fetching the script.
---
SW registration failed: TypeError: Failed to register a ServiceWorker
for scope ('https://localhost:44357/') with script ('https://localhost:44357/sw.js'):
A bad HTTP response code (500) was received when fetching the script.
What could be a solution for it?
Thank you
Solved using clean-webpack-plugin and write-file-webpack-plugin:
plugins: [
new CleanWebpackPlugin(),
new WorkboxPlugin.GenerateSW({
swDest: 'sw.js',
clientsClaim: true,
skipWaiting: true,
}),
new WriteFilePlugin(),
],
but not sure it's the best way
I am trying to run my unit tests with Karma. I have calendar.tests.js file that looks a lot like this:
import { handleSelectDay } from '../components/Calendar/index.vue'
describe('Calendar', () => {
describe('handleSelectDay', () => {
const data = {};
describe('updates data', () => {
it('should set the selectedDay to a new id', () => {
handleSelectDay('id');
expect(data.daySelected).to.equal('id');
});
});
});
});
When I run this test with Karma I get the following: TypeError: (0 , _index.handleSelectDay) is not a function is not a function
My karma.conf.js looks like:
module.exports = function (config) {
config.set({
frameworks: ['browserify', 'mocha'],
files: ['static/js/apps/FutureHours/test/calender.tests.js'],
preprocessors: {
'static/js/apps/**/test/*.js': ['browserify']
},
browsers: ['Chrome'],
logLevel: 'LOG_DEBUG',
plugins: [
'karma-mocha',
'karma-browserify',
'karma-chrome-launcher',
'karma-spec-reporter'
],
browserify: {
debug: true,
transform: [['babelify', { presets: ['env'] }], 'vueify']
}
})
}
How can I get Karma to play nice with VueJS single file components?
The problem with this is you can't have a named export from a .vue component. Instead, any methods used in the component will have to accessed via the component object in a unit test. Any functions used outside the component's methods, should probably live in their own ES module to make unit testing them much easier.
I have a big old project on Angular2, which I didn't start, and now I need to add tests there. I setup jasmine and karma, but, unfortunately, when I start "npm test", it don't see the .ts files, so I see the result only in .js-tests.
Here are the setup code:
system.config.js
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'src',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
'angular-in-memory-web-api': {
main: './index.js',
defaultExtension: 'js'
}
}
});
})(this);
karma.conf.js
// #docregion
module.exports = function(config) {
var appBase = 'src/'; // transpiled app JS and map files
var appSrcBase = 'src/'; // app source TS files
var appAssets = '/base/src/'; // component assets fetched by Angular's compiler
config.set({
basePath: '',
frameworks: ['jasmine'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'), // click "Debug" in browser to see it
require('karma-htmlfile-reporter') // crashing w/ strange socket error
],
customLaunchers: {
// From the CLI. Not used here but interesting
// chrome setup for travis CI using chromium
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
files: [
// System.js for module loading
'node_modules/systemjs/dist/system.src.js',
// Polyfills
'node_modules/core-js/client/shim.js',
'node_modules/reflect-metadata/Reflect.js',
// zone.js
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
'node_modules/zone.js/dist/proxy.js',
'node_modules/zone.js/dist/sync-test.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
// RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
// Paths loaded via module imports:
// Angular itself
{pattern: 'node_modules/#angular/**/*.js', included: false, watched: false},
{pattern: 'node_modules/#angular/**/*.js.map', included: false, watched: false},
{pattern: 'systemjs.config.js', included: false, watched: false},
'karma-test-shim.js',
// transpiled application & spec code paths loaded via module imports
{pattern: appBase + '**/*.js', included: false, watched: true},
{pattern: appBase + '**/*.ts', included: false, watched: true},
// Asset (HTML & CSS) paths loaded via Angular's component compiler
// (these paths need to be rewritten, see proxies section)
{pattern: appBase + '**/*.html', included: false, watched: true},
{pattern: appBase + '**/*.css', included: false, watched: true},
// Paths for debugging with source maps in dev tools
{pattern: appSrcBase + '**/*.ts', included: false, watched: false},
// {pattern: appBase + '**/*.js.map', included: false, watched: false}
],
// Proxied base paths for loading assets
proxies: {
// required for component assets fetched by Angular's compiler
"/src/": appAssets
},
exclude: [],
preprocessors: {},
// disabled HtmlReporter; suddenly crashing w/ strange socket error
reporters: ['progress', 'kjhtml'],//'html'],
// HtmlReporter configuration
htmlReporter: {
// Open this file to see results in browser
outputFile: '_test-output/tests.html',
// Optional
pageTitle: 'Unit Tests',
subPageTitle: __dirname
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
})
}
karma-test-shim.js
// #docregion
// /*global jasmine, __karma__, window*/
Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
// Uncomment to get full stacktrace output. Sometimes helpful, usually not.
// Error.stackTraceLimit = Infinity; //
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
var builtPath = '/base/src/';
__karma__.loaded = function () { };
function isJsFile(path) {
return path.slice(-3) == '.js';
}
function isSpecFile(path) {
return /\.spec\.(.*\.)?js$/.test(path);
}
function isBuiltFile(path) {
return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
}
var allSpecFiles = Object.keys(window.__karma__.files)
.filter(isSpecFile)
.filter(isBuiltFile);
System.config({
baseURL: '/base',
// Extend usual application package list with test folder
packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
// Assume npm: is set in `paths` in systemjs.config
// Map the angular testing umd bundles
map: {
'#angular/core/testing': 'npm:#angular/core/bundles/core-testing.umd.js',
'#angular/common/testing': 'npm:#angular/common/bundles/common-testing.umd.js',
'#angular/compiler/testing': 'npm:#angular/compiler/bundles/compiler-testing.umd.js',
'#angular/platform-browser/testing': 'npm:#angular/platform-browser/bundles/platform-browser-testing.umd.js',
'#angular/platform-browser-dynamic/testing': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
'#angular/http/testing': 'npm:#angular/http/bundles/http-testing.umd.js',
'#angular/router/testing': 'npm:#angular/router/bundles/router-testing.umd.js',
'#angular/forms/testing': 'npm:#angular/forms/bundles/forms-testing.umd.js',
},
});
System.import('systemjs.config.js')
.then(initTestBed)
.then(initTesting);
function initTestBed(){
return Promise.all([
System.import('#angular/core/testing'),
System.import('#angular/platform-browser-dynamic/testing')
])
.then(function (providers) {
var coreTesting = providers[0];
var browserTesting = providers[1];
coreTesting.TestBed.initTestEnvironment(
browserTesting.BrowserDynamicTestingModule,
browserTesting.platformBrowserDynamicTesting());
})
}
// Import all spec files and start karma
function initTesting () {
return Promise.all(
allSpecFiles.map(function (moduleName) {
return System.import(moduleName);
})
)
.then(__karma__.start, __karma__.error);
}
I know, that it is simplier to use solutions of angular-seed or angular-CLI, but it's really hard to migrate this huge project to new platform, so please help! )
What should I do to my "npm test" finally see the .spec.ts files?
This function is capturing only .js files:
function isSpecFile(path) {
return /\.spec\.(.*\.)?js$/.test(path);
}
To fix that, change to an expression that will include .ts files, such as:
function isSpecFile(path) {
return /\.spec\.(.*\.)?[jt]s$/.test(path);
}
Similar issue with:
function isJsFile(path) {
return path.slice(-3) == '.js';
}
...which could be changed to:
function isJsFile(path) {
return path.slice(-3) == '.js' || path.slice(-3) == '.ts';
}
I'd probably change the name isJsFile to isJsOrTsFile too, but you'd have to replace all instances.
I spent few hours on this issue and can't find what's wrong, I'm using karma/jasmine to create test in my angular app. I use, or at least try to use angular-mock to inject and test my controllers but I get this error :
Error: [$injector:unpr] Unknown provider: ENVProvider <- ENV
http://errors.angularjs.org/1.3.17/$injector/unpr?p0=ENVProvider%20%3C-%20ENV
in my test
describe('controllers', function(){
beforeEach(module('myModule'));
var $controller;
beforeEach(inject(function(_$controller_){
$controller = _$controller_;
}));
describe('$scope.testMessage', function() {
it('check the test message is ok', function() {
//TODO
});
});
});
So I suppose it's the inject call which cause the issue
here is my karma.conf.js
'use strict';
module.exports = function(config) {
var configuration = {
autoWatch : true,
frameworks: ['jasmine'],
ngHtml2JsPreprocessor: {
stripPrefix: 'src/',
moduleName: 'hematiteFront'
},
browsers : ['PhantomJS'],
plugins : [
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor'
],
files: [
'bower_components/jquery/dist/jquery.js',
'bower_components/angular/*.js',
'bower_components/angular-cookies/angular-cookies.js',
'bower_components/angular-touch/angular-touch.js',
'bower_components/angular-sanitize/angular-sanitize.js',
'bower_components/angular-resource/angular-resource.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/angular-materialize/js/*.js',
'bower_components/angular-materialize/src/*.js',
'bower_components/angular-translate/angular-translate.js',
'bower_components/angular-translate-loader-partial/angular-translate-loader-partial.js',
'bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.js',
'bower_components/angular-mocks/angular-mocks.js',
'src/**/*.js'
],
logLevel: 'LOG_ERROR',
exclude: [
'src/app/app.constants.js',
'bower_components/**/index.js',
'bower_components/**/*.min.js'
],
preprocessors: {
'src/**/*.html': ['ng-html2js']
}
};
config.set(configuration);
};
Any idea or piece of advice would be more than wellcome
thanks