diff --git a/webapp/components/LoginForm/LoginForm.spec.js b/webapp/components/LoginForm/LoginForm.spec.js index de79e4a49..2f036882f 100644 --- a/webapp/components/LoginForm/LoginForm.spec.js +++ b/webapp/components/LoginForm/LoginForm.spec.js @@ -1,3 +1,4 @@ +import Vue from 'vue' import LoginForm from './LoginForm.vue' import Styleguide from '@human-connection/styleguide' import Vuex from 'vuex' @@ -38,7 +39,7 @@ describe('LoginForm', () => { error: jest.fn(), }, } - return mount(LoginForm, { mocks, localVue, propsData, store, data }) + return mount(LoginForm, { mocks, localVue, propsData, store }) } describe('fill in email and password and submit', () => { @@ -57,13 +58,44 @@ describe('LoginForm', () => { }) }) }) - - describe('Click event', () => { - it('clicking icon shows/hides password and changes icon', () => { - wrapper.find('a.click-wrapper').trigger('click') - expect(wrapper.data.showPassword).toEqual(!showPassword) + + describe('Click on show password input field type change', () => { + const wrapper = Wrapper() + it('does not show the password by default', () => { + expect(wrapper.find('input[name ="password"]').attributes('type')).toEqual('password') + }) + + it('shows the password after click on show password', async () => { + wrapper.find('span.click-wrapper').trigger('click') + await Vue.nextTick() + await expect(wrapper.find('input[name = "password"]').attributes('type')).toEqual('text') + }) + + }) + + describe('Click on show password icon, icon change', () => { + const wrapper = Wrapper() + it('shows eye icon by default', () => { + expect(wrapper.find('span.icon-wrapper').attributes('data-test')).toEqual('eye') + }) + + it('shows the slash-eye icon after click', async () => { + wrapper.find('span.click-wrapper').trigger('click') + await Vue.nextTick() + await expect(wrapper.find('span.icon-wrapper').attributes('data-test')).toEqual('eye-slash') + }) + }) + + describe('Focus returns to password input container after show password click', () =>{ + const wrapper = Wrapper() + const componentToGetFocus = wrapper.find('input[name ="password"]') + it('Focus is on the password field container after click', async () => { + wrapper.find('span.click-wrapper').trigger('click', { + relateTarget: componentToGetFocus + }) + await Vue.nextTick() + await expect(wrapper.emitted('focus')).toBeTruthy() }) }) }) - }) diff --git a/webapp/components/LoginForm/LoginForm.vue b/webapp/components/LoginForm/LoginForm.vue index 2010d2ae3..e25b42dd4 100644 --- a/webapp/components/LoginForm/LoginForm.vue +++ b/webapp/components/LoginForm/LoginForm.vue @@ -20,7 +20,7 @@ name="email" icon="envelope" /> -
+
- - - + + + + +
{{ $t('login.forgotPassword') }} @@ -74,6 +77,9 @@ export default { pending() { return this.$store.getters['auth/pending'] }, + iconName() { + return this.showPassword ? 'eye-slash' : 'eye' + } }, methods: { async onSubmit() { @@ -89,6 +95,10 @@ export default { toggleShowPassword(event) { this.showPassword = !this.showPassword event.preventDefault() + this.$nextTick(() => { + this.$refs.password.$el.children[1].children[1].focus() + this.$emit('focus') + }) }, }, } @@ -126,15 +136,17 @@ export default { outline: none; transition: all $duration-short $ease-out; - .click-wrapper { + .icon-wrapper { padding: 8px; margin: 4px; + padding-left: 16px; color: $text-color-disabled; } .click-wrapper:hover { cursor: pointer; + &:focus-within { background-color: $background-color-base; border: $input-border-size solid $border-color-active; @@ -153,10 +165,11 @@ export default { color: $text-color-base; } } + .password-field { position: relative; padding-top: 16px; - padding-right: 16px; + padding-right: 8px; border: none; border-style: none; appearance: none;