Closing toastr in webdriver - javascript

UI automation testing
I have toast message all around my app, sometimes I get multiple toasts, which blocks clicking on other parts of the app. meaning I have to close them before I can interact with other buttons.
I wrote an if else statement to close them. when there is only one it works. when there are more than 2 toasts it fails.
I am using JS and Node js
Using Webdriverio and Mocha
This is the toastr library https://github.com/CodeSeven/toastr
Can someone tell me what am I missing?
closeToastMessage() {
let close_toast = $$('.toast-close-button');
const closeToasts = $$('.toast-close-button');
let toast_exist = browser.waitForExist('.toast', 5000);
if (close_toast.value) {
close_toast.click();
browser.waitUntil(function() {
return close_toast.waitForExist(5000, true);
}, 5000, 'expecte toast to disappear');
} else if (closeToasts.length) {
for (let i = 0; i < closeToasts.length; i++) {
closeToasts[i].click();
browser.waitUntil(() => {
return !closeToasts[i].isVisible();
}, 5000, `Close toast ${i} still visible after 5 s`, 1000);
} else {
throw new Error('Oops! toast did NOT disappear');
}
}
}

There is a preventDuplicates option. Try setting it to true.
Other options to check out.
toastr.options = {
"closeButton": true, // Allow force-closing
"newestOnTop": false, // Keep the oldest one up-front
"preventDuplicates": true, // Do not allow duplicates to appear
"showDuration": 300, // Time it take to show up, 0.3 sec default
"hideDuration": 1000, // Time it take to hide, 1 sec default
"timeOut": 5000, // Duration it is displayed, 5 sec default
"extendedTimeOut": 1000 // Time it takes to hide if hovered, 1 sec default
}
Checkout their demo.

Related

Glide.js slider not pausing on last slide

What i am trying to achieve, is a basic slideshow that starts, gets to the last slide and stops. I am using Glide.js as it is so small and is really awesome however, with the below code it does not actually pause and the slide spins round back to the beginning again.
/**
* Homepage Slideshow
*/
if(document.querySelector('.glide')) {
var item_length = document.querySelectorAll('.glide__slide').length - 1;
let glide = new Glide('.glide', {
type: 'slider',
startAt: 0,
perView: 1,
autoplay: 6000,
hoverpause: true,
});
glide.on('move', (e) => {
if(glide.index == item_length) {
console.log(glide.index, item_length);
glide.pause();
}
});
glide.mount();
}
I am getting the console.log out which is telling me 5 5 meaning I am on the glide.index at the 5th slide and the item_length is 5. So the glide.pause() should work. Any help would be greatly appreciated I have been scratching my head for ages on this. I have tried run and other events instead of move and still no success.
Try setting the rewind option to false:
/**
* Homepage Slideshow
*/
if(document.querySelector('.glide')) {
var item_length = document.querySelectorAll('.glide__slide').length - 1;
let glide = new Glide('.glide', {
type: 'slider',
startAt: 0,
perView: 1,
autoplay: 6000,
hoverpause: true,
rewind: false,
});
glide.mount();
}
Reference

How to display notification if request takes a certain amount of time?

This is what i've done:
response.config.responseTiming = performance.now();
var timing = response.config.responseTiming - response.config.requestTiming;
if (timing > 15000) {
var toastr = $injector.get('toastr');
toastr.info($filter('i18n')('_request_info_'));
angular.extend(toastrConfig, {
preventOpenDuplicates: true
});
}
But the problem is, the notification will appear when the request is completed, not when 15-sec pass(example: if it goes over 30sec, it will display notification after 30 sec not on 15 sec). Any idea how to do this?

Chrome App - webview.cleardata, reload and periodic refresh

I'm working on a kiosk app with a webview to display a Google Slides presentation. Basic mechanics are all working fine, but I need for the webview to refresh periodically to reflect changes made to the Slides.
Watched Chromium bug 406437 to clear webview cache (yay!), and am attempting to implement the webview.cleardata and webview.reload, but doesn't seem to work. Console log shows "Cannot read property 'reload' of null"
Am I on the right track? Is there something simple I'm overlooking, or is there a design flaw in my logic?
Contents of my browser.js (at least the first part)...
// NOTE: Refresh timing is on line 26 - in milliseconds
// 5 min: 5 x 60 (sec) x 1000 (ms)
window.onresize = doLayout;
var isLoading = false;
// Define the function
function refreshWebView() {
var webview = document.querySelector('webview');
// https://github.com/GoogleChrome/chrome-app-samples/blob/master/samples/webview-samples/browser/browser.js
// Set up the clear data variable
var clearDataType = {
appcache: true,
cookies: true,
fileSystems: true,
indexedDB: true,
localStorage: true,
webSQL: true,
cache: true
}
webview.clearData({since: 0}, clearDataType, function() { webview.reload(true); });
webview.reload(true);
setTimeout(function() { refreshWebView(); }, 60*1000);
}
// Kick off the refresh (with the delay defined above)
console.log('starting refreshWebView...');
refreshWebView();
onload = function() {
var webview = document.querySelector('webview');
doLayout();
document.querySelector('#back').onclick = function() {
webview.back();
};
... remaining code removed for brevity...

Custom transition timing in impress.js

I'm trying to create different transition times for each slide in an impress.js presentation.
I found the code below in a book about impress.js. But checking it on JSLint it shows errors. I am not good enough with javascript to correct this myself. Anybody willing to help me out?
Edit: I need a solution without jQuery. This is because impress.js allows you to navigate through the presentation with spacebar and arrow keys and I don't want to lose that functionality.
I found that when navigating with the keys (while jQuery is timing the auto-advance) it does not respect the position where you navigated to, but forces you away from where you are. I would like instead that if you navigate to a slide (position) the auto-advance starts running the custom set time for that particular slide and advances to the next slide when the set amount of time has passed. This would be an awesome addition to impress.js. I hope this can be done. Thanks for your effort!
JSFiddle: http://jsfiddle.net/5sSE5/8/ (script added at the end of impress.js)
var step_transitions = [
{ "slide": 1, "duration": 2000 },
{ "slide": 2, "duration": 4000 },
{ "slide": 3, "duration": 1000 }
];
$(document).ready(function () {
var time_frame = 0;
step_transitions.filter(function (steps) {
time_frame = time_frame + steps.duration;
setTimeout(function () {
api.goto(steps.slide);
}); time_frame;
});
});
Addition: below script respects keyboard navigation, but all the slides have the same transition time.
var impress = impress();
impress.init();
document.addEventListener('impress:stepenter', function(e){
if (typeof timing !== 'undefined') clearInterval(timing);
var duration = (e.target.getAttribute('data-transition-duration') ? e.target.getAttribute('data-transition-duration') : 10000); // in ms
timing = setInterval(impress.next, duration);
});
There is an error in your code in the setTimeout:
setTimeout(function () {
api.goto(steps.slide);
}, time_frame);
It seems that the time_frame variable should be second argument of the setTimeout method.
Update
You also forgot to initialize the api variable before using it:
var api = impress();
You also need the jQuery library to be able to use the $ function.
See updated fiddle
Update 2
I reworked your code to make it continue from the first slide after the last is reached:
var step_transitions = [
{ "slide": 0, "duration": 3000 },
{ "slide": 1, "duration": 4000 },
{ "slide": 2, "duration": 2000 }
];
$(document).ready(function () {
var time_frame = 0,
api = impress(),
current_step_index = 0,
do_transition = function (){
var step = step_transitions[current_step_index];
api.goto(step.slide);
current_step_index++;
if(current_step_index >= step_transitions.length){
current_step_index = 0;
}
setTimeout(do_transition, step.duration);
};
//initial run
do_transition();
});
Note, that slides must start from 0, not 1.
See updated fiddle

How do I make a QML rectangle spawn?

I'm currently making a game called Snowflake to learn how to program QML with Javascript.
I have my sourcecode here: https://gist.github.com/4510190.
The only files i got besides that is a default qmlproject file and a png file.
I have made this timer(Timer) and a rectangle(skullflake) which it should spawn for every interval it has finished.
Timer { //spawnrate
interval: 2000; running: true; repeat: true
onTriggered: Qt.createQmlObject(skullflake)
}
But when I try to run it, it gives me the error:
file:///where/the/project/is/saved/Snowflake/Snowflake.qml:21: Error: Qt.createQmlObject(): Invalid arguments
I have tried with both these elements but I can't seem to make it work
Qt.createComponent(skullflake)
Qt.createQmlObject(skullflake)
You were using wrong Qt.createQmlComponent().
It requires 3 parameters:
Qt::createQmlObject ( string qml, object parent, string filepath )
So it should look like something like this (parent should be id of element which should contain skullflake):
Timer { //spawnrate
interval: 2000; running: true; repeat: true
onTriggered: Qt.createQmlObject("YOUR skullflake QML CODE (NOT FILE PATH)", parent, "skullflake")
}
I solved it by using the Qt.createComponents() which requires you to use a QML file on the side or use the Component element.
Item {
id: container
width: 300; height: 300
function skullFlake() {
var component = Qt.createComponent("Skullflake.qml");
if (component.status == Component.Ready) {
var flake = component.createObject(container);
flake.color = "purple";
}
}
Component.onCompleted: loadButton()
}
Timer { //spawnrate
interval: 2000; running: true; repeat: true
onTriggered: skullFlake();
}

Categories

Resources