Added test waiter
MODIFY
addon/index.js
addon/index.js
export {
+ setupRouter,
+ reset,
+ beginTransition,
+ endTransition,
didTransition,
afterFirstRoutePaint,
afterContentPaint,

MODIFY
addon/scheduler.js
addon/scheduler.js
import RSVP from 'rsvp';
import { run } from '@ember/runloop';
+import { DEBUG } from '@glimmer/env';
+import { registerWaiter } from '@ember/test';
const USE_RAF = typeof requestAnimationFrame === 'function';
let _didTransition;
@@ -9,13 +11,17 @@ let _afterContentPaint;
reset();
export function beginTransition() {
+ _checkForPriorTransition();
+
_didTransition = RSVP.defer();
+ _didTransition.isResolved = false;
_afterFirstRoutePaint = _didTransition.promise.then(() => afterNextPaint());
_afterContentPaint = _afterFirstRoutePaint.then(() => afterNextPaint());
}
export function endTransition() {
_didTransition.resolve();
+ _didTransition.isResolved = true;
}
export function setupRouter(router) {
@@ -28,6 +34,8 @@ export function reset() {
_afterFirstRoutePaint = _didTransition.promise.then(() => {});
_afterContentPaint = _afterFirstRoutePaint.then(() => {});
_didTransition.resolve();
+ _didTransition.isResolved = true;
+ _activeRAFs = 0;
}
/**
@@ -55,8 +63,19 @@ export function afterContentPaint() {
return _afterContentPaint;
}
+function _checkForPriorTransition() {
+ if (!_didTransition.isResolved) {
+ _didTransition.reject('fuck off');
+ }
+}
+
+let _activeRAFs = 0;
function afterNextPaint() {
- return new RSVP.Promise(resolve => {
+ let promise = new RSVP.Promise(resolve => {
+ if (DEBUG) {
+ _activeRAFs++;
+ }
+
if (USE_RAF) {
requestAnimationFrame(() => {
run.later(resolve, 0);
@@ -65,4 +84,17 @@ function afterNextPaint() {
run.later(resolve, 0);
}
});
+
+ if (DEBUG) {
+ promise.finally(() => {
+ _activeRAFs--;
+ });
+ }
+
+ return promise;
+}
+
+if (DEBUG) {
+ // wait until no active rafs
+ registerWaiter(() => _activeRAFs === 0);
}

MODIFY
tests/acceptance/deferred-render-test.js
tests/acceptance/deferred-render-test.js
-import { module, test } from 'qunit';
+import { module } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
-import { visit, find } from '@ember/test-helpers';
+import { setupRouter, reset } from 'ember-app-scheduler';
module('Acceptance | deferred render', function(hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function() {
- this.scheduler = this.owner.lookup('service:scheduler');
this.router = this.owner.lookup('router:main');
- });
-
- test('visiting /demo', async function(assert) {
- assert.expect(3);
- let done = assert.async();
-
- this.router.on('didTransition', () => {
- this.scheduler.queues['afterFirstRoutePaint'].afterPaintPromise.then(
- () => {
- const deferredElement = find('.deferred-container ul');
- assert.isVisible(
- deferredElement,
- 'Deferred content should be visible.'
- );
- const adElement = find('.ad-container h3');
- assert.isNotVisible(adElement, 'Ad should not be visible.');
- }
- );
-
- this.scheduler.queues['afterContentPaint'].afterPaintPromise.then(() => {
- const adElement = find('.ad-container h3');
- assert.isVisible(adElement, 'Ad should be visible.');
- done();
- });
- });
- await visit('/demo');
- });
-
- test('visiting /demo when requestAnimationFrame is not present', async function(assert) {
- this.scheduler._useRAF = false;
- assert.expect(3);
- let done = assert.async();
-
- this.router.on('didTransition', () => {
- this.scheduler.queues['afterFirstRoutePaint'].afterPaintPromise.then(
- () => {
- const deferredElement = find('.deferred-container ul');
- assert.isVisible(
- deferredElement,
- 'Deferred content should be visible.'
- );
- const adElement = find('.ad-container h3');
- assert.isNotVisible(adElement, 'Ad should not be visible.');
- }
- );
-
- this.scheduler.queues['afterContentPaint'].afterPaintPromise.then(() => {
- const adElement = find('.ad-container h3');
- assert.isVisible(adElement, 'Ad should be visible.');
- this.scheduler._useRAF = true;
- done();
- });
+ setupRouter(this.router);
});
- await visit('/demo');
+ hooks.afterEach(() => {
+ reset();
});
});

ADD
tests/acceptance/deferred-render-with-service-test.js
+import { module, test } from 'qunit';
+import { setupApplicationTest } from 'ember-qunit';
+import { visit, find } from '@ember/test-helpers';
+
+module('Acceptance | deferred render', function(hooks) {
+ setupApplicationTest(hooks);
+
+ hooks.beforeEach(function() {
+ this.scheduler = this.owner.lookup('service:scheduler');
+ this.router = this.owner.lookup('router:main');
+ });
+
+ test('visiting /demo', async function(assert) {
+ assert.expect(3);
+ let done = assert.async();
+
+ this.router.on('didTransition', () => {
+ this.scheduler.queues['afterFirstRoutePaint'].afterPaintPromise.then(
+ () => {
+ const deferredElement = find('.deferred-container ul');
+ assert.isVisible(
+ deferredElement,
+ 'Deferred content should be visible.'
+ );
+ const adElement = find('.ad-container h3');
+ assert.isNotVisible(adElement, 'Ad should not be visible.');
+ }
+ );
+
+ this.scheduler.queues['afterContentPaint'].afterPaintPromise.then(() => {
+ const adElement = find('.ad-container h3');
+ assert.isVisible(adElement, 'Ad should be visible.');
+ done();
+ });
+ });
+
+ await visit('/demo');
+ });
+
+ test('visiting /demo when requestAnimationFrame is not present', async function(assert) {
+ this.scheduler._useRAF = false;
+ assert.expect(3);
+ let done = assert.async();
+
+ this.router.on('didTransition', () => {
+ this.scheduler.queues['afterFirstRoutePaint'].afterPaintPromise.then(
+ () => {
+ const deferredElement = find('.deferred-container ul');
+ assert.isVisible(
+ deferredElement,
+ 'Deferred content should be visible.'
+ );
+ const adElement = find('.ad-container h3');
+ assert.isNotVisible(adElement, 'Ad should not be visible.');
+ }
+ );
+
+ this.scheduler.queues['afterContentPaint'].afterPaintPromise.then(() => {
+ const adElement = find('.ad-container h3');
+ assert.isVisible(adElement, 'Ad should be visible.');
+ this.scheduler._useRAF = true;
+ done();
+ });
+ });
+
+ await visit('/demo');
+ });
+});

Added test waiter