I'm trying to open a couple of URLs in sequence with Casperjs.
Here is a simplified version of my actual code.
casper = require('casper').create()
casper.start()
casper.then () ->
items = ['http://www.google.com', 'http://www.yahoo.com']
for item, idx in items
this.open item
this.then ((idx) ->
() ->
this.capture idx + '.png')(idx)
casper.run()
In my actual code, the items array is generated at runtime. I expect that this code will provide screenshots of google.com and yahoo.com, but actually both screen shots end up as yahoo.com. I feel like this has something to do with creating a closure inside a loop, but I can't see how. When open is called, item refers to a specific string. I'm never closing over it, am I?
The problem is that casper.open doesn't add a step, so it is not asynchronous (like thenOpen). It is immediately executed inside of the outer then. But the following then is asynchronous so its step is added to be executed after the current step (outer then). Both opens are executed, but the callbacks of both thens are executed after the last open.
So the solution would be to use thenOpen as a combined asynchronous step. There is a slight problem with the straigt forward solution:
CoffeeScript is a little language that compiles into JavaScript.
Which means that JavaScript misconceptions apply. This is the one: JavaScript closure inside loops – simple practical example
The for item, idx in items line is still a for loop in JavaScript. JavaScript has function level scope and casper.then is an asynchronous step function which means that the callbacks of all the casper.then calls are executed after the loop has run completely through (more precisely after the current step is finished or after casper.run was called), but casper.open is immediately executed.
Solution: Combine casper.open and casper.then to casper.thenOpen and pass item and idx through an IIFE so that they are fixed to each iteration:
for item, idx in items
((item, idx) ->
casper.thenOpen item, () ->
this.capture idx + '.png'
)(item, idx)
or use Array.prototype.forEach:
items.forEach (item, idx) ->
casper.thenOpen item, () ->
this.capture idx + '.png'
Related
I'm working on a project where i have a window with a size of 4 days, with a step of 1 day
.timewindow(Time.days(4), Time.days(1))
and i have also a trigger
.trigger(new myTrigger)
onEventTime ---> Continue
onProccessingTime ---> Continue
clear ---> Purge
onElement---> (if element.isFinalTransaction) TriggerResult.FIRE_AND_PRUGE
isFinalTransaction is a boolean, when true it call FAP.
the mean question is how can i make it return true/false depending on if the element is the last in the window or not
is there any method that can tell us if the current element is the last one in the window?
is there any method that can tell us if the current window is done (before sliding) or not ?
From the abstract trigger class (https://github.com/apache/flink/blob/master//flink-streaming-java/src/main/java/org/apache/flink/streaming/api/windowing/triggers/Trigger.java)
The short answer is no. The method onElement is called for every element that gets added to the pane. When an element gets added it's impossible to know if it is the last element, because that information is not known until the next element comes (and we see if it was in this window or the next one).
However, one alternative would be to check if the element is sufficiently close to the end of the end of the window (because onElement has access to window e.g. if (timestamp > window.getEnd - delta) ...
However, I can not think of a use case in which I would recommend this. If you need access to the last element in the window, you should probably just use a WindowFunction and in the apply method get the last element of the input iterable (input.last).
This is my Block which contain an element.element(by.model("$ctrl.benchmark.name"));
This is not present on Dom. It give me error that element is not on page but still execute all lines of code written after it. I want this to handle in sequential way if above passes then go to next only. How can I handle these types of problem in Protractor.
it("Test BenchMark",function(){
browser.getTitle().then(function (name) {
console.log(name);
browser.sleep(2000);
element(by.linkText("Manage Benchmarks")).click();
browser.sleep(4000)
//element(by.xpath("//main[#class='ng-scope']//a[text()='Create Benchmark']")).click();
console.log("megha");
element(by.model("$ctrl.benchmark.name")).sendKeys("bench");
element(by.buttonText("Save")).click();
console.log(megha);
element(by.xpath("//button[#class='dropdown-toggle']")).click();
console.log("dropdown clicked")
});
The behavior which you are expecting will not be handled by Protractor, it will be by testing framework(ex: Jasmine). But
"Jasmine doesn't support failing early, in a single spec. The idea is to give
you all of the failures in case that helps figure out what is really wrong
in your spec"
You can use browser.wait() combined with Expected Conditions.
browser.wait() blocks control flow execution until a promise is resolved, and Expected Conditions all evaluate to a promise.
So in your case, you could use either presenceOf() and/or visibilityOf().
var EC = protractor.ExpectedConditions;
var el = element(by.model("$ctrl.benchmark.name"));
var present = EC.presenceOf(el); // wait for it to be added to DOM
var visible = EC.visibilityOf(el); // wait for it to be visible on page
browser.wait(EC.and(present, visible), 10000); // wait maximum of 10 seconds
// rest of code
I'm confused by the behavior of a shared stream that is created using Rx.Observable.just.
For example:
var log = function(x) { console.log(x); };
var cold = Rx.Observable
.just({ foo: 'cold' });
cold.subscribe(log); // <-- Logs three times
cold.subscribe(log);
cold.subscribe(log);
var coldShare = Rx.Observable
.just({ foo: 'cold share' })
.share();
coldShare.subscribe(log); // <-- Only logs once
coldShare.subscribe(log);
coldShare.subscribe(log);
Both streams only emit one event, but the un-shared one can be subscribed to three times. Why is this?
I need to "fork" a stream but share its value (and then combine the forked streams).
How can I share the value of a stream but also subscribe to it multiple times?
I realize that this is probably related to the concept of "cold" and "hot" observables. However:
Is the stream created by Rx.Observable.just() cold or hot?
How is one supposed to determine the answer to the previous question?
Is the stream created by Rx.Observable.just() cold or hot?
Cold.
How is one supposed to determine the answer to the previous question?
I guess the documentation is the only guide.
How can I share the value of a stream but also subscribe to it multiple times?
You are looking for the idea of a connectable observable. By example:
var log = function(x) { console.log(x); };
var coldShare = Rx.Observable
.just({ foo: 'cold share' })
.publish();
coldShare.subscribe(log); // Does nothing
coldShare.subscribe(log); // Does nothing
coldShare.subscribe(log); // Does nothing
coldShare.connect(); // Emits one value to its three subscribers (logs three times)
var log = function(x) {
document.write(JSON.stringify(x));
document.write("<br>");
};
var coldShare = Rx.Observable
.just({ foo: 'cold share' })
.publish();
coldShare.subscribe(log); // <-- Only logs once
coldShare.subscribe(log);
coldShare.subscribe(log);
coldShare.connect();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.min.js"></script>
The example above logs three times. Using publish and connect, you essentially "pause" the observable until the call to connect.
See also:
How do I share an observable with publish and connect?
Are there 'hot' and 'cold' operators?
I don-t understand your first question, but about the last one, as I have been having problem getting that one too:
Rxjs implementation of Observables/Observers is based on the observer pattern, which is similar to the good old callback mechanism.
To exemplify, here is the basic form of creating an observable (taken from the doc at https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md)
var source = Rx.Observable.create(function (observer) {
observer.onNext(42);
observer.onCompleted();
// Note that this is optional, you do not have to return this if you require no cleanup
return function () {
console.log('disposed');
};
});
Rx.Observable.create takes as argument a function (say factory_fn to be original) which takes an observer. Your values are generated by a computation of your choice in the body of factory_fn, and because you have the observer in parameter you can process/push the generated values when you see fit. BUT factory_fn is not executed, it is just registered (like a callback would). It will be called everytime there is a subscribe(observer) on the related observable (i.e. the one returned by Rx.Observable.create(factory_fn).
Once subscription is done (creation callback called), values flow to your observer according to the logic in the factory function and it remains that way till your observable completes or the observer unsubscribes (supposing you did implement an action to cancel value flow as the return value of factory_fn).
What that basically means is by default, Rx.Observables are cold.
My conclusion after using quite a bit of the library, is that unless it is duely documented, the only way to know FOR SURE the temperature of an observable is to eye the source code. Or add a side effect somewhere, subscribe twice and see if the side effect happens twice or only once (which is what you did). That, or ask on stackoverflow.
For instance, Rx.fromEvent produce hot observables, as you can see from the last line in the code (return new EventObservable(element, eventName, selector).publish().refCount();). (code here : https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromevent.js). The publish operator is among those operators which turns a cold observable into a hot one. How that works is out of scope so I won-t detail it here.
But Rx.DOM.fromWebSocket does not produce hot observables (https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/src/dom/websocket.js). Cf. How to buffer stream using fromWebSocket Subject
Confusion often comes I think from the fact that we conflate the actual source (say stream of button clicks) and its representation (Rx.Observable). It is unfortunate when that happens but what we imagine as hot sources can end up being represented by a cold Rx.Observable.
So, yes, Rx.Observable.just creates cold observables.
I was trying to create a greasemonkey script which removes Facebook and twitter from a website.
In my case 9gag.
I looked and I need to hide the classes:
1. 'social-action' (works fine)
2. 'badge-sticky-social sticky-social' (every second post)
3. 'post-afterbar-a in-list-view' (every second post)
my Code so far (differing classes)
(function() {
var ads=document.getElementsByClassName('badge-sticky-social sticky-social');
for (var i=0; i<ads.length; i++) {
ads[i].parentNode.removeChild(ads[i]);
}
})()
I don't know why it only works on half the post and not all of them
Because you're removing the very elements that you're iterating over, the iteration ends up in the wrong place. That is, you look at the first one and then remove it, and then try to look at the second one. But the one that had been the second one is now the first one, so that one gets skipped.
The solution, as CBroe says, is to run the loop from high to low, so that you're not trying to count things that already have been removed:
for (var i=ads.length-1; i>=0; i--)
1-The code below displays the properties of the pressed key.Try it by pressing a key and observe the results.
figure('Name','Press keys to put event data in Command Window',...
'KeyPressFcn',#(obj,evt)disp(evt));
you will see outputs like this( e.g upon pressing space bar)
Character: ' '
Modifier: {1x0 cell}
Key: 'space'
2-Now simply add the following line of code to above ( or simply execute it before clearing the workspace)
cameratoolbar('SetMode','orbit');
Now press any key and nothing happens! the control will no longer be transferred to your costume call back function! ( here:#(obj,evt)disp(evt)).
same thing happens for WindowButtonDownFcn, WindowButtonUpFcn too.
How can I get around this? I wanna be able to handle KeyPressFcn or WindowButtonDownFcn after executing cameratoolbar('SetMode','orbit').
I found the answer: Once the cameratoolbar('SetMode','orbit') is called one of these two happens:the handle to the figure is lost or the event handler gets its default value. I am not sure which one though. Therefore we can add the following code to re-assign the lost handler back to our own call back function:
set(gcf,'KeyPressFcn',#(obj,evt)disp(evt))