单一测试在PhantomJS中失败,但在Chrome和Firefox中有效

丹尼尔·马克

我在Ember.js 1.10和Ember CLI 0.1.12中进行了一次验收测试,该测试在PhantomJS上失败,但在Chrome和Firefox上均能正常运行。我已经尝试调试了2天,但是我的想法已经用完了。测试的名称是用户登录后可以查看仅登录页面基本上,当您没有登录,您尝试访问classic的路线,例如/about您将被重定向到start.loginbeforeModel经典路线的钩:

beforeModel: ->
  if not @controllerFor('application').get 'logged'
    @transitionTo 'start.login'

当您打开start.login并输入正确的名称和用户名时,将执行以下logIn操作StartLoginController

logIn: ->
  if not @get('logged')
    @get('controllers.application').send 'logIn', @get('username'), @get('password'), @get('rememberMe')

其中调用以下动作ApplicationController

  actions:
    logIn: (username, password, remember) ->
      if not @get 'logged'
        $.ajax
          url: @get('apiURL') + '/auth/login'
          type: 'POST'
          data:
            name: username
            password: password
            remember: remember
          xhrFields:
            withCredentials: true #ensure CORS
        .then (response) =>
          if response.success

            expires = if remember then new Date(response.cookieExpiration) else null

            $.cookie 'auth_user_id', response.user.id,
              expires: expires
              path: '/'

            $.cookie 'auth_expiration', response.cookieExpiration,
              expires: expires
              path: '/'

            @setProperties
              logged: true
              'controllers.auth.userId': response.user.id

            @transitionToRoute 'classic.index'
        , =>
          @send 'openModal', 'modal/wrong-credentials'

      false

即使在PhantomJS中也可以正常工作。其他测试通过。正确调用操作,正确设置属性,正确设置cookie。甚至beforeModel钩正确调用(或不正确)transitionTo方法。我以为跟PhantomJS问题是与调用事情的一些异步命令,但我已经试过在封装代码Ember.run,并andThen在很多地方。完全没有运气。

testem.json

{
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed",
  "launch_in_ci": [
    "PhantomJS"
  ],
  "launch_in_dev": [
    "PhantomJS",
    "Chrome",
    "Firefox"
  ]
}

验收测试login-test.coffee(不合格测试是最后一个):

`import Ember from 'ember'`
`import startApp from '../helpers/start-app'`

application = null

run = Ember.run

login = ->
  visit '/'

  fillIn '[placeholder=Login]', 'test'
  fillIn '[placeholder=Hasło]', 'test'

  click '.button-login'

clearCookies = ->
  cookies = $.cookie()

  for cookie of cookies
    $.removeCookie cookie,
      path: '/'

  cookies = document.cookie.split ';'
  for i in [0...cookies.length] by 1
    equals = cookies[i].indexOf '='
    name = if equals > -1 then cookies[i].substr(0, equals) else cookies[i]
    document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT"

module 'Acceptance: Login',
  setup: ->
    application = startApp()

    clearCookies()

    time = new Date()

    $.mockjaxSettings.logging = false

    $.mockjax
      type: 'POST'
      url: 'api/v1/auth/login'
      dataType: 'json'
      responseText:
        success: true
        user:
          id: 1
        cookieExpiration: time.setDate time.getDate() + 14

    $.mockjax
      type: 'GET'
      url: '/api/v1/users/1'
      dataType: 'json'
      responseText:
        user:
          id: 1

    $.mockjax
      type: 'GET'
      url: '/api/v1/statuses' # ?limitOld=10&friends=true&comments[limit]=5
      data:
        comments:
          limit: 5
        friends: true
        limitOld: 10
      responseText:
        statuses: {}

    $.mockjax
      type: 'GET'
      url: '/api/v1/getRandomQuote'

    $.mockjax
      type: 'GET'
      url: '/api/v1/statuses/?friends=true&count=true'
      responseText:
        count: 0

    $.mockjax
      type: 'GET'
      url: '/api/v1/meals'

    $.mockjax
      type: 'GET'
      url: '/api/v1/notifications'

    $.mockjax
      type: 'GET'
      url: '/api/v1/notifications'
      data:
        read: false
      responseText: {}

    return

  teardown: ->
    $.mockjax.clear()

    clearCookies()

    run application, 'destroy'

test 'user lands on default page when he is not logged', ->
  expect 1

  visit '/'

  andThen ->
    equal currentPath(), 'start.login'

test 'login page is displayed when you are trying to access logged-only page', ->
  expect 1

  visit '/kitchen'

  andThen ->
    equal currentPath(), 'start.login'

test 'user can login', ->
  expect 2

  appController = application.__container__.lookup 'controller:application'

  equal appController.get('logged'), false, 'user is not logged before login'

  login()

  andThen ->
    ok appController.get 'logged', 'user is logged when response is success'

test 'user can view logged-only pages when he is logged', ->
  expect 2
  console.log '-- LOGGED-ONLY TEST START --'

  visit '/about'

  andThen ->
    equal currentPath(), 'start.login'

  login()

  visit '/about'

  andThen ->
    equal currentPath(), 'classic.about'

最后是测试的输出:

TEST'EM 'SCRIPTS!                                                          
Open the URL below in a browser to connect.                                
http://localhost:7357/                                                     
━━━━━━━━━━━━━━┓                                                            
 PhantomJS 1.9┃  Firefox 37.0                                              
  198/199 ✘   ┃  199/199 ✔                                                 
              ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Acceptance: Login: user can view logged-only pages when he is logged
    ✘ failed
         expected classic.about
         actual start.login

-- LOGGED-ONLY TEST START --

我不认为这classic.about是错误的根源,因为用其他classic资源的子路由替换它会导致相同的PhantomJS失败测试。

好的,看来问题出在模型上ClassicRoute(注释使测试通过):

  model: ->
    new Promise (resolve, reject) =>
      @store.find 'user', @controllerFor('auth').get('userId')
        .then (user) =>
          @controllerFor('auth').set 'user', user
          resolve
            profile: user.get 'profile'
丹尼尔·马克

我将逻辑分为两个而不是一个,现在可以正常工作:

  beforeModel: ->
    if not @controllerFor('application').get 'logged'
      @transitionTo 'start.login'
    else
      @store
      .find 'user', @controllerFor('auth').get('userId')
      .then (user) =>
        @controllerFor('auth').set 'user', user
        @set 'profileId', user.get('profile.id')    

  model: ->
    @store.find 'profile', @get('profileId')

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Selenium 测试用例在 Firefox 中有效,但在 Chrome 中无效 - Headless Setup

日期构造函数在IE中返回NaN,但在Firefox和Chrome中有效

添加的间距在Firefox中有效,但在Chrome和Safari中不起作用

日期差异在Firefox和IE中有效,但在Chrome中返回NaN

测试在浏览器中有效,但在PhantomJS中无效

元素上的過渡在 Chrome 中有效,但在 Firefox 中無效

应用于音频元素的样式在 firefox 和 safari 中有效,但在 chrome 中无效

内联在 CSS 中的 SVG 在 Chrome/Edge 中有效,但在 Firefox 中无效

window.open在Firefox中有效,但在IE或Chrome中不起作用

伪元素在 Firefox 中有效,但在 Chrome 中无效,为什么?

解构错误对象在Chrome中有效,但在Firefox中无效。该怎么办?

我的专栏文章将在Firefox / Safari中换行,但在Chrome中有效

Rmarkdown flexdashboard值框在Chrome或IE中无法正确呈现(但在FireFox中有效)

解析XML标签属性在Firefox中有效,但在Chrome中不起作用

CSS剪切路径在Firefox中有效,但在chrome中不可用

Angular HTTP请求在Chrome中返回null,但在Firefox中有效

动态生成的html链接在Firefox中有效,但在Chrome中不起作用

jQuery Click 功能在 Firefox 中有效,但在 Chrome/Safari 中无效

fibonacci在python中有效,但在Java中失败

命令在crontab中失败,但在终端中有效

在网站中嵌入 google 文档:用户评论在 Chrome 中始终是匿名的(但在 Firefox 中有效)

表格在Firefox中无法响应,在Chrome中有效

位置粘性在 Firefox 中有效,在 Chrome 中无效

为什么按钮内的文件输入在 Firefox 中不起作用,但在 Chrome 中有效?

在Chrome或Firefox中,jquery $ .ajax调用会导致401未经授权的响应,但在IE中有效

我的音频可视化器在Chrome中不起作用(但在Firefox中有效)

Ubuntu linux 上的 R 和 SSL/curl:在 R 中 SSL 连接失败,但在 curl 中有效

jQuery过滤选择选项在Safari中不起作用(但在Chrome和FF中有效)

链导入在Python 2中有效,但在Python 3中失败