Browse Source

Changes options and fix e2e tests

Fixes #587
Option are not good in term of accessibility, so use checkbox instead.
Fix test using Cypress 6
pull/599/head
Guillaume Vincent 3 years ago
parent
commit
1111a8021b
8 changed files with 872 additions and 103 deletions
  1. +11
    -5
      packages/lesspass-pure/cypress/integration/connectedMode.spec.js
  2. +1
    -2
      packages/lesspass-pure/cypress/integration/index.spec.js
  3. +10
    -4
      packages/lesspass-pure/cypress/integration/passwordGeneration.spec.js
  4. +33
    -17
      packages/lesspass-pure/cypress/integration/settings.spec.js
  5. +3
    -0
      packages/lesspass-pure/package.json
  6. +70
    -40
      packages/lesspass-pure/src/components/Options.vue
  7. +26
    -7
      packages/lesspass-pure/src/views/PasswordGenerator.vue
  8. +718
    -28
      packages/lesspass-pure/yarn.lock

+ 11
- 5
packages/lesspass-pure/cypress/integration/connectedMode.spec.js View File

@@ -17,10 +17,12 @@ describe("Connected Mode", function() {
cy.get("#generatePassword__btn").click();
cy.get("#generated-password").should("have.value", "hjV@\\5ULp3bIs,6B");
cy.get(".fa-save").should("be.visible");
cy.get(".fa-user").first().click();
cy.get(".fa-user")
.first()
.click();
cy.get("#signOutButton").should("be.visible");
cy.get("#signOutButton").click();
cy.get(".fa-save").should("not.be.visible");
cy.get(".fa-save").should('not.exist');
});
it("can log in and log out", function() {
cy.visit("/");
@@ -34,9 +36,11 @@ describe("Connected Mode", function() {
cy.get("#signInButton").click();
cy.get("#siteField").should("be.visible");
cy.get(".fa-key").should("be.visible");
cy.get(".fa-user").first().click();
cy.get(".fa-user")
.first()
.click();
cy.get("#signOutButton").click();
cy.get(".fa-key").should("not.be.visible");
cy.get(".fa-key").should('not.exist');
});
it("reset password page", function() {
cy.visit("/");
@@ -61,7 +65,9 @@ describe("Connected Mode", function() {
.click();
cy.get("#siteField").should("have.value", "example.org");
cy.get("#login").should("have.value", "contact@example.org");
cy.get(".fa-user").first().click();
cy.get(".fa-user")
.first()
.click();
cy.get("#signOutButton").click();
});
});

+ 1
- 2
packages/lesspass-pure/cypress/integration/index.spec.js View File

@@ -6,7 +6,6 @@ describe("LessPass", function() {
it("should focus site field", function() {
cy.visit("/");
cy.wait(500);
cy.focused()
.should('have.id', 'siteField')
cy.focused().should("have.id", "siteField");
});
});

+ 10
- 4
packages/lesspass-pure/cypress/integration/passwordGeneration.spec.js View File

@@ -18,7 +18,9 @@ describe("Password Generation", function() {

cy.visit("/");
cy.wait(500);
cy.get("#siteField").type("lesspass.com").tab();
cy.get("#siteField")
.type("lesspass.com")
.tab();
cy.get("#login").type("test@lesspass.com");
cy.get("#passwordField").type("test@lesspass.com");
cy.wait(500);
@@ -98,7 +100,9 @@ describe("Password Generation", function() {
it("should generate password when hit enter nrt_266", function() {
cy.visit("/");
cy.wait(500);
cy.get("#siteField").type("lesspass.com").tab();
cy.get("#siteField")
.type("lesspass.com")
.tab();
cy.get("#login").type("test@lesspass.com");
cy.get("#passwordField")
.type("test@lesspass.com")
@@ -124,13 +128,15 @@ describe("Password Generation", function() {
it("should clear password generated when master password change", function() {
cy.visit("/");
cy.wait(500);
cy.get("#siteField").type("example.org").tab();
cy.get("#siteField")
.type("example.org")
.tab();
cy.get("#login").type("user");
cy.get("#passwordField").type("password");
cy.get("#generatePassword__btn").should("be.visible");
cy.get("#generatePassword__btn").click();
cy.get("#copyPasswordButton").should("be.visible");
cy.get("#generatePassword__btn").should("not.be.visible");
cy.get("#generatePassword__btn").should("not.exist");
cy.get("#passwordField").type("password");
cy.get("#copyPasswordButton").should("not.be.visible");
cy.get("#generatePassword__btn").should("be.visible");


+ 33
- 17
packages/lesspass-pure/cypress/integration/settings.spec.js View File

@@ -7,21 +7,35 @@ const getLength = () => cy.get("#options #passwordLength");
const getCounter = () => cy.get("#options #passwordCounter");

function editSettings() {
getLogin().clear().type("New login");
getLowercase().click().should("have.class", "btn-secondary");
getUppercase().click().should("have.class", "btn-secondary");
getNumbers().click().should("have.class", "btn-secondary");
getSymbols().click().should("have.class", "btn-secondary");
getLength().clear().type("5");
getCounter().clear().type("2");
getLogin()
.clear()
.type("New login");
getLowercase()
.click()
.should("not.be.checked");
getUppercase()
.click()
.should("not.be.checked");
getNumbers()
.click()
.should("not.be.checked");
getSymbols()
.click()
.should("not.be.checked");
getLength()
.clear()
.type("5");
getCounter()
.clear()
.type("2");
}

function checkSettingsEdited() {
getLogin().should("have.value", "New login");
getLowercase().should("have.class", "btn-secondary");
getUppercase().should("have.class", "btn-secondary");
getNumbers().should("have.class", "btn-secondary");
getSymbols().should("have.class", "btn-secondary");
getLowercase().should("not.be.checked");
getUppercase().should("not.be.checked");
getNumbers().should("not.be.checked");
getSymbols().should("not.be.checked");
getLength().should("have.value", "5");
getCounter().should("have.value", "2");
}
@@ -31,10 +45,10 @@ describe("Settings", function() {
cy.visit("/#/settings");
cy.wait(500);
getLogin().should("have.value", "");
getLowercase().should("have.class", "btn-primary");
getUppercase().should("have.class", "btn-primary");
getNumbers().should("have.class", "btn-primary");
getSymbols().should("have.class", "btn-primary");
getLowercase().should("be.checked");
getUppercase().should("be.checked");
getNumbers().should("be.checked");
getSymbols().should("be.checked");
getLength().should("have.value", "16");
getCounter().should("have.value", "1");
});
@@ -43,7 +57,9 @@ describe("Settings", function() {
cy.visit("/#/settings");
cy.wait(500);
cy.get("#btn-submit-settings").click();
cy.location("pathname").should("be", "/");
cy.location().should(location => {
expect(location.pathname).to.eq("/");
});
});

it("should pass on the settings to the password generator page after save", () => {
@@ -62,5 +78,5 @@ describe("Settings", function() {
cy.visit("/#/settings");
cy.wait(500);
checkSettingsEdited();
})
});
});

+ 3
- 0
packages/lesspass-pure/package.json View File

@@ -58,9 +58,12 @@
"@vue/test-utils": "^1.1.3",
"axios-mock-adapter": "^1.19.0",
"babel-core": "7.0.0-bridge.0",
"cypress": "^6.8.0",
"cypress-plugin-tab": "^1.0.5",
"jest": "^26.6.3",
"jquery": "^3.6.0",
"popper.js": "^1.16.1",
"start-server-and-test": "^1.12.1",
"vue-jest": "^3.0.7",
"vue-polyglot-utils": "^0.1.1",
"vue-template-compiler": "^2.6.12",


+ 70
- 40
packages/lesspass-pure/src/components/Options.vue View File

@@ -15,56 +15,72 @@
<div class="col-12">
<div class="row">
<div class="col">
<label for="types">{{ $t('Options') }}</label>
<label for="types">{{ $t("Options") }}</label>
</div>
</div>
<div id="types" class="row">
<div class="col-3">
<button
id="lowercase__btn"
type="button"
class="btn btn-block btn-sm px-0"
tabindex="1"
v-bind:class="{'btn-primary':options.lowercase===true, 'btn-secondary':options.lowercase===false}"
v-on:click="options.lowercase=!options.lowercase"
>a-z</button>
<div class="form-check">
<input
id="lowercase__btn"
type="checkbox"
tabindex="1"
class="form-check-input"
v-model="options.lowercase"
/>
<label class="form-check-label" for="lowercase__btn">
a-z
</label>
</div>
</div>
<div class="col-3">
<button
id="uppercase__btn"
type="button"
class="btn btn-block btn-sm px-0"
tabindex="1"
v-bind:class="{'btn-primary':options.uppercase===true, 'btn-secondary':options.uppercase===false}"
v-on:click="options.uppercase=!options.uppercase"
>A-Z</button>
<div class="form-check">
<input
id="uppercase__btn"
type="checkbox"
tabindex="1"
class="form-check-input"
v-model="options.uppercase"
/>
<label class="form-check-label" for="uppercase__btn">
A-Z
</label>
</div>
</div>
<div class="col-3">
<button
id="numbers__btn"
type="button"
class="btn btn-block btn-sm px-0"
tabindex="1"
v-bind:class="{'btn-primary':options.numbers===true,'btn-secondary':options.numbers===false}"
v-on:click="options.numbers=!options.numbers"
>0-9</button>
<div class="form-check">
<input
id="numbers__btn"
type="checkbox"
tabindex="1"
class="form-check-input"
v-model="options.numbers"
/>
<label class="form-check-label" for="numbers__btn">
0-9
</label>
</div>
</div>
<div class="col-3">
<button
id="symbols__btn"
type="button"
class="btn btn-block btn-sm px-0"
tabindex="1"
v-bind:class="{'btn-primary':options.symbols===true,'btn-secondary':options.symbols===false}"
v-on:click="options.symbols=!options.symbols"
>%!@</button>
<div class="form-check">
<input
id="symbols__btn"
type="checkbox"
tabindex="1"
class="form-check-input"
v-model="options.symbols"
/>
<label class="form-check-label" for="symbols__btn">
%!@
</label>
</div>
</div>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-5 col-sm-4">
<label for="passwordLength">{{ $t('Length') }}</label>
<label for="passwordLength">{{ $t("Length") }}</label>
<div class="input-group input-group-sm">
<span class="input-group-btn">
<button
@@ -72,7 +88,9 @@
class="btn btn-primary btn-sm px-2"
tabindex="1"
type="button"
v-on:click="options.length=decrement(options.length, {min: 5, max: 35})"
v-on:click="
options.length = decrement(options.length, { min: 5, max: 35 })
"
>
<small>
<i class="fa fa-minus"></i>
@@ -94,7 +112,9 @@
class="btn btn-primary btn-sm px-2"
tabindex="1"
type="button"
v-on:click="options.length=increment(options.length, {min: 5, max: 35})"
v-on:click="
options.length = increment(options.length, { min: 5, max: 35 })
"
>
<small>
<i class="fa fa-plus"></i>
@@ -107,9 +127,15 @@
<label
for="passwordCounter"
data-balloon-length="large"
v-bind:data-balloon="$t('CounterFieldHelp', 'Increment this value to change the generated password without changing your master options.')"
v-bind:data-balloon="
$t(
'CounterFieldHelp',
'Increment this value to change the generated password without changing your master options.'
)
"
data-balloon-pos="up"
>{{$t('Counter')}}</label>
>{{ $t("Counter") }}</label
>
<div class="input-group input-group-sm">
<span class="input-group-btn">
<button
@@ -117,7 +143,9 @@
class="btn btn-primary btn-sm px-2"
tabindex="1"
type="button"
v-on:click="options.counter=decrement(options.counter, {min: 1})"
v-on:click="
options.counter = decrement(options.counter, { min: 1 })
"
>
<small>
<i class="fa fa-minus"></i>
@@ -138,7 +166,9 @@
class="btn btn-primary btn-sm px-2"
tabindex="1"
type="button"
v-on:click="options.counter=increment(options.counter, {min: 1})"
v-on:click="
options.counter = increment(options.counter, { min: 1 })
"
>
<small>
<i class="fa fa-plus"></i>


+ 26
- 7
packages/lesspass-pure/src/views/PasswordGenerator.vue View File

@@ -12,7 +12,11 @@ div.awesomplete > ul {
}
</style>
<template>
<form id="password-generator" v-on:submit.prevent="generatePassword" novalidate>
<form
id="password-generator"
v-on:submit.prevent="generatePassword"
novalidate
>
<div class="form-group">
<input-site
ref="site"
@@ -25,7 +29,7 @@ div.awesomplete > ul {
</div>
<remove-auto-complete></remove-auto-complete>
<div class="form-group">
<label for="login" class="sr-only">{{ $t('Username') }}</label>
<label for="login" class="sr-only">{{ $t("Username") }}</label>
<div class="inner-addon left-addon">
<i class="fa fa-user"></i>
<input
@@ -59,7 +63,9 @@ div.awesomplete > ul {
tabindex="0"
class="btn btn-primary btn-block"
v-if="!passwordGenerated"
>{{ $t('Generate') }}</button>
>
{{ $t("Generate") }}
</button>
<div class="input-group" v-show="passwordGenerated">
<span class="input-group-btn">
<button
@@ -198,6 +204,19 @@ export default {
);
return;
}
const lowercase = this.password.lowercase;
const uppercase = this.password.uppercase;
const numbers = this.password.numbers;
const symbols = this.password.symbols;
if (!lowercase && !uppercase && !numbers && !symbols) {
message.error(
this.$t(
"AtLeastOneOptionShouldBeSelected",
"You must select at least one option among lowercase, uppercase, numbers or symbols."
)
);
return;
}
const length = this.password.length;
if (length > 35) {
message.warning(
@@ -209,10 +228,10 @@ export default {
}
this.cleanErrors();
const passwordProfile = {
lowercase: this.password.lowercase,
uppercase: this.password.uppercase,
numbers: this.password.numbers,
symbols: this.password.symbols,
lowercase,
uppercase,
numbers,
symbols,
length: this.password.length,
counter: this.password.counter,
version: this.password.version


+ 718
- 28
packages/lesspass-pure/yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save