如何在 EmberJS 验收测试中调用输入和按钮?

Posted

技术标签:

【中文标题】如何在 EmberJS 验收测试中调用输入和按钮?【英文标题】:How do I call inputs and buttons in my EmberJS acceptance tests? 【发布时间】:2016-03-18 17:12:16 【问题描述】:

这令人抓狂,因为谷歌/互联网对此几乎没有帮助。 https://guides.emberjs.com/v2.4.0/testing/acceptance/ 也不是很有帮助,即使它尝试过。我基本上是从头开始学习的。我知道少量的 html、handlebars 和 javascript,但强调的是适度的。

这是我的模板,其中大部分是从我的建筑师设计中复制的代码,他没有时间帮助我:

<form action "login" on="submit" class="col-md-4 col-md-offset-4">
    #if loginFailed
    <div class="alert">Invalid username or password.</div>
  /if

  <div class="form-group">
    <label for="inputEmail">Email address</label>
    input value=username type="email" class="form-control" id="inputEmail1" placeholder="Email"
  </div>

  <div class="form-group">
    <label for="inputPassword">Password</label>
    input value=password type="password" class="form-control" id="inputPassword" placeholder="Password"
  </div>

  <button type="submit" class="btn btn-default" disabled=isProcessing>Log in!</button>
</form>

请注意,应用程序运行正常(我能够生成一个连接到我的本地数据库的登录屏幕,并且当凭据正确时我能够正确登录,而当凭据不正确时则无法登录)。

还有一个用于路由的大 .js 文件,其中有一个 ajax 调用和相应的承诺,我可以理解,但最重要的是,它可以工作:

import Ember from 'ember';
import ajax from 'ic-ajax';

export default Ember.Route.extend(

    loginFailed: false,
  isProcessing: false,

    beforeModel: function()
        this.store.unloadAll('security-setting');
        this.store.unloadAll('org');

        var user = this.modelFor('application').user;
        user.setProperties(email: '', auth: '');
    ,

  actions: 
    login: function() 
        this.setProperties(
          loginFailed: false,
          isProcessing: true
        );
        var _this = this;

        ajax(
            url: _this.modelFor('application').url + '/signin.json/',
            type: 'post',
            data: session: email: this.controller.get("username"), password: this.controller.get("password"),
      ).then(
                function(result) 
                  // proprietary stuff, it all works
                ,
                function(error)
                    alert(error.jqXHR.responseText);
                    this.set('isProcessing', false);
                _this.set("loginFailed", true);
                
            );


      ,
  ,

  reset: function() 
    this.set('isProcessing', false);
    this.controller.set('password', '');
    this.controller.set('username', '');
  
);

这是我正在尝试编写的验收测试:

import Ember from 'ember';
import  module, test  from 'qunit';
import startApp from 'ember-super-user/tests/helpers/start-app';

module('Acceptance | login', 
  beforeEach: function() 
    this.application = startApp();
  ,

  afterEach: function() 
    Ember.run(this.application, 'destroy');
  
);

test('visiting /login and fail a login attempt', function(assert) 
  visit('/login');
  fillIn('input.username', 'insert-username-here');
  fillIn('input.password', 'insert-password-here');
  click('button.submit');

  // I know this assert is wrong but I haven't even gotten this far yet so I'm     // not thinking about it; basically what happens is a popup appears and says    // wrong-username-or-password-etc
  andThen(function() 
    assert.equal(currentURL(), '/login');
  );
);

fillIn 代码行中执行终止。我真的不知道该怎么做,我已经尝试了'input.username','input.inputEmail1','input.inputEmail'的所有组合......我只是不确定我应该做什么做,在所有。我也很确定'button.submit' 也不会神奇地工作。然后,我知道当我尝试填写 andThen 承诺以承认弹出窗口显示错误密码等事实时,我会更加迷失。

请帮忙;非常感谢您的宝贵时间。

编辑:我已经能够修复测试的fillIn 部分,但是click(可能是点击,无论如何,因为错误消息不清楚哪一行是问题)正在产生一些错误我无法诊断。 QUnit 测试套件的输出中出现对我没有意义的错误消息 --

TypeError: Cannot read property 'set' of undefined@ 4286 ms
Expected:   
true
Result:     
false
Diff:   
trufalse
 at http://localhost:7357/assets/test-support.js:3592:13
    at exports.default._emberTestingAdaptersAdapter.default.extend.exception (http://localhost:7357/assets/vendor.js:52460:7)
    at onerrorDefault (http://localhost:7357/assets/vendor.js:43162:24)
    at Object.exports.default.trigger (http://localhost:7357/assets/vendor.js:67346:11)
    at Promise._onerror (http://localhost:7357/assets/vendor.js:68312:22)
    at publishRejection (http://localhost:7357/assets/vendor.js:66619:15)

编辑 2:将“按钮”更改为“提交”的最新更改仍然无效。当前错误信息:

Error: Element input[type='submit'] not found.@ 166 ms
Expected:   
true
Result:     
false
Diff:   
trufalse
Source:     
    at http://localhost:7357/assets/test-support.js:3592:13
    at exports.default._emberTestingAdaptersAdapter.default.extend.exception (http://localhost:7357/assets/vendor.js:52460:7)
    at onerrorDefault (http://localhost:7357/assets/vendor.js:43162:24)
    at Object.exports.default.trigger (http://localhost:7357/assets/vendor.js:67346:11)
    at Promise._onerror (http://localhost:7357/assets/vendor.js:68312:22)
    at publishRejection (http://localhost:7357/assets/vendor.js:66619:15)

【问题讨论】:

【参考方案1】:

您的每个输入的选择器都是错误的。既然你给了每个人一个 id,你可以这样做:

fillIn('#inputEmail1', 'insert-username-here');
fillIn('#inputPassword', 'insert-password-here');

请记住,fillIn 的第一个参数使用 CSS 选择器,ID 使用 # 前缀,类使用 .

对于提交按钮,您没有添加类或 ID,但如果它是页面上唯一的提交按钮,您可以像这样定位它:

click('button[type="submit"]');

【讨论】:

感谢您的帮助,不过我现在遇到了一个新错误:TypeError: undefined is not an object (evaluate 'this.set')。我还尝试给按钮一个 id “submitButton”,然后以与 fillIns 相同的方式使用它,但发生了同样的错误。 我的直觉是它与测试无关,更多地与您的应用程序代码有关。我会尝试查看哪一行引发了该错误以及它产生的堆栈跟踪。 你可能是对的,虽然堆栈跟踪对我来说是荒谬的,但我不知道它如何导致我发现错误所在。考虑到其他编程语言可以为您提供关于错误发生位置的非常清晰的堆栈跟踪,这非常令人抓狂。任何进一步的帮助都会很棒——谢谢。 我在扫描您的代码后看到了一些错误。您正在尝试直接访问var user = this.modelFor('application').user;,它应该是var user = this.modelFor('application').get('user'); 在您的错误处理程序中,您有this.set('isProcessing', false);,它应该是_this.set...。如果你使用 chrome devtools,你可以让它在捕获的错误时中断,选中 async 复选框,并探索更完整的堆栈跟踪以查看它尝试调用 set 的位置。【参考方案2】:

fillIn 和 click 函数采用 css 选择器。例如,点击提交看起来像,

click("input[type='submit']");

【讨论】:

遗憾的是,这也不起作用。检查对问题的编辑以获取错误消息;谢谢。 我的错误,应该是 button[type='submit']

以上是关于如何在 EmberJS 验收测试中调用输入和按钮?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法用假计时器运行 Ember.Testing 验收测试?

验收测试(Capybara)找不到我的提交按钮

如何使用 selenium 和 codeception 检测验收测试中的 dom 变化

Ember 验收测试:检查按钮是不是已启用

如何在 Ember.js 验收测试中触发“输入”字段的“换行”操作?

如何在 Ember js 控制器功能测试中调用路由功能?