Проблемы
У меня есть /login
маршрута, который использует ember-simple-auth
для осуществления аутентификации. Во время тестирования ember-cli-mirage
используется для фальсификации бэкэнд. Пользователь регистрируется, указав свой адрес электронной почты и пароль.EmberJS тест не первый раз работаю в phantomjs
В общей сложности у меня есть 4 приемочные испытания для данного маршрута, аналогичные ниже теста:
test('should show error message for invalid email', function(assert) {
visit('/login');
fillIn('input#email', 'invalid-email');
fillIn('input#password', 'invalid-password');
click('button.button');
andThen(function() {
assert.equal(find('div.notification').text(), "Invalid email/password");
});
});
Когда я запускаю тесты с использованием ember t
только первый тест в файл не удается. Если я прокомментирую этот тест, следующий не удастся и т. Д. Если я запускаю тесты в режиме сервера с ember t -s
, то те же тесты терпят неудачу; однако, когда я нажимаю , введите для повторного запуска тестов, все тесты пройдут.
сообщение о сбое всегда то же самое, как показано ниже:
not ok 7 PhantomJS 2.1 - Acceptance | login: should show error message for invalid email
---
actual: >
expected: >
Invalid email/password
stack: >
http://localhost:7357/assets/tests.js:22:19
[email protected]://localhost:7357/assets/vendor.js:48231:41
http://localhost:7357/assets/vendor.js:48174:24
[email protected]://localhost:7357/assets/vendor.js:49302:30
http://localhost:7357/assets/vendor.js:49258:23
[email protected]://localhost:7357/assets/vendor.js:68726:20
[email protected]://localhost:7357/assets/vendor.js:68738:21
[email protected]://localhost:7357/assets/vendor.js:68709:21
http://localhost:7357/assets/vendor.js:48192:24
[email protected]://localhost:7357/assets/vendor.js:10892:18
[email protected]://localhost:7357/assets/vendor.js:10960:15
[email protected]://localhost:7357/assets/vendor.js:11084:20
[email protected]://localhost:7357/assets/vendor.js:11154:28
[email protected]://localhost:7357/assets/vendor.js:11277:19
[email protected]://localhost:7357/assets/vendor.js:32073:32
http://localhost:7357/assets/vendor.js:48783:24
Log: |
После того, как все тесты закончились, тест выдает исключение:
# tests 60
# pass 59
# skip 0
# fail 1
Not all tests passed.
Error: Not all tests passed.
at EventEmitter.getExitCode (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/lib/app.js:434:15)
at EventEmitter.exit (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/lib/app.js:189:23)
at /home/jon/projects/jonblack/wishlist-web/node_modules/testem/lib/app.js:103:14
at tryCatcher (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/promise.js:510:31)
at Promise._settlePromise (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/promise.js:567:18)
at Promise._settlePromise0 (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/promise.js:612:10)
at Promise._settlePromises (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/promise.js:691:18)
at Async._drainQueue (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/async.js:138:16)
at Async._drainQueues (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/async.js:148:10)
at Immediate.Async.drainQueues (/home/jon/projects/jonblack/wishlist-web/node_modules/testem/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:637:20)
at tryOnImmediate (timers.js:610:5)
at processImmediate [as _immediateCallback] (timers.js:582:5)
Кажется странным, что это испускается для испытаний а не просто сообщить об ошибке тестирования, поэтому, возможно, это связано.
Выполнение тестов в Firefox и Chromium, а также запуск приложения в режиме разработки и ведение журнала вручную. Проблема ограничена фантомами.
У меня есть другие приемочные испытания для другого маршрута, и все это проходит. Кажется, он ограничен маршрутом /login
, что указывает на то, что он, возможно, связан с аутентификацией.
Debugging
Я пытался отладки путем добавления pauseTest()
к тесту и "phantomjs_debug_port": 9000
к testem.js
но и Firefox и Chromium ничего не делать, когда я использую консоль отладки. Возможно, это недостаток опыта отладки phantomjs, но я бы по крайней мере ожидал, что он даст мне ошибку - это буквально ничего не делает.
Похоже, что существует проблема синхронизации между фантомами и чем-то, возможным ember-simple-auth, в моем приложении Ember.
Я не испытываю проблем с отладочной ошибкой phantomjs и ошибок при приеме проб с использованием Ember, поэтому любая помощь оценивается.
Версия
ember-cli 2.10.0
ember-simple-auth 1.1.0
ember-cli-mirage 0.2.4
Update 1
Кнопка находится внутри login-form
компонента:
<form {{action 'login' on='submit'}}>
<p class="control has-icon">
{{input value=email id='email' placeholder='email' class='input'}}
<i class="fa fa-envelope"></i>
</p>
<p class="control has-icon">
{{input value=password id='password' placeholder='password'
type='password' class='input'}}
<i class="fa fa-lock"></i>
</p>
<p class="control">
<button class="button is-success" disabled={{isDisabled}}>Log In</button>
</p>
</form>
Войти компонента действия только вызовы переданных в обработчик входа:
import Ember from 'ember';
export default Ember.Component.extend({
email: "",
password: "",
isDisabled: Ember.computed('email', 'password', function() {
return this.get('email') === "" || this.get('password') === "";
}),
actions: {
login() {
var email = this.get('email');
var password = this.get('password');
this.attrs.login(email, password);
}
}
});
Какой authenticate
метод в контроллере авторизации:
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service(),
actions: {
authenticate(email, password) {
this.get('session').authenticate('authenticator:oauth2', email, password).catch((data) => {
this.set('errors', data['errors']);
});
}
}
});
Update 2
Как предложил Даниилу я добавил задержку теста:
test('should show error message for invalid email', function(assert) {
visit('/login');
fillIn('input#email', 'invalid-email');
fillIn('input#password', 'invalid-password');
click('button.button');
andThen(function() {
Ember.run.later(this, function() {
assert.equal(find('div.notification').text(), "Invalid email/password");
}, 0);
});
});
Использование только Ember.run.later
тест еще провалился, но при этом он попал внутрь andThen
. Вы заметили причудливую часть? Задержка составляет 0 миллисекунд.
Я все еще хочу найти объяснение этого, потому что я не верю, что это будет работать на той же машине, на которой запущены тесты.
Update 3
Сегодня у меня был сюрприз: вдруг тесты снова работает!
Я добавил новый маршрут с приемочными испытаниями. Сам маршрут является аутентифицированным маршрутом, поэтому в тестах используется тестовый помощник authenticateSession
от ember-simple-auth для аутентификации.
При удалении тестов, которые используют этот помощник, возвращается ошибка!.
Я не уверен, что это значит. Похоже, проблема связана с ember-simple-auth, но также может быть гигантским совпадением, что помощник решает другую проблему с синхронизацией.
вниз кроличью нору мы идем ...
Update 4
Ниже конфигурация для AUTH конечных точек в Ember-CLI-мираж:
this.post('/token', function({db}, request) {
var data = parsePostData(request.requestBody);
if (data.grant_type === 'password') {
// Lookup user in the mirage db
var users = db.users.where({ email: data.username });
if (users.length !== 1) {
return new Mirage.Response(400, {'Content-Type': 'application/json'}, {
errors: [{
id: 'invalid_login',
status: '400',
title: 'Invalid email/password',
}]
});
}
var user = users[0];
// Check password
if (data.password === user.password) {
if (!user.active) {
return new Mirage.Response(400, {'Content-Type': 'application/json'}, {
errors: [{
id: 'inactive_user',
status: '400',
title: 'Inactive user',
}]
});
} else {
return new Mirage.Response(200, {
'Content-Type': 'application/json'
}, {
access_token: 'secret token!',
user_id: user.id
});
}
} else {
return new Mirage.Response(400, {'Content-Type': 'application/json'}, {
errors: [{
id: 'invalid_login',
status: '400',
title: 'Invalid email/password',
}]
});
}
} else {
return new Mirage.Response(400, {'Content-Type': 'application/json'}, {
errors: [{
id: 'invalid_grant_type',
status: '400',
title: 'Invalid grant type',
}]
});
}
});
this.post('/revoke', function(db, request) {
var data = parsePostData(request.requestBody);
if (data.token_type_hint === 'access_token' ||
data.token_type_hint === 'refresh_token') {
return new Mirage.Response(200, {'Content-Type': 'application/json'});
} else {
return new Mirage.Response(400, {'Content-Type': 'application/json'},
{error: 'unsupported_token_type'});
}
});
Update 5
Вот мой config/environment.js
файл:
/* jshint node: true */
module.exports = function(environment) {
var ENV = {
modulePrefix: 'wishlist-web',
environment: environment,
rootURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false
}
},
APP: {
}
};
if (environment === 'development') {
}
if (environment === 'test') {
// Testem prefers this...
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
}
if (environment === 'production') {
ENV.ServerTokenEndpoint = 'http://localhost:9292/token';
ENV.ServerTokenRevocationEndpoint = 'http://localhost:9292/revoke';
ENV.ApiHost = 'http://localhost:9292';
}
return ENV;
};
Когда вы нажали кнопку 'button.button', как вы создаете обещание? Можете ли вы предоставить код, который создает обещание? (Мое предположение заключается в том, что обещание не может быть разрешено в среде phantomjs.) – ykaragol