Javascript console.log status of Cucumber scenario - javascript

I would like to print the status of each cucumber scenario using the afterScenario hook.
I've tried printing out scenario.status (code below) but it prints out "undefined"
afterScenario: (scenario) => {
console.log(scenario.status);
}
When printing out just scenario, I don't see status.
Scenario {
feature:
Feature {
description: undefined,
keyword: 'Feature',
line: 1,
name: 'Sample Test',
tags: [],
uri: '/Users/Daredevil/e2e/features/sampleProject/intro.feature',
scenarios: [ [Circular] ] },
keyword: 'Scenario',
lines: [ 15, 7 ],
name: 'Getting test status',
tags:
[ Tag { line: 6, name: '#WIP' }],
uri: '/Users/Daredevil/e2e/features/sampleProject/intro.feature',
line: 15,
description: undefined,
steps:
[ Step {
arguments: [],
line: 4,
name: 'I am on the app',
scenario: [Circular],
uri: '/Users/Daredevil/e2e/features/sampleProject/intro.feature',
isBackground: true,
keyword: 'Given ',
keywordType: 'precondition' },
Step {
arguments: [],
line: 8,
name: 'I am viewing the splash screen',
scenario: [Circular],
uri: '/Users/Daredevil/e2e/features/sampleProject/intro.feature',
isBackground: false,
keyword: 'Given ',
keywordType: 'precondition' } ] }
I had a read through https://docs.cucumber.io/cucumber/api/#hooks which suggested (from my understanding) to do scenario.failed, but I still get undefined.
Would anyone be able to tell me how I can get the status of a scenario?
I am using cucumber v3.2.1 and wdio-cucumber-framework v1.0.3.

Answer is simple, you should be console logging "scenario.result.status" instead of scenario.status.
Hope this answer helps you!

Below should work-
(tried with wdio-cucumber)
After(function (scenarioResult) {
const scenario = scenarioResult.scenario;
console.log('SCENARIO EXECUTION COMPLETED:',scenario.name);
});

This is not an answer just a suggestion. I would look into how the report.json is built as that report has all the scenarios and their result.
Another pointer is in your cucumber.js file set the reporting format you want to progress which will output progress to the console.
Take a look at https://github.com/cucumber/cucumber-js/blob/master/docs/cli.md#Formats

Related

JS: Extracting data from an array of objects

I have a complex query with 100s of fields and nested fields. What I want to do is, for each Index, extract the English and French text. As you can see in the array, there is no French text for some indexes. In that case I want to get the English text.
For me extracting the English text works fine because the text is already there, but incase of French, I get undefined errors. What would be the best way to implement this. Is Loadash needed for this or just pure JS methods?
Just to be clear, I have erros with extracting french because in some fields, french text is not available, I want to use the english value in that case.
Also It is recommend if I am able to get the English and French values by it's language field rather than the index. I have no idea how to do that.
Any suggestion, documentation is appreciated. Thank you!
example array:
[
{
id: "1",
name: [
{
language: "en-US",
text: "HOLIDAY"
}
],
order: 6,
Groups: [
{
name: [
{
language: "en-US",
text: "REGULAR"
}
],
code: "REGEARN"
},
{
name: [
{
language: "en-US",
text: "CHARGE"
}
],
code: "CHARGE"
}
]
}
]
and here is the code sandbox that reproduces my error:
CODE SAND BOX
https://codesandbox.io/s/javascript-forked-5073j
EDIT:
EXPECTED OUTPUT:
{
key: key,
englishtext: "Value Here",
frenchtext: "Value Here"
}
below is a working code, but issue is it does not work when there is no french language or that field. I get undefined errors. So is it possible I can get the needed data from the language field?
x.map((y) => ({
key: y.id,
name: y.name[0].text,
groupname: y.Groups ? x.Groups[0].name?.[0].text : 'N/A',
}))
Do you expect result like this? If you don't mind lodash.
const _ = require('lodash');
const getNames = (arr) => {
return arr.map((obj) => {
const id = obj.id;
const englishtext = _.get(obj, 'name[0].text', 'N/A');
const frenchtext = _.get(obj, 'name[1].text', englishtext);
return { id, englishtext, frenchtext };
});
};
console.log(getNames(x));
// [
// { id: '1', englishtext: 'HOLIDAY', frenchtext: 'HOLIDAY' },
// { id: '2', englishtext: 'Stat Holiday', frenchtext: 'Congé Férié' },
// { id: '3', englishtext: 'Over', frenchtext: 'Over' }
// ]

BigQuery API does not return newest table of a dataset

I need to find the most recent table by creation time in a BigQuery dataset. I have an Google Apps Script function that could find the newest table and it used to work fine when there were only a few tables in the dataset, but ever since there are more tables in the dataset(72 to be exact) it just keeps returning the same "newest" table (e.g tablename_1623468444656), even though I know that there exists a newer one.
The problem seems to be the size of the logger output, because when I log the output it says: "Logging output too large. Truncating output". But regardless of whether I log the output or not, it just returns the allegedly newest table (e.g tablename_1623468444656).
I don't know what I need to change so that the function can find the actual newest table again. The function looks like this:
function findNewestTables() {
const data = BigQuery.Tables.list('Projectname', 'Datasetname');
let
maxSoFar = 0,
id = "";
data.tables.forEach(table => {
const time = parseInt(table.creationTime);
if(time > maxSoFar){
maxSoFar = time;
id = table.id;
}
});
const formattedId = id.replace(":", ".");
// return formattedId;
console.log(data);
console.log(formattedId);
};
Part of the output looks something like this and then it is just abruptly cut off.
Logging output too large. Truncating output. { totalItems: 72,
kind: 'bigquery#tableList',
etag: '7+eK1beNA7CVq0xasdfdsfYw==',
nextPageToken: 'Team_1627356444573',
tables:
[ { id: 'tablename_1623468444656',
type: 'TABLE',
kind: 'bigquery#table',
creationTime: '1628585864499',
tableReference: [Object] },
{ tableReference: [Object],
id: 'tablename_1623554844685',
kind: 'bigquery#table',
creationTime: '1628585864503',
type: 'TABLE' },
{ id: 'tablename_1623641244614',
type: 'TABLE',
kind: 'bigquery#table',
tableReference: [Object],
creationTime: '1628585864573' },
{ tableReference: [Object],
kind: 'bigquery#table',
creationTime: '1628585864714',
type: 'TABLE',
id: 'tablename_1623727644545' },
{ tableReference: [Object],
kind: 'bigquery#table',
type: 'TABLE',
creationTime: '1628585865059',
id: 'tablename_1623814044558' },
{ creationTime: '1628585865037',
id: 'tablename_1623900444676',
type:
Thanks in advance for any tips.
So, this is one of those cases where you need to paginate. See the nextPageToken? If that value isn't empty/nil, it means you can call tables.list again and pass that token as the pageToken GET param in a subsequent request to get the next page of results.
More details about the API: https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/list

update multiple different documents in mongodb (nodejs backend) [duplicate]

This question already has answers here:
MongoDB: How to update multiple documents with a single command?
(13 answers)
Closed 3 years ago.
I looked at other questions and I feel mine was different enough to ask.
I am sending a (potentially) large amount of information back to my backend, here is an example data set:
[ { orders: [Array],
_id: '5c919285bde87b1fc32b7553',
name: 'Test',
date: '2019-03-19',
customerName: 'Amego',
customerPhone: '9991112222',
customerStreet: 'Lost Ave',
customerCity: 'WestZone',
driver: 'CoolCat',
driverReq: false, // this is always false when it is ready to print
isPrinted: false, // < this is important
deliveryCost: '3',
total: '38.48',
taxTotal: '5.00',
finalTotal: '43.48',
__v: 0 },
{ orders: [Array],
_id: '5c919233bde87b1fc32b7552',
name: 'Test',
date: '2019-03-19',
customerName: 'Foo',
customerPhone: '9991112222',
customerStreet: 'Found Ave',
customerCity: 'EastZone',
driver: 'ChillDog',
driverReq: false,// this is always false when it is ready to print
isPrinted: false, // < this is important
deliveryCost: '3',
total: '9.99',
taxTotal: '1.30',
finalTotal: '11.29',
__v: 0 },
{ orders: [Array],
_id: '5c91903b6e0b7f1f4afc5c43',
name: 'Test',
date: '2019-03-19',
customerName: 'Boobert',
customerPhone: '9991112222',
customerStreet: 'Narnia',
customerCity: 'SouthSzone',
driver: 'SadSeal',
driverReq: false,// this is always false when it is ready to print
isPrinted: false, // < this is important
deliveryCost: '3',
total: '41.78',
taxTotal: '5.43',
finalTotal: '47.21',
__v: 0 } ] }
My front end can find all the orders that include isPrinted:false, I then allow the end user to 'print' all the orders that are prepared, in which, I need to change isPrinted into true, that way when I pull up a next batch I won't have reprints.
I was looking at db.test.updateMany({foo: "bar"}, {$set: {isPrinted: true}}), and I currently allow each order to set a new driver, which I update by:
Order.update({
_id: mongoose.Types.ObjectId(req.body.id)
},
{
$set: {
driver:req.body.driver, driverReq:false
}
which is pretty straight forward, as only 1 order comes back at a time.
I have considered my front end doing a foreach and posting each order individually, then updating the isPrinted individually but that seems quite inefficient. Is there a elegant solutions within mongo for this?
I'm not sure how I would user updateMany considering each _id is unique, unless I grab all the order's who are both driverReq:false and isPrinted:false (because that is the case where they are ready to print.
I found a solution, that was in fact using UpdateMany.
Order.updateMany({
isPrinted: false, driverReq:false
},
{
$set: {
isPrinted: true
}
consider there this special case where both are false when it needs to be changed too true. But I do wonder if there is a way to iterate over multiple document id's with ease.

How to write this Store structure?

I'm trying to figure out the best way for my Redux Store to handle lists. Right now it looks like this:
Store = {
users: [],
posts: [],
lists: [],
}
My problem with this, is the list array. Essentially it's a store for paginated lists of a specific resource, so for example:
lists: [
{
id: 'users/43/posts',
items: [25, 36, 21]
}
]
Since I am using the url as the id, my component that shows a user's list of posts will know exactly which list to display. Now someone has told me that, this is a very very bad idea. And I just want some advice on what could be better. Another approach suggested was this:
users: [{
id: 2,
posts: [
{
url: 'users/2/posts',
items: [13, 52, 26],
}
]
}]
So what I don't understand, how does Redux know where to save this list? Do I have to specify in the action arguments where to save it?
Thank you for your advice.
Well, technically, anything works if you make it work! The second approach looks more mature, though. You don't want to use URLs as ID. IDs should be numbers or special sequence of characters+numbers. When your application grows, you'll want to normalize your data i.e. store the IDs in a separate array and transform the array of objects into an object with keys as ID.
Example from Normalizr
[{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
}
}, {
id: 2,
title: 'Other Article',
author: {
id: 1,
name: 'Dan'
}
}]
can be normalized to -
{
result: [1, 2],
entities: {
articles: {
1: {
id: 1,
title: 'Some Article',
author: 1
},
2: {
id: 2,
title: 'Other Article',
author: 1
}
}
}
}
When your application grows, you'll have multiple reducers and sub-reducers. You'll want to slice a specific portion of your state-tree and so on. For that reason someone might have advised you to store your state in a different manner.
But again, anything works if you make it work! Good luck!

Programmatically Set Constructor Parameters in Javascript

I am trying to interact with a javascript api (bare in mind I have never done this before). An example of what I am attempting to work with is here:
SearchSpring.Catalog.init({
leaveInitialResults : true,
facets : '.leftNav',
results : '#results',
result_layout: 'list',
results_per_page : 12,
layout: 'top',
loadCSS: false,
filters: {
color: ['Blue']
},
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens']
},
maxFacets: 5,
maxFacetOptions: 10,
sortText: 'Sort By ',
sortType: 'dropdown',
filterText: 'Refine Search Results',
previousText: 'Previous',
scrollType: 'scroll',
scrollTo: 'body',
backgroundSortField: 'price',
backgroundSortDir: 'desc',
compareText: 'Compare Items',
summaryText: 'Current Filters',
showSummary: true,
subSearchText: 'Subsearch:',
showSubSearch: true,
forwardSingle: false,
afterResultsChange: function() { $('.pagination').hide(); },
filterData: function(data) { console.debug(data); }
});
In the example I want to add a "backgroundFilter" to this with a value:
var cat="MyNewCategory";
cat.value="ANewValue;
How would I add this category and value to the backgroundFilters: listed above?
This is a very common framework initialization pattern when working with frameworks.
Your example code is passing a JavaScript Object {} as a parameter into a function () that is called init.
Taking out all definitions the pattern looks like this:
SomeFramework.frameworkFunction({});
In the above code the {} is an empty object used for initialization. There are two ways that you can work with that object in practice.
Regarding your first code snippet, you can add code into that 'object literal'.
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens'],
cat: ['My value']
},
Notice the added comma, this is an important tripping point. This may or may not fit your needs, depending on a few factors.
Regarding your second code snippet, you can apply members to JavaScript objects at runtime. What I mean is, your var cat can be added to the anonymous object-literal that is being passed in. Hard to say, but a simple concept. Here is how:
//Say this is initialized in some separate way. //There is a bug here I'll describe later.
var cat="MyNewCategory";
cat.value="ANewValue";
//Extract and name the initialization object. It is verbatim at this point.
var initObject = {
leaveInitialResults : true,
facets : '.leftNav',
results : '#results',
result_layout: 'list',
results_per_page : 12,
layout: 'top',
loadCSS: false,
filters: {
color: ['Blue']
},
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens']
},
maxFacets: 5,
maxFacetOptions: 10,
sortText: 'Sort By ',
sortType: 'dropdown',
filterText: 'Refine Search Results',
previousText: 'Previous',
scrollType: 'scroll',
scrollTo: 'body',
backgroundSortField: 'price',
backgroundSortDir: 'desc',
compareText: 'Compare Items',
summaryText: 'Current Filters',
showSummary: true,
subSearchText: 'Subsearch:',
showSubSearch: true,
forwardSingle: false,
afterResultsChange: function() { $('.pagination').hide(); },
filterData: function(data) { console.debug(data); }
};
//Now we can add variables (and functions) dynamically at runtime.
initObject.cat = cat;
//And pass them into the framework initialization in a separated way.
SearchSpring.Catalog.init(initObject);
Now for the bug. I don't know the solution because I do not know what it is intended to do, but I can point out what is potentially incorrect.
var cat="MyNewCategory";
cat.value="ANewValue;
This code is: 1 creating a String Object called cat. 2 changing the value to a new string.
I do not think this is what you really want.
To add a new backgroundFilter, in the separated way above, it would be:
initObject.backgroundFilters.cat = ['A', 'B'];
//Line above would give you this type of definition within the initObject (at runtime):
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens'],
cat: ['A','B']
},
For this to work it will depend on what the framework is expecting regarding backgroundFilters.
Hope that helps.
All the best!
Nash
I don't quite understand - do you want to have the backgroundFilters categories as structured objects rather than plain strings? If you are in control of the entire API, you can do something like
...
backgroundFilters: {
category: [
new SearchSpring.Catalog.Category("Shirt"),
new SearchSpring.Catalog.Category("Shoes"),
new SearchSpring.Catalog.Category("MyNewCategory", "ANewValue")
],
department: 'Mens'
}
...

Categories