Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Acceptance tests with ember-tether #48

Open
john-griffin opened this issue Jun 24, 2015 · 13 comments
Open

Acceptance tests with ember-tether #48

john-griffin opened this issue Jun 24, 2015 · 13 comments
Labels

Comments

@john-griffin
Copy link

I would like to clarify what the best practices are around acceptance tests with ember-tether.

When I write a basic ember-modal-dialog acceptance test that launches a modal, makes an assertion and closes it works fine and as expected. When I switch over to using ember-tether the same test fails because it can't find the content inside the modal. Is there a recommended way support ember-tether based modals in acceptance tests?

I tried switching the modalRootElementId in the test environment but that does not seem to work.

@lukemelia
Copy link
Contributor

The problem you're encountering is that Tether / ember-tether appends items to the body element. But Ember acceptance testing expects the app to be contained wholly within the test container, so click helpers and the like don't work.

We've worked around this in out apps by creating helpers that are not scoped. e.g.

function unscopedClick(app, selector, context) {
  var $el = $(selector, context);
  Ember.run($el, 'mousedown');

  focus($el);

  Ember.run($el, 'mouseup');
  Ember.run($el, 'click');

  return app.testHelpers.wait();
}

function unscopedFillIn(app, selector, contextOrText, text) {
  var $el, context;
  if (typeof text === 'undefined') {
    text = contextOrText;
  } else {
    context = contextOrText;
  }
  $el = $(selector, context);
  focus($el);
  Ember.run(function() {
    $el.val(text).change();
  });
  return app.testHelpers.wait();
}
Ember.Test.registerAsyncHelper('unscopedClick', unscopedClick);
Ember.Test.registerAsyncHelper('unscopedFillIn', unscopedFillIn);

I'm not sure if this qualifies as a "recommended" approach. I wish there was a better solution, but I don't have one yet.

@john-griffin
Copy link
Author

@lukemelia thanks for the detailed explanation.

Based on this example I implemented helpers that are successfully filling out forms and clicking buttons inside a Tether based modal. However the tests fail to complete because it seems like the actions aren't bubbling correctly. Is this due to the event delegation caveat mentioned here?

@john-griffin
Copy link
Author

I can see now this is a deeply rooted issue in Ember event dispatching yapplabs/ember-tether#3.

An alternative approach would be to disable ember-tether when running tests but keep it enabled in other environments. Is there a good way of doing this? Digging through the source it seems to be auto detected so I can't find an obvious way to switch it off in test mode.

@chrislopresto
Copy link
Contributor

This is definitely not a recommended approach, as it would special case your test environment state and could therefore mask real bugs. But the ember-modal-dialog test suite does have a set of tests that cover non-ember-tether environments by stubbing hasEmberTether to false:

As you can see, it uses several private apis, doesn't work for 1.10 and prior, etc. So...

Use At Your Own Risk

@gzurbach
Copy link

gzurbach commented Jul 6, 2015

We are currently dealing with the same issue. We wanted to use ember-tether for something else than modals and now our existing tests are broken. A good solution for us would be an option to tell ember-modal-dialog to not use tether even though it is available.

@chrislopresto
Copy link
Contributor

@gzurbach It's not directly documented, but you can specify useEmberTether=false to fall back to the positioned-container-based positioning.

{{#modal-dialog useEmberTether=false}}
I am a modal that will never use ember-tether.
{{/modal-dialog}}

useEmberTether: computed('hasEmberTether', 'alignment', 'renderInPlace', function() {

@gzurbach
Copy link

gzurbach commented Jul 6, 2015

Awesome! Thanks for the quick answer.

@harlio
Copy link

harlio commented Nov 24, 2015

+1. Would love to see a good solution for this... the unscopedClick test helper seems like it would be the least hacky way to implement acceptance tests, but I wasn't able to get it to work properly.

@Gaurav0
Copy link

Gaurav0 commented Dec 7, 2015

If you are using tether-dialog and want to disable it during tests while this issue is unresolved, you can set the renderInPlace property to true during tests.

Please fix this!

@RustyToms
Copy link
Contributor

If I understand correctly, there are two problems in testing environments where the body tag is not the Ember rootElement. Getting the test helpers to interact with an ember-tether dialog box, and getting the actions to propagate correctly from the ember-tether dialog box. The first problem has a couple work arounds, but I don't see anything on here that worked for me for the second problem with the actions. Here's my work-around in case anyone finds it helpful (this is using Ember 1.13):

{{#component (if Ember.testing "modal-dialog" "tether-dialog")
    attachment="top right"
    clickOutsideToClose=false
    hasOverlay=false
    offset= "-10px -10px"
    target=".submit-search__submit-btn"
    targetAttachment="bottom right"}}
    {{!-- dialog template here --}}
{{/component}}

So during the tests it just uses "modal-dialog" which doesn't look right but works. The tether-dialog specific properties are just ignored. And then you can use the regular test helpers. I know its not a good idea to make the code different between the production environment and the testing environment, but in this case I figured you can go for either less-than-ideal acceptance tests or no acceptance tests at all of the "actions up" part of a component dependent on ember-tether.

@samselikoff
Copy link
Collaborator

I believe setting renderInPlace to true in test environments is the best workaround for this issue, currently.

@axsuul
Copy link

axsuul commented Feb 26, 2018

If you're doing acceptance testing the emberjs/rfcs#268 way, you can bypass renderInPlace which always felt a little dirty with this in your environment:

if (environment === 'test') {
  ENV.APP.rootElement = '#ember-testing';
  ENV['ember-tether'] = {
    bodyElementId: 'ember-testing'
  };
}

and in your acceptance tests, ensure you're importing the appropriate test selectors

import { click } from '@ember/test-helpers'

Perhaps we can now close this issue?

@samselikoff
Copy link
Collaborator

@axsuul That sounds much better! Could you PR the README with a new section for Testing, and add your snippet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants