Protractor & Cucumberjs after hook doesn't work as expected - protractor

I have written a basic after hook in cucumberjs for some reason , it is not working as expected.It is supposed to attached screenshot and write browser console log , when scenario fails. But it attaches the screen shot after the feature in html report and prints the browser console log at after in between the second scenarioenter image description here.Any clue what's wrong??
this.After(function(scenario, callback) {
if (scenario.isFailed()) {
global.browser.takeScreenshot().then(function(base64png) {
var decodedImage = new Buffer(base64png,'base64').toString('binary');
scenario.attach(decodedImage, 'image/png');
});
global.browser.manage().logs().get('browser').then(function (browserlog){
browserlog.forEach(function (log) {
if (log.level.value > 900) {
console.error(log.message.substring(log.message.indexOf('Error'),log.message.indexOf('\n')))
}
})
});
callback();
} else {
callback();
}
});

According to the cucumberjs github page https://github.com/cucumber/cucumber-js#attachments
Images and other binary data can be attached using a stream.Readable. In that case, passing a callback to attach() becomes mandatory:
You could split the single after hook into two separate hooks:
this.After(function(scenario, next) {
browser.takeScreenshot().then(function(png) {
var decodedImage = new Buffer(png, 'base64').toString('binary');
scenario.attach(decodedImage, 'image/png', next);
}, function(err) {
next(err);
});
});
this.After(function(scenario, next) {
global.browser.manage().logs().get('browser').then(function (browserlog){
browserlog.forEach(function (log) {
if (log.level.value > 900) {
console.error(log.message.substring(log.message.indexOf('Error'),log.message.indexOf('\n')))
}
});
});
});

Related

unininstall PWA Manually

The following code can be used to install the program in the PWA:
var fab = document.querySelector('#fab');
var deferredPrompt;
fab.addEventListener('click', function () {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then(function (choice) {
if (choice.outcome === 'dismissed') {
console.log('installation was cancelled');
} else {
console.log('User Added To Home Screen');
}
});
deferredPrompt = null;
}
});
//********************************************************************
window.addEventListener('beforeinstallprompt', function (event) {
console.log('beforeinstallprompt run .');
event.preventDefault();
deferredPrompt = event;
return false;
});
now for Uninstall:
It can only be removed from the browser
Now my question is here:
Is it possible to create a code such as manual installation (mentioned above) that the user can uninstall the program without the need to use the browser tool?
Thank you all for your answers

How to stop functions when leaving the page in Ionic 4

I am working in my Ionic 4 app and I want to stop the functions when the page will leave.
This is my tab4.page.ts:
async getUserDetail(){
this.dataexists = false;
this.userActiveChallanges = [];
let me=this;
const loading = await this.loadingController.create({
message: '',
// duration: 2200,
translucent: true,
spinner: 'crescent',
showBackdrop: false,
cssClass: 'my-loading-class'
});
await loading.present();
this.userActiveChallanges=[];
this.storage.get('USERPROFILE').then(userObj => {
// console.log('User Profile :',userObj);
me.userprofile = userObj;
me.sendFitDatafunction(userObj);
me.myapi.apiCall('userActiveChallenges/'+userObj.id,'GET','').subscribe((data) => {
// console.log(data);
me.response=data;
loading.dismiss();
if(me.response.status === 'success'){
if(me.response && me.response.data && me.response.data.length>0){
this.userActiveChallanges=me.response.data;
this.flip(this.userActiveChallanges[0].challenge_id);
}
this.dataexists = true;
} else{
this.userActiveChallanges = '';
this.dataexists = true;
}
}, error => { loading.dismiss(); console.log(error); });
});
}
ionViewWillLeave() {
}
I want to stop this function when the page will leave because when I am not getting any response nor any error from the api the loader keeps running and when I move to the other page, it is showing there.
So, I want to stop the function when the page will leave.
Any help is much appreciated.
instead of local const loading, declare it as a property of your ts class (tab4).
now change your code and assign loader to it:
replace: const loading
with:
this.loading
Now inside ionViewWillLeave call:
ionViewWillLeave() {
if (this.loading) { this.loading.dismiss() }
}
Well, I don't know the function to stop your function, but to make something when you leave a page, you make it in IonViewDidLeave()

Amchart annotations . Returning back to normal mode from annotations mode

I am using external buttons for am charts export. when i enter into annotations mode and do export, the chart gets exported with annotations. But when the chart gets reloaded , the annotations mode does not revert back.
Could somebody let me know how to go back from annotations to normal mode.
if (chart.export.drawing.buffer.enabled === true) {
// Exporting the annotated chart with out "
//chart.export.capture"
chart.export.toPNG({}, function (data) {
chartimage.postImageData(data, chart_image_name)
});
} else {
chart.export.capture({
// action: "draw"
}, function () {
this.toPNG({
}, function (data) {
images.push({
"image": data,
"fit": [523.28, 769.89]
});
pending--;
if (pending === 0) {
chart.export.toPNG({
content: images
}, function (data) {
chartimage.postImageData(data, chart_image_name)
});
}
});
});
}
}
To exit from Annotation mode, simply use Export plugin's internal API method done():
chart["export"].drawing.handler.done();
BTW, export keyword is reserved and will result in errors on some browsers. It's better to access Export instance via named key: chart["export"].toPNG() versus chart.export.toPNG().
Please find the workaround below..
First capture the events for set and cancel annotations using menu reviewer
menuReviver: function (item, li) {
if (item.format === "XLSX" || item.format === "JSON") {
li.style.display = "none";
}
$(li).click(function () {
if (item.action == "draw") {
$("#chart_annotations").val(1);
}
if (item.action == "cancel") {
$("#chart_annotations").val(0);
}
});
return li;
}
Now while exporting the chart image use $("#chart_annotations").val() value as a
flag whether to export annotated chart or a normal chart. Please find the code below...
if (window.fabric) {
if ($("#chart_annotations").val() == 1) {
chart.export.toPNG({}, function (data) {
chartimage.postImageData(data, chart_image_name)
});
} else {
chart.export.capture({
//action: "change"
}, function () {
this.toPNG({
}, function (data) {
images.push({
"image": data,
"fit": [523.28, 769.89]
});
pending--;
if (pending === 0) {
chart.export.toPNG({
content: images
}, function (data) {
//post the image data using ajax
chartimage.postImageData(data, chart_image_name)
});
}
});
});
}

Protractor ignoring specs passed in a callback function

I'm running into an issue and need your help.
I have a list of products and I want to run some it blocks for each product.
The function getProducts is an asynchronous function. Here is my code.
jsonLoader = new Promise(function(resolve, reject) {
beforeAll(function(done) {
getProducts(function(loadedProducts) {
resolve(loadedProducts);
done();
});
});
});
describe('product-maintenance', function() {
jsonLoader.then(function(products) {
productsList = products;
//productsList contains the desired products
_.forOwn(productsList, function(product) {
//execute it-blocks
});
});
it('some test', function() {
expect(1).toBe(1);
});
});
He is only executing the it 'some test' and simply ignoring the it blocks in the _.forOwn loop.
Thanks !!! :)
I solved this by using promises in the onPrepare function.
onPrepare: function() {
var deferred = protractor.promise.defer();
getProducts(function(products) {
if (!products) {
deferred.reject(new Error('An error occured while loading products'));
} else {
productsModule.setProducts(products);
deferred.fulfill();
}
});
return deferred.promise;
}

Drop MongoDB database before running Mocha test

If I try to drop the database using after (at the end of my tests) it works.
If I try the following:
var db = mongoose.connect('mongodb://localhost/db-test')
describe('Database', function() {
before(function (done) {
db.connection.db.dropDatabase(function(){
done()
})
})
...
it does not drop the DB. what is going on? I would prefer dropping the db before starting testing -- so that after testing I can explore the db.
solved by connect in another define.. not sure if ideal.
describe('Init', function() {
before(function (done) {
mongoose.connect('mongodb://localhost/db-test', function(){
mongoose.connection.db.dropDatabase(function(){
done()
})
})
})
describe('Database', function() {
I implemented it a bit different.
I removed all documents in the "before" hook - found it a lot faster than dropDatabase().
I used Promise.all() to make sure all documents were removed before exiting the hook.
beforeEach(function (done) {
function clearDB() {
var promises = [
Model1.remove().exec(),
Model2.remove().exec(),
Model3.remove().exec()
];
Promise.all(promises)
.then(function () {
done();
})
}
if (mongoose.connection.readyState === 0) {
mongoose.connect(config.dbUrl, function (err) {
if (err) {
throw err;
}
return clearDB();
});
} else {
return clearDB();
}
});