diff --git a/addon/components/ember-tether.hbs b/addon/components/ember-tether.hbs new file mode 100644 index 0000000..9e7e9ff --- /dev/null +++ b/addon/components/ember-tether.hbs @@ -0,0 +1,8 @@ +
+ {{yield}} +
\ No newline at end of file diff --git a/addon/components/ember-tether.js b/addon/components/ember-tether.js index ee97b8c..4614550 100644 --- a/addon/components/ember-tether.js +++ b/addon/components/ember-tether.js @@ -1,126 +1,89 @@ import { getOwner } from '@ember/application'; import { schedule } from '@ember/runloop'; -import { computed, get, observer } from '@ember/object'; import { isNone } from '@ember/utils'; -import Component from '@ember/component'; +import Component from '@glimmer/component'; import Tether from 'tether'; +import { action } from '@ember/object'; -export default Component.extend({ - classNames: ['ember-tether'], - classPrefix: 'ember-tether', - target: null, - attachment: null, - targetAttachment: null, - offset: null, - targetOffset: null, - targetModifier: null, - constraints: null, - optimizations: null, - emberTetherConfig: computed(function() { - return (getOwner(this).resolveRegistration('config:environment') || {})['ember-tether']; - }), - bodyElement: computed(function() { - let config = get(this, 'emberTetherConfig'); +export default class EmberTetherComponent extends Component { + _tether; + element; + + get classPrefix() { + return this.args.classPrefix || 'ember-tether'; + } + + get emberTetherConfig() { + return (getOwner(this).resolveRegistration('config:environment') || {})[ + 'ember-tether' + ]; + } + + get bodyElement() { + let config = this.emberTetherConfig; if (config && config.bodyElementId) { return document.getElementById(config.bodyElementId); } - }), - attributeBindings: [ - 'aria-atomic', - 'aria-busy', - 'aria-controls', - 'aria-current', - 'aria-describedby', - 'aria-details', - 'aria-disabled', - 'aria-errormessage', - 'aria-flowto', - 'aria-haspopup', - 'aria-hidden', - 'aria-invalid', - 'aria-keyshortcuts', - 'aria-label', - 'aria-labelledby', - 'aria-live', - 'aria-owns', - 'aria-relevant', - 'aria-roledescription' - ], - didInsertElement() { - this._super(...arguments); - this.addTether(); - }, + return undefined; + } - willDestroyElement() { - this._super(...arguments); + willDestroy() { + super.willDestroy(...arguments); if (!this._tether) return; - let { _tether, element } = this; schedule('render', () => { this.removeElement(element); this.removeTether(_tether); }); - }, - - didRender() { - this._super(...arguments); - this.positionTether(); - }, + } - tetherDidChange: observer( - 'classPrefix', - 'target', - 'attachment', - 'targetAttachment', - 'offset', - 'targetOffset', - 'targetModifier', - 'constraints', - 'optimizations', - function() { - this.removeTether(this._tether); - this.addTether(); - } - ), + @action updateTether() { + this.removeTether(this._tether); + this.addTether(); + } + @action positionTether() { - if (this._tether) { - this._tether.position(); - } - }, + this._tether?.position(); + } - addTether() { - if (get(this, '_tetherTarget')) { - this._tether = new Tether(this._tetherOptions()); + @action + addTether(el = null) { + // when called from did-insert modifier, el will be passed + if (el) { + this.element = el; } - }, - - removeTether(tether) { - if (tether) { - tether.destroy(); + if (this._tetherTarget) { + this._tether = new Tether(this._tetherOptions); + this.positionTether(); } - }, + } + removeTether(tether) { + tether?.destroy(); + } removeElement(element) { - if (element.parentNode) { - element.parentNode.removeChild(element); - } - }, + element.parentNode?.removeChild(element); + } - _tetherTarget: computed('target', function() { - let t = get(this, 'target'); + get _tetherTarget() { + let t = this.args.target; if (t && t.element) { t = t.element; } return t; - }), + } - _tetherOptions() { + get _tetherOptions() { let options = { element: this.element, - target: get(this, '_tetherTarget') + target: this._tetherTarget, + classPrefix: this.classPrefix, }; - [ 'classPrefix', + if (this.bodyElement) { + options.bodyElement = this.bodyElement; + } + [ 'attachment', 'targetAttachment', 'offset', @@ -128,13 +91,12 @@ export default Component.extend({ 'targetModifier', 'constraints', 'optimizations', - 'bodyElement' ].forEach((k) => { - let v = get(this, k); + let v = this.args[k]; if (!isNone(v)) { options[k] = v; } }); return options; } -}); +} diff --git a/app/components/ember-tether.js b/app/components/ember-tether.js index 07e68c4..dfcc899 100644 --- a/app/components/ember-tether.js +++ b/app/components/ember-tether.js @@ -1 +1 @@ -export { default } from 'ember-tether/components/ember-tether'; \ No newline at end of file +export { default } from 'ember-tether/components/ember-tether'; diff --git a/package.json b/package.json index 97e2ea0..d3b28e8 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,10 @@ "test:ember-compatibility": "ember try:each" }, "dependencies": { + "@ember/render-modifiers": "^2.0.5", "ember-auto-import": "^2.6.3", "ember-cli-babel": "^7.26.11", + "ember-cli-htmlbars": "^6.2.0", "tether": "^2.0.0" }, "devDependencies": { @@ -48,7 +50,6 @@ "ember-cli": "~4.12.0", "ember-cli-dependency-checker": "^3.3.1", "ember-cli-github-pages": "^0.2.1", - "ember-cli-htmlbars": "^6.2.0", "ember-cli-inject-live-reload": "^2.1.0", "ember-cli-terser": "^4.0.2", "ember-load-initializers": "^2.1.2", diff --git a/tests/.eslintrc.js b/tests/.eslintrc.js index 9fc5132..e249f4c 100644 --- a/tests/.eslintrc.js +++ b/tests/.eslintrc.js @@ -1,5 +1,6 @@ +/* eslint-disable no-undef */ module.exports = { env: { - 'embertest': true - } + embertest: true, + }, }; diff --git a/tests/acceptance/tether-test.js b/tests/acceptance/tether-test.js index 8b2d35a..ea9a30d 100644 --- a/tests/acceptance/tether-test.js +++ b/tests/acceptance/tether-test.js @@ -1,60 +1,65 @@ import { click, visit } from '@ember/test-helpers'; -import $ from 'jquery'; -import { set } from '@ember/object'; import { module, test } from 'qunit'; import QUnit from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; -import { run } from '@ember/runloop'; +import { next } from '@ember/runloop'; -let viewRegistry; const { assert } = QUnit; const { abs } = Math; -module('Acceptance | tether test', function(hooks) { +function offset(el) { + let box = el.getBoundingClientRect(); + let docElem = document.documentElement; + return { + top: box.top + window.pageYOffset - docElem.clientTop, + left: box.left + window.pageXOffset - docElem.clientLeft, + }; +} + +module('Acceptance | tether test', function (hooks) { setupApplicationTest(hooks); - assert.topAligned = function(thingSelector, targetSelector) { - let thing = $(thingSelector); - let target = $(targetSelector); - let topDifference = abs(thing.offset().top - target.offset().top); + assert.topAligned = function (thingSelector, targetSelector) { + let thing = document.querySelector(thingSelector); + let target = document.querySelector(targetSelector); + let topDifference = abs(offset(thing).top - offset(target).top); let withinOnePixel = topDifference < 1; - assert.ok(withinOnePixel, `${thingSelector} top within one pixel of ${targetSelector} top, difference was ${topDifference}`); + assert.ok( + withinOnePixel, + `${thingSelector} top within one pixel of ${targetSelector} top, difference was ${topDifference}` + ); }; - assert.leftOf = function(thingSelector, targetSelector) { - let thing = $(thingSelector); - let target = $(targetSelector); - let leftOf = thing.offset().left < target.offset().left; + assert.leftOf = function (thingSelector, targetSelector) { + let thing = document.querySelector(thingSelector); + let target = document.querySelector(targetSelector); + let leftOf = offset(thing).left < offset(target).left; assert.ok(leftOf, `${thingSelector} left of ${targetSelector}`); }; - assert.rightOf = function(thingSelector, targetSelector) { - let thing = $(thingSelector); - let target = $(targetSelector); - let leftOf = thing.offset().left > target.offset().left; + assert.rightOf = function (thingSelector, targetSelector) { + let thing = document.querySelector(thingSelector); + let target = document.querySelector(targetSelector); + let leftOf = offset(thing).left > offset(target).left; assert.ok(leftOf, `${thingSelector} right of ${targetSelector}`); }; - assert.classPresent = function(thingSelector, className) { - let thing = $(thingSelector); - assert.ok(thing.attr('class').indexOf(className) > -1); + assert.classPresent = function (thingSelector, className) { + let thing = document.querySelector(thingSelector); + assert.ok(thing.classList.contains(className)); }; - assert.classAbsent = function(thingSelector, className) { - let thing = $(thingSelector); - assert.ok(thing.attr('class').indexOf(className) <= -1); + assert.classAbsent = function (thingSelector, className) { + let thing = document.querySelector(thingSelector); + assert.ok(!thing.classList.contains(className)); }; - assert.attribute = function(thingSelector, attributeName, attributeValue) { - let thing = $(thingSelector); - assert.equal(thing.attr(attributeName), attributeValue, `${attributeName} has value ${attributeValue}`); - } - - function getTetherComponent(context, selector) { - // jscs:disable - let anotherEl = $(selector)[0]; - // jscs:enable - viewRegistry = context.owner.lookup('-view-registry:main'); - return viewRegistry[anotherEl.id]; - } + assert.attribute = function (thingSelector, attributeName, attributeValue) { + let thing = document.querySelector(thingSelector); + assert.equal( + thing.getAttribute(attributeName), + attributeValue, + `${attributeName} has value ${attributeValue}` + ); + }; - test('tethering a thing to a target', async function(assert) { + test('tethering a thing to a target', async function (assert) { await visit('/'); assert.topAligned('.tethered-thing', '#tether-target-1'); @@ -63,77 +68,85 @@ module('Acceptance | tether test', function(hooks) { assert.leftOf('.another-tethered-thing', '#tether-target-3'); }); - test('tethering to an Ember Component', async function(assert) { + test('tethering to an Ember Component', async function (assert) { await visit('/'); assert.topAligned('.component-tether', '.example-component'); assert.rightOf('.component-tether', '.example-component'); }); - test('changing tether attachment', async function(assert) { + test('changing tether attachment', async function (assert) { assert.expect(4); await visit('/'); assert.topAligned('.another-tethered-thing', '#tether-target-3'); assert.leftOf('.another-tethered-thing', '#tether-target-3'); - let anotherThing = getTetherComponent(this, '.another-tethered-thing'); - //wrap this in a run to fix failing test in ember-lts-2.12 - await run(() => { - set(anotherThing, 'attachment', 'top left'); - set(anotherThing, 'targetAttachment', 'top right'); + let applicationController = this.owner.lookup('controller:application'); + applicationController.exampleAttachment = 'top left'; + applicationController.exampleTargetAttachment = 'top right'; + next(() => { assert.topAligned('.another-tethered-thing', '#tether-target-3'); assert.rightOf('.another-tethered-thing', '#tether-target-3'); }); }); - test('surviving target removal', async function(assert) { + test('surviving target removal', async function (assert) { await visit('/'); assert.topAligned('.third-tethered-thing', '#tether-target-2 .within'); assert.rightOf('.third-tethered-thing', '#tether-target-2 .within'); assert.classPresent('.third-tethered-thing', 'ember-tether-enabled'); - assert.ok($('.third-tethered-thing .highlight').text() === 'true'); + assert.strictEqual( + document.querySelector('.third-tethered-thing .highlight').textContent, + 'true' + ); await click('.third-tethered-thing button'); assert.classAbsent('.third-tethered-thing', 'ember-tether-enabled'); - assert.ok($('.third-tethered-thing .highlight').text() === 'false'); + assert.strictEqual( + document.querySelector('.third-tethered-thing .highlight').textContent, + 'false' + ); await click('.third-tethered-thing button'); assert.topAligned('.third-tethered-thing', '#tether-target-2 .within'); assert.rightOf('.third-tethered-thing', '#tether-target-2 .within'); assert.classPresent('.third-tethered-thing', 'ember-tether-enabled'); - assert.ok($('.third-tethered-thing .highlight').text() === 'true'); + assert.strictEqual( + document.querySelector('.third-tethered-thing .highlight').textContent, + 'true' + ); }); - test('binding accessibility elements', async function(assert) { + test('binding accessibility elements', async function (assert) { await visit('/'); let expectedAttributes = { 'aria-atomic': 'true', 'aria-busy': 'true', 'aria-controls': 'element-id', - 'aria-current': 'current-element-id', + 'aria-current': 'page', 'aria-describedby': 'described-element-id', 'aria-details': 'details-element-id', - 'aria-disabled': 'true', - 'aria-errormessage': 'errormessage-element-id', 'aria-flowto': 'flowto-elemenet-id', - 'aria-haspopup': 'grid', 'aria-hidden': 'true', - 'aria-invalid': 'true', 'aria-keyshortcuts': 'A', 'aria-label': 'tether-label', 'aria-labelledby': 'labelledby-element-id', 'aria-live': 'polite', 'aria-owns': 'owns-element-id', 'aria-relevant': 'additions', - 'aria-roledescription': 'tether-role-description' + 'aria-roledescription': 'tether-role-description', }; assert.attribute('.accessible-thing', 'role', 'region'); Object.keys(expectedAttributes).forEach((attributeName) => { - assert.attribute('.accessible-thing', attributeName, expectedAttributes[attributeName]); - }) + assert.attribute( + '.accessible-thing', + attributeName, + expectedAttributes[attributeName] + ); + }); }); }); diff --git a/tests/dummy/app/components/example-component/component.js b/tests/dummy/app/components/example-component/component.js index 54acbf0..ecbcfd5 100644 --- a/tests/dummy/app/components/example-component/component.js +++ b/tests/dummy/app/components/example-component/component.js @@ -1,16 +1,18 @@ -import { run } from '@ember/runloop'; -import Component from '@ember/component'; +import Component from '@glimmer/component'; +import { action } from '@ember/object'; -export default Component.extend({ - classNames: ['example-component'], +export default class ExampleComponent extends Component { + element; - didInsertElement() { - run.schedule('afterRender', () => { - if (this.isDestroying || this.isDestroyed) { - return; - } - // eslint-disable-next-line - this.sendAction('registerComponentTarget', this); - }); + @action + registerComponent(element) { + this.element = element; + // schedule('afterRender', () => { + if (this.isDestroying || this.isDestroyed) { + return; + } + // eslint-disable-next-line + this.args.registerComponentTarget(this); + // }); } -}); +} diff --git a/tests/dummy/app/components/example-component/template.hbs b/tests/dummy/app/components/example-component/template.hbs new file mode 100644 index 0000000..56f9ff9 --- /dev/null +++ b/tests/dummy/app/components/example-component/template.hbs @@ -0,0 +1,5 @@ +
\ No newline at end of file diff --git a/tests/dummy/app/controllers/application.js b/tests/dummy/app/controllers/application.js index 13c3a71..9ef04b8 100644 --- a/tests/dummy/app/controllers/application.js +++ b/tests/dummy/app/controllers/application.js @@ -1,16 +1,15 @@ -import { isNone } from '@ember/utils'; -import { observer, set, get, computed } from '@ember/object'; -import { run } from '@ember/runloop'; import Controller from '@ember/controller'; +import { isNone } from '@ember/utils'; +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; -export default Controller.extend({ - exampleTarget: 1, - exampleTargetSelector: computed('exampleTarget', function() { - return `#tether-target-${get(this, 'exampleTarget')}`; - }), +export default class ApplicationController extends Controller { + @tracked exampleTarget = 1; + get exampleTargetSelector() { + return `#tether-target-${this.exampleTarget}`; + } - // eslint-disable-next-line - attachmentConfigurations: [ + attachmentConfigurations = [ { targetAttachment: 'top left', attachment: 'top right' }, { targetAttachment: 'middle left', attachment: 'top right' }, { targetAttachment: 'bottom left', attachment: 'top right' }, @@ -22,80 +21,84 @@ export default Controller.extend({ { targetAttachment: 'top right', attachment: 'top left' }, { targetAttachment: 'top right', attachment: 'bottom left' }, { targetAttachment: 'top center', attachment: 'bottom left' }, - { targetAttachment: 'top left', attachment: 'bottom left' } - ], - attachmentConfigurationIndex: 0, + { targetAttachment: 'top left', attachment: 'bottom left' }, + ]; + + @tracked attachmentConfigurationIndex = 0; - exampleTargetAttachment: computed('attachmentConfigurationIndex', function() { - let i = get(this, 'attachmentConfigurationIndex'); - let config = get(this, 'attachmentConfigurations')[i]; + @tracked _exampleTargetAttachment; + get exampleTargetAttachment() { + if (this._exampleTargetAttachment) return this._exampleTargetAttachment; + + let i = this.attachmentConfigurationIndex; + let config = this.attachmentConfigurations[i]; return config.targetAttachment; - }), - exampleAttachment: computed('attachmentConfigurationIndex', function() { - let i = get(this, 'attachmentConfigurationIndex'); - let config = get(this, 'attachmentConfigurations')[i]; + } + set exampleTargetAttachment(val) { + this._exampleTargetAttachment = val; + } + @tracked _exampleAttachment; + get exampleAttachment() { + if (this._exampleAttachment) return this._exampleAttachment; + + let i = this.attachmentConfigurationIndex; + let config = this.attachmentConfigurations[i]; return config.attachment; - }), + } + set exampleAttachment(val) { + this._exampleAttachment = val; + } - exampleOffset: null, - exampleConstraintsOn: computed('exampleConstraints', function() { - if (get(this, 'exampleConstraints')) { - return 'on'; - } else { - return 'off'; - } - }), - exampleConstraints: null, + @tracked exampleOffset; - isShowingTargetWithin: true, - computedTargetWithin: computed('isShowingTargetWithin', function() { - if (get(this, 'isShowingTargetWithin')) { - return '#tether-target-2 .within'; - } - }), - exampleTargetWithin: '#tether-target-2 .within', - - computedTargetWithinDidChange: observer('isShowingTargetWithin', function() { - run.next(() => { - set(this, 'exampleTargetWithin', get(this, 'computedTargetWithin')); - }); - }), - - actions: { - registerComponentTarget(component) { - this.set('exampleTargetComponent', component); - }, - switchTether() { - let dt = get(this, 'exampleTarget'); - let nt = dt === 7 ? 1 : dt + 1; - set(this, 'exampleTarget', nt); - }, - rotateTether() { - let numConfigs = get(this, 'attachmentConfigurations').length; - let i = get(this, 'attachmentConfigurationIndex'); - let nc = i === (numConfigs - 1) ? 0 : i + 1; - set(this, 'attachmentConfigurationIndex', nc); - }, - toggleOffset() { - if (isNone(get(this, 'exampleOffset'))) { - set(this, 'exampleOffset', '0 -20px'); - } else { - set(this, 'exampleOffset', null); - } - }, - toggleConstraints() { - if (isNone(get(this, 'exampleConstraints'))) { - set(this, 'exampleConstraints', [{ + @tracked exampleConstraints = null; + get exampleConstraintsOn() { + return this.exampleConstraints ? 'on' : 'off'; + } + + @tracked isShowingTargetWithin = true; + + get exampleTargetWithin() { + return this.isShowingTargetWithin ? '#tether-target-2 .within' : undefined; + } + + @tracked exampleTargetComponent; + @action registerComponentTarget(component) { + this.exampleTargetComponent = component; + } + + @action switchTether() { + let dt = this.exampleTarget; + let nt = dt === 7 ? 1 : dt + 1; + this.exampleTarget = nt; + } + + @action rotateTether() { + let numConfigs = this.attachmentConfigurations.length; + let i = this.attachmentConfigurationIndex; + let nc = i === numConfigs - 1 ? 0 : i + 1; + this.attachmentConfigurationIndex = nc; + } + + @action toggleOffset() { + this.exampleOffset = isNone(this.exampleOffset) ? '0 -20px' : null; + } + + @action toggleConstraints() { + if (isNone(this.exampleConstraints)) { + this.exampleConstraints = [ + { to: 'scrollParent', attachment: 'together', - pin: true - }]); - } else { - set(this, 'exampleConstraints', null); - } - }, - toggleTargetWithin() { - this.toggleProperty('isShowingTargetWithin'); + pin: true, + }, + ]; + } else { + this.exampleConstraints = null; } } -}); + + @action toggleTargetWithin() { + this.isShowingTargetWithin = !this.isShowingTargetWithin; + } +} diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index 34ef7b3..7578ec1 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -9,41 +9,41 @@

- + Switch the target for "A tethered thing". - Target is square {{exampleTarget}} + Target is square {{this.exampleTarget}}
- + Rotate "Another tethered thing" around square 3. - attachment: {{exampleAttachment}} - targetAttachment: {{exampleTargetAttachment}} + attachment: {{this.exampleAttachment}} + targetAttachment: {{this.exampleTargetAttachment}}
- + Add spacing between "A tethered thing" and its target square. - Offset is {{if exampleOffset exampleOffset "null"}} + Offset is {{if this.exampleOffset this.exampleOffset "null"}}
- + Trap "Another tethered thing" within the box. Scroll to see it pin. - Constraints are {{exampleConstraintsOn}} + Constraints are {{this.exampleConstraintsOn}}
- + Remove target from DOM. Watch "A third tethered thing" behave sensibly. - Target in DOM: {{isShowingTargetWithin}} + Target in DOM: {{this.isShowingTargetWithin}}
1 - {{example-component registerComponentTarget="registerComponentTarget"}} +
2 - {{#if isShowingTargetWithin}} + {{#if this.isShowingTargetWithin}}
{{/if}}
@@ -53,75 +53,71 @@
6
7
- {{#ember-tether - target=exampleTargetSelector - targetAttachment="top right" - attachment="top left" - class="tethered-thing" - offset=exampleOffset - }} + A tethered thing - {{/ember-tether}} + - {{#ember-tether - target="#tether-target-3" - targetAttachment=exampleTargetAttachment - attachment=exampleAttachment - class="another-tethered-thing" - constraints=exampleConstraints - }} + Another tethered thing - {{/ember-tether}} + - {{#ember-tether - target=exampleTargetWithin - targetAttachment="top right" - attachment="top left" - class="third-tethered-thing" - }} + A third tethered thing - Target in DOM: {{isShowingTargetWithin}} - - {{/ember-tether}} + Target in DOM: {{this.isShowingTargetWithin}} + + - {{#ember-tether - target=exampleTargetComponent - targetAttachment="top right" - attachment="top left" - class="component-tether" - }} + Component - {{/ember-tether}} + - {{#ember-tether - target="#tether-target-5" - targetAttachment="top right" - attachment="top left" - class="accessible-thing" - offset=exampleOffset - ariaRole="region" - aria-atomic="true" - aria-busy="true" - aria-controls="element-id" - aria-current="current-element-id" - aria-describedby="described-element-id" - aria-details="details-element-id" - aria-disabled="true" - aria-errormessage="errormessage-element-id" - aria-flowto="flowto-elemenet-id" - aria-haspopup="grid" - aria-hidden="true" - aria-invalid="true" - aria-keyshortcuts="A" - aria-label="tether-label" - aria-labelledby="labelledby-element-id" - aria-live="polite" - aria-owns="owns-element-id" - aria-relevant="additions" - aria-roledescription="tether-role-description" - }} +
diff --git a/tests/dummy/app/views/.gitkeep b/tests/dummy/app/views/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index 3810df5..2ac4b9f 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -39,7 +39,7 @@ module.exports = function (environment) { ENV.APP.rootElement = '#ember-testing'; ENV['ember-tether'] = { - bodyElementId: 'ember-testing' + bodyElementId: 'ember-testing', }; ENV.APP.autoboot = false; } diff --git a/tests/helpers/module-for-acceptance.js b/tests/helpers/module-for-acceptance.js index e127b48..fe514ec 100644 --- a/tests/helpers/module-for-acceptance.js +++ b/tests/helpers/module-for-acceptance.js @@ -3,7 +3,7 @@ import startApp from '../helpers/start-app'; import destroyApp from '../helpers/destroy-app'; import { Promise } from 'rsvp'; -export default function(name, options = {}) { +export default function (name, options = {}) { module(name, { beforeEach() { this.application = startApp(); @@ -14,8 +14,11 @@ export default function(name, options = {}) { }, afterEach() { - let afterEach = options.afterEach && options.afterEach.apply(this, arguments); - return Promise.resolve(afterEach).then(() => destroyApp(this.application)); - } + let afterEach = + options.afterEach && options.afterEach.apply(this, arguments); + return Promise.resolve(afterEach).then(() => + destroyApp(this.application) + ); + }, }); } diff --git a/tests/helpers/start-app.js b/tests/helpers/start-app.js index 7d20e8a..681aa01 100644 --- a/tests/helpers/start-app.js +++ b/tests/helpers/start-app.js @@ -1,6 +1,6 @@ import Application from '../../app'; import config from '../../config/environment'; -import { merge } from '@ember/polyfills' +import { merge } from '@ember/polyfills'; import { run } from '@ember/runloop'; export default function startApp(attrs) { diff --git a/tests/index.html b/tests/index.html index 462407a..643174c 100644 --- a/tests/index.html +++ b/tests/index.html @@ -21,6 +21,8 @@ #ember-testing-container { width: 100%; border: none; + height: 50vh; + overflow-y: scroll; } #ember-testing { transform: none; @@ -36,14 +38,23 @@ right: 0; z-index: 10000; } + #qunit-fixture { + position: absolute; + left: auto; + bottom: 0; + width: auto; + height: auto; + top: auto; + } .note { position: absolute; - font-size: 1.3rem; + font-size: 1.1rem; margin: 0 auto; background-color: cyan; border: dotted 6px black; - padding: 10px 30px; - width: 80%; + padding: 10px 25px; + width: 90%; + bottom: 50vh; } strong { color: white; diff --git a/yarn.lock b/yarn.lock index dbc5a44..42d2eda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1864,6 +1864,15 @@ mkdirp "^1.0.4" silent-error "^1.1.1" +"@ember/render-modifiers@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-2.0.5.tgz#4b1d9496a82ca471aeaa3ecddd94ef089450f415" + integrity sha512-5cJ1niIdOJC6k6KtIn9HGbr1DATJQp4ZqMv1vbi6LKQWbVCQ3byvKONtUEi3H0wcewlrcaWCqXOgm0nACzCOQA== + dependencies: + "@embroider/macros" "^1.0.0" + ember-cli-babel "^7.26.11" + ember-modifier-manager-polyfill "^1.2.0" + "@ember/string@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@ember/string/-/string-3.0.1.tgz#42cf032031a4432c2dd69c327ae1876d2c13df9c" @@ -4096,15 +4105,10 @@ can-symlink@^1.0.0: dependencies: tmp "0.0.28" -caniuse-lite@^1.0.30001254: - version "1.0.30001255" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001255.tgz#f3b09b59ab52e39e751a569523618f47c4298ca0" - integrity sha512-F+A3N9jTZL882f/fg/WWVnKSu6IOo3ueLz4zwaOPbPYHNmM/ZaDUyzyJwS1mZhX7Ex5jqTyW599Gdelh5PDYLQ== - -caniuse-lite@^1.0.30001449: - version "1.0.30001475" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001475.tgz#1cf0a3003eddc6986f79b54c804981423ce127e3" - integrity sha512-6xvTuQbEjQvvdknKCA/B6w6edEG9OMrkTY3M2sre8Iau/5f9stnJA3RfnzUMZlVhcsp1Lyl2KsM8T2R8B3P0Kg== +caniuse-lite@^1.0.30001254, caniuse-lite@^1.0.30001449: + version "1.0.30001478" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz" + integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw== capture-exit@^1.2.0: version "1.2.0" @@ -5089,7 +5093,7 @@ ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.1: resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.1.tgz#5016b80cdef37036c4282eef2d863e1d73576879" integrity sha512-sKvOiPNHr5F/60NLd7SFzMpYPte/nnGkq/tMIfXejfKHIhaiIkYFqX8Z9UFTKWLLn+V7NOaby6niNPZUdvKCRw== -ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.22.1, ember-cli-babel@^7.26.11, ember-cli-babel@^7.26.6: +ember-cli-babel@^7.10.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.22.1, ember-cli-babel@^7.26.11, ember-cli-babel@^7.26.6: version "7.26.11" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.26.11.tgz#50da0fe4dcd99aada499843940fec75076249a9f" integrity sha512-JJYeYjiz/JTn34q7F5DSOjkkZqy8qwFOOxXfE6pe9yEJqWGu4qErKxlz8I22JoVEQ/aBUO+OcKTpmctvykM9YA== @@ -5304,7 +5308,7 @@ ember-cli-typescript@^2.0.2: stagehand "^1.0.0" walk-sync "^1.0.0" -ember-cli-version-checker@^2.1.0: +ember-cli-version-checker@^2.1.0, ember-cli-version-checker@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz#47771b731fe0962705e27c8199a9e3825709f3b3" integrity sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg== @@ -5437,7 +5441,7 @@ ember-cli@~4.12.0: workerpool "^6.4.0" yam "^1.0.0" -ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.1: +ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0, ember-compatibility-helpers@^1.2.1: version "1.2.6" resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.6.tgz#603579ab2fb14be567ef944da3fc2d355f779cd8" integrity sha512-2UBUa5SAuPg8/kRVaiOfTwlXdeVweal1zdNPibwItrhR0IvPrXpaqwJDlEZnWKEoB+h33V0JIfiWleSG6hGkkA== @@ -5465,6 +5469,15 @@ ember-load-initializers@^2.1.2: ember-cli-babel "^7.13.0" ember-cli-typescript "^2.0.2" +ember-modifier-manager-polyfill@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz#cf4444e11a42ac84f5c8badd85e635df57565dda" + integrity sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA== + dependencies: + ember-cli-babel "^7.10.0" + ember-cli-version-checker "^2.1.2" + ember-compatibility-helpers "^1.2.0" + ember-page-title@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/ember-page-title/-/ember-page-title-7.0.0.tgz#11bebd4901d80757646c9006954a13e4fc187421"