Ember acceptance test not seeing updated DOM

I'm still getting into the depths of Ember's acceptance testing. One issue I seem to keep having is the DOM not getting updated after an event. For example, my page has a side menu. A simple toggle changes a property in it's component which then toggles a "hide" class on the menu itself:

Component

import Ember from 'ember';

export default Ember.Component.extend({
  menuHidden: true,
  actions: {
    toggleMenu(){
      this.set('menuHidden', !this.get('menuHidden'));
    },
  }
});

Template

<a id="menu-toggle" class="{{unless menuHidden 'open'}}" {{ action 'toggleMenu' }}>
  <span></span><span></span><span></span>
</a>
<div id="menu" class="{{if menuHidden 'hide'}}">
  {{#link-to 'dashboard' invokeAction='closeMenu'}}Dashboard{{/link-to}}
  {{#each menu as |child|}}
    {{menu-child child=child createCase=(action 'createCase') menuHidden=menuHidden}}
  {{/each}}
  <a href="javascript:void(0)" {{ action 'logout' }}>Logout</a>
</div>

Acceptance Test

import { test } from 'ember-qunit';
import moduleForAcceptance from '../helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | side menu');

test('side menu opens and closes', assert=>{

  logIn('my@email.com', 'password');

  andThen(()=>{
    assert.equal(find('#menu').attr('class'), 'hide', 'Hidden by default');

    click('#menu-toggle');

    andThen(()=>{
      assert.equal(find('#menu').attr('class'), '', 'Now visible');
    });
  });

});

Now this is running fine in the browser. The test is logging in fine with my custom helper (the menu is only visible when logged in) and if I drop a console.log into toggleMenu() it is being triggered by the test. But it fails the last assert. I've done a console.log on the menu's wrapper's HTML before the last assert, it's still seeing the #menu element with class=hide

Is there something obvious I'm doing wrong? I can't find many examples of people with multiple andThen calls in acceptance tests, so I've tried having it nested - as above - and pulling the second andThen out inline with the first one. No difference.

Answers


If you open the developer console in the test browser window, you will likely see this error:

Assertion failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run

The following line in your component is considered code with asynchronous side-effects:

this.set('menuHidden', !this.get('menuHidden'));

Instead, for the test to work, you need to manually add the line to the run-loop, which is achieved by adding that line of code in an Ember.run, like so:

import Ember from 'ember';

export default Ember.Component.extend({
  menuHidden: true,
  actions: {
    toggleMenu(){
      Ember.run(this, function(){
        this.set('menuHidden', !this.get('menuHidden'));
      });
    },
  }
});

This will not affect the actual running code as the operations in your Ember.run will get merged into the main run-loop.

I had a similar issue which I managed to resolve after going through the steps mentioned in here


Need Your Help

Windows Service: OnPowerEvent doesn't fire

c# .net windows-services service

I want to create a Windows Service that tracks if the A/C power adapter is plugged in or not. For that, I am trying to build Windows Service as below:

How to solve WAMP and Skype conflict on Windows 7?

windows-7 wamp skype

I have Windows 7 (32-bit) installed on laptop.