MASL
MASL

Reputation: 949

Emberjs 3.0 tests: how to select link by content

The following is a test that apparently works in Ember.js 2.15, but seem not to work in version 3.0: Failed to execute 'querySelector' on 'Element': 'a:contains('Contact')' is not a valid selector.

import { module, test } from 'qunit';
import { visit, currentURL, click } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';

module('Acceptance | list rentals', function(hooks) {
  setupApplicationTest(hooks);
    test('should show link to contact', async function(assert){
            await visit('/');
            await click("a:contains('Contact')");
            assert.equal(currentURL(),'/contact','should navigate to contact');
    });
});

How to do this in Ember.js 3.0?

I couldn't find it in the online Ember guides. The tutorials seem to refer thus to previous versions.

PS:The application's template file contains

 {{#link-to "contact"}}
    Contact
  {{/link-to}}

PS: The idea of using such a selector comes from the tutorial for Ember version...3.0! (See towards the end here https://guides.emberjs.com/v3.0.0/tutorial/routes-and-templates/)

EDIT: Emberjs 3.1 guide is already available and the tutorial examples finally match the new code:

https://guides.emberjs.com/v3.1.0/tutorial/model-hook/

Upvotes: 2

Views: 1219

Answers (3)

nruth
nruth

Reputation: 1068

I came across this during an upgrade and think there's a way to get the jQuery pseudo-selectors back. It's a bit hacky, so think about whether you should re-write as the others advised.

  1. import jQuery (assuming it's still in your app)
  2. use $(your-old-selector-string)[0] to get a plain DOM element
  3. pass the element to the test helper

I'm not confident that this is robust or future-proof, but it may be interesting during upgrades to get green tests before dealing with deprecations and whatnot.

Taking the original example and applying what I've done in a 3.8 app I'm updating:

// changed here
import $ from 'jquery'; // assuming @ember/jquery is in packages.json 

import { module, test } from 'qunit';
import { visit, currentURL, click } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';

module('Acceptance | list rentals', function(hooks) {
  setupApplicationTest(hooks);
    test('should show link to contact', async function(assert){
            await visit('/');
            // changed here
            await click($("a:contains('Contact')")[0]);
            assert.equal(currentURL(),'/contact','should navigate to contact');
    });
});

Upvotes: 1

Raghavendra Bhat
Raghavendra Bhat

Reputation: 76

I would add custom class name to {{#link-to}} and use that class name as a selector for click event

{{#link-to "contact" class="menu-contact"}}
   Contact
{{/link-to}}

And in my acceptance test i will call

 await click(".menu-contact");

Upvotes: 2

Gaurav
Gaurav

Reputation: 12796

The new find helper from @ember/test-helpers uses the browser's native document.querySelector behind the scenes rather than jQuery. Unfortunately, since :contains is not a real CSS selector, it is not supported by any browser.

The older, global find helper is still available, if you use moduleForAcceptance instead of setupApplicationTest. I do not know if there are any plans to deprecate that in the future.

Personally I would recommend placing a class or a data-test- attribute on the element and search for it that way.

Upvotes: 2

Related Questions