Add new tests for login (#1580)

* always run critical

* tests for login

* tests for login
This commit is contained in:
Karolina Rakoczy 2021-12-05 16:03:29 +01:00 committed by GitHub
parent b7da933bf2
commit e2c05e7dd6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 159 additions and 19 deletions

View file

@ -69,3 +69,44 @@ jobs:
with:
name: cypress-videos
path: cypress/videos
cypress-run-critical:
if: github.event.pull_request.head.repo.full_name == 'saleor/saleor-dashboard' && ((github.event.label.name != 'run e2e') || !(contains(github.event.pull_request.labels.*.name, 'run e2e')))
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Get API_URI
id: api_uri
# Search for CYPRESS_API_URI in PR description and use default if not defined
env:
pull_request_body: ${{ github.event.pull_request.body }}
prefix: CYPRESS_API_URI=
pattern: (http|https)://[a-zA-Z0-9.-]+/graphql/?
fallback_uri: ${{ secrets.CYPRESS_API_URI }}
run: |
echo "::set-output name=custom_api_uri::$(echo $pull_request_body | grep -Eo "$prefix$pattern" | sed s/$prefix// | head -n 1 | { read custom_uri; if [ -z "$custom_uri" ]; then echo "$fallback_uri"; else echo "$custom_uri"; fi })"
- name: Cypress run critical
if: ${{ steps.api_uri.outputs.custom_api_uri != 'https://qa.staging.saleor.cloud/graphql/' }}
uses: cypress-io/github-action@v2
env:
API_URI: ${{ steps.api_uri.outputs.custom_api_uri }}
APP_MOUNT_URI: ${{ secrets.APP_MOUNT_URI }}
CYPRESS_baseUrl: ${{ secrets.CYPRESS_BASEURL }}
CYPRESS_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
CYPRESS_SECOND_USER_NAME: ${{ secrets.CYPRESS_SECOND_USER_NAME }}
CYPRESS_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
CYPRESS_PERMISSIONS_USERS_PASSWORD: ${{ secrets.CYPRESS_PERMISSIONS_USERS_PASSWORD }}
with:
build: npm run build
start: npx local-web-server --spa index.html
wait-on: http://localhost:9000/
wait-on-timeout: 120
command: npm run cy:run:critical
- uses: actions/upload-artifact@v1
if: ${{ failure() }}
with:
name: cypress-videos
path: cypress/videos

View file

@ -5,5 +5,8 @@ export const LOGIN_SELECTORS = {
signInButton: "[data-test=submit]",
userMenu: "[data-test=userMenu]",
warningCredentialMessage: "[data-test=loginErrorMessage]",
welcomePage: "[data-test=welcomeHeader]"
welcomePage: "[data-test=welcomeHeader]",
logOutButton: "[data-test='logOutButton']",
resetPasswordLink: "[data-test-id='reset-password-link']",
confirmPassword: "[name='confirmPassword']"
};

View file

@ -17,7 +17,10 @@ import {
deleteChannelsStartsWith,
getDefaultChannel
} from "../../../support/api/utils/channelsUtils";
import { getMailsForUser } from "../../../support/api/utils/users";
import {
getMailActivationLinkForUserAndSubject,
getMailsForUser
} from "../../../support/api/utils/users";
import filterTests from "../../../support/filterTests";
filterTests({ definedTags: ["stagedOnly"], version: "3.1.1" }, () => {
@ -76,10 +79,13 @@ filterTests({ definedTags: ["stagedOnly"], version: "3.1.1" }, () => {
.confirmationMessageShouldDisappear();
requestPasswordReset(Cypress.env("USER_NAME"), defaultChannel.slug)
.then(() => {
getMailsForUser(customerEmail);
getMailActivationLinkForUserAndSubject(
Cypress.env("USER_NAME"),
randomName
);
})
.then(mails => {
expect(mails[0].Content.Headers.Subject[0]).to.eq(randomName);
.then(link => {
expect(link).to.be.ok;
});
});
});

View file

@ -14,7 +14,7 @@ filterTests({ definedTags: ["all"] }, () => {
it("should successfully log in an user", () => {
cy.visit(urlList.homePage);
cy.loginUser();
cy.get(LOGIN_SELECTORS.welcomePage);
cy.get(LOGIN_SELECTORS.welcomePage).should("be.visible");
});
it("should fail for wrong password", () => {
@ -25,20 +25,20 @@ filterTests({ definedTags: ["all"] }, () => {
.type("wrong-password")
.get(LOGIN_SELECTORS.signInButton)
.click()
.get(LOGIN_SELECTORS.warningCredentialMessage);
.get(LOGIN_SELECTORS.warningCredentialMessage)
.should("be.visible");
});
it("should successfully log out an user", () => {
cy.window().then(win => {
win.sessionStorage.clear();
});
cy.visit(urlList.homePage);
cy.loginUser();
cy.get(LOGIN_SELECTORS.userMenu)
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.homePage)
.get(LOGIN_SELECTORS.userMenu)
.click()
.get(LOGIN_SELECTORS.accountSettings)
.click();
cy.location("pathname").should("contains", "/staff/");
.get(LOGIN_SELECTORS.logOutButton)
.click()
.get(LOGIN_SELECTORS.emailAddressInput)
.should("be.visible");
});
});
});

View file

@ -4,16 +4,19 @@
import faker from "faker";
import { LEFT_MENU_SELECTORS } from "../elements/account/left-menu/left-menu-selectors";
import { LOGIN_SELECTORS } from "../elements/account/login-selectors";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import { STAFF_MEMBER_DETAILS } from "../elements/staffMembers/staffMemberDetails";
import { STAFF_MEMBERS_LIST } from "../elements/staffMembers/staffMembersList";
import { urlList, userDetailsUrl } from "../fixtures/urlList";
import { updatePlugin } from "../support/api/requests/Plugins";
import {
deleteStaffMembersStartsWith,
updateStaffMember
} from "../support/api/requests/StaffMembers";
import {
getMailActivationLinkForUser,
getMailActivationLinkForUserAndSubject,
inviteStaffMemberWithFirstPermission
} from "../support/api/utils/users";
import filterTests from "../support/filterTests";
@ -115,5 +118,37 @@ filterTests({ definedTags: ["stagedOnly"] }, () => {
);
});
});
it("should reset password", () => {
const newPassword = faker.random.alphaNumeric(8);
updatePlugin(
"mirumee.notifications.admin_email",
"staff_password_reset_subject",
"Reset"
)
.then(() => {
cy.clearSessionData()
.visit(urlList.homePage)
.get(LOGIN_SELECTORS.resetPasswordLink)
.click()
.get(LOGIN_SELECTORS.emailAddressInput)
.type(email)
.get(BUTTON_SELECTORS.submit)
.click();
getMailActivationLinkForUserAndSubject(email, "Reset");
})
.then(link => {
cy.visit(link)
.get(LOGIN_SELECTORS.emailPasswordInput)
.type(newPassword)
.get(LOGIN_SELECTORS.confirmPassword)
.type(newPassword)
.get(BUTTON_SELECTORS.confirm)
.click()
.get(LOGIN_SELECTORS.welcomePage)
.should("be.visible")
.loginUserViaRequest({ email, password: newPassword });
});
});
});
});

View file

@ -0,0 +1,16 @@
export function updatePlugin(id, name, value) {
const mutation = `mutation{
pluginUpdate(id:"${id}", input:{
configuration:{
name:"${name}"
value:"${value}"
}
}){
errors{
field
message
}
}
}`;
return cy.sendRequestWithQuery(mutation);
}

View file

@ -44,6 +44,40 @@ export function getMailActivationLinkForUser(email, i = 0) {
});
}
export function getMailActivationLinkForUserAndSubject(email, subject, i = 0) {
if (i > 3) {
throw new Error(`There is no email invitation for user ${email}`);
}
return cy.mhGetMailsByRecipient(email).should(mails => {
if (!mails.length) {
cy.wait(10000);
getMailActivationLinkForUserAndSubject(email, subject, i + 1);
} else {
cy.wrap(mails)
.mhGetMailsBySubject(subject)
.should(mailsWithSubject => {
if (!mailsWithSubject.length) {
cy.wait(10000);
getMailActivationLinkForUserAndSubject(email, subject, i + 1);
} else {
cy.wrap(mailsWithSubject)
.mhFirst()
.should("not.eq", undefined)
.mhGetBody()
.then(body => {
const urlRegex = /\[([^\]]*)\]/;
const bodyWithoutWhiteSpaces = body.replace(
/(\r\n|\n|\r|\s)/gm,
""
);
return urlRegex.exec(bodyWithoutWhiteSpaces)[1];
});
}
});
}
});
}
export function getMailsForUser(email, i = 0) {
if (i > 3) {
throw new Error(`There is no email invitation for user ${email}`);
@ -51,9 +85,9 @@ export function getMailsForUser(email, i = 0) {
return cy.mhGetMailsByRecipient(email).should(mails => {
if (!mails.length) {
cy.wait(10000);
getEmailForUser(email, i + 1);
getMailsForUser(email, i + 1);
} else {
return mails[0].Content.Headers.Subject[0];
return mails;
}
});
}

View file

@ -150,7 +150,11 @@ const LoginCard: React.FC<LoginCardProps> = props => {
description="description"
values={{
resetPasswordLink: (
<a className={classes.link} onClick={onPasswordRecovery}>
<a
className={classes.link}
onClick={onPasswordRecovery}
data-test-id="reset-password-link"
>
<FormattedMessage
defaultMessage="Use this link to recover it"
description="link"

View file

@ -71,6 +71,7 @@ const ResetPasswordPage: React.FC<ResetPasswordPageProps> = props => {
/>
<FormSpacer />
<Button
data-test="submit"
className={classes.submit}
color="primary"
disabled={disabled}