In my Ember app, I currently have a model that has a findResults
function that returns a promise that is wrapping a Google Places library to fetch results for auto-completion. To use this in my UI, I setup a PromiseMixin controller. I instruct the controller to watch the searchText
value, and when that changes I update the controller's promise value to be the promise returned by the findResults
function, but with the new value from searchText
. This works nicely when I'm playing with the app in the browser, however when I run my acceptance tests the test seems to finish before the promise is returned and therefore the tests fail. I'll include the relevant files below.
I'm not sure how to tell Ember to wait for the promise to resolve during testing.
app/services/google-autocomplete-location.js
import Ember from "ember";
var googleAutocompleteLocation = Ember.Object.extend({
placeId: null,
description: null
});
googleAutocompleteLocation.reopenClass({
findResults: function(query) {
var self = this;
var promise = new Ember.RSVP.Promise(function(resolve, reject) {
var autocompleteService = new google.maps.places.AutocompleteService();
return autocompleteService.getPlacePredictions({ input: query },
function(predictions, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
Ember.run(null, reject, status);
}
else {
Ember.run(null, resolve, self._decorateGoogleResults(predictions));
}
});
});
return promise;
},
_decorateGoogleResults: function(predictions) {
var locations = [];
predictions.forEach(function(prediction) {
locations.push(
googleAutocompleteLocation.create({
placeId: prediction.place_id,
description: prediction.description
})
);
});
return locations;
}
});
export default googleAutocompleteLocation;
app/controllers/index.js
import Ember from "ember";
import GoogleLocation from "../services/google-location";
import GoogleAutocompleteLocation from '../services/google-autocomplete-location';
export default Ember.ArrayController.extend(Ember.PromiseProxyMixin, {
searchText: '',
map: null,
mapUrl: null,
actions: {
submit: function() {
return this.transitionToRoute('entries.new');
}
},
highlightedResult: function() {
if (this.get('model').length) {
return this.get('model')[0];
} else {
return null;
}
}.property('model'),
setMap: (function() {
if (this.get('highlightedResult') === null) {
return this.set('map', null);
} else {
if (this.get('map') === null) {
return this.set('map', GoogleLocation.create({
mapContainer: Ember.$('.maps-info'),
placeId: this.get('highlightedResult').placeId
}));
} else {
return this.get('map').set('placeId', this.get('highlightedResult').placeId);
}
}
}).observes('highlightedResult'),
searchTextChanged: (function() {
if (this.get('searchText').length) {
this.set('promise',
GoogleAutocompleteLocation.findResults(this.get('searchText')));
console.log(this.get('promise'));
} else {
this.set('model', []);
}
}).observes('searchText')
});
tests/acceptance/create-new-entry-test.js
test('finding a location', function() {
expect(1);
visit('/');
click('.location-input input');
fillIn('.location-input input', "Los Angeles, CA");
andThen(function() {
var searchResult = find('.search-results ul li:first a').text();
equal(searchResult, 'Los Angeles, CA, United States');
});
});