Appium waitForElementByName always returns state: pending - webdriver

So I'm using Appium to test an iOS app. I've written my tests in javascript and am using Mocha as the testing framework. Everything runs fine except for trying to get an example test to pass:
it('should find sign up label', function () {
return driver.waitForElementByName('_signUpLabel', 3000)
.then(function (el) {
el.text().should.equal('Sign up with...');
});
});
And this is the app's code in question:
_signUpLabel = [[UILabel alloc] init];
[_signUpLabel setAccessibilityIdentifier:#"_signUpLabel"];
...
[_signUpLabel setText:#"Sign up with..."];
[view addSubview:_signUpLabel];
The iOS simulator loads, then the app loads, then the login view loads just fine with the element in view, yet the error I receive is: AssertionError: expected { state: 'pending' } to equal 'Sign up with...'
I can see that Appium has found an element through its logging:
> CALL waitForElementByName("_signUpLabel",3000)
> CALL elements("name","_signUpLabel")
> POST /session/:sessionID/elements {"using":"name","value":"_signUpLabel"}
> RESPONSE elements("name","_signUpLabel") [{"ELEMENT":"0"}]
> RESPONSE waitForElementByName("_signUpLabel",3000) {"ELEMENT":"0"}
> CALL element.text()
> GET /session/:sessionID/element/0/text
So can someone tell me where I'm being stupid?

Is el.text() sync or async? The pending suggests you might need to wait for a result?

Related

Calling showNotification does not show anything special

I would like to implement Google's Push Notification in a website and followed this tutorial by Google:
https://developers.google.com/web/ilt/pwa/introduction-to-push-notifications
I managed to display a Push Notification and the permission status in the Console but got stuck with the stage where the showNotification method is used to bring up a message.
My code goes as follows:
Notification.requestPermission(status => {
console.log('Notification permission status:', status);
});
function displayNotification() {
if (Notification.permission == 'granted') {
navigator.serviceWorker.getRegistration().then(function(reg) {
reg.showNotification('Hello world!');
});
}
}
I browsed the videos and labs to no avail. They simply use the code stated above or similar with with the optional array incorporated.
Please help me work out how calling the showNotification method can modify the Push Notification.

How do I use Meteor and a Cordova BLE plugin to connect to a BLE device

I'm trying to use Meteor and this Cordova plugin -https://github.com/don/cordova-plugin-ble-central - added to my project using meteor add cordova in order to connect to a Bluetooth LE device (TI Sensortag). All I want to do to begin with is, when a link is clicked, to connect to the device and show a message.
I have the following code in the events section of my template javascript.
Template.measure.events({'click [data-action=scan-connect-stream]':
function(event, template) {
event.preventDefault();
if (Meteor.isCordova) {
Meteor.startup(function () {
ble.connect('24:09:00:DE:00:42',
function(){
alert('Connect success');
return;
},
function(){
alert('Connect failed');
return;
});
});
}
}
});
My problem is that sometimes the code works and I get a 'Connect success' alert but more often than not it it fails to connect and shows the 'Connect failed' alert. Before I added the return statements in the success and fail callbacks it didn't work at all.
I'm debugging this on an android device (meteor run android-device --verbose) and can see via adb logcat that the BLE Connect event in the Cordova plugin is firing but then doesn't connect. I get the same issue debugging on two different phones and when using a BLE device that isn't a TI Sensortag so I'm guessing this is an problem with the way the plugin is interacting with Meteor (maybe Meteor isn't waiting long enough for a success callback?).
Has anyone used this plugin successfully with Meteor or can anyone provide any clue as to what I'm doing wrong? Should I try wrapping it in a Meteor package or is there any way I can give the plugin more time to respond before the success or fail callbacks fire? Any help would be much appreciated!
For anyone who's having similar issues this is what sorted it for me. I put the ble.connect call into the success callback of the ble.scan function. Not sure why but scanning for a few seconds first does the job.
Template.measure.events({
'click [data-action=scan-connect-stream]': function(event, template) {
event.preventDefault();
if (Meteor.isCordova) {
Meteor.startup(function () {
device_id = '24:09:00:DE:00:42';
ble.scan([], 5,
function(peripherals){
connectDevice(device_id);
},
function(){
alert('No devices found');
}
);
});
}
}
});
var connectDevice = function (device_id) {
ble.connect(device_id,
function(){
alert('Device ' + device_id + ' connnected');
},
function(){
alert('Couldn\'t connect to device ' + device_id);
});
}
If anyone can explain why the ble.connect won't work on its own that'd be great!
EDIT: Looking at the Android code it seems that the plugin is designed in such a way that ble.scan has to be called before calling ble.connect. The ble.scan causes a LinkedHashMap in the Android code to be populated with any discovered devices. Only once the device is listed in the LinkedHashMap can you then connect to it using ble.connect.

ngCordova/Ionic Push Notifications when application is in the background

I'm currently building an android application using ionic/ngcordova. I'm at the point of implementing push notifications. I've implemented push notifications as a service which is injected at app.run(function(){..}) stage. The registration part works and I receive a callback containing the regid. Also, when the application is in the active state, the event is raised and the notification is received.
The problem I'm having is that when the application goes into the background, the notifications are not received at all. I would expect that a local notification would be raised when the app isn't running or something similar, but absolutely nothing happens, which is weird.
I've trawled the web for the last couple of days looking for a solution but I've been unable to find anything which kind of indicates to me that it should just work.
The following is my notificationService.js inside my app
app.factory('notificationService', ['$cordovaPush', function($cordovaPush){
var dataFactory = {};
//
// When the device is ready and this service has been plumbed in...
document.addEventListener("deviceready", function(){
console.log("initializing push notifications...");
_register();
}, false);
//
// Registers the device for push notifications...
var _register = function(){
var config = {};
if ( device.platform == 'android' || device.platform == 'Android' || device.platform == "amazon-fireos" ){
// TODO: centralise this value as it can change...
config = {
senderID: "448168747432",
ecb: "onNotificationGCM"
};
}else {
// iOS
config = {
"badge":"true",
"sound":"true",
"alert":"true"
};
// Can add the following property to the config object to raise a callback with the information if need be...
// "ecb": "onNotificationRegisterAPN"
}
$cordovaPush.register(config).then(function(result){
//
// Typically returns "ok" for android and devicetoken for iOS
console.log(result);
});
};
window.onNotificationGCM = function(result){
console.log(result);
/*
I get called when the app is in the foreground, but nothing happens when the app is in the background.
*/
};
dataFactory.register = _register;
return dataFactory;
}]);
If it helps, I'm using PushSharp via a .net application in order to deliver the notifications. Any help would be greatly appreciated.
UPDATE: I'm using the following frameworks/libs:
Ionic Framework 1.2.14-beta6
Cordova 4.2.0
PushPlugin
For anyone else who's been pulling their hair out for a couple of days like I have, the solution was really simple...I was missing two properties in my Pushsharp QueueNotification request. So using the example given on the PushSharp github repo here: https://github.com/Redth/PushSharp#sample-code
push.QueueNotification(new GcmNotification().ForDeviceRegistrationId("DEVICE-REGISTRATION-ID-HERE").WithJson("{\"alert\":\"Hello World!\",\"badge\":7,\"sound\":\"sound.caf\"}"));
Needs to be updated to add the missing properties:
push.QueueNotification(new GcmNotification().ForDeviceRegistrationId("DEVICE REGISTRATION ID HERE")
.WithJson(#"{""alert"":""This is the future"",""badge"":7,""sound"":""sound.caf"",""title"":""Status Bar title"",""message"":""Some text you want to display to the user""}"));
Otherwise if your app happens to be developed using Cordova and its not currently in the foreground, nothing, repeat nothing will happen.
Tip my hat to gdelavald with his comment on PushPlugin for pointing me in the right direction here:
https://github.com/phonegap-build/PushPlugin/issues/212

Meteor Streams : client doesn't receive streams

i'm working on a simple app based on meteor and MeteorStreams.
The aim is simple :
one user will click on a button to create a room
other users will join the room
those users can emit streams with simple message
the creator will listen to that message and then display them
In fact : message from other users are sent (log in server script), but the creator doesn't receive them.
If i reload the page of the creator, then it will get messages sent from other user.
I don't really understand why it doesn't work the first time.
I use meteor-router for my routing system.
Code can be seen here
https://github.com/Rebolon/MeetingTimeCost/tree/feature/pokerVoteProtection
for the client side code is availabel in client/views/poker/* and client/helpers
for the server stream's code is in server/pokerStreams.js
Application can be tested here : http://meetingtimecost.meteor.com
The creator must be logged.
If you have any idea, any help is welcome.
Thanks
Ok, Ok,
after doing some debugging, i now understand what is wrong in my code :
it's easy in fact. The problem comes from the fact that i forgot to bind the Stream.on event to Deps.autorun.
The result is that this part of code was not managed by reactivity so it was never re-run automatically when the Session changed.
The solution is so easy with Meteor : just wrap this part of code inside the Deps.autorun
Meteor.startup(function () {
Deps.autorun(function funcReloadStreamListeningOnNewRoom () {
PokerStream.on(Session.get('currentRoom') + ':currentRoom:vote', function (vote) {
var voteFound = 0;
// update is now allowed
if (Session.get('pokerVoteStatus') === 'voting') {
voteFound = Vote.find({subscriptionId: this.subscriptionId});
if (!voteFound.count()) {
Vote.insert({value: vote, userId: this.userId, subscriptionId: this.subscriptionId});
} else {
Vote.update({_id: voteFound._id}, {$set: {value: vote}});
}
}
});
});
});
So it was not a Meteor Streams problem, but only my fault.
Hope it will help people to understand that outside Template and Collection, you need to wrap your code inside Deps if you want reactivity.

Meteor error message: "Failed to receive keepalive! Exiting."

I am just starting to build a new Meteor app. The only thing I have done so far is add one Collection. It will start, run fine for about 5 minutes, and then give me the error message "Failed to receive keepalive! Exiting."
What is failing to receive keepalive from what? I assume this has something to do with Mongo since that is the only thing I have added. Googling the error message turns up nothing except Meteor sites that are just showing this error message instead of the their app.
My MongoDB collection already had data in it that was not created by Meteor and it is over 4GB if that makes any difference.
This is the complete app.
pitches_sum = new Meteor.Collection( 'pitches_sum' );
if (Meteor.is_client) {
Template.hello.greeting = function () {
return "Welcome to my site.";
};
Template.hello.events = {
'click input' : function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
};
}
if (Meteor.is_server) {
Meteor.startup(function () {
console.log( '**asdf**' );
});
}
If I comment out the pitches_sum = new Meteor.Collection( 'pitches_sum' ); line, then I don't think I will get the error message any more.
This was being caused by my large data set and autopublish. Since autopublish was on, Meteor was trying to send the whole 4GB collection down to the client. Trying to process all the data prevented the client from responding to the server's keep alive pings. Or something to that effect.
Removing autopublish with meteor remove autopublish and then writing my own publish and subscribe functions fixed the problem.

Resources