How to conditionally click an element in Protractor? - dom

In a protractor test, I need to close a pop-up if it appears (it doesn't always) and proceed with the test as normal. Here's the code I've got to do so-
let checkForPopUp = async function() {
element(by.css('button[id="gdprStopEmails"]')).isPresent().then(function (isVisible) {
return isVisible;
});
}
it('description', async function() {
let hasPopUp = await checkForPopUp();
if(hasPopUp) {
await element(by.id("gdprStopEmails")).click();
}
await connectedAccounts.revokePermission(partnerInfo.revokeId, partnerInfo.confirmRevokeId);
});
I ran this test a few times without checking if the element was there, and it closed the popup every time it was there (and failed the test when it wasn't). It hasn't closed the popup a single time since I introduced the condition check, and despite my best efforts I can't figure out what's up. Does anything jump out to you guys? Thanks in advance!

you're missing return. Your function returns nothing explicitly and thus implicitly returns undefined which is always falsy, and your if block doesn't get executed
This should work
let checkForPopUp = async function() {
return element(by.css('button[id="gdprStopEmails"]')).isPresent().then(function (isVisible) {
return isVisible;
});
}
it('description', async function() {
let hasPopUp = await checkForPopUp();
if(hasPopUp) {
await element(by.id("gdprStopEmails")).click();
}
await connectedAccounts.revokePermission(partnerInfo.revokeId, partnerInfo.confirmRevokeId);
});
but since you're using async/await don't mix syntaxes. I'd do it this way
let checkForPopUp = async function() {
return element(by.css('button[id="gdprStopEmails"]')).isPresent()
}
it('description', async function() {
let hasPopUp = await checkForPopUp();
if(hasPopUp) {
await element(by.id("gdprStopEmails")).click();
}
await connectedAccounts.revokePermission(partnerInfo.revokeId, partnerInfo.confirmRevokeId);
});
and keep in mind isPresent doesn't guarantee the visibility

Related

Run multiple asyn function flutter one after one flutter

hello I want have to run two functions(Function1() and Function2()) and store value of these returns and run third function. But some time according to condition Function1() or Function2() or both not be run.
if(condition1){
await Function1();
}
if(condition2){
await Function2();
}
await Functon3();
I try as above but Function3() run simultaneously with Function1() or with Function2().
My Function1() code looks like following...
Future Function1() async {
apiService
.apiFileUpload()
.then((value) async {
///codes goes here
}).catchError((error) {
print('EEEE: ' + error.toString());
});
}
If anything not clear please let me know in the comment section.
Please do not use .then() in combination with async/await. It is technically possible, but it takes some skill to get it right, so why make it hard on yourself. Stick with one way of doing it, use either one or the other. You mixed it up and through a slight oversight, your Function1 does not actually wait on it's result. It just returns, with the function still running in the then block. So you await it, but that does not help.
Since you are using await already, stick with that and remove .then() from your repertoire for now:
Future Function1() async {
try {
final value = await apiService.apiFileUpload();
///codes goes here
} catch(error) {
print('EEEE: ' + error.toString());
}
}
You can use await
Future Function1() async {
try{
final value = await apiService
.apiFileUpload();
final value2 = await secondFuntion();
///add more and condition on values
} catch(e){
.....
}
}
from your question you need to tell the compiler to stop on particular task with await and avoid using then function it will never stop your compiler
your future fuction:
Future Function1() async {
apiService
.apiFileUpload()
.then((value) async {
///codes goes here
}).catchError((error) {
print('EEEE: ' + error.toString());
});
}
Modified Future func
Future Function1() async {
var result = await apiService.apiFileUpload();
if(result == success){
// code goes here
}else{
//you can show your error here
}
}

Function expressions can't be named: then(

Im having issues with my code and since I'm new at using Flutter, I have no clue on how to fix it. I was trying to fix the http.get(string) and I kind of did, but now I'm having issues with then(()).
void submitForm(FeedbackForm feedbackForm) async {
try {
await http.get(Uri.parse(URL + feedbackForm.toParams()).then((response)) {
callback(convert.jsonDecode(response.body['status']));
});
} catch (e) {
print(e);
}
}
}
It seems you got a parenthesis missplaced:
await http.get(...).then((response) => callback(...))
The them allows you to use the result of the previous Future, as soon as it becomes available. If you find it confusing you can declare one variable at a time.
final response = await http.get(...);
// Check if response was as expected
await callback();

Is there a way to get notified when a dart stream gets its first result?

I currently have an async function that does the following:
Initializes the stream
Call stream.listen() and provide a function to listen to the stream.
await for the stream to get its first result.
The following is some pseudo code of my function:
Future<void> initStream() async {
// initialize stream
var stream = getStream();
// listen
stream.listen((result) {
// do some stuff here
});
// await until first result
await stream.first; // gives warning
}
Unfortunately it seems that calling stream.first counts as listening to the stream, and streams are not allowed to be listened by multiple...listeners?
I tried a different approach by using await Future.doWhile()
Something like the following:
bool gotFirstResult = false;
Future<void> initStream() async {
var stream = getStream();
stream.listen((result) {
// do some stuff here
gotFirstResult = true;
});
await Future.doWhile(() => !gotFirstResult);
}
This didn't work for me, and I still don't know why. Future.doWhile() was successfully called, but then the function provided to stream.listen() was never called in this case.
Is there a way to wait for the first result of a stream?
(I'm sorry if I didn't describe my question well enough. I'll definitely add other details if needed.)
Thanks in advance!
One way is converting your stream to broadcast one:
var stream = getStream().asBroadcastStream();
stream.listen((result) {
// do some stuff here
});
await stream.first;
Another way, without creating new stream, is to use Completer. It allows you to return a Future which you can complete (send value) later. Caller will be able to await this Future as usual.
Simple example:
Future<int> getValueAsync() {
var completer = Completer<int>();
Future.delayed(Duration(seconds: 1))
.then((_) {
completer.complete(42);
});
return completer.future;
}
is equivalent of
Future<int> getValueAsync() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
In your case:
Future<void> initStream() {
var stream = getStream();
var firstValueReceived = Completer<void>();
stream.listen((val) {
if (!firstValueReceived.isCompleted) {
firstValueReceived.complete();
}
// do some stuff here
});
return firstValueReceived.future;
}

Dart Flutter, help me understand futures

See this code:
class SomeClass{
String someVariable;
SomeClass();
Future<String> getData () async {
Response response = await get('http://somewebsite.com/api/content');
Map map = jsonDecode(response.body); // do not worry about statuscode, trying to keep it minimal
someVariable = map['firstName'];
return 'This is the first name : $someVariable';
}
}
Now look at main:
void main(){
String someFunction() async {
SomeClass instance = SomeClass(); // creating object
String firstNameDeclaration = await instance.getData().then((value) => value);
return firstNameDeclaration;
}
}
When working with Future, like in the case of firstNameDeclaration why do I have to use .then() method to access the string object, since I am waiting for the function to finish?
When searching on the web, some people use .then() others don't, I am confused.
Kindly help me have a clearer understanding of how Futures and async functions overall work.
Background
Asynchronous operations let your program complete work while waiting for another operation to finish. Here are some common asynchronous operations:
Fetching data over a network.
Writing to a database.
Reading data from a file.
To perform asynchronous operations in Dart, you can use the Future class and the async and await keywords.
When an async function invokes "await", it is converted into a Future, and placed into the execution queue. When the awaited future is complete, the calling function is marked as ready for execution and it will be resumed at some later point. The important difference is that no Threads need to be paused in this model.
Futures vs async-await
When an async function invokes "await", it is converted into a Future, and placed into the execution queue. When the awaited future is complete, the calling function is marked as ready for execution and it will be resumed at some later point. The important difference is that no Threads need to be paused in this model.
async-await is just a a declarative way to define asynchronous functions and use their results into Future and it provides syntactic sugar that help you write clean code involving Futures.
Consider this dart code snipped involving Futures -
Future<String> getData(int number) {
return Future.delayed(Duration(seconds: 1), () {
return 'this is a future string $number.';
});
}
main(){
getData(10).then((data) => {
print(data)
});
}
As you can see when you use Futures, you can use then callback when the function return a future value. This is easy to manage if there is single "then" callback but the situation escalates quickly as soon as there are many nested "then" callbacks for example -
Future<String> getProductCostForUser() {
return getUser().then((user) => {
var uid = user.id;
return getOrder(uid).then((order) => {
var pid = order.productId;
return getProduct(pid).then((product) => {
return product.totalCost;
});
});
});
}
main(){
getProductCostForUser().then((cost) => {
print(cost);
});
}
As you can when there multiple chained "then" callback the code become very hard to read and manage. This problem is solved by "async-await". Above chained "then" callbacks can be simplified by using "async-await" like so -
Future<String> getProductCostForUser() async {
var user = await getUser();
var order = await getOrder(user.uid);
var product = await getProduct(order.productId);
return product.totalCost;
}
main() async {
var cost = await getProductCostForUser();
print(cost);
}
As you can above code is much more readable and easy to understand when there are chained "then" callbacks.
I hope this explains some basic concepts and understanding regarding the "async-await" and Futures.
You can further read about topic and examples here
Basically, you should either use await OR then(). However, Dart guidelines advocates that you should prefer use await over then() :
This code :
Future<int> countActivePlayers(String teamName) {
return downloadTeam(teamName).then((team) {
if (team == null) return Future.value(0);
return team.roster.then((players) {
return players.where((player) => player.isActive).length;
});
}).catchError((e) {
log.error(e);
return 0;
});
}
should be replaced by :
Future<int> countActivePlayers(String teamName) async {
try {
var team = await downloadTeam(teamName);
if (team == null) return 0;
var players = await team.roster;
return players.where((player) => player.isActive).length;
} catch (e) {
log.error(e);
return 0;
}
}
In your case, you should write :
void main(){
Future<String> someFunction() async {
SomeClass instance = SomeClass(); // creating object
String firstNameDeclaration = await instance.getData();
return firstNameDeclaration;
// Or directly : return await instance.getData();
// Or : return instance.getData();
}
}

Dart Completer.complete() results never resolve

I have a function that returns a future which depends on the result of a callback to resolve:
Future connectSocket(String email, String password, {Function onConnectCallback}) async {
var completer = new Completer();
print("Connecting...");
var query = getQueryString(email, password);
socketIO = await SocketIOManager().createInstance(SocketOptions(localDomainWindows, query: query));
socketIO.on("loginError", (data) {
print("Login err");
_connected = false;
connectedCallback();
completer.complete(false);
});
socketIO.onConnect((data) {
print("***CONNECTED***");
_connected = true;
completer.complete(true);
connectedCallback();
});
socketIO.connect();
return completer.future;
}
I can see ***CONNECTED*** printed to the console, and my socket server acknowledges the connection, but the function await-ing the resolution never resumes, it just hangs.
socketConnection.connectSocket(_email, _password)
.then((success) {
print("SUCCESS") // never gets printed
}
The only possible explanation for this is that some code in the callback is blocking your program from continuing because Completer.complete should otherwise always make the future complete.
If it is blocked, however, the event loop will never be able to call your code.
As a bool assignment should never be blocking (_connected = true;), the only part of your function that could be halting your program is connectedCallack();. If you remove or fix it, you should see your future complete.