diff --git a/cypress/e2e/article.cy.js b/cypress/e2e/article.cy.js index e1ef839b..b0354cd7 100644 --- a/cypress/e2e/article.cy.js +++ b/cypress/e2e/article.cy.js @@ -1,24 +1,72 @@ /// /// +import { faker } from '@faker-js/faker'; +import ArticlePageObject from "../support/pages/article.pageObject"; + +const articlePage = new ArticlePageObject(); + describe('Article', () => { - before(() => { + let user; + const articleTitle = faker.lorem.sentence(); + const articleDesc = faker.lorem.sentences(2); + const articleBody = faker.lorem.sentences(5); + const articleTag = faker.lorem.word(); + before(() => { + cy.task('generateUser').then((generateUser) => { + user = generateUser; + }); }); beforeEach(() => { cy.task('db:clear'); + cy.visit('/'); + cy.register(); + cy.login(); + articlePage.visit(); }); it('should be created using New Article form', () => { + articlePage.typeArticleTitle(articleTitle); + articlePage.typeArticleDesc(articleDesc); + articlePage.typeArticleBody(articleBody); + articlePage.typeArticleTags(articleTag); + + articlePage.clickPublishBtn(); + articlePage.verifyArticleCreation(articleTitle); }); it('should be edited using Edit button', () => { + articlePage.typeArticleTitle(articleTitle); + articlePage.typeArticleDesc(articleDesc); + articlePage.typeArticleBody(articleBody); + articlePage.typeArticleTags(articleTag); + + articlePage.clickPublishBtn(); + articlePage.clickEditArticleBtn(); + + articlePage.typeArticleTitle(articleTitle); + articlePage.typeArticleDesc(articleDesc); + articlePage.typeArticleBody(articleBody); + + articlePage.clickPublishBtn(); + + articlePage.verifyArticleCreation(articleTitle); }); it('should be deleted using Delete button', () => { + articlePage.typeArticleTitle(articleTitle); + articlePage.typeArticleDesc(articleDesc); + articlePage.typeArticleBody(articleBody); + articlePage.typeArticleTags(articleTag); + + articlePage.clickPublishBtn(); + + articlePage.clickDeleteArticleBtn(); + articlePage.verifyDeletedArticle(); }); }); diff --git a/cypress/e2e/settings.cy.js b/cypress/e2e/settings.cy.js index e9208789..2e16faf9 100644 --- a/cypress/e2e/settings.cy.js +++ b/cypress/e2e/settings.cy.js @@ -1,32 +1,50 @@ /// /// +import SettingsPageObject from '../support/pages/settings.pageObject'; + +const settingsPage = new SettingsPageObject(); + describe('Settings page', () => { - before(() => { + let user; + before(() => { + cy.task('generateUser').then((generateUser) => { + user = generateUser; + }); }); beforeEach(() => { - + cy.task('db:clear'); + cy.visit('/'); + cy.register(); + cy.login(); + settingsPage.visit(); }); it('should provide an ability to update username', () => { - + settingsPage.editUsername(user.username); + settingsPage.submitEdit(); + settingsPage.verifyProfilePage(user.username); }); it('should provide an ability to update bio', () => { - + settingsPage.editBio(user.bio); + settingsPage.submitEdit(); }); it('should provide an ability to update an email', () => { - + settingsPage.editEmail(user.email); + settingsPage.submitEdit(); }); it('should provide an ability to update password', () => { - + settingsPage.editPassword(user.password); + settingsPage.submitEdit(); }); it('should provide an ability to log out', () => { - + settingsPage.logoutUser(); + settingsPage.verifyLogout(); }); }); diff --git a/cypress/e2e/signIn.cy.js b/cypress/e2e/signIn.cy.js index 3ae60e04..6517618f 100644 --- a/cypress/e2e/signIn.cy.js +++ b/cypress/e2e/signIn.cy.js @@ -9,6 +9,8 @@ const homePage = new HomePageObject(); describe('Sign In page', () => { let user; + const wrongEmail = 'rodionmail.com'; + const wrongPassword = 'password'; before(() => { cy.task('db:clear'); @@ -17,6 +19,10 @@ describe('Sign In page', () => { }); }); + beforeEach(() => { + signInPage.visit(); + }); + it('should provide an ability to log in with existing credentials', () => { signInPage.visit(); cy.register(user.email, user.username, user.password); @@ -28,7 +34,21 @@ describe('Sign In page', () => { homePage.assertHeaderContainUsername(user.username); }); - it('should not provide an ability to log in with wrong credentials', () => { + it('shouldn\'t provide an ability to log in with wrong email', () => { + signInPage.typeEmail(wrongEmail); + signInPage.typePassword(user.password); + + signInPage.clickSignInBtn(); + + signInPage.assertLoginFailed(); + }); + + it('shouldn\'t provide an ability to log in with wrong password', () => { + signInPage.typeEmail(user.email); + signInPage.typePassword(wrongPassword); + + signInPage.clickSignInBtn(); + signInPage.assertLoginFailed(); }); }); diff --git a/cypress/e2e/signUp.cy.js b/cypress/e2e/signUp.cy.js index ccf57970..af0035f1 100644 --- a/cypress/e2e/signUp.cy.js +++ b/cypress/e2e/signUp.cy.js @@ -1,12 +1,66 @@ /// /// +import HomePageObject from "../support/pages/home.pageObject"; +import SignUpPageObject from "../support/pages/signUp.pageObject"; + +const homePage = new HomePageObject(); +const signUpPage = new SignUpPageObject(); + describe('Sign Up page', () => { + let user; + const wrongUsername = 'rodion'; + const wrongEmail = 'rodionmail.com'; + const wrongPassword = 'password'; + before(() => { + cy.task('db:clear'); + cy.task('generateUser').then((generateUser) => { + user = generateUser; + }); + }); + beforeEach(() => { + signUpPage.visit(); }); - it('should ...', () => { + it('should provide an ability to sign up with valid credentials', () => { + signUpPage.typeUsername(user.username); + signUpPage.typeEmail(user.email); + signUpPage.typePassword(user.password); + + signUpPage.clickSignUpBtn(); + + homePage.assertHeaderContainUsername(user.username); + }); + + it('shouldn\'t provide an ability to sign up with wrong username', () => { + signUpPage.typeUsername(wrongUsername); + signUpPage.typeEmail(user.email); + signUpPage.typePassword(user.password); + + signUpPage.clickSignUpBtn(); + + signUpPage.assertSignUpFailed(); + }); + + it('shouldn\'t provide an ability to sign up with wrong email', () => { + signUpPage.typeUsername(user.username); + signUpPage.typeEmail(wrongEmail); + signUpPage.typePassword(user.password); + + signUpPage.clickSignUpBtn(); + + signUpPage.assertSignUpFailed(); + }); + + it('shouldn\'t provide an ability to sign up with wrong password', () => { + signUpPage.typeUsername(user.username); + signUpPage.typeEmail(user.email); + signUpPage.typePassword(wrongPassword); + + signUpPage.clickSignUpBtn(); + signUpPage.assertSignUpFailed(); }); }); diff --git a/cypress/e2e/user.cy.js b/cypress/e2e/user.cy.js index 012f6fa7..1e2a0104 100644 --- a/cypress/e2e/user.cy.js +++ b/cypress/e2e/user.cy.js @@ -2,11 +2,29 @@ /// describe('User', () => { + let user; + before(() => { + cy.task('generateUser').then((generateUser) => { + user = generateUser; + }); + }); + beforeEach(() => { + cy.task('db:clear'); + cy.visit('/'); + cy.register(); + cy.login(); }); - it.skip('should be able to follow the another user', () => { + it('should be able to follow/unfollow the another user', () => { + cy.visit('#/@riot'); + cy.get('.btn.btn-sm.btn-outline-secondary.action-btn').click(); + + cy.get('.btn').should('contain', 'Unfollow'); + + cy.get('.btn.btn-sm.btn-outline-secondary.action-btn').click(); + cy.get('.btn').should('contain', 'Follow'); }); }); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 40634fe9..5b604c0d 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -32,10 +32,33 @@ Cypress.Commands.add('getByDataCy', (selector) => { cy.get(`[data-cy="${selector}"]`); }); -Cypress.Commands.add('register', (email = 'riot@qa.team', username = 'riot', password = '12345Qwert!') => { - cy.request('POST', '/users', { - email, - username, - password +Cypress.Commands.add('register', + (email = 'riot@qa.team', username = 'riot', password = '12345Qwert!') => { + cy.request('POST', '/users', { + email, + username, + password + }); + }); + +Cypress.Commands.add('login', + (email = 'riot@qa.team', username = 'riot', password = '12345Qwert!') => { + cy.request('POST', '/api/users', { + user: { + email, + username, + password + } + }).then(response => { + const user = { + bio: response.body.user.bio, + effectiveImage: "https://static.productionready.io/images/smiley-cyrus.jpg", + email: response.body.user.email, + image: response.body.user.image, + token: response.body.user.token, + username: response.body.user.username + }; + window.localStorage.setItem('user', JSON.stringify(user)); + cy.setCookie('auth', response.body.user.token); + }); }); -}); diff --git a/cypress/support/pages/article.pageObject.js b/cypress/support/pages/article.pageObject.js new file mode 100644 index 00000000..45403f9f --- /dev/null +++ b/cypress/support/pages/article.pageObject.js @@ -0,0 +1,79 @@ +import PageObject from "../PageObject"; + +class ArticlePageObject extends PageObject { + url = '#/editor'; + + get articleTitleField() { + return cy.getByDataCy('article-title-field'); + } + + typeArticleTitle(articleTitle) { + this.articleTitleField.clear().type(articleTitle); + } + + get articleDescField() { + return cy.getByDataCy('article-desc-field'); + } + + typeArticleDesc(articleDesc) { + this.articleDescField.clear().type(articleDesc); + } + + get articleBodyField() { + return cy.getByDataCy('article-body-field'); + } + + typeArticleBody(articleBody) { + this.articleBodyField.clear().type(articleBody); + } + + get articleTagsField() { + return cy.getByDataCy('article-tags-field'); + } + + typeArticleTags(articleTag) { + this.articleTagsField.clear().type(`${articleTag}{enter}`); + } + + get publishBtn() { + return cy.getByDataCy('article-publish-btn'); + } + + clickPublishBtn() { + this.publishBtn.click(); + } + + get container() { + return cy.get('.container'); + } + + verifyArticleCreation(articleTitle) { + this.container.should('contain', articleTitle) + .and('contain', 'Delete Article') + .and('contain', 'Edit Article'); + } + + get deleteArticleBtn() { + return cy.getByDataCy('delete-article-btn'); + } + + clickDeleteArticleBtn() { + this.deleteArticleBtn.click(); + } + + verifyDeletedArticle(articleTitle) { + this.container.should('not.contain', articleTitle) + .and('not.contain', 'Delete Article') + .and('not.contain', 'Edit Article'); + } + + get editArticleBtn() { + return cy.getByDataCy('edit-article-btn'); + } + + clickEditArticleBtn() { + this.editArticleBtn.click(); + } +} + +export default ArticlePageObject; diff --git a/cypress/support/pages/settings.pageObject.js b/cypress/support/pages/settings.pageObject.js new file mode 100644 index 00000000..31d21392 --- /dev/null +++ b/cypress/support/pages/settings.pageObject.js @@ -0,0 +1,63 @@ +import PageObject from '../PageObject'; + +class SettingsPageObject extends PageObject { + url = '/settings'; + + get usernameField() { + return cy.getByDataCy('settings-username-field'); + } + + editUsername(username) { + this.usernameField.clear().type(username); + } + + get bioField() { + return cy.getByDataCy('settings-bio-field'); + } + + editBio(bio) { + this.bioField.clear().type(bio); + } + + get emailField() { + return cy.getByDataCy('settings-email-field'); + } + + editEmail(email) { + this.emailField.clear().type(email); + } + + get passwordField() { + return cy.getByDataCy('settings-password-field'); + } + + editPassword(password) { + this.passwordField.clear().type(password); + } + + get submitBtn() { + return cy.getByDataCy('settings-submit-btn'); + } + + submitEdit() { + this.submitBtn.click(); + } + + get logoutBtn() { + return cy.getByDataCy('settings-logout-btn'); + } + + logoutUser() { + this.logoutBtn.click(); + } + + verifyProfilePage(username = 'riot') { + return cy.url().should('contain', `/profile/${username}`); + } + + verifyLogout(username = 'riot') { + return cy.url().should('not.contain', `/profile/${username}`); + } +} + +export default SettingsPageObject; diff --git a/cypress/support/pages/signIn.pageObject.js b/cypress/support/pages/signIn.pageObject.js index 3a1e21c8..7ac5683b 100644 --- a/cypress/support/pages/signIn.pageObject.js +++ b/cypress/support/pages/signIn.pageObject.js @@ -29,6 +29,10 @@ class SignInPageObject extends PageObject { this.signInBtn .click(); } + + assertLoginFailed() { + cy.get('.swal-modal').should('contain', 'Login failed!'); + } } export default SignInPageObject; diff --git a/cypress/support/pages/signUp.pageObject.js b/cypress/support/pages/signUp.pageObject.js new file mode 100644 index 00000000..1154a2ab --- /dev/null +++ b/cypress/support/pages/signUp.pageObject.js @@ -0,0 +1,43 @@ +import PageObject from "../PageObject"; + +class SignUpPageObject extends PageObject { + url = '/#/register'; + + get usernameField() { + return cy.getByDataCy('sign-up-username-field'); + } + + typeUsername(username) { + this.usernameField.clear().type(username); + } + + get emailField() { + return cy.getByDataCy('sign-up-email-field'); + } + + typeEmail(email) { + this.emailField.clear().type(email); + } + + get passwordField() { + return cy.getByDataCy('sign-up-password-field'); + } + + typePassword(password) { + this.passwordField.clear().type(password); + } + + get signUpBtn() { + return cy.getByDataCy('sign-up-btn'); + } + + clickSignUpBtn() { + this.signUpBtn.click(); + } + + assertSignUpFailed() { + cy.get('.swal-modal').should('contain', 'Registration failed!'); + } +} + +export default SignUpPageObject;