Ember tests/Mirage not finding DOM elements

1.4k views Asked by At

I'm trying to do some basic acceptance tests in Ember, using Mirage. I'm using only fixtures at this point to populate the test environment, just to find my feet. When I run ember in the test environment (i.e., with -e test), I can see my app is populating with expected data. And the DOM has some buttons, etc. All is well.

However, when I run a test to visit a page and click a button, the test is telling me it can't find the button. In other words, running -e test and checking localhost shows the app seems to be fine. But then checking localhost/tests has a test failing saying it can't find a button that is definitely there in the -e test screen.

I've confirmed that the button exists in the -e test environment, using both inspector and just issuing a basic jquery select at the console line.

So I assume there's something wrong in the setup or somewhere in a configuration?

In particular:

module('Acceptance | basic tests', {
  beforeEach: function() {
    this.application = startApp();
  },

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

test('visiting /orders', function(assert) {
  visit('/orders');

  andThen(function() {
    assert.equal(currentURL(), '/orders');
  });
});

test('visiting /basic', function(assert) {
  visit('/orders');
  click('top-row-orders-button'); //button.top-row-orders-button fails too
  andThen(function() {
    assert.equal(currentURL(), '/orders');
  });
});

The first test (just visiting the url) passes. The second test is where it says it can't find the button. And again, when I serve -e test, and enter this at the console: $('.top-row-orders-button') it returns the button in question.

Happy to provide any more info anyone needs. Would appreciate any help. I've been banging my head on this for a few days now with no luck.

Edited to Add:

More generally, when using Mirage, is there a way to see what the DOM is within the /tests environment (i.e., the DOM that the actual tests are running on)? I.e., what the DOM looks like to each Mirage test?

3

There are 3 answers

2
Nishan Miranda On BEST ANSWER

I ran through ur repository and found that u made the mirage factory configuration wrong...When using mirage u should define exactly what the app expects.

Eg: the api ur calling returns the movies in Search object when running the app. While in tests it returns the movies list object as an reponse. And you made a check in adapters -> query function to return [ ] if there is no Search object.

What Mirage does is api mocking. When calling the api it returns the response which u had defined in it's config.js and it still goes through the then promise u had defined in query function in adapters. Since the model is empty, there in nothing to render and the test failed.

Change the mirage config file as

this.get('http://www.omdbapi.com/', function(db, request) {
  return { Search: db.movies };
});

and also change the factories/movie to return the object keys accordingly(say in ur case 'imdbID' not 'id').

1
Christopher Milne On

Add a debugger statement within the body of the test and open the console. Rerun the test.

The app should be paused. In the console, you can examine the DOM. Use Chrome.

Try $('#ember-testing') in the console.

You should see a DOM fragment in the console. You can interact with this DOM fragment. Click the arrows to open it up.

Do you see the element you are trying to target in the html? If it is there, try selecting it again with jQuery. If jQuery doesn't find it, your selector is wrong.

1
Sam Selikoff On

The click helper (click('top-row-orders-button')) takes a CSS selector, so if you're looking for a DOM node with class top-row-orders-button you'd want to use

click('.top-row-orders-button');

If the button isn't found, try putting a debugger before the click helper, and typing $('.top-row-orders-button') in console.

Could you clarify what -e test means? There are two ways people typically view the test runner in the browser. First, if you've done ember serve, you can visit localhost:4200/tests. However, the recommended way is to use ember test --server. This will use testem and start the test runner in your console, but it will also show you a link, something like

Open the URL below in a browser to connect.
http://localhost:7357/

which you can visit to see the test runner.

The reason the second method is preferred is because the ember test command uses an Ember app with both a build-time (node) environment of test, as well as a run-time environment of test (i.e. the environment vars under config/environment.js), whereas using ember serve and then visiting /tests uses a build-time environment of development and a run-time environment of test.

Typically you don't need to specify --environment test - you can just use the ember test --server command.

Finally, to your final question, there isn't really any such thing as a "Mirage test". Mirage's server is booted up alongside your Ember application in acceptance tests. But Mirage doesn't know anything about your Ember app, or even the fact that it's being used in a test. It basically just mocks out XMLHttpRequest, and stops there.