SailsJS pass data to view - undefined - sails.js

I'm playing about with SailsJS and I've got the following view:
<p>Products <%= category %></p>
With the following Controller:
module.exports = {
get: function(req, res) {
res.view('pages/products', {
category: req.params.category
});
}
};
And the route:
'/products/:category': 'ProductsController.get',
When navigating to this really simple setup, I get the following:
error: Sending 500 ("Server Error") response:
ReferenceError: /var/www/html/curioushaven/views/pages/products.ejs:1
>> 1| <p>Products <%= category %></p>
2|
category is not defined
at eval (eval at <anonymous> (/usr/lib/node_modules/sails/node_modules/ejs-locals/node_modules/ejs/lib/ejs.js:237:14), <anonymous>:30:54)
at eval (eval at <anonymous> (/usr/lib/node_modules/sails/node_modules/ejs-locals/node_modules/ejs/lib/ejs.js:237:14), <anonymous>:30:80)
at /usr/lib/node_modules/sails/node_modules/ejs-locals/node_modules/ejs/lib/ejs.js:250:15
at Object.exports.render (/usr/lib/node_modules/sails/node_modules/ejs-locals/node_modules/ejs/lib/ejs.js:288:13)
at Object.exports.renderFile (/usr/lib/node_modules/sails/node_modules/ejs-locals/node_modules/ejs/lib/ejs.js:318:20)
at SailsView.module.exports [as engine] (/usr/lib/node_modules/sails/node_modules/ejs-locals/index.js:85:7)
at SailsView.View.render (/usr/lib/node_modules/sails/node_modules/express/lib/view.js:76:8)
at Function.app.render (/usr/lib/node_modules/sails/node_modules/express/lib/application.js:561:10)
at ServerResponse.res.render (/usr/lib/node_modules/sails/node_modules/express/lib/response.js:845:7)
at ServerResponse.res.view (/usr/lib/node_modules/sails/lib/hooks/views/res.view.js:284:16)
at Object.module.exports.get (/var/www/html/curioushaven/api/controllers/ProductsController.js:10:7)
at wrapper (/usr/lib/node_modules/sails/node_modules/lodash/index.js:3095:19)
at routeTargetFnWrapper (/usr/lib/node_modules/sails/lib/router/bind.js:181:5)
at callbacks (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:164:37)
at param (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:138:11)
at param (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:135:11)
at pass (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:145:5)
at nextRoute (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:100:7)
at callbacks (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:167:11)
at alwaysAllow (/usr/lib/node_modules/sails/lib/hooks/policies/index.js:224:11)
at routeTargetFnWrapper (/usr/lib/node_modules/sails/lib/router/bind.js:181:5)
at callbacks (/usr/lib/node_modules/sails/node_modules/express/lib/router/index.js:164:37)
Can anyone explain what I'm doing wrong? Thanks!
Edit - I should point out that I've tried varying forms of req.param('category') and req.params.category etc etc...

Instead of using
req.param('category')
this
req.params.id
should fix your problem. However req.param('category') should work as well and from your code I cannot see why it should not work.

Related

allure.createAttachment exception error - Cannot read property 'currentStep' of undefined

I can successfully add screenshots to allure reports, but i get the following exception error:
error:
TypeError: Cannot read property 'currentStep' of undefined
at Allure.addAttachment (/Users//xxx/xxx/xxx/node_modules/allure-js-commons/index.js:86:45)
at Allure.createAttachment (/Users/xxx/xxx/xxx/node_modules/allure-js-commons/runtime.js:48:29)
at /Users/xxx/xxx/xxx/lib/class/class-name.js:30:20
at process._tickCallback (internal/process/next_tick.js:68:7)
class:
browser.takeScreenshot().then(function (png) {
allure.createAttachment(title, new Buffer(png, 'base64'));
}).catch((error: any) => console.log(error));
const allure = require('mocha-allure-reporter');
allure is a global identifier, injected by reporter to your code.
Add the following line to the top of your file to tell Typescript about it
declare const allure: any;
I think createAttachment requires a callback function and not a buffer being passed directly.
Can you try changing your code to reflect the following
browser.takeScreenshot().then(function (png) {
allure.createAttachment('Screenshot', function () {
return new Buffer(png, 'base64')
}, 'image/png')()
}).catch((error: any) => console.log(error));

sails helpers and machine spec

I upgrade sails to the #^1.0.0 version and while I'm developing an API, I wanted to use a Service but the Sails document advice to use Helper now. And I don't realy use to work with the new way to discripe helper, build script or actions.
And all the try I have mad wasn't successful.
In the following exemple..
Here is my controller call:
var ob = await ails.helpers.testy('sayHello');
res.json({ob:ob});
helper
module.exports = {
friendlyName: 'Testy',
description: 'Testy something.',
inputs: {
bla: {
type: 'string'
}
},
exits: {
success: {
}
},
fn: async function (inputs, exits) {
console.log({blabla:inputs.bla})
if(!inputs.bla) return exits.error(new Error('text not found'));
var h = "Hello "+ inputs.bla;
// All done.
return exits.success(h);
}
};
I'm getting this error
error: A hook (`helpers`) failed to load!
error:
error: Attempted to `require('*-serv\api\helpers\testy.js')`, but an error occurred:
--
D:\*-serv\api\helpers\testy.js:28
fn: async function (inputs, exits) {
^^^^^^^^
SyntaxError: Unexpected token function.......
and if I remove the "async" and the "await" form the Controller, the ob object return null and I'm having this error
WARNING: A function that was initially called over 15 seconds
ago has still not actually been executed. Any chance the
source code is missing an "await"?
To assist you in hunting this down, here is a stack trace:
```
at Object.signup [as auth/signup] (D:\*-serv\api\controllers\AuthController.js:106:26)
The first guy from the comments is right.
After removing async from fn: async function (inputs, exists) {}; you need to setup sync: true which is false by default. It is described at helpers doc page at Synchronous helpers section.
So your code should look like this
module.exports = {
friendlyName: 'Testy',
description: 'Testy something.',
sync: true, // Here is essential part
inputs: {
bla: {
type: 'string'
}
},
exits: {
success: {
}
},
fn: function (inputs, exits) {
console.log({blabla:inputs.bla})
if(!inputs.bla) return exits.error(new Error('text not found'));
var h = "Hello "+ inputs.bla;
// All done.
return exits.success(h);
}
};
From the another side, you have a problem with async/await. The top most reason for this are
Not supported Node.js version - check that you current version support it
If you use sails-hook-babel or another Babel related solution, you may miss required plugin for async/await processing

How to read locators from a json file in protractor?

I want to develop a framework where i keep all the locators at one place, in a json file say test.json. like this.
{
"yourName": "by.model('yourName')"
}
And I want to read this in specs as below.
var test = require('./test.json');
describe('angularjs homepage todo list', function() {
it('should add a todo', function() {
browser.get('https://angularjs.org');
var webElement = element(testtest.yourName);
webElement.sendKeys('write first protractor test');
});
});
but when i do this getting error as Failed: Invalid locator with following error trace.
Failures:
1) angularjs homepage todo list should add a todo
Message:
Failed: Invalid locator
Stack:
TypeError: Invalid locator
at Object.check [as checkedLocator] (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\by.js:267:9)
at WebDriver.findElements (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:919:18)
at C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:159:44
at ManagedPromise.invokeCallback_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14)
at TaskQueue.execute_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at asyncRun (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2775:27)
at C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:639:7
at process._tickCallback (internal/process/next_tick.js:103:7)Error
at ElementArrayFinder.applyAction_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:396:27)
at ElementArrayFinder._this.(anonymous function) [as sendKeys] (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:99:30)
at ElementFinder.(anonymous function) [as sendKeys] (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:730:22)
at Object.<anonymous> (E:\ui\TestTest\todo-spec.js:9:20)
at C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:94:23
at new ManagedPromise (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1082:7)
at controlFlowExecute (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:80:18)
at TaskQueue.execute_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at asyncRun (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2820:25)
From: Task: Run it("should add a todo") in control flow
at Object.<anonymous> (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:79:14)
From asynchronous test:
Error
at Suite.<anonymous> (E:\ui\TestTest\todo-spec.js:4:7)
at Object.<anonymous> (E:\ui\TestTest\todo-spec.js:3:5)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
Is there any better way to do this? or what should i need to make it work?
Probably not the direct answer to the question, but I think you are not attempting the problem in a traditional way and sort of partially reinventing the wheel.
Instead of keeping locators in a separate JSON structure, organize them into Page Objects - separate page objects (including element locators and methods to interact with a page) for separate pages or parts of pages.
This should work.
test.json
{
"siteURL": "https://angularjs.org",
"locators": {
"todoText": {
"model": "todoList.todoText"
}
}
}
spec.js
var test = require('./test.json');
describe('angularjs homepage todo list', function() {
it('should add a todo', function() {
browser.get(test.siteURL);
var webElement = element(by.model(test.locators.todoText.model));
webElement.sendKeys('write first protractor test');
});
});
One complete example using BDD Cucumber, json and pageobject model here. https://github.com/aluzardo/protractor-cucumber-tests/
One simple mistake in your approach.
The values from JSON are read as string and you are passing a string to element() and not a locator(not a by object)
var webElement = element(test.yourName); // Incorrect. test.yourName returns string
Change it way and voila ! You should be good. Use eval(). Refer here
var webElement = element(eval(test.yourName));

Use of Expected Conditions on Non Angular Site with Protractor Leads to "Type Error: Cannot read property 'bind' of undefined"

I am seeing following issue when I am using Expected Conditions on webelements returned through element object of Protractor. I tried with $ as well, that resulted in the same thing. I am using Protractor 3.1.1 on Node 4.2.4, Chrome V47.*
"Type Error: Cannot read property 'bind' of undefined"
Before asking, I searched the forums, and understood there are some known issues with using Expected Conditions with selenium elements using driver.findElement.
However, I could not come across a similar issues reported while using element object itself.
https://github.com/angular/protractor/issues/1853
We have a non angular app for login page, which will be switched to Angular, post login. So, I have set ignoreSynchronization=true and later planned to reset it to false after login. Below is the sample code, appreciate any thoughts from community.
Page Objects File
module.exports = {
login: element(by.model('credentials.username')),
password: element(by.model('credentials.password')),
user: "Email",
passwd: "Password",
goButton: $('input.btn.btn-primary'),
EC: protractor.ExpectedConditions,
go: function() {
browser.get("Application URL",30000);
browser.wait(this.EC.elementToBeClickable(this.login),30000);
},
Below is my Sample Test Suite
var VMPage = require('./LoginPage.js');
describe('App Demo', function() {
beforeEach(function() {
console.log("Before Each Started");
browser.driver.manage().timeouts().implicitlyWait(30000);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1800000;
browser.ignoreSynchronization = true;
VMPage.go();
VMPage.login();
});
it('Test Case', function() {
console.log("***Test Started***");
});
});
Stack trace reported looks as follows:
Stack:
TypeError: Cannot read property 'bind' of undefined
at [object Object].ExpectedConditions.presenceOf (C:\Users\PJ\Ap
pData\Roaming\npm\node_modules\protractor\lib\expectedConditions.js:289:33)
at [object Object].ExpectedConditions.visibilityOf (C:\Users\PJ\
AppData\Roaming\npm\node_modules\protractor\lib\expectedConditions.js:328:10)
at [object Object].ExpectedConditions.elementToBeClickable (C:\Users\PJ0
0366401\AppData\Roaming\npm\node_modules\protractor\lib\expectedConditions.js:17
8:12)
at Object.module.exports.go (D:\protractor_git\Demo\\Log
inPage.js:14:24)
at Object.<anonymous> (D:\protractor_git\Demo\\LoginTest
.js:9:10)
at C:\Users\PJ\AppData\Roaming\npm\node_modules\protractor\node_
modules\jasminewd2\index.js:96:23
at new wrappedCtr (C:\Users\PJ\AppData\Roaming\npm\node_modules\
protractor\node_modules\selenium-webdriver\lib\goog\base.js:2468:26)
at controlFlowExecute (C:\Users\PJ\AppData\Roaming\npm\node_modu
les\protractor\node_modules\jasminewd2\index.js:82:18)
From: Task: Run beforeEach in control flow
at Object.<anonymous> (C:\Users\PJ\AppData\Roaming\npm\node_modu
les\protractor\node_modules\jasminewd2\index.js:81:14)
at attemptAsync (C:\Users\PJ\AppData\Roaming\npm\node_modules\pr
otractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasmine
.js:1916:24)
at QueueRunner.run (C:\Users\PJ\AppData\Roaming\npm\node_modules
\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasm
ine.js:1871:9)
at QueueRunner.execute (C:\Users\PJ\AppData\Roaming\npm\node_mod
ules\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\
jasmine.js:1859:10)
at Spec.Env.queueRunnerFactory (C:\Users\PJ\AppData\Roaming\npm\
node_modules\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmi
ne-core\jasmine.js:697:35)
at Spec.execute (C:\Users\PJ\AppData\Roaming\npm\node_modules\pr
otractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasmine
.js:359:10)
at Object.fn (C:\Users\PJ\AppData\Roaming\npm\node_modules\protr
actor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasmine.js
:2479:37)
at attemptAsync (C:\Users\PJ\AppData\Roaming\npm\node_modules\pr
otractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasmine
.js:1916:24)
at QueueRunner.run (C:\Users\PJ\AppData\Roaming\npm\node_modules
\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasm
ine.js:1871:9)
at QueueRunner.execute (C:\Users\PJ\AppData\Roaming\npm\node_mod
ules\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\
jasmine.js:1859:10)
From asynchronous test:
Error
at Suite.<anonymous> (D:\protractor_git\Demo\\LoginTest.
js:3:2)
at addSpecsToSuite (C:\Users\PJ\AppData\Roaming\npm\node_modules
\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasm
ine.js:833:25)
at Env.describe (C:\Users\PJ\AppData\Roaming\npm\node_modules\pr
otractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine-core\jasmine
.js:802:7)
at jasmineInterface.describe (C:\Users\PJ\AppData\Roaming\npm\no
de_modules\protractor\node_modules\jasmine\node_modules\jasmine-core\lib\jasmine
-core\jasmine.js:3375:18)
at Object.<anonymous> (D:\protractor_git\Demo\\LoginTest
.js:2:1)
Your page object should be defined as a function:
var Page = function () {
this.login = element(by.model('credentials.username'));
this.password = element(by.model('credentials.password'));
this.user = "Email";
this.passwd = "Password";
this.goButton = $('input.btn.btn-primary');
this.EC = protractor.ExpectedConditions;
this.go = function() {
browser.get("Application URL", 30000);
browser.wait(this.EC.elementToBeClickable(this.login), 30000);
};
};
module.exports = new Page();
Thanks for the suggestion, I agree it should work the way you mentioned, however, it’s strange that we still get into unrecognized types issue.
We are a bit new to the node js and this stack. I tried multiple options including the one you mentioned, by wrapping everything into a function, by individually exposing the elements/functions as module exports etc..
Finally, I found the following one to be working for me, using prototyping.
var AngularPage = function () {
};
AngularPage.prototype.login = element(by.model('credentials.username'));
AngularPage.prototype.password = element(by.model('credentials.password'));
AngularPage.prototype.goButton = $('input.btn.btn-primary');
AngularPage.prototype.user = "username";
AngularPage.prototype.passwd = "password";
AngularPage.prototype.EC = protractor.ExpectedConditions;
AngularPage.prototype.go = function(){
browser.get("Application URL",30000)
.then(browser.wait(this.EC.elementToBeClickable(this.login),30000));
expect(browser.getTitle()).toContain(‘String’);
};
AngularPage.prototype.loginMethod = function(){
console.log("Login started");
this.login.sendKeys(this.user);
this.password.sendKeys(this.passwd);
this.goButton.click();
browser.wait(this.EC.elementToBeClickable(this.compute));
};
module.exports = AngularPage;
In the test file, this is how, I was able to import and call it, a sample snippet.
var page = require('./LoginPage_Export_As_Prototype.js');
var LoginPage = new page();
LoginPage.go();
LoginPage.loginMethod();
Thanks,
Prakash

Unknown provider error when injecting factory

I am using yeoman angular full stack generator. Trying out ToDo items tutorial with MongoDB.
Everything worked fine i.e. I was able to read from DB using $http.get. However I decided to go further and create a factory so I can perform CURD.
After creating factory I tried to inject it but getting error as follows:
Error: [$injector:unpr] Unknown provider: factToDoProvider <- factToDo
http://errors.angularjs.org/1.2.6/$injector/unpr?p0=factToDoProvider%20%3C-NaNactToDo
at http://localhost:9000/bower_components/angular/angular.js:78:12
at http://localhost:9000/bower_components/angular/angular.js:3538:19
at Object.getService [as get] (http://localhost:9000/bower_components/angular/angular.js:3665:39)
at http://localhost:9000/bower_components/angular/angular.js:3543:45
at getService (http://localhost:9000/bower_components/angular/angular.js:3665:39)
at invoke (http://localhost:9000/bower_components/angular/angular.js:3687:13)
at Object.instantiate (http://localhost:9000/bower_components/angular/angular.js:3708:23)
at http://localhost:9000/bower_components/angular/angular.js:6758:28
at link (http://localhost:9000/bower_components/angular-route/angular-route.js:897:26)
at nodeLinkFn (http://localhost:9000/bower_components/angular/angular.js:6212:13)
Main.js controller looks like
'use strict';
angular.module('angularFsApp')
.controller('MainCtrl', function ($scope, $http, factToDo) {
$http.get('/api/awesomeThings').success(function(awesomeThings) {
$scope.awesomeThings = awesomeThings;
});
$http.get('/todo/todoItems').success(function(todoItems) {
$scope.todoItems = todoItems;
});
//$scope.newtodoItems = factToDo.getAllItems();
});
Where factToDo is my factory which look like as follows (todo.js)
angular.module('angularFsApp')
.factory('factToDo', function() {
return {
getAllItems: function () {
return [
{description: 'Hello World 1', priority: '15'},
{description: 'Hello World 2', priority: '15'},
{description: 'Love for all', priority: '1500'}
];
}
}
});
I tried by changing my code in main.js as described in AngularJS error ref as follows
angular.module('angularFsApp')
.controller('MainCtrl', ['$scope', '$http', 'factToDo', function ($scope, $http, factToDo) {
as well as I tried Dan Wahlin but i got same issue.
Make sure the file with the 'factToDo' is included into your app.
For a convenient development and to avoid issues like this in the future try the Grunt task runner to concatenate all your code for you and include it as a one file.
This tutorial seems to be sufficient for starting with Grunt and file concatenation.