Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Leveraging the complete Ember Toolbelt

Leveraging the complete Ember Toolbelt

How can we identify elements in the DOM in Ember acceptance and integration tests? And how can we make that so that it doesn't negatively affect our apps in production?

In this talk I'm showing how we can leverage the Ember toolbelt to answer both questions for the complete Ember community at once.

Marco Otte-Witte

July 11, 2017
Tweet

More Decks by Marco Otte-Witte

Other Decks in Programming

Transcript

  1. import { moduleForComponent, test } from 'ember-qunit'; import hbs from

    'htmlbars-inline-precompile'; moduleForComponent('blog-post', 'blog post component', { integration: true }); test('it renders', function(assert) { … this.render(hbs`{{blog-post post=post}}`); assert.equal( this.$('h1').text().trim(), 'My awesome post' ); assert.equal( this.$('p').text().trim(), "You won't believe it, …" ); });
  2. import { moduleForComponent, test } from 'ember-qunit'; import hbs from

    'htmlbars-inline-precompile'; moduleForComponent('blog-post', 'blog post component', { integration: true }); test('it renders', function(assert) { … this.render(hbs`{{blog-post post=post}}`); assert.equal( this.$('.js-post-title').text().trim(), 'My awesome post' ); assert.equal( this.$('.js-post-body').text().trim(), "You won't believe it, …" ); });
  3. {{! templates/components/blog-post.hbs}} - <h2 class="js-post-title">{{post.title}}</h2> + <div class="title js-post-title">{{post.title}}</h2> -

    <p class="js-post-body">{{post.body}}</p> + <div class="body js-post-body">{{post.body}}</div>
  4. - .js-post-title { + .js-post-header { font-size: 20px; font-weight: bold;

    } {{! templates/components/blog-post.hbs}} - <h2 class="js-post-title">{{post.title}}</h2> + <h2 class="js-post-headerd">{{post.title}}</h2> <p class="js-post-body">{{post.body}}</p>
  5. import { moduleForComponent, test } from 'ember-qunit'; import hbs from

    'htmlbars-inline-precompile'; moduleForComponent('blog-post', 'blog post component', { integration: true }); test('it renders', function(assert) { … this.render(hbs`{{blog-post post=post}}`); assert.equal( this.$('[data-test-post-title]').text().trim(), 'My awesome post' ); assert.equal( this.$('[data-test-post-body]').text().trim(), "You won't believe it, …" ); });
  6. /* global Ember */ (function() { var bindDataTestAttributes; Ember.Component.reopen({ init:

    function() { this._super.apply(this, arguments); if (!bindDataTestAttributes) { bindDataTestAttributes = require( 'ember-test-selectors/utils/bind-data-test-attributes' )['default']; } bindDataTestAttributes(this); } }); })();
  7. included(app) { this._super.included.apply(this, arguments); … if (this._stripTestSelectors) { … if

    (checker.satisfies('^5.0.0')) { … app.options.babel.plugins.push( require('./strip-data-test-properties-plugin') ); } else if (checker.satisfies('^6.0.0-beta.1')) { … app.options.babel6.plugins.push( require('./strip-data-test-properties-plugin6') ); } } }
  8. let TEST_SELECTOR_PREFIX = /data-test-.*/; function StripDataTestPropertiesPlugin() { return { visitor:

    { Property(path) { if (TEST_SELECTOR_PREFIX.test(path.node.key.value)) { path.remove(); } }, }, }; }
  9. included(app) { _setupPreprocessorRegistry(registry) { if (this._stripTestSelectors) { let StripTestSelectorsTransform =

    require( './strip-test-selectors' ); registry.add('htmlbars-ast-plugin', { name: 'strip-test-selectors', plugin: StripTestSelectorsTransform, baseDir() { return __dirname; } }); } … } }
  10. StripTestSelectorsTransform.prototype.transform = function(ast) { let walker = new this.syntax.Walker(); walker.visit(ast,

    function(node) { if (node.type === 'ElementNode') { node.attributes = node.attributes.filter(function(attribute) { return !isTestSelector(attribute.name); }); } else if (node.type === 'MustacheStatement' || node.type === 'BlockStatement') { node.params = node.params.filter(function(param) { return !isTestSelector(param.original); }); node.hash.pairs = node.hash.pairs.filter(function(pair) { return !isTestSelector(pair.key); }); } }); return ast; };
  11. StripTestSelectorsTransform.prototype.transform = function(ast) { let walker = new this.syntax.Walker(); walker.visit(ast,

    function(node) { if (node.type === 'ElementNode') { node.attributes = node.attributes.filter(function(attribute) { return !isTestSelector(attribute.name); }); } else if (node.type === 'MustacheStatement' || node.type === 'BlockStatement') { node.params = node.params.filter(function(param) { return !isTestSelector(param.original); }); node.hash.pairs = node.hash.pairs.filter(function(pair) { return !isTestSelector(pair.key); }); } }); return ast; };
  12. StripTestSelectorsTransform.prototype.transform = function(ast) { let walker = new this.syntax.Walker(); walker.visit(ast,

    function(node) { if (node.type === 'ElementNode') { node.attributes = node.attributes.filter(function(attribute) { return !isTestSelector(attribute.name); }); } else if (node.type === 'MustacheStatement' || node.type === 'BlockStatement') { node.params = node.params.filter(function(param) { return !isTestSelector(param.original); }); node.hash.pairs = node.hash.pairs.filter(function(pair) { return !isTestSelector(pair.key); }); } }); return ast; };