When I run protractor I keep getting the error that no specs are found. I have tried a specific single file, 1 directory e2e/*.js and an entire tree e2e/**/*.js.
protractor.config.js
exports.config = {
specs: ['e2e/**/*.js'],
capabilities:{
browserName: 'chrome',
debug: true
},
localSeleniumStandaloneOpts:{
port:8082
}
}
gulpfile.js
'use strict';
var gulp = require('gulp');
var protractor = require("gulp-protractor").protractor;
// Setting up the test task
gulp.task('protractor', function(callback) {
gulp
.src(['e2e/**/*.js'])
.pipe(protractor({
configFile: 'protractor.conf.js',
args:['-port','8095']
}))
.on('error', function(e) {
console.log(e);
});
});
e2e/login.specs.js
'use strict';
describe('login to admin app', function(){
beforeEach(function(){
browser.get('http://localhost:3000/#!/login');
it('expect to be on the login page', function(){
expect(browser.findElement(by.className('login-page')).isPresent()).toBe(true);
});
it('login to application', function(){
var loginInput = browser.findElement(by.name('username'));
var passwordInput = browser.findElement(by.name('password'));
var submitButton = browser.findElement(by.tagNam('button'));
loginInput.sendKeys('****');
passwordInput.sendKeys('****');
submitButton.click();
expect(browser.getCurrentUrl()).toMatch('http://localhost:3000/#!/landing');
});
it('check header after login', function(){
var loginInput = browser.findElement(by.name('username'));
var passwordInput = browser.findElement(by.name('password'));
var submitButton = browser.findElement(by.tagNam('button'));
loginInput.sendKeys('*****');
passwordInput.sendKeys('*****');
submitButton.click();
expect(browser.findElement(by.id('role')));
expect(browser.findElement(by.id('username')));
var languages = brower.findElement(by.className("language"));
expect(language[0][0].getText().toEqual("NL"));
expect(language[1][0].getText().toEqual("FR"));
});
});
});
Did I miss a configuration?
I found it, according to the e2e testing site of AngularJS: https://docs.angularjs.org/guide/e2e-testing everything is divided into code blocks. So within describe function you have beforeEach, afterEach and it.
And I put my 'it' functions within 'beforeEach'.
describe('login to admin app', function(){
beforeEach(function(){
browser.get('http://localhost:3000/#!/login');
});//this line was missing
it('expect to be on the login page', function(){
expect(browser.findElement(by.className('login-page')).isPresent()).toBe(true);
});
it('login to application', function(){
var loginInput = browser.findElement(by.name('username'));
var passwordInput = browser.findElement(by.name('password'));
var submitButton = browser.findElement(by.tagNam('button'));
loginInput.sendKeys('****');
passwordInput.sendKeys('****');
submitButton.click();
expect(browser.getCurrentUrl()).toMatch('http://localhost:3000/#!/landing');
});
it('check header after login', function(){
var loginInput = browser.findElement(by.name('username'));
var passwordInput = browser.findElement(by.name('password'));
var submitButton = browser.findElement(by.tagNam('button'));
loginInput.sendKeys('****');
passwordInput.sendKeys('****');
submitButton.click();
expect(browser.findElement(by.id('role')));
expect(browser.findElement(by.id('username')));
var languages = brower.findElement(by.className("language"));
expect(language[0][0].getText().toEqual("NL"));
expect(language[1][0].getText().toEqual("FR"));
});
});
Related
So when I press start button I get this output
Init1
and this error
Source map error: Error: Invalid URL: webpack://Packs.[name]/webpack/bootstrap
Resource URL: http://0.0.0.0:3000/packs/js/application-50e3aceac3d862ba8b6d.js
Source Map URL: application-50e3aceac3d862ba8b6d.js.map
Even according my code I have to get "Init2" and "Init3" too.
my games.html.haml view file:
%h1 Catcher game
%p Catch bloks which are failling
%canvas#main_canvas
=button_tag "Start!", class: 'start_button', onclick: 'Packs.application.start'
my start() and init() functions in chatcher.js file:
function start() {
console.log("Init3")
var eater = new BigBlock(20, "pink");
var smallBlocks = [];
setInterval(function() { game(eater, smallBlocks); }, 1000/16);
addEventListener("keydown", function(key) { eater.move(key) } );
}
window.init = function() {
console.log("init2")
var canvas = document.getElementById("main_canvas");
var ctx = canvas.getContext("2d");
}
my application.js file
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
require("jquery")
export * from '../packs/games/chatcher'
$(document).ready(function() {
console.log("init1")
window.init;
})
and lastly my config/webpack/environment.js
const { environment } = require('#rails/webpacker')
var webpack = require('webpack');
environment.plugins.append(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery/src/jquery'
})
)
module.exports = environment
environment.config.merge({
output: {
library: ['Packs', '[name]'],
libraryTarget: 'var'
},
})
Thank you for helping. Have a nice day.
I'm following this tutorial on using angularjs alongside laravel: http://angular-tips.com/blog/2014/11/working-with-laravel-plus-angular-part-2/. However, if I define a route in config.routes.js which points to a controller, any controller, my app crashes. In the console the error "Error: too much recursion" comes up, along with a useless stack trace.
All my files are exactly the same as in the tutorial, I only changed the name of the route and the controller, but that shouldn't make a difference.
I googled around a bit and it seems this error might be caused by using a wrong version of jquery. I use angularjs 1.3.0 and I have no idea which jquery version my app is using, but I used npm install angular, so it'd be weird if that installed a wrong version, right?
I'm completely lost on why this happens and also very frustrated, so any help would be greatly appreciated.
Thanks.
EDIT: Added code:
app/js/config.routes.js
angular.module('app').config(function($routeProvider, $locationProvider)
{
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider.when('/transactions',
{
templateUrl: 'features/transactions/transactions.tpl.html',
controller: 'Transactions'
});
});
app/js/transactions/transactions.js:
angular.module('app').controller('Transactions', function($scope, $http)
{
$http.get('/api/transactions').then(function(result)
{
$scope.shows = result.data;
});
});
transactions.tpl.html is empty.
app.js:
angular.module('app', ['ngRoute']);
EDIT 2: added gulp.js
The only thing I changed here is, is that I added the 'webserver' task.
var gulp = require('gulp');
var fs = require('fs');
var plugins = require('gulp-load-plugins')();
var es = require('event-stream');
var del = require('del');
var publicFolderPath = '../public';
var paths = {
appJavascript: ['app/js/app.js', 'app/js/**/*.js'],
appTemplates: 'app/js/**/*.tpl.html',
appMainSass: 'app/scss/main.scss',
appStyles: 'app/scss/**/*.scss',
appImages: 'app/images/**/*',
indexHtml: 'app/index.html',
vendorJavascript: ['vendor/js/angular.js', 'vendor/js/**/*.js'],
vendorCss: ['vendor/css/**/*.css'],
finalAppJsPath: '/js/app.js',
finalAppCssPath: '/css/app.css',
specFolder: ['spec/**/*_spec.js'],
publicFolder: publicFolderPath,
publicJavascript: publicFolderPath + '/js',
publicAppJs: publicFolderPath + '/js/app.js',
publicCss: publicFolderPath + '/css',
publicImages: publicFolderPath + '/images',
publicIndex: publicFolderPath + '/angular.html',
publicJsManifest: publicFolderPath + '/js/rev-manifest.json',
publicCssManifest: publicFolderPath + '/css/rev-manifest.json'
};
gulp.task('scripts-dev', function() {
return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
.pipe(plugins.if(/html$/, buildTemplates()))
.pipe(plugins.sourcemaps.init())
.pipe(plugins.concat('app.js'))
.pipe(plugins.sourcemaps.write('.'))
.pipe(gulp.dest(paths.publicJavascript));
});
gulp.task('scripts-prod', function() {
return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
.pipe(plugins.if(/html$/, buildTemplates()))
.pipe(plugins.concat('app.js'))
.pipe(plugins.ngAnnotate())
.pipe(plugins.uglify())
.pipe(plugins.rev())
.pipe(gulp.dest(paths.publicJavascript))
.pipe(plugins.rev.manifest({path: 'rev-manifest.json'}))
.pipe(gulp.dest(paths.publicJavascript));
});
gulp.task('styles-dev', function() {
return gulp.src(paths.vendorCss.concat(paths.appMainSass))
.pipe(plugins.if(/scss$/, plugins.sass()))
.pipe(plugins.concat('app.css'))
.pipe(gulp.dest(paths.publicCss));
});
gulp.task('styles-prod', function() {
return gulp.src(paths.vendorCss.concat(paths.appMainSass))
.pipe(plugins.if(/scss$/, plugins.sass()))
.pipe(plugins.concat('app.css'))
.pipe(plugins.minifyCss())
.pipe(plugins.rev())
.pipe(gulp.dest(paths.publicCss))
.pipe(plugins.rev.manifest({path: 'rev-manifest.json'}))
.pipe(gulp.dest(paths.publicCss));
});
gulp.task('images', function() {
return gulp.src(paths.appImages)
.pipe(gulp.dest(paths.publicImages));
});
gulp.task('indexHtml-dev', ['scripts-dev', 'styles-dev'], function() {
var manifest = {
js: paths.finalAppJsPath,
css: paths.finalAppCssPath
};
return gulp.src(paths.indexHtml)
.pipe(plugins.template({css: manifest['css'], js: manifest['js']}))
.pipe(plugins.rename(paths.publicIndex))
.pipe(gulp.dest(paths.publicFolder));
});
gulp.task('indexHtml-prod', ['scripts-prod', 'styles-prod'], function() {
var jsManifest = JSON.parse(fs.readFileSync(paths.publicJsManifest, 'utf8'));
var cssManifest = JSON.parse(fs.readFileSync(paths.publicCssManifest, 'utf8'));
var manifest = {
js: '/js/' + jsManifest['app.js'],
css: '/css/' + cssManifest['app.css']
};
return gulp.src(paths.indexHtml)
.pipe(plugins.template({css: manifest['css'], js: manifest['js']}))
.pipe(plugins.rename(paths.publicIndex))
.pipe(gulp.dest(paths.publicFolder));
});
gulp.task('lint', function() {
return gulp.src(paths.appJavascript.concat(paths.specFolder))
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('jshint-stylish'));
});
gulp.task('testem', function() {
return gulp.src(['']) // We don't need files, that is managed on testem.json
.pipe(plugins.testem({
configFile: 'testem.json'
}));
});
gulp.task('clean', function(cb) {
del([paths.publicJavascript, paths.publicImages, paths.publicCss, paths.publicIndex], {force: true}, cb);
});
gulp.task('watch', ['indexHtml-dev', 'images'], function() {
gulp.watch(paths.appJavascript, ['lint', 'scripts-dev']);
gulp.watch(paths.appTemplates, ['scripts-dev']);
gulp.watch(paths.vendorJavascript, ['scripts-dev']);
gulp.watch(paths.appImages, ['images-dev']);
gulp.watch(paths.specFolder, ['lint']);
gulp.watch(paths.indexHtml, ['indexHtml-dev']);
gulp.watch(paths.appStyles, ['styles-dev']);
gulp.watch(paths.vendorCss, ['styles-dev']);
});
gulp.task('webserver', ['indexHtml-dev', 'images-dev'], function() {
plugins.connect.server({
root: paths.tmpFolder,
port: 5000,
livereload: true,
middleware: function(connect, o) {
return [ (function() {
var url = require('url');
var proxy = require('proxy-middleware');
var options = url.parse('http://localhost:8000/api');
options.route = '/api';
return proxy(options);
})(), historyApiFallback ];
}
});
});
gulp.task('default', ['watch']);
gulp.task('production', ['scripts-prod', 'styles-prod', 'images', 'indexHtml-prod']);
function buildTemplates() {
return es.pipeline(
plugins.minifyHtml({
empty: true,
spare: true,
quotes: true
}),
plugins.angularTemplatecache({
module: 'app'
})
);
}
Hi I am using ember for my client side application .here is my code which is in emberView
When I want to use transitionToRoute inside the kill action, it is showing the above error.
and my routes are like this
App.Router.map(function () {
this.route('groups');
this.resource('group', { path: 'group/:uuid' }, function() {
this.route('people');
this.route('vehicles');
this.route('reports');
this.route('geofences');
});
});
currently I am at the route of child View (group/:uuid/people) and once if i call the above Tile View of kill action it has redirect to parentRoute of (groups)
App.TileView = Ember.View.extend({
actions:{
kill: function() {
var dfd = new $.Deferred();
var t = this,resolveEntity = false;
this.set('waitingOnDelete', true);
//this.get('entity').kill().done(this.remove.bind(this));
var pid = this.get('entity').id;
this.get('entity').kill().then(function() {
t.remove();
if ((t.get('entityType') === 'association') && (DS.session.user_uuid === pid)) {
resolveEntity = true;
dfd.resolve(resolveEntity);
if(resolveEntity){
t.get('controller').transitionToRoute('groups');
}
}
});
}
}
});
I've a controller that uses a Dialog from angular-ui/bootstrap:
function ClientFeatureController($dialog, $scope, ClientFeature, Country, FeatureService) {
//Get list of client features for selected client (that is set in ClientController)
$scope.clientFeatures = ClientFeature.query({clientId: $scope.selected.client.id}, function () {
console.log('getting clientfeatures for clientid: ' + $scope.selected.client.id);
console.log($scope.clientFeatures);
});
//Selected ClientFeature
$scope.selectedClientFeature = {};
/**
* Edit selected clientFeature.
* #param clientFeature
*/
$scope.editClientFeature = function (clientFeature) {
//set selectedClientFeature for data binding
$scope.selectedClientFeature = clientFeature;
var dialogOpts = {
templateUrl: 'partials/clients/dialogs/clientfeature-edit.html',
controller: 'EditClientFeatureController',
resolve: {selectedClientFeature: function () {
return clientFeature;
} }
};
//open dialog box
$dialog.dialog(dialogOpts).open().then(function (result) {
if (result) {
$scope.selectedClientFeature = result;
$scope.selectedClientFeature.$save({clientId: $scope.selectedClientFeature.client.id}, function (data, headers) {
console.log('saved.');
}, null);
}
});
};
});
I'm almost completely new to testing, and figured that maybe I need to test two things:
That a dialog opens when $scope.editClientFeature() is called
That $save is called successfully after a dialog is closed and returns a 'result'
My really messed up test now looks like this:
describe('ClientFeatureController', function () {
var scope, $dialog, provider;
beforeEach(function () {
inject(function ($controller, $httpBackend, $rootScope, _$dialog_) {
scope = $rootScope;
$dialog = _$dialog_;
//mock client
scope.selected = {};
scope.selected.client = {
id: 23805
};
$httpBackend.whenGET('http://localhost:3001/client/' + scope.selected.client.id + '/clientfeatures').respond(mockClientFeatures);
$controller('ClientFeatureController', {$scope: scope});
$httpBackend.flush();
});
});
it('should inject dialog service from angular-ui-bootstrap module', function () {
expect($dialog).toBeDefined();
console.log($dialog); //{}
});
var dialog;
var createDialog = function (opts) {
dialog = $dialog.dialog(opts);
};
describe('when editing a clientfeature', function () {
createDialog({});
console.log(dialog); //undefined
// var res;
// var d;
// beforeEach(function () {
// var dialogOpts = {
// template: '<div>dummy template</div>'
// };
// console.log(dialog);
// d = $dialog.dialog(dialogOpts);
// d.open();
// });
//
// it('should open a dialog when editing a client feature', function () {
// expect(d.isOpen()).toBe(true);
// });
});
});
The immediate problem now is that I'm unable to create/open a dialog. I get the following error:
Chrome 25.0 (Mac) ClientFeatureController when editing a clientfeature encountered a declaration exception FAILED
TypeError: Cannot call method 'dialog' of undefined
It would be great if someone has already written a test for a similar use case and can provide me with an example as I'm pretty lost.
Thanks,
Shaun
I was struggling with the same problem until right now, after trolling the the github repo i found the dialog tests and used that as a starting point :
var $dialog,$scope,$httpBackend;
beforeEach(module('ui.bootstrap.dialog'));
beforeEach(function(){
inject(function (_$dialog_, _$httpBackend_, $controller){
$dialog = _$dialog_;
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('/appServer/list')
.respond([{
id:1,
name:'test1'
},
{
id:2,
name:'test2'
},
{
id:3,
name:'test3'
}]);
//setup controller scope
scope = {};
ServerCtrl = $controller('ServerCtrl', {
$scope: scope,
$dialog:$dialog
});
});
});
I also prefer a proper mock. When it is not available, i patch the service
To test this:
$dialog.messageBox(title, msg, btns)
.open()
.then(function (result) {
if (result == 'ok') {
// block executed if user click OK
}
});
You can patch $dialog like this:
$dialog.messageBox = function (title, msg, btns) {
return {
open: function () {
return {
then: function (callback) {
callback('ok'); // 'ok' will be set to param result
}
}
}
}
};
Personally I try to mock all services out. If the ui-bootstrap project does not provide a $dialog mock, you should open a bug ticket there and ask them for one. However creating one is as easy.
The mock service should have fake methods that do nothing but return promises. It should also give you a method to flush all asynchronous methods to make it easier to do synchronous testing.
I find it clearest to write my own mock of the dialog. Here's an example of mocking out a dialog to simulate "yes" being chosen.
Code under test
.controller('AdminListingCtrl', function AdminListingController($scope, $dialog, houseRepository) {
$scope.houses = houseRepository.query();
$scope.remove = function (house) {
var dlg = $dialog.messageBox('Delete house', 'Are you sure?', [
{label: 'Yep', result: 'yes'},
{label: 'Nope', result: 'no'}
]);
dlg.open().then(function (result) {
if (result == 'yes') {
houseRepository.remove(house.id);
$scope.houses = houseRepository.query();
}
});
};
}
Tests
describe('when deleting a house', function () {
var fakeDialog = {
open: function()
{
return {
then: function(callback) {
callback("yes");
}
};
}
};
beforeEach(inject(function($dialog) {
spyOn($dialog, 'messageBox').andReturn(fakeDialog);
}));
it('should call the remove method on the houseRepository', function () {
scope.remove({id: 99});
expect(houseRepository.remove).toHaveBeenCalledWith(99);
});
// etc
});
I'm trying to use backbone routes with parameters and for some reason, I just can't seem to make the code below to work:
var App = new Backbone.Marionette.Application();
App.Router = Backbone.Router.extend({
routes: {
"export": "export",
"show": "show/:id", // This just won't work
"providers": "providers"
},
export: function() {
var exportView = new App.ExportView();
exportView.render();
$("#main").html(exportView.el);
},
show: function(id) {
console.log('from here'); // This is not even firing
var show = this.collection.get(id);
showView.render();
$("#main").html(showView.el);
},
providers: function() {
var contentProvidersView = new App.ProvidersView();
providersView.render();
$("#main").html(providersView.el);
}
});
App.addInitializer(function() {
var router = new App.Router();
});
Nothing happens when I try to access this: #show/2 (Where 2 is the show id)
Many thanks.
It's the other way around :
routes: {
"show/:id": "show",
}