Add new tests for login (#1580)
* always run critical * tests for login * tests for login
This commit is contained in:
parent
b7da933bf2
commit
e2c05e7dd6
9 changed files with 159 additions and 19 deletions
41
.github/workflows/e2e.yml
vendored
41
.github/workflows/e2e.yml
vendored
|
@ -69,3 +69,44 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: cypress-videos
|
name: cypress-videos
|
||||||
path: 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
|
||||||
|
|
|
@ -5,5 +5,8 @@ export const LOGIN_SELECTORS = {
|
||||||
signInButton: "[data-test=submit]",
|
signInButton: "[data-test=submit]",
|
||||||
userMenu: "[data-test=userMenu]",
|
userMenu: "[data-test=userMenu]",
|
||||||
warningCredentialMessage: "[data-test=loginErrorMessage]",
|
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']"
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,10 @@ import {
|
||||||
deleteChannelsStartsWith,
|
deleteChannelsStartsWith,
|
||||||
getDefaultChannel
|
getDefaultChannel
|
||||||
} from "../../../support/api/utils/channelsUtils";
|
} 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";
|
import filterTests from "../../../support/filterTests";
|
||||||
|
|
||||||
filterTests({ definedTags: ["stagedOnly"], version: "3.1.1" }, () => {
|
filterTests({ definedTags: ["stagedOnly"], version: "3.1.1" }, () => {
|
||||||
|
@ -76,10 +79,13 @@ filterTests({ definedTags: ["stagedOnly"], version: "3.1.1" }, () => {
|
||||||
.confirmationMessageShouldDisappear();
|
.confirmationMessageShouldDisappear();
|
||||||
requestPasswordReset(Cypress.env("USER_NAME"), defaultChannel.slug)
|
requestPasswordReset(Cypress.env("USER_NAME"), defaultChannel.slug)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
getMailsForUser(customerEmail);
|
getMailActivationLinkForUserAndSubject(
|
||||||
|
Cypress.env("USER_NAME"),
|
||||||
|
randomName
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(mails => {
|
.then(link => {
|
||||||
expect(mails[0].Content.Headers.Subject[0]).to.eq(randomName);
|
expect(link).to.be.ok;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ filterTests({ definedTags: ["all"] }, () => {
|
||||||
it("should successfully log in an user", () => {
|
it("should successfully log in an user", () => {
|
||||||
cy.visit(urlList.homePage);
|
cy.visit(urlList.homePage);
|
||||||
cy.loginUser();
|
cy.loginUser();
|
||||||
cy.get(LOGIN_SELECTORS.welcomePage);
|
cy.get(LOGIN_SELECTORS.welcomePage).should("be.visible");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail for wrong password", () => {
|
it("should fail for wrong password", () => {
|
||||||
|
@ -25,20 +25,20 @@ filterTests({ definedTags: ["all"] }, () => {
|
||||||
.type("wrong-password")
|
.type("wrong-password")
|
||||||
.get(LOGIN_SELECTORS.signInButton)
|
.get(LOGIN_SELECTORS.signInButton)
|
||||||
.click()
|
.click()
|
||||||
.get(LOGIN_SELECTORS.warningCredentialMessage);
|
.get(LOGIN_SELECTORS.warningCredentialMessage)
|
||||||
|
.should("be.visible");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should successfully log out an user", () => {
|
it("should successfully log out an user", () => {
|
||||||
cy.window().then(win => {
|
cy.clearSessionData()
|
||||||
win.sessionStorage.clear();
|
.loginUserViaRequest()
|
||||||
});
|
.visit(urlList.homePage)
|
||||||
cy.visit(urlList.homePage);
|
.get(LOGIN_SELECTORS.userMenu)
|
||||||
cy.loginUser();
|
|
||||||
cy.get(LOGIN_SELECTORS.userMenu)
|
|
||||||
.click()
|
.click()
|
||||||
.get(LOGIN_SELECTORS.accountSettings)
|
.get(LOGIN_SELECTORS.logOutButton)
|
||||||
.click();
|
.click()
|
||||||
cy.location("pathname").should("contains", "/staff/");
|
.get(LOGIN_SELECTORS.emailAddressInput)
|
||||||
|
.should("be.visible");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,16 +4,19 @@
|
||||||
import faker from "faker";
|
import faker from "faker";
|
||||||
|
|
||||||
import { LEFT_MENU_SELECTORS } from "../elements/account/left-menu/left-menu-selectors";
|
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 { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
|
||||||
import { STAFF_MEMBER_DETAILS } from "../elements/staffMembers/staffMemberDetails";
|
import { STAFF_MEMBER_DETAILS } from "../elements/staffMembers/staffMemberDetails";
|
||||||
import { STAFF_MEMBERS_LIST } from "../elements/staffMembers/staffMembersList";
|
import { STAFF_MEMBERS_LIST } from "../elements/staffMembers/staffMembersList";
|
||||||
import { urlList, userDetailsUrl } from "../fixtures/urlList";
|
import { urlList, userDetailsUrl } from "../fixtures/urlList";
|
||||||
|
import { updatePlugin } from "../support/api/requests/Plugins";
|
||||||
import {
|
import {
|
||||||
deleteStaffMembersStartsWith,
|
deleteStaffMembersStartsWith,
|
||||||
updateStaffMember
|
updateStaffMember
|
||||||
} from "../support/api/requests/StaffMembers";
|
} from "../support/api/requests/StaffMembers";
|
||||||
import {
|
import {
|
||||||
getMailActivationLinkForUser,
|
getMailActivationLinkForUser,
|
||||||
|
getMailActivationLinkForUserAndSubject,
|
||||||
inviteStaffMemberWithFirstPermission
|
inviteStaffMemberWithFirstPermission
|
||||||
} from "../support/api/utils/users";
|
} from "../support/api/utils/users";
|
||||||
import filterTests from "../support/filterTests";
|
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 });
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
16
cypress/support/api/requests/Plugins.js
Normal file
16
cypress/support/api/requests/Plugins.js
Normal 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);
|
||||||
|
}
|
|
@ -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) {
|
export function getMailsForUser(email, i = 0) {
|
||||||
if (i > 3) {
|
if (i > 3) {
|
||||||
throw new Error(`There is no email invitation for user ${email}`);
|
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 => {
|
return cy.mhGetMailsByRecipient(email).should(mails => {
|
||||||
if (!mails.length) {
|
if (!mails.length) {
|
||||||
cy.wait(10000);
|
cy.wait(10000);
|
||||||
getEmailForUser(email, i + 1);
|
getMailsForUser(email, i + 1);
|
||||||
} else {
|
} else {
|
||||||
return mails[0].Content.Headers.Subject[0];
|
return mails;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,11 @@ const LoginCard: React.FC<LoginCardProps> = props => {
|
||||||
description="description"
|
description="description"
|
||||||
values={{
|
values={{
|
||||||
resetPasswordLink: (
|
resetPasswordLink: (
|
||||||
<a className={classes.link} onClick={onPasswordRecovery}>
|
<a
|
||||||
|
className={classes.link}
|
||||||
|
onClick={onPasswordRecovery}
|
||||||
|
data-test-id="reset-password-link"
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="Use this link to recover it"
|
defaultMessage="Use this link to recover it"
|
||||||
description="link"
|
description="link"
|
||||||
|
|
|
@ -71,6 +71,7 @@ const ResetPasswordPage: React.FC<ResetPasswordPageProps> = props => {
|
||||||
/>
|
/>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<Button
|
<Button
|
||||||
|
data-test="submit"
|
||||||
className={classes.submit}
|
className={classes.submit}
|
||||||
color="primary"
|
color="primary"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
Loading…
Reference in a new issue