Why is cy.log() is not printing any values in the left pane in Cypress? - javascript-objects

I am new to Cypress. I have a repo at https://github.com/martian86/PractiseJavaScript.git
I have a math.js file which has a simple code to calculate sum of 2 numbers and another function to return square of the number. There is another file strings.js which returns a string. I am using module.exports in one of the files and exports in another. I intend to print it using cy.log() in the tests written in test.js
The tests pass without without error but cy.log() does not print anything.
Can anyone suggest what is going wrong.
math.js
module.exports = {
square: (x) =>{
return x*x;
},
sum: (a,b)=>{
return a+b;
}
}
test.js
/// <reference types="cypress" />
const { describe } = require("mocha");
let testFirstName = require("/cypress/support/strings.js");
let {square, sum} = require("/cypress/support/math.js");
describe("Test suite",function(){
it("Square of the number",function(){
cy.log(square(90));
cy.log(sum(25,67));
});
it("Display Name",function(){
cy.log(testFirstName.stringsFirstName)
})
})
strings.js
let firstName = "John";
let lastName = "Cena"
exports.stringsFirstName=firstName;

Related

Typescript: Array is empty after calling and passing it to function

Hi I am building function to recursively "denest" a object of following interface:
export interface IUnit {
code: string
artifacts: IArtifact[]
units: IUnit[]
}
The idea is that I have a separate array that I returns with every immersion and after each return the returned array is "pushed" to local array and so on...
the function is as following:
const denestList = async (incomingUnit: IUnit): Promise<{ allUnits: IUnit[], allArtifacts: IArtifact[] }> => {
var units = [incomingUnit];
var artifacts = [...incomingUnit.artifacts];
//Array is full
console.log(unit.units)
//Array is empty
console.log(unit.units.length)
console.log([...unit.units])
console.log(Array.from(unit.units)?.length)
for (unit of incomingUnit.units) {
console.log(unit.code)
//Recursion happens here.
var result = await denestList(unit)
units.push(...result.allUnits)
artifacts.push(...result.allArtifacts)
}
return { allUnits: units, allArtifacts: artifacts }
}
The problem is that for (unit of incomingUnit.units) never happens. When I log unit.units it shows array full of IArtifact[], but when I run console.log(unit.units.length) it return 0.
Here is how to "denestList" function is called:
useEffect(() => {
asyncStart(unit)
}, []);
const asyncStart = async (mainUnit: IUnit) => {
var result = await denestList(mainUnit);
setAllUnits(result.allUnits)
setAllArtifacts(result.allArtifacts)
}
I would really appreciate any help. Thank you in advance

vscode findFiles returns nothing but npm glob returns correct results

I'm writing and vscode extension in which I need a list of the test files inside workspace.
To find the test files I'm using the default testMatch from the jest.config.js which is:
[
'**/__tests__/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[jt]s?(x)'
]
My problem is that vscode.workspace.findFiles returns empty array and I cannot set it up to get correct results, but using Glob package the output is correct.
protected async findTestFiles(
matchTestsGlobPatterns: string[]
): Promise<vscode.Uri[]> {
const testFilesUris: vscode.Uri[] = [];
const glob_testFilesUris: vscode.Uri[] = [];
const { name: workspaceName, workspaceFolders } = vscode.workspace;
if (workspaceName === undefined || workspaceFolders === undefined) {
throw new Error(`No active workspace${!workspaceFolders ? ' folders' : ''}.`);
}
for (let folderIdx = 0; folderIdx < workspaceFolders.length; folderIdx++) {
const folder = workspaceFolders[folderIdx];
// - by vscode.workspace.findFiles
for (let patternIdx = 0; patternIdx < matchTestsGlobPatterns.length; patternIdx++) {
const currentPattern = matchTestsGlobPatterns[patternIdx];
const pattern = new vscode.RelativePattern(
folder.uri.fsPath,
currentPattern
);
const files = await vscode.workspace.findFiles(
pattern,
'**/node_modules/**'
);
testFilesUris.push(...files);
}
console.log('by [vscode.workspace.findFiles]', testFilesUris.length);
// - by npm Glob
var glob = require('glob');
for (let patternIdx = 0; patternIdx < matchTestsGlobPatterns.length; patternIdx++) {
const currentPattern = matchTestsGlobPatterns[patternIdx];
const files: any[] = await new Promise((resolve, reject) => {
glob(
currentPattern,
{
absolute: true,
cwd: folder.uri.fsPath,
ignore: ['**/node_modules/**']
},
function (err: Error, files: any[]) {
if (err) {
return reject(err);
}
resolve(files);
}
);
});
glob_testFilesUris.push(...files);
}
console.log('by [npm Glob]', glob_testFilesUris.length);
}
// #todo: remove duplicates.
return testFilesUris;
}
The example console output of this function for some project is:
by [vscode.workspace.findFiles] 0
by [npm Glob] 45
Project structure:
rootFolder
src
__tests__
files.test.ts
...
utils
array.test.ts
...
So my question is how do I call vscode.workspace.findFiles to get correct results, or is there known problem with this function?
I have found some kind of answer to the question.
The problem is ?(x) in patterns. The vscode.workspace.findFiles does not work with this pattern as other packages do. If remove it from mentioned glob patterns they work except the .jsx | .tsx files are ommited.
After deep dive into vscode github's issues I have learned (here) that vscode.workspace.findFiles does not support extended patterns like ?(patterLike)

Gulp-eslint throws errors on dynamically loaded JSs

I have a project structure like
There are approx 10 JS files in com. lab1 and lab2 has a config.json file which tells, out of 10 files which files to be concatenated and placed as app-min.js in dist/lab1 or dist/lab2.
In the gulp file I've created something like this.
var filesArr = [];
var labName;
// Player Task
gulp.task('player', function () {
return gulp.src(filesArr)
.pipe(eslint())
.pipe(babel())
.pipe(concat('app-min.js'))
.pipe(uglify({
compress: {
drop_console: true
}
}).on('error', gutil.log))
.pipe(gulp.dest('dist/' + labName));
});
// Clean
gulp.task('clean', function () {
if (readJson()) {
return del([
'dist/' + labName
]);
}
return null;
});
// Watch
gulp.task('watch', function () {
gulp.watch(filesArr, gulp.series('player'));
});
// Read Json and create JS Array
function readJson() {
// LAB STRUCTURE
var _n = prompt('Specify the LAB name. ');
labName = _n;
var _path = path.resolve('./src/' + _n);
var _exists = fs.existsSync(_path);
if (_exists) {
var _json = fs.readFileSync(path.resolve(_path + '/labstructure.json'), 'utf-8');
var _jObj = JSON.parse(_json).labObj.components;
for (var i = 0; i < _jObj.length; i++) {
var _jsName = 'src/com/component/' + _jObj[i].ref + '.js';
if (filesArr.indexOf(_jsName) === -1) {
filesArr.push(_jsName);
}
}
}
return _exists;
}
gulp.task('default', gulp.series('clean', 'player', 'watch'));
Here the filesArr looks like:
[ 'src/com/component/ColorActClass.js',
'src/com/component/PanelCompClass.js',
'src/com/component/ToggleCompClass.js',
'src/com/component/SliderCompClass.js',
'src/com/component/CheckBoxCompClass.js',
'src/com/component/ButtonCompClass.js',
'src/com/component/LabelCompClass.js',
'src/com/component/InputBoxClass.js',
'src/com/component/ColorMonitorClass.js',
'src/com/component/MsgBoxClass.js',
'src/com/component/ConfBoxClass.js',
'src/com/component/NumberPadClass.js',
'src/com/main/lib/webfontloader.js',
'src/com/main/lib/howler.core.min.js',
'src/com/main/PlayerClass.js',
'src/kl1001_color/BrainClass.js' ]
This works perfectly fine at the first place. But when any JS is modified then in watch player task throws eslint error on some files which are untouched. This doesn't happen always rather if watch is running for 10-20 mins then it throws error. Like this:
In this case CheckBoxCompClass.js is not the file which is modified, but still got the issue. On top of that, the semicolon is in place. If this file has issue then eslint should have thrown the error at the first place.
Please help.
Accidentally, my NVM was set to an older version. Solved the issue after updating the NVM and by setting the current NVM version to the latest one.

While loop in nightwatch.js

I'm trying to run the following code (a number of steps) several times (e.g: 10 times) so that:
the user navigates to the detailed url
a random button is clicked, as per the defined var values
this is repeated 10 times
the test is then complete
I'm working with the following NightwatchJS code:
var randomEmail = faker.internet.email()
var competitionReference = ['drawing_21715','drawing_21704']
var randomCompetitionReference = competitionReference[Math.floor(Math.random()*competitionReference.length)]
module.exports = {
'navigate to homepage': function (browser) {
browser
.url('http://clickswin-stage.bellamagazine.co.uk/')
},
'select a competition': function (browser) {
browser
.useXpath()
.click('//*[#id="' + randomCompetitionReference + '"]/div/div[1]')
},
};
I've read that the best way to do this would be to use a while loop, but I'm not really sure how to set this up for my code above.
For example, if I were to use:
var i = 0
while ( i < 10) {
etc, whereabouts would I need to put this loop code within my code above?
Any help would be greatly appreciated.
One solution could be using a recursive function. Here is an example of how this could look like:
var randomEmail = faker.internet.email()
var competitionReference = ['drawing_21715', 'drawing_21704']
// var randomCompetitionReference = competitionReference[Math.floor(Math.random() * competitionReference.length)]
var randomCompetitionReference = function() {return competitionReference[Math.floor(Math.random() * competitionReference.length)]}
module.exports = {
'navigate to homepage': function (browser) {
browser
.url('http://clickswin-stage.bellamagazine.co.uk/')
},
'select a competition': function (browser, recursions) {
// Put the main code into a separat recursive function.
const doClick = function(times) {
if (times > 0) { // This is the equivalent to "while ( i < 10) {"
return browser
.useXpath()
.click('//*[#id="' + randomCompetitionReference() + '"]/div/div[1]')
.useCss()
.perform(()=>{ // perform() makes sure, that one function call is only executed after the other has fineshed (not concorrent)
return doClick(times -1)
})
} else {
return browser
}
}
doClick(recursions)
}
}
In your case you would call the function 'select a competition' with 10 as the parameter "recursions".
Note that I have changed "randomCompetitionReference" to be a function, so this generates a different value every time it is called. Else it would get one random value when its defined, and would reuse that same value for every click().

How to extend returned objects in the list returned by $asArray?

I'm having trouble decorate the objects in my list returned by $asArray in angularfire with a new method (not decorating the array itself).
The angularfire documentation seems to suggest that the right way to do this is to override the $$added method in the factory for $FirebaseArray, returning a new object that either encapsulates or extends the snapshot that gets passed in to that method. From the documentation:
// an object to return in our JokeFactory
app.factory("Joke", function($firebaseUtils) {
function Joke(snapshot) {
this.$id = snapshot.name();
this.update(snapshot);
}
Joke.prototype = {
update: function(snapshot) {
// apply changes to this.data instead of directly on `this`
this.data = snapshot.val();
},
makeJoke: function() {
alert("Why did the " + this.animal + " cross the " + this.obstacle + "?");
},
toJSON: function() {
// since we didn't store our data directly on `this`, we need to return
// it in parsed format. We can use the util function to remove $ variables
// and get it ready to ship
return $firebaseUtils.toJSON(this.data);
}
};
return Joke;
});
app.factory("JokeFactory", function($FirebaseArray, Joke) {
return $FirebaseArray.$extendFactory({
// change the added behavior to return Joke objects
$$added: function(snap) {
return new Joke(snap);
},
// override the update behavior to call Joke.update()
$$updated: function(snap) {
this.$getRecord(snap.name()).update(snap);
}
});
});
However, when I do this in my code, nothing ever gets added to the array, although I can see from outputting to the console that it is getting called.
var printMessageObjConstructor = function(snap) {
this.$id = snap.name();
this.snapshot = snap;
this.$update = function(snap) {
this.snapshot = snap;
};
this.printMessage = function() {
return this.author + "'s question is: " + this.body;
};
};
var ref = new Firebase("https://danculley-test.firebaseio.com/questions");
//What Am I Doing Wrong Here?
var arrayFactory = $FirebaseArray.$extendFactory({
$$added: function(snap, prevChild) {
var x = new printMessageObjConstructor(snap);
console.log("I am being called from FirebaseDecoratedCtlOverloadAddedinNewObj.");
return x;
},
$createObject: function(snap) {
return new printMessageObjConstructor(snap);
},
$$updated: function(snap) {
var i = this.$indexFor(snap.name());
var q = this.$list[i];
q.$update(snap);
}
});
var sync = $firebase(ref, {arrayFactory:arrayFactory});
var list = sync.$asArray();
list.$loaded(function(list) {
$scope.questions = list;
});
I've set up a new plunk stripped down to show the issue with a couple other use cases that I've tried. (The actual method I'm adding is more complex and isn't related to the view, but I wanted to do something simple to reproduce the issue.)
I think the issue is that I don't quite understand what exactly $$added is supposed to return, or what additional behavior beside returning the value to be stored $$added is supposed to have. There also doesn't really seem to be an $$added on the prototype or on $FirebaseArray to call as a super to get the default behavior. Can someone point me in the right direction?
UPDATE
For the benefit of others, after reviewing the like that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}
For the benefit of others, after reviewing the link that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}

Resources