@@ -20,28 +20,32 @@ | |||
</div> | |||
<div id="types" class="row"> | |||
<div class="col-3"> | |||
<button type="button" class="btn btn-block btn-sm px-0" | |||
<button id="lowercase__btn" | |||
type="button" class="btn btn-block btn-sm px-0" | |||
v-bind:class="{'btn-primary':password.lowercase===true && password.version===2,'btn-warning':password.lowercase===true && password.version===1,'btn-secondary':password.lowercase===false}" | |||
v-on:click="password.lowercase=!password.lowercase"> | |||
a-z | |||
</button> | |||
</div> | |||
<div class="col-3"> | |||
<button type="button" class="btn btn-block btn-sm px-0" | |||
<button id="uppercase__btn" | |||
type="button" class="btn btn-block btn-sm px-0" | |||
v-bind:class="{'btn-primary':password.uppercase===true && password.version===2,'btn-warning':password.uppercase===true && password.version===1,'btn-secondary':password.uppercase===false}" | |||
v-on:click="password.uppercase=!password.uppercase"> | |||
A-Z | |||
</button> | |||
</div> | |||
<div class="col-3"> | |||
<button type="button" class="btn btn-block btn-sm px-0" | |||
<button id="numbers__btn" | |||
type="button" class="btn btn-block btn-sm px-0" | |||
v-bind:class="{'btn-primary':password.numbers===true && password.version===2,'btn-warning':password.numbers===true && password.version===1,'btn-secondary':password.numbers===false}" | |||
v-on:click="password.numbers=!password.numbers"> | |||
0-9 | |||
</button> | |||
</div> | |||
<div class="col-3"> | |||
<button type="button" class="btn btn-block btn-sm px-0" | |||
<button id="symbols__btn" | |||
type="button" class="btn btn-block btn-sm px-0" | |||
v-bind:class="{'btn-primary':password.symbols===true && password.version===2,'btn-warning':password.symbols===true && password.version===1,'btn-secondary':password.symbols===false}" | |||
v-on:click="password.symbols=!password.symbols"> | |||
%!@ | |||
@@ -55,7 +59,7 @@ | |||
<label for="passwordLength">{{ $t('Length') }}</label> | |||
<div class="input-group input-group-sm"> | |||
<span class="input-group-btn" v-on:click="password.length=decrement(password.length, {min: 5, max: 35})"> | |||
<button class="btn btn-secondary p-1" type="button"> | |||
<button id="decreaseLength__btn" class="btn btn-secondary p-1" type="button"> | |||
<i class="fa fa-minus"></i> | |||
</button> | |||
</span> | |||
@@ -67,7 +71,7 @@ | |||
v-model.number="password.length"> | |||
<span class="input-group-btn" | |||
v-on:click="password.length=increment(password.length, {min: 5, max: 35})"> | |||
<button class="btn btn-secondary p-1" type="button"> | |||
<button id="increaseLength__btn" class="btn btn-secondary p-1" type="button"> | |||
<i class="fa fa-plus"></i> | |||
</button> | |||
</span> | |||
@@ -80,7 +84,7 @@ | |||
{{$t('Counter')}} | |||
</label> | |||
<div class="input-group input-group-sm"> | |||
<span class="input-group-btn" v-on:click="password.counter=decrement(password.counter, {min: 1})"> | |||
<span id="decreaseCounter__btn" class="input-group-btn" v-on:click="password.counter=decrement(password.counter, {min: 1})"> | |||
<button class="btn btn-secondary p-1" type="button"> | |||
<i class="fa fa-minus"></i> | |||
</button> | |||
@@ -90,7 +94,7 @@ | |||
type="number" | |||
min="1" | |||
v-model.number="password.counter"> | |||
<span class="input-group-btn" v-on:click="password.counter=increment(password.counter, {min: 1})"> | |||
<span id="increaseCounter__btn" class="input-group-btn" v-on:click="password.counter=increment(password.counter, {min: 1})"> | |||
<button class="btn btn-secondary p-1" type="button"> | |||
<i class="fa fa-plus"></i> | |||
</button> | |||
@@ -130,7 +134,7 @@ | |||
v-bind:aria-label="$t('DefaultOptionLocalStorage', 'We use local storage to save default options locally. Each time you open the app, these options will be loaded by default.')" | |||
v-bind:class="{'btn-outline-warning':password.version===1,'btn-outline-primary':password.version!==1}" | |||
v-on:click="saveDefaultOptions()"> | |||
<i class="fa fa-floppy-o" aria-hidden="true"></i> {{$t('Save options')}} | |||
<i class="fa fa-floppy-o"></i> {{$t('Save options')}} | |||
</button> | |||
</div> | |||
</div> | |||
@@ -19,7 +19,6 @@ | |||
<i class="fa fa-globe"></i> | |||
<input id="site" | |||
name="site" | |||
type="text" | |||
ref="site" | |||
class="form-control awesomplete" | |||
autocorrect="off" | |||
@@ -35,7 +34,6 @@ | |||
<i class="fa fa-user"></i> | |||
<input id="login" | |||
name="login" | |||
type="text" | |||
ref="login" | |||
class="form-control" | |||
autocomplete="off" | |||
@@ -61,10 +59,10 @@ | |||
{{ $t('Generate') }} | |||
</button> | |||
<button type="button" | |||
class="btn btn-secondary pull-right" | |||
class="btn btn-secondary pull-right showOptions__btn" | |||
v-show="!passwordGenerated" | |||
v-on:click="toggleShowOptions()"> | |||
<i class="fa fa-sliders" aria-hidden="true"></i> | |||
<i class="fa fa-sliders"></i> | |||
</button> | |||
</div> | |||
<div class="btn-group" v-show="passwordGenerated"> | |||
@@ -75,7 +73,7 @@ | |||
type="button" | |||
v-on:click="copyPassword()" | |||
v-bind:class="{ 'btn-warning': password.version===1, 'btn-primary': password.version===2 }"> | |||
<i class="fa fa-clipboard" aria-hidden="true"></i> | |||
<i class="fa fa-clipboard"></i> | |||
</button> | |||
</span> | |||
<input id="generated-password" | |||
@@ -89,7 +87,7 @@ | |||
type="button" | |||
class="btn btn-secondary" | |||
v-on:click="togglePasswordType($refs.passwordGenerated)"> | |||
<i class="fa fa-eye" aria-hidden="true"></i> | |||
<i class="fa fa-eye"></i> | |||
</button> | |||
</span> | |||
<span class="input-group-btn"> | |||
@@ -97,14 +95,14 @@ | |||
type="button" | |||
class="btn btn-secondary" | |||
v-on:click="sharePasswordProfile()"> | |||
<i class="fa fa-share-alt pointer" aria-hidden="true"></i> | |||
<i class="fa fa-share-alt pointer"></i> | |||
</button> | |||
</span> | |||
<span class="input-group-btn"> | |||
<button type="button" | |||
class="btn btn-secondary" | |||
class="btn btn-secondary showOptions__btn" | |||
v-on:click="toggleShowOptions()"> | |||
<i class="fa fa-sliders" aria-hidden="true"></i> | |||
<i class="fa fa-sliders"></i> | |||
</button> | |||
</span> | |||
</div> | |||
@@ -135,16 +133,16 @@ | |||
computed: { | |||
...mapState(['passwords', 'password', 'passwordURL', 'showOptions']), | |||
}, | |||
beforeMount () { | |||
beforeMount() { | |||
this.$store.dispatch('getPasswords'); | |||
this.$store.dispatch('getPasswordFromUrlQuery', {query: this.$route.query}); | |||
}, | |||
mounted(){ | |||
mounted() { | |||
setTimeout(() => { | |||
this.focusBestInputField(); | |||
}, 500); | |||
}, | |||
data(){ | |||
data() { | |||
return { | |||
masterPassword: '', | |||
fingerprint: '', | |||
@@ -184,21 +182,21 @@ | |||
} | |||
}, | |||
methods: { | |||
toggleShowOptions(){ | |||
toggleShowOptions() { | |||
this.$store.dispatch('toggleShowOptions'); | |||
}, | |||
togglePasswordType(element){ | |||
togglePasswordType(element) { | |||
if (element.type === 'password') { | |||
element.type = 'text'; | |||
} else { | |||
element.type = 'password'; | |||
} | |||
}, | |||
cleanErrors(){ | |||
cleanErrors() { | |||
clearTimeout(this.cleanTimeout); | |||
this.passwordGenerated = ''; | |||
}, | |||
cleanFormInSeconds(seconds = 15){ | |||
cleanFormInSeconds(seconds = 15) { | |||
clearTimeout(this.cleanTimeout); | |||
this.cleanTimeout = setTimeout(() => { | |||
this.masterPassword = ''; | |||
@@ -206,7 +204,7 @@ | |||
this.fingerprint = ''; | |||
}, 1000 * seconds); | |||
}, | |||
generatePassword(){ | |||
generatePassword() { | |||
const site = this.password.site; | |||
const login = this.password.login; | |||
const masterPassword = this.masterPassword; | |||
@@ -233,13 +231,13 @@ | |||
this.$store.dispatch('passwordGenerated'); | |||
}); | |||
}, | |||
focusBestInputField(){ | |||
focusBestInputField() { | |||
const site = this.$refs.site; | |||
const login = this.$refs.login; | |||
const masterPassword = this.$refs.masterPassword.$refs.passwordField; | |||
site.value ? (login.value ? masterPassword.focus() : login.focus()) : site.focus(); | |||
}, | |||
copyPassword(){ | |||
copyPassword() { | |||
const copied = copy(this.passwordGenerated); | |||
if (copied) { | |||
showTooltip(document.getElementById('copyPasswordButton'), this.$t('Copied', 'copied !')); | |||
@@ -250,7 +248,7 @@ | |||
message.warning(this.$t('SorryCopy', 'We are sorry the copy only works on modern browsers')) | |||
} | |||
}, | |||
sharePasswordProfile(){ | |||
sharePasswordProfile() { | |||
const copied = copy(this.passwordURL); | |||
if (copied) { | |||
const copySuccessMessage = this.$t('PasswordProfileCopied', 'Your password profile has been copied'); | |||
@@ -1,5 +1,18 @@ | |||
var assert = require("assert"); | |||
function clickAndAssertOption(browser, button, password1, password2) { | |||
browser | |||
.waitForElementVisible(button) | |||
.click(button) | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", password1) | |||
.click(button) | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", password2); | |||
} | |||
module.exports = { | |||
"Password generation tests": function(browser) { | |||
browser | |||
@@ -14,8 +27,56 @@ module.exports = { | |||
.waitForElementVisible("#generatePassword__btn") | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", "hjV@\\5ULp3bIs,6B") | |||
.click(".showOptions__btn") | |||
.waitForElementVisible("#decreaseLength__btn") | |||
.click("#decreaseLength__btn") | |||
.assert.value("#passwordLength", "15") | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", "h6j@r\\ULp3!CIs6") | |||
.click("#increaseLength__btn") | |||
.assert.value("#passwordLength", "16") | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", "hjV@\\5ULp3bIs,6B") | |||
.waitForElementVisible("#decreaseCounter__btn") | |||
.click("#increaseCounter__btn") | |||
.assert.value("#passwordCounter", "2") | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", "#wOxv!q;URh:k82(") | |||
.click("#decreaseCounter__btn") | |||
.assert.value("#passwordCounter", "1") | |||
.click("#generatePassword__btn") | |||
.waitForElementVisible("#generated-password") | |||
.assert.value("#generated-password", "hjV@\\5ULp3bIs,6B"); | |||
clickAndAssertOption( | |||
browser, | |||
"#lowercase__btn", | |||
"^>_9>+}OV?[3[_U,", | |||
"hjV@\\5ULp3bIs,6B" | |||
); | |||
clickAndAssertOption( | |||
browser, | |||
"#uppercase__btn", | |||
"^>_9>+}ov?[3[_u,", | |||
"hjV@\\5ULp3bIs,6B" | |||
); | |||
clickAndAssertOption( | |||
browser, | |||
"#numbers__btn", | |||
'jCmMpNy=T."+u^ZQ', | |||
"hjV@\\5ULp3bIs,6B" | |||
); | |||
clickAndAssertOption( | |||
browser, | |||
"#symbols__btn", | |||
"XAwlOl5mtjGSY6PA", | |||
"hjV@\\5ULp3bIs,6B" | |||
); | |||
browser.end(); | |||
} | |||
}; |