My super, awesome loading overlay component pops up after a delay.
The purpose is when the user is logging in, we don’t want the overlay to popup and then immediately clear (flash) when the system is responsive. Only when the log in takes more than a couple of seconds do we want it show. This part works.
The problem is testing it.
I tried to register the child component.
this.owner.register('component:bui/loading-overlay', BuiLoadingOverlayComponentStub);
And I put a console.log in the attempted over load, which never shows up in the console.
What’s the right way to do this?
Component
import Component from '@glimmer/component'
import { tracked } from '@glimmer/tracking'
import { action } from '@ember/object'
const PAUSE_SPINNER_TIME = 2000
export default class BuiLoadingOverlayComponent extends Component {
get spinnierPauseTime() {
return !!this.args.spinnerPauseTime
? this.args.spinnerPauseTime
: PAUSE_SPINNER_TIME
}
_spinnerPauseTimer = null
startSpinnerPause() {
if (this._spinnerPauseTimer) {
this.stopSpinnerPause()
}
let spt = this.spinnierPauseTime
this._spinnerPauseTimer = setTimeout(() => {
this._spinnerPauseTimer = null
this.showSpinner = true
}, spt)
}
stopSpinnerPause() {
clearTimeout(this._spinnerPauseTimer)
this.showSpinner = false
this._spinnerPauseTimer = null
}
@tracked showSpinner = false
@action onUpdate() {
if (this.args.isLoading) {
this.startSpinnerPause()
} else {
this.stopSpinnerPause()
}
}
}
<div {{did-update this.onUpdate @isLoading}}>
{{#if this.showSpinner}}
<div class="absolute top-0 left-0 bottom-0 w-full z-50 flex justify-center items-center bg-besler-blue bg-opacity-50" data-test-loading-overlay>
<div class="p-6 italic text-2xl text-red-500 border-4 border-red-500 bg-white">
<div class="flex justify-start align-middle">
<Bui::Icon @icon="spinner" class="h-6 w-6 animate-spin fill-current" />
<span class="pl-2 font-bold">{{@caption}}</span>
</div>
<div>
<span class="font-normal">{{@message}}</span>
</div>
<div ...attributes>
{{yield}}
</div>
</div>
</div>
{{/if}}
</div>
Test
class BuiLoadingOverlayComponentStub extends BuiLoadingOverlayComponent {
get spinnierPauseTime() {
console.log('Holy Crap! That worked!')
return 50
}
}
test('LoadingOverlay displays', async function (assert) {
this.owner.register('service:orcaApi', class extends Service {
async requestAuthenticationPasscode() {
const delay = millis => new Promise((resolve, reject) => {
setTimeout(_ => resolve(), millis)
});
await delay(2020)
return { data: { wasSuccessful: true } }
}
});
this.owner.register('component:bui/loading-overlay', BuiLoadingOverlayComponentStub);
await render(hbs`<UserAuthenticator />`);
await waitFor('[data-test-user-athenticator-box-password-input]')
await fillIn('[data-test-user-athenticator-box-text-input]', 'username')
await fillIn('[data-test-user-athenticator-box-password-input]', 'password')
await triggerKeyEvent('[data-test-user-athenticator-box-password-input]', 'keyup', 'Enter') // this is the test--does the enter key call onSignIn?
await waitFor('[data-test-loading-overlay]',{ timeout: 2040 })
assert.dom('[data-test-loading-overlay]').exists() // this is the real test;
});
});