Skip to content

Commit 2789f4e

Browse files
author
mcibique
committed
Added lolex example and how to use time traveling
1 parent 55e20e3 commit 2789f4e

File tree

5 files changed

+97
-1
lines changed

5 files changed

+97
-1
lines changed

src/di.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ export {
3232
};
3333

3434
export default container;
35+
36+
// global registrations
37+
export const GLOBAL_ID = Symbol('global');
38+
container.bind(GLOBAL_ID).toConstantValue(global);

src/views/Login.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
</div>
1515

1616
<my-button type="submit" class="c-login__submit-button" tid="login__submit-button" :primary="true">Log in</my-button>
17+
<div class="c-login__help-section" tid="login__help-section" v-if="displayHelp">
18+
<a class="c-login__help-section-link" href="#" tid="login__help-section-link">Need help?</a>
19+
<a class="c-login__help-section-link" href="#" tid="login__help-section-link">Forgot your password?</a>
20+
</div>
1721
</form>
1822
</section>
1923
</template>
@@ -22,6 +26,7 @@
2226
import Vue from 'vue';
2327
import { Component } from 'vue-property-decorator';
2428
29+
import { LazyInject, GLOBAL_ID } from '@di';
2530
import MyButton from '@/components/MyButton';
2631
import Focus from '@/directives/focus';
2732
@@ -33,6 +38,9 @@ export default class LoginView extends Vue {
3338
password = '';
3439
username = '';
3540
validationError = null;
41+
displayHelp = false;
42+
43+
@LazyInject(GLOBAL_ID) global;
3644
3745
login (username, password) {
3846
return this.$store.dispatch('auth/login', { username, password });
@@ -66,6 +74,16 @@ export default class LoginView extends Vue {
6674
this.validationError = response.data.error.message;
6775
});
6876
}
77+
78+
created () {
79+
this.displayHelpTimeout = this.global.setTimeout(() => {
80+
this.displayHelp = true;
81+
}, 5000);
82+
}
83+
84+
destroyed () {
85+
this.global.clearTimeout(this.displayHelpTimeout);
86+
}
6987
}
7088
</script>
7189

@@ -104,4 +122,14 @@ export default class LoginView extends Vue {
104122
.c-login__submit-button {
105123
margin-top: 2rem;
106124
}
125+
126+
.c-login__help-section {
127+
margin-top: 2rem;
128+
line-height: 2.5rem;
129+
}
130+
131+
.c-login__help-section-link:after {
132+
content: '';
133+
display: block;
134+
}
107135
</style>

src/views/Login.vue.po.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export default class LoginViewPageObj extends BasePageObj {
2222
return this.tid('login__validation-error');
2323
}
2424

25+
get helpSection () {
26+
return this.tid('login__help-section');
27+
}
28+
29+
get helpSectionLinks () {
30+
return this.tids('login__help-section-links');
31+
}
32+
2533
submit () {
2634
this.form.trigger('submit');
2735
}

src/views/Login.vue.spec.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import '@unit/globals';
22
import { mount, createLocalVue } from '@vue/test-utils';
33
import { expect } from 'chai';
44
import sinon from 'sinon';
5+
import lolex from 'lolex';
56
import axios from 'axios';
67
import AxiosMockAdapter from 'axios-mock-adapter';
78
import flushPromises from 'flush-promises';
89

9-
import container from '@di';
10+
import container, { GLOBAL_ID } from '@di';
1011
import LoginView from '@/views/Login.vue';
1112
import LoginViewPageObj from '@/views/Login.vue.po';
1213
import { createStore, STORE_ID } from '@/store';
@@ -25,6 +26,11 @@ describe('Login view', function () {
2526
this.router = createRouter(this.localVue);
2627
container.bind(ROUTER_ID).toConstantValue(this.router);
2728

29+
// mocking setTimeout, clearTimeout global functiion and enable time traveling
30+
let globalMock = {};
31+
this.clock = lolex.install({ target: globalMock, toFake: ['setTimeout', 'clearTimeout'] });
32+
container.rebind(GLOBAL_ID).toConstantValue(globalMock);
33+
2834
this.mountLoginView = function (options) {
2935
let wrapper = mount(LoginView, { localVue: this.localVue, router: this.router, store: this.store, ...options });
3036
return new LoginViewPageObj(wrapper);
@@ -40,6 +46,8 @@ describe('Login view', function () {
4046

4147
this.axios.verifyNoOutstandingExpectation();
4248
this.axios.restore();
49+
50+
this.clock.uninstall();
4351
});
4452

4553
it('should enter route', function () {
@@ -154,4 +162,44 @@ describe('Login view', function () {
154162
expect(this.store.state.auth.token).to.equal(null);
155163
});
156164
});
165+
166+
describe('help section', function () {
167+
beforeEach(function () {
168+
this.loginView = this.mountLoginView();
169+
});
170+
171+
it('should not be visible during initial render', function () {
172+
expect(this.loginView.helpSection.exists()).to.be.false;
173+
});
174+
175+
it('should be visible after few seconds', function () {
176+
this.timeout(10000);
177+
178+
let expectedTimeWhenHelpSectionIsVisible = 5000;
179+
let tickStep = 1000;
180+
181+
while ((this.clock.now + tickStep) < expectedTimeWhenHelpSectionIsVisible) {
182+
this.clock.tick(tickStep);
183+
this.loginView.update();
184+
expect(this.loginView.helpSection.exists()).to.be.false;
185+
}
186+
187+
this.clock.tick(tickStep);
188+
this.loginView.update();
189+
expect(this.loginView.helpSection.exists()).to.be.true;
190+
});
191+
});
192+
193+
describe('when the view is destroyed', function () {
194+
beforeEach(function () {
195+
this.loginView = this.mountLoginView();
196+
expect(Object.keys(this.clock.timers).length).to.equal(1);
197+
198+
this.loginView.destroy();
199+
});
200+
201+
it('should perform a clean up', function () {
202+
expect(Object.keys(this.clock.timers).length).to.equal(0);
203+
});
204+
});
157205
});

test/unit/base.po.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ export default class BasePageObj {
2323
return this.wrapper.attributes();
2424
}
2525

26+
update () {
27+
return this.wrapper.update();
28+
}
29+
30+
destroy () {
31+
return this.wrapper.destroy();
32+
}
33+
2634
tid (...args) {
2735
return this.wrapper.tid(...args);
2836
}

0 commit comments

Comments
 (0)