7
votes

Trying to test-drive my first ember.js app. Using ember app kit.

Puzzled by how qunit works with selectors (I assumed that jquery selectors would work, and they do - for the most part...).

My handlebars has this code:

{{#link-to 'locations.new' classNames='add-btn'}}
  Add new location
{{/link-to}}

and I intend to test for existence of a link with an appropriate href and also click the link and verify the current url and route after click.

So, my tests are as follows:

// There is an element that links to locations/new
var link = find('a[href="#/locations/new"]');
ok(link, 'There is a link to add new location on the page');

click(link);
andThen(function() {
  equal(currentRouteName(), 'locations.new', 'Clicked "add" button - now locations.new route is active');
  equal(currentURL(), '/locations/new', 'Clicked "add" button - and current url is /locations/new');
});

note: I am using currentRouteName and currentURL helpers from this PR on EAK, and they do work as intended.

My test fails on the click(link) part, with Error: Element [object Object] not found..

If I try to pass the selector directly to click - like so - click("a[href='#/locations/new']") - I get an error Element a[href='#/locations/new'] not found.. Same result if I try to escape the special character # with a backslash or double backslash.

For the time being, I mitigated the issue by grabbing the div by class - like so:

var link-by-class = find('.add-btn');
click(link-by-class);
andThen( as above )

And the tests pass.

Questions:

  1. how come I can't invoke "click()" on the same variable found by href?
  2. Am I testing with reasonable indifference to implementation? (well, the workaround of finding an element by the class doesn't fit that bill?)

Thanks in advance!

UPDATE

Per kingpin2k's comment, my test was passing due to the wrong assertion method I chose - ok(foo, 'bar') will pass if foo is an empty array (which find returns if there are no results. Ember API docs guided me to use findWithAssert, and it fails to find the link with such href.

Befuddlingly, using the [attribute='value'] jquery selector per jQuery docs in JS console works; and the implementation of find as well as findWithAssert in ember-testing seems to just pass down the selector to jQuery...

Why does it fail? I don't know. One would think as GLaDOS explained speedy thing goes in, speedy thing comes out - just passing the selector over to jQuery would give it back as jQuery would return it - but apparently not.

I'll stick to using the class selector then, although it does kind of dictate implementation.

1
I think click accepts a selector, not a element. Could you try click('a[href="#/locations/new"]') instead?MartinElvar
Could it be because # is a special char (api.jquery.com/category/selectors), can you try escaping it in your selector and see if that does the trick.Deewendra Shrestha
@MartinElvar I thought so too - but using click('a[href="#/locations/new"]') results in an error as follows: Element a[href='#/locations/new'] not found.apprenticeDev
are you navigating to the route containing that link? just a fyi, the find selector can return an empty array if nothing is found and an empty array is truthy... aka ok([], 'everything is good') will work just fine. ok(find('blahblah').length, 'everything is good') would work better, or equal(find('blahblah').length, 1, 'there is 1 blahblah element')Kingpin2k
Thanks for the comment @Deewendra, and big ups @kingpin2k I didn't realize an empty array would pass the ok test. Let me try this stuff. FWIW - such jquery selector does find the proper link in JS console in dev tools, so it is valid jquery at least...apprenticeDev

1 Answers

4
votes

refusing to give up on making the test implementation-agnostic, I decided to use basic selectors, and discovered the undocumented culprit of my failures.

First, I wanted to get all links - and filter them by href attribute:

  var links = findWithAssert('a');
  var my-link = links.filter('[href="#/location/new"]');

That gave me a correct length of links, but my-link was still empty. So I alerted all hrefs, to be sure I'm not missing anything:

  for(var i=0; i<links.length; i++){
    alert(links[i].getAttribute('href'));
  }

And to my surprise I saw hrefs alerted without the leading #.

Answer: When using complex css selectors with href attribute in ember.js find() helper, drop the hash from the url.