Jasmine ignoring typescript test files? - node.js

This is my first time making a project with Jasmine, and I'm following a tutorial but right off the bat having issues.
I've installed jasmine-node, typings, and typescript. I also ran:
typings install dt~jasmine --save-dev --global
For Jasmine typescript.
Now I have a test file in my ./spec folder that looks like this:
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { DatePickerComponent } from '../src/components/via-datepicker.component';
import * as moment from 'moment';
const Moment: any = (<any>moment).default || moment;
describe('DatePickerComponent', () => {
let component: DatePickerComponent;
let fixture: ComponentFixture<DatePickerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DatePickerComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DatePickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should open when clicked', () => {
fixture.debugElement.nativeElement.querySelector('body').click();
fixture.whenStable().then(() => {
expect(component.opened);
});
component.close();
});
describe('While open', () => {
beforeEach(() => {
component.open();
});
describe('Pressing the "Today\'s date" button', () => {
it('should set the value of the picker to the current date and close it', () => {
fixture.debugElement.nativeElement.querySelector('.datepicker-buttons button').click();
expect(Moment().isSame(component.value, 'day') && Moment().isSame(component.value, 'month'));
expect(!component.opened);
});
});
describe('Clicking on a date', () => {
it('should change the value of the picker and close it', () => {
let oldValue: any = component.value;
fixture.debugElement.nativeElement.querySelectorAll('.day')[10].click();
expect(!component.opened);
expect(!component.value.isSame(oldValue));
});
});
});
});
But when I run this command:
node_modules/jasmine-node/bin/jasmine-node spec
I get this result:
Finished in 0 seconds
0 tests, 0 assertions, 0 failures, 0 skipped
So clearly my test file is being ignored. Or maybe I'm missing some library? Would I receive an error message if this were the case? The main issue here is that I'm not being given much direction as to what the issue is, other than Jasmine doesn't seem to "see" the test file for some reason.
Just trying to move forward with my project. Any advice would be greatly appreciated.

It appears as if your test runner doesn't know that you're trying to run typescript tests. Are you using Karma as your test runner? If so, you need to add your Typescript files to your karma.config file and install karma-typescript and configure your karma.config file similar to what is shown below. Pay close attention to the addition to the frameworks, files, and preprocessors sections.
karma.config
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'karma-typescript'],
// list of files / patterns to load in the browser
files: [
{ pattern: "app/tests/**/*.spec.js"}
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
"app/tests/**/*.spec.ts": ["karma-typescript"]
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true
})
};

Related

Protractor generates an error when disabling flow control to test an Angular app

I've been struggling with this error for a while and I'm running out of mana. I'm currently trying to test an Angular app with protractor and async/await. According to the doc, I have to disable the control flow by adding the following to my config file:
SELENIUM_PROMISE_MANAGER: false but doing so produces the following error:
UnhandledPromiseRejectionWarning: Error: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See https://github.com/angular/protractor/issues/2643 for details" I visited the url (https://github.com/angular/protractor/issues/2643) but it didn't turn out very helpful.
At this point I'm not sure if I'm doing something wrong or if it's a bug with protractor itself. For this reason I also opened an issue on GitHub.
Here is my test:
import {
browser,
ExpectedConditions,
$
} from 'protractor';
describe('When user click \"Test\" button', async () => {
beforeAll(async () => {
expect(browser.getCurrentUrl()).toContain('myawesomewebsite');
});
it ("should click the button", async () => {
var button = $(".button");
button.click();
});
});
And here is my full configuration:
exports.config = {
capabilities: {
'browserName': 'chrome'
},
seleniumAddress: 'http://localhost:4444/wd/hub',
framework: 'jasmine',
specs: ['test.spec.ts'],
SELENIUM_PROMISE_MANAGER: false,
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
},
beforeLaunch: function () {
require('ts-node/register')
}
};
You missed await before each protractor api invoking.
describe('When user click \"Test\" button', async () => {
beforeAll(async () => {
expect(await browser.getCurrentUrl()).toContain('myawesomewebsite');
});
it ("should click the button", async () => {
var button = $(".button");
await button.click();
});
});
So, thanks to #CrispusDH on GitHub, I figured out that I could use waitForAngularEnabled in the configuration file and not just in the spec file. Using it in the spec file was not working, but if used in the onPrepare hook of the configuration file, the error goes away.
A lot of resources online were saying to set it to false, but this wasn't working for me as Protractor couldn't find element without waiting for Angular, so I did set it to false in the configuration and file but called browser.waitForAngularEnabled(true); in my specs file (beforeAll hook). Now the error is gone, allowing me to use async/await.
Here is the proper configuration to use:
SELENIUM_PROMISE_MANAGER: false,
onPrepare: async () => {
await browser.waitForAngularEnabled(false);
}
And here is the code to call in spec file:
beforeAll(async () => {
browser.waitForAngularEnabled(true);
});

Browsersync not reloading browser or injecting css

I've been trying to get this straight for a few days now but haven't been able to get it working the way I need to. I'm unable to find any examples of other people using Browsersync with .net core, that may even be the reason I'm experiencing all of these issues. But I can't find any evidence that proves that and wouldn't understand why exactly that would be the case.
Anyway... I've got everything working in my gulp file exactly how I want it to for sass/js for handling errors, etc. I'm not new to gulp otherwise I'd blame my lack of experience for my inability to get this working.
Here's my gulp file followed by what the output is when running gulp.
Default Task:
const gulp = require("gulp"),
uglify = require("gulp-uglify"),
sass = require("gulp-sass"),
rename = require('gulp-rename'),
sassGlob = require('gulp-sass-glob'),
postcss = require('gulp-postcss'),
autoprefixer = require('gulp-autoprefixer'),
sourcemaps = require('gulp-sourcemaps'),
cleanCSS = require('gulp-clean-css'),
concat = require('gulp-concat'),
msbuild = require('gulp-msbuild'),
through = require('through2'),
notifier = require('node-notifier'),
browserSync = require('browser-sync').create();
// Static Server + watching scss/html files
gulp.task('serve', ['sass', 'compileJS'], function() {
browserSync.init({
proxy : {
target: "https://localhost:3000",
},
files: ['./wwwroot/css/*'],
rewriteRules: [
{
match: new RegExp('/css/main.min.css'),
fn: function() {
return './wwwroot/css/main.min.css'
}
}
]
});
//Watch for any changes to the scss files.
gulp.watch('./wwwroot/sass/**/*.scss', ['sass']);
//Watch for any changes to the js files, reload after those changes are made.
gulp.watch('./wwwroot/js/source/*.js', ['compileJS']).on('change', browserSync.reload);
//Watch for any changes to a .cshtml file and reload the browser if/when that change happens.
gulp.watch("./**/*.cshtml").on('change', browserSync.reload);
});
gulp.task('default', ['serve']);
/**
* Compiles SASS files and stores the result into the public folder
*/
gulp.task('sass', function () {
return gulp.src('./wwwroot/sass/main.scss')
.pipe(sassGlob())
.pipe(sass().on('error', function (err) {
console.log('Sass Error:', err.toString());
notifier.notify({
'title': 'Gettin\' Sassy 💁‍♀️',
'message': 'You goofed. Check your terminal window for more information.'
});
this.emit("end");
}))
.pipe(postcss([require('autoprefixer')]))
.pipe(
autoprefixer({
browsers: ['last 2 versions'],
cascade: false
})
)
.pipe(
through.obj(function(chunk, enc, cb) {
cb(null, chunk)
})
)
.pipe(cleanCSS({compatibility: 'ie8',
level: 2}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./wwwroot/css'))
.pipe(browserSync.stream());
});
/**
* Compiles the Javascript files and stores the result in the public folder
*/
gulp.task('compileJS', function (done) {
return gulp.src('./wwwroot/js/source/*.js')
.pipe(sourcemaps.init())
.pipe(concat('main.js'))
.pipe(uglify().on('error', function (err) {
console.log('JS Uglify Error:', err.toString());
notifier.notify({
'title': 'JS Compile Error',
'message': 'Something about your JS is a little off. Check yourself before you wreck yourself.'
});
this.emit("end");
}))
.pipe(rename({suffix: '.min'}))
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('./wwwroot/js/dist'));
});
Output:
$ gulp
[21:34:15] Using gulpfile
~/Repos/PROJECT_DIRECTORY/PROJECT_NAME/gulpfile.js
[21:34:15] Starting 'sass'...
[21:34:15] Starting 'compileJS'...
[21:34:15] Finished 'sass' after 437 ms
[21:34:15] Finished 'compileJS' after 426 ms
[21:34:15] Starting 'serve'...
[21:34:16] Finished 'serve' after 1 s
[21:34:16] Starting 'default'...
[21:34:16] Finished 'default' after 68 μs
[Browsersync] Proxying: https://localhost:3000
[Browsersync] Access URLs:
------------------------------------
Local: https://localhost:3000
External: https://10.0.0.137:3000
------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
------------------------------------
[21:34:35] Starting 'sass'...
[Browsersync] 1 file changed (main.min.css)
[21:34:35] Finished 'sass' after 207 ms
[21:34:58] Starting 'compileJS'...
[21:34:58] Finished 'compileJS' after 154 ms
[Browsersync] Reloading Browsers...
So, looking at that output you would probably think to yourself, "This dude is an idiot... Browsersync states that it's reloading browsers..." Right, it does state that, but it is not reloading the browser. Browsersync also fails to inject my css into the browser as well.
As I mentioned, I've used gulp before, and this setup closely represents the gulp files that I use when doing Wordpress development as well. However, it won't work for this project (which has led me to my .net core / Visual Studio suspicions).
You could just do something like this
Create a env variable thats global to your application then above the closing tag in your view you can add the following code.
This code is how I do it in Laravel with my Blade templates but it should be exactly the same you just need to replace it with the way .NET does it, I think they use Razor templating engine :)
{{-- Live reload with browser sync --}}
#if (!empty(env('APP_ENV')) && env('APP_ENV') === 'local')
<script
async
defer
src="{{ URL::to('/') . ':3000/browser-sync/browser-sync-client.js?v=2.26.7'}}">
</script>
#endif
Hope this helps you.
Just for interest sake below is my gulp pipeline:
const browserSync = require("browser-sync");
const sass = require("gulp-sass");
const autoprefixer = require("gulp-autoprefixer");
const sourcemaps = require("gulp-sourcemaps");
const rename = require("gulp-rename");
const reviser = require("gulp-rev");
const runSequence = require("run-sequence");
gulp.task("browserSync", function() {
return browserSync.init({
open: false,
https: false,
notify: false,
injectChanges: true,
proxy: "http://{site-name-here}.local/",
});
});
gulp.task("compile:scss", function() {
return (
gulp
// Gets the main.scss file
.src("resources/assets/scss/main.scss")
// Passes it through a gulp-sass, log errors to console
.pipe(sass().on("error", sass.logError))
// Adds versioning
.pipe(reviser())
// Add vendor prefixes
.pipe(
autoprefixer({
browsers: ["last 2 versions"],
cascade: false
})
)
// Rename the file
.pipe(rename({ suffix: ".min" }))
// Outputs it in the css folder
.pipe(gulp.dest("public/css"))
// Add sourcemaps
.pipe(sourcemaps.write())
// Adds versioned file to manifest so we can access with the same name
.pipe(reviser.manifest("manifest/rev-manifest.json"), { merge: true })
// Outputs it in the css folder
.pipe(gulp.dest("public/css"))
.pipe(
browserSync.reload({
// Reloading with Browser Sync
stream: true
})
)
);
});
// Watchers
gulp.task("watch", function() {
gulp.watch(["./resources/assets/scss/**/*"], "compile:scss", browserSync.reload);
});
// Default task
gulp.task("start", function(callback) {
return runSequence(
"browserSync",
"compile:scss",
"watch",
callback
);
});
to use it I just run gulp start
Keep in mind that running gulp like this you will need to have gulp installed globally. to do this run npm install --global gulp-cli

Karma test runner error: "An error was thrown in afterAll\nTypeError: _fs2.default.readdirSync is not a function"

I have been trying to trigger the browser and open Google using Karma with Jasmine.
Karma console is giving the following error:
Karma error message
Selenium-standalone log:
Selenium standalone log
Karma.conf.js->
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
plugins: [
'karma-browserify',
'karma-jasmine',
'karma-firefox-launcher'
],
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['browserify','jasmine'],
// list of files / patterns to load in the browser
files: [
'../../../scripts/jasmineTest.spec.js'
],
// list of files / patterns to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'../../../scripts/jasmineTest.spec.js' : [ 'browserify' ]
},
browserify: {
debug: true,
// transform: [ 'brfs' ]
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Firefox'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
My Jasmine script:
var wdio = require('../webdriverio')
describe("Jasmine test", function(){
var client = {}
client = wdio.remote({
desiredCapabilities: {
browserName: 'firefox'
}
})
client.init()
client.url("https://www.google.co.in")
it("test-1", function(done){
// expect(false).not.toBe(true)
// expect(2).toEqual(2)
done()
})
it("test-2", function(done){
// var a = ['A','B','C']
// expect(a).toContain('D')
done()
})
})

Karma: Executed 0 of 0 Error

I think I have everything set up properly. I followed the specs of the Karma Tutorial for RequireJS, but everything I've tried seems to result in the same error.
It appears that my test-main.js file is being loaded since a console.log() will fire. However, in the Object.keys loop, the files will get listed, but TEST_REGEXP fails so the allTestFiles ends up being an empty array. I'm sure it's something silly, but it's created just like the Tutorial - with the exception of using node_modules for jquery, require, underscore.
My test-main.js file:
var allTestFiles = [];
var TEST_REGEXP = /test\.js$/;
var pathToModule = function(path) {
return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};
Object.keys(window.__karma__.files).forEach(function(file)
{
if(TEST_REGEXP.test(file))
{
// Normalize paths to RequireJS module names
allTestFiles.push(pathToModule(file));
}
});
if(console) console.log(allTestFiles);
require.config(
{
// Karma serves files under /base, which is the basePath from the config file
baseUrl: '/base/src',
paths:
{
'jquery':'../node_modules/jquery/dist/jquery',
'underscore':'../node_modules/underscore/underscore-min'
},
shim:
{
'underscore': { exports: '_' }
},
// dynamically load all test files
deps: allTestFiles,
// kick off jasmine, as it is asynchronous
callback: window.__karma__.start
});
My karma.conf.js file:
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'requirejs'],
// list of files / patterns to load in the browser
files: [
'test/test-main.js',
{pattern: 'node_modules/jquery/dist/jquery.js', included: false},
{pattern: 'src/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false}
],
// list of files to exclude
exclude: [
'src/main.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
I came across a solution to the problem.
I ended up changing my test-main.js file above the require.config section to this:
// Karma RequireJS configuration
var tests = [];
for (var file in window.__karma__.files) {
if (/Spec\.js$/.test(file)) {
tests.push(file);
}
}
If I simply changed TEST_REGEXP to /Spec\.js$/ I ended up getting a timestamp error. I don't know why. More interesting is why following the guide produces errors. But it is all working now.

Requirejs do not add ".js" for modules using karma

I have simple test, that must work in webstorm using karma and requirejs.
The problem is that for some reason requirejs do not add ".js" for modules i was loading for tests. So it crashed trying to load "../ts/mamats/mama", while "../ts/mamats/mama.js" exists
Test (main.jasmine.js):
define(["require", "exports", "../ts/mamats/mama"], function(require, exports, mama) {
describe("first test", function () {
it("should be true", function () {
var object = new mama.block();
expect(object instanceof mama.block).toBe(true);
});
});
});
//# sourceMappingURL=main.jasmine.js.map
every thing works correctly when i replace "../ts/mamats/mama" with "../ts/mamats/mama.js"
sourceMappingURL here because javaScript file generated from typeScript source file, and because of that i cannot add ".js" for modules manually
Test starts with this entry point (main-test.js):
var tests = Object.keys(window.__karma__.files).filter(function (file) {
return (/\.jasmine\.js$/).test(file);
});
requirejs.config({
baseUrl: '/base',
deps: tests,
callback: window.__karma__.start
});
Why requirejs don't add ".js" for modules here?
Karma conf file:
module.exports = function(config) {
config.set({
basePath: '../',
frameworks: ['jasmine', 'requirejs'],
files: [
'static-tests/main-test.js',
{ pattern: 'static/**/*', included: false },
{ pattern: 'static-tests/**/*', included: false }
],
exclude: [],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: false
});
};
Here is an interesting read on how RequireJs handles this:
http://requirejs.org/docs/api.html#jsfiles
Reading that makes it seem like an issue with RequireJS, but there seems to be some debate on whether or not that is true. Regardless, this gist seems to solve the issue.
var tests = Object.keys(window.__karma__.files).filter(function (file) {
return /\.spec\.js$/.test(file);
}).map(function(file){
return file.replace(/^\/base\/src\/js\/|\.js$/g,'');
});
require.config({
baseUrl: '/base/src/js'
});
require(tests, function(){
window.__karma__.start();
});
It looks like trouble in require.js
The problem is in next:
1. When in deps appear absolute path - requirejs stop add ".js" for any require call
2. When in deps appear file with extension, for some reason requirejs again stop add ".js" for modules
Other Solution here - to replace bathUrl and add it to requirejs conf do not help.
For me solution is next:
var tests = Object.keys(window.__karma__.files).filter(function (file) {
return (/\-jasmine\.js$/).test(file);
}).map(function (file) {
return file.replace(/^\/|\.js$/g, '');
});
and
baseUrl: '',
for requirejs.conf
and i have no idea why requirejs still add "/base" for all url that are requested, but now all works fine

Resources