How to get Scenario name from cucumber js? - node.js

In case of error I want to be able to log the scenario name. I'm using cucumber.js and node.
Feature file
Scenario: As me I can go to google
Given that I have a computer
When I go to google
Then I see wondrous stuff
I have tried the code below, but the name comes back as an empty string.
When(/^I go to google$/, (scenario) => {
// do something
var scenarioName = scenario.name;
});
By stepping through the code I can see that it's a function.
It has :
[[FunctionLocation]] = Object
[[Scopes]] = Scopes(6)
length = 2
name= ""

It seems like you can't do this in a Given or When, it has to be done in the Before or After hook:
Before((scenario) => {
const scenarioName = scenario.name;
console.log(`${scenarioName}`);
});

I could get the scenario name using this code:
Before((scenario: any) => {
console.log(`Starting scenario ${scenario.sourceLocation.uri}:${scenario.sourceLocation.line} (${scenario.pickle.name})`);
});
As you can see, there's more in there than just the scenario name. The entire test, with all the steps, tags, etc is in the object. I'm using CucumberJS 5.0.3.

I found the scenario name using below code
console.log(`The scenario is ${JSON.stringify(scenario.pickle.name)}.`);

Related

Retrieve ms-rest-azure authentication code with interactiveLogin method

I'm trying to push one inputless TV screen dashboard (using chromecast) with azure authentication in nodejs (working fine without auth so far)
My best move (?) is using ms-rest-azure package allowing to perform initial authentication from another device with https://aka.ms/devicelogin & a code
However, is there a clean way to retrieve this code and make it available outside the console ? I can't find reference or callback.
My fallback scenario would be to intercept process.stdout.write but feels like dirty.
There is an options object you can pass to interactiveLogin. One option is "userCodeResponseLogger", which should be a function, eg
let options = {"userCodeResponseLogger":(msg)=>{
console.log("I have the message",msg)
}
}
msRestAzure.interactiveLogin(options).then((credentials) => {
// doing authentication stuff
});
Note you'll still need to parse the msg to extract the code.
had to go forward on this issue and finally ends up by intercepting process.stdout.write with a better implementation then mine : https://gist.github.com/pguillory/729616/32aa9dd5b5881f6f2719db835424a7cb96dfdfd6
function auth() {
hook_stdout(function(std) {
var matches = / the code (.*) to /.exec(std);
if(matches !== null && matches.length >=2) {
var code = matches[1];
// doing something with the code
unhook();
}
});
msRestAzure.interactiveLogin().then((credentials) => {
// doing authentication stuff
});
}

How to test the bad cases?

Given that there are plenty of libraries for generating mock/fake data starting from a JSON schema or a Mongoose model and so on, how to test the behavior of a sw (let's say a web api) for the wrong data cases.
For example let's say I have a user service with name, email, phone, etc and a deep description of its fields data content. Let's say I have also different error codes that should be thrown for each possible error. I can't understand how to programmatically produce bad mock data (wrong email, bad formed name, etc) to put inside a test.
Moreover are there some test-process specs for these cases?
Thanks!
---- Integration for to answer to TGW: I'm doing standard tests, something like:
const app = require(-myapp-); //express or whatever app
const userModel = require('-myModelDefinition-); //e.g. json schema
const mockingLibrary = require(-mockingLibrary-); //Sinon or any other
//I'll test that the user->create method works properly on good input
const fakeUser = mockingLibrary.mock(userModel);
describe('\'users\' service', () => {
it('create method - good case',()=>{
return app.service('users')
.create(fakeUser)
.should.eventually
.have.property('_id'); //or any other test
});
});
//What if I want to test on bad input?
const fakeUserWithErrorOnEmail = mockingLibrary.mock(userModel,{errorOn:'email'});
describe('\'users\' service', () => {
it('create method - bad email case',done=>{
return app.service('users')
.create(fakeUserWithErrorOnEmail)
should.be.rejectedWith(Error, "email-error-message");
});
});
So what I'm looking for, maybe, is a mocking library able to produce both good and bad mock data given the description/schema of good ones.

Accessing response headers using NodeJS

I'm having a problem right now which I can't seem to find a solution to.
I'm using Uservoice's NodeJS framework to send some requests to UserVoice regarding Feedback posts. A problem I've run into are ratelimits so I want to save the header values X-Rate-Limit-Remaining, X-Rate-Limit-Limit and X-Rate-Limit-Reset locally. I've made a function for updating and getting that value and am calling it like this:
var content = "Test"
c.post(`forums/${config.uservoice.forumId}/suggestions/${id}/comments.json`, {
comment: {
text: content
}
}).then(data => {
rl.updateRL(data.headers['X-Rate-Limit-Limit'],data.headers['X-Rate-Limit-Remaining'],data.headers['X-Rate-Limit-Reset'])
When running this code I get the error Cannot read property 'X-Rate-Limit-Limit' of undefined.
This is not a duplicate, I've also tried it lowercase as described here but had no luck either. Thanks for helping out!
EDIT:
The function takes the following parameters:
module.exports = {
updateRL: (lim, rem, res) {SAVING STUFF HERE}
}
It is defined in the file rates.jsand is imported in the above file as const rl = require('../rates').

how to access hook object using .validate from feathers-hooks-common

I'm trying to create a simple validator in my feathersjs app and I need to have access to hook.app so I can retrieve the users service and check for uniqueness. Below is my code
checkUniqueEmail = (values, hook) => {
const userService = hook.app.service('users');
//below is my validation
}
The problem is that the hook variable is returning undefined instead of the hook object. The feathers-hooks-common github code it shows that this should be possible since hook is being pass as the 2nd parameter. (see below)
const results = validator(getItems(hook), hook); // line 18
I'm not sure what I'm doing wrong here.
I found a good documentation about feathers-hooks-common validate. It is better explained here. https://eddyystop.gitbooks.io/feathers-docs-common/content/hooks/validation.html
all you need to do is at create hook
//pass context or hook
create:[
validate((values,context) =>validations.signupAsync(values,context))
]
//at validations.signupAsync
clientValidations.signupAsync = (values,context) => {
const userService= context.app.service('users')
}

Meteor cannot retrieve data from MongoDB

Pretty straightforward and without any sort of configuration ->
In the project directory I entered the command:
$ meteor mongo to access the mongodb
From there (mongo shell), I switched to db meteor using the command use meteor then entered some basic data to test:
j = { name: "mongo" }
k = { x: 3 }
db.testData.insert(j)
db.testData.insert(k)
I checked and got results by entering: db.testData.find()
Here's my meteor code provided that mongodb access is only required on the client:
if (Meteor.isClient) {
Template.hello.greeting = function () {
return "Welcome to test.";
};
Template.hello.events({
'click input' : function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
Documents = new Meteor.Collection('testData');
var document = Documents.find();
console.log(document);
var documentCbResults = Documents.find(function(err, items) {
console.log(err);
console.log(items);
});
}
Upon checking on the browser and based on the logs, it says undefined. I was unsuccessful from retrieving data from mongodb and showing to the client console.
What am I missing?
For this answer I'm going to assume this is a newly created project with autopublish still on.
As Christian pointed out, you need to define Documents on both the client and the server. You can easily accomplish this by just putting the collection definition at the top of the file or in another file which isn't in either of the server or client directories.
An example which prints the first two test documents could look like this:
Documents = new Meteor.Collection('testData');
if (Meteor.isClient) {
Template.hello.greeting = function () {
return "Welcome to apui.";
};
Template.hello.events({
'click input' : function () {
var documents = Documents.find().fetch();
console.log(documents[0]);
console.log(documents[1]);
}
});
}
Note the following:
The find function returns a cursor. This is often all you want when writing template code. However, in this case we need direct access to the documents to print them so I used fetch on the cursor. See the documentation for more details.
When you first start the client, the server will read the contents of the defined collections and sync all documents (if you have autopublish on) to the client's local minimongo database. I placed the find inside of the click event to hide that sync time. In your code, the find would have executed the instant the client started and the data probably would not have arrived in time.
Your method of inserting initial items into the database works (you don't need the use meteor by the way), however mongo will default to using an ObjectId instead of a string as the _id. There are subtle ways that this can be annoying in a meteor project, so my recommendation is to let meteor insert your data if at all possible. Here is some code that will ensure the testData collection has some documents:
if (Meteor.isServer) {
Meteor.startup(function() {
if (Documents.find().count() === 0) {
console.log('inserting test data');
Documents.insert({name: "mongo"});
Documents.insert({x: 3});
}
});
}
Note this will only execute if the collection has no documents in it. If you ever want to clear out the collection you can do so via the mongo console. Alternatively you can drop the whole database with:
$ meteor reset
It's not enough to only define collections on the client side. Your mongo db lives on the server and your client needs to get its data from somewhere. It doesn't get it directly from mongodb (I think), but gets it via syncing with the collections on the server.
Just define the Documents collection in the joint scope of client and server. You may also need to wait for the subscription to Documents to complete before you can expect content. So safer is:
Meteor.subscribe('testData', function() {
var document = Documents.find();
console.log(document);
});

Resources