diff --git a/cypress.config.ts b/cypress.config.ts index 22755f9..d4a396c 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -7,7 +7,7 @@ export default defineConfig({ viewportWidth: 1920, viewportHeight: 1080, defaultCommandTimeout: 4000, - retries: { runMode: 1, openMode: 1 }, + retries: { runMode: 1, openMode: 0 }, scrollBehavior: 'center', setupNodeEvents(on, config) { // implement node event listeners here diff --git a/cypress/e2e/api/api.spec.js b/cypress/e2e/api/api.spec.js new file mode 100644 index 0000000..e22d88c --- /dev/null +++ b/cypress/e2e/api/api.spec.js @@ -0,0 +1,46 @@ +describe('API Tests', () => { + const baseUrl = 'https://jsonplaceholder.typicode.com'; + + it('should get a post by id', () => { + cy.request(`${baseUrl}/posts/1`) + .its('status') + .should('eq', 200); + }); + + it('should get a list of posts', () => { + cy.request(`${baseUrl}/posts`) + .its('status') + .should('eq', 200); + cy.request(`${baseUrl}/posts`) + .its('body') + .should('not.be.empty') + }); + + it('should create a new post', () => { + const newPost = { + title: 'New Post', + body: 'This is a new post.', + userId: 1 + }; + cy.request('POST', `${baseUrl}/posts`, newPost) + .its('status') + .should('eq', 201); + }); + + it('should update a post by id', () => { + const updatedPost = { + title: 'Updated Post', + body: 'This post has been updated.', + userId: 1 + }; + cy.request('PUT', `${baseUrl}/posts/1`, updatedPost) + .its('status') + .should('eq', 200); + }); + + it('should delete a post by id', () => { + cy.request('DELETE', `${baseUrl}/posts/1`) + .its('status') + .should('eq', 200); + }); +}); \ No newline at end of file diff --git a/cypress/e2e/auth/login.spec.js b/cypress/e2e/auth/login.spec.js new file mode 100644 index 0000000..cdd8abd --- /dev/null +++ b/cypress/e2e/auth/login.spec.js @@ -0,0 +1,11 @@ +import AuthPage from "../../page-Objects/AuthTab.js"; + +const authPage = new AuthPage(); + +describe("Auth page functionality", () => { + it("Login to dashboard", () => { + cy.visit("/auth/login"); + authPage.login(); + cy.url({timeout: 6000}).should("contains", "/pages/dashboard") + }); + }); \ No newline at end of file diff --git a/cypress/e2e/modal-and-overlays/dialog.spec.js b/cypress/e2e/modal-and-overlays/dialog.spec.js new file mode 100644 index 0000000..f4233e4 --- /dev/null +++ b/cypress/e2e/modal-and-overlays/dialog.spec.js @@ -0,0 +1,14 @@ +describe("Dialog page functionality", () => { + it("Opening 'Enter your name' modal window", () => { + cy.visit("/pages/modal-overlays/dialog"); + cy.get(".result-from-dialog").find("button").click(); + cy.get(".ng-star-inserted > nb-card") + .should("be.visible") + .within(() => { + cy.get("nb-card-header").should("contain", "Enter your name"); + cy.get("nb-card-body > .size-medium").should("exist"); + cy.get(".cancel").should("be.visible"); + cy.get(".status-success").should("be.visible"); + }); + }); + }); \ No newline at end of file diff --git a/cypress/e2e/stepper/stepperHomework.spec.js b/cypress/e2e/stepper/stepperHomework.spec.js new file mode 100644 index 0000000..78de184 --- /dev/null +++ b/cypress/e2e/stepper/stepperHomework.spec.js @@ -0,0 +1,13 @@ +describe("stepper functionality", () => { + it("after click on next button moves to following step", () => { + const stepperSelector = ".col-lg-12 > nb-card-body"; + cy.visit("/pages/layout/stepper"); + cy.get(`${stepperSelector} h3`).contains("Step content #1"); + cy.get(`${stepperSelector} button`).contains("next").click(); + cy.get(`${stepperSelector} h3`).contains("Step content #2"); + cy.get(`${stepperSelector} button`).contains("next").click(); + cy.get(`${stepperSelector} h3`).contains("Step content #3"); + cy.get(`${stepperSelector} button`).contains("next").click(); + cy.get(`${stepperSelector} h3`).contains("Step content #4"); + }); + }); \ No newline at end of file diff --git a/cypress/e2e/tables-and-data/smart-tables.spec.js b/cypress/e2e/tables-and-data/smart-tables.spec.js new file mode 100644 index 0000000..aa28b0a --- /dev/null +++ b/cypress/e2e/tables-and-data/smart-tables.spec.js @@ -0,0 +1,54 @@ +import SmartTablePage from "../../page-Objects/SmartTablePage.js"; +import { faker } from '@faker-js/faker'; + +const smartTablePage = new SmartTablePage(); + +describe("Smart tables functionality", () => { + beforeEach(() => { + cy.visit("pages/tables/smart-table"); + }); + + it("Creates new user and checks if it's added to the table", () => { + cy.get(".ng2-smart-actions-title").should("be.visible").click(); + + const user = { + id: faker.number.int(), + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + username: faker.internet.userName(), + email: faker.internet.email(), + age: faker.number.int({ min: 18, max: 100 }) + }; + + smartTablePage.createUser(user); + smartTablePage.filterCreatedUser(user); + cy.get("tbody") + .should("be.visible") + .within(() => { + cy.get(".ng2-smart-row").should("have.length", 1); + smartTablePage.verifyCreatedUserData(user); + }); + }); + + it("Creates new user, edits it and checks if edited values are added to the table", () => { + cy.get(".ng2-smart-actions-title").should("be.visible").click(); + + const user = { + id: faker.number.int(), + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + username: faker.internet.userName(), + email: faker.internet.email(), + age: faker.number.int({ min: 18, max: 100 }) + }; + + smartTablePage.createUser(user); + smartTablePage.filterCreatedUser(user); + smartTablePage.verifyCreatedUserData(user); + cy.wait(1000); + cy.get(".nb-edit").click(); + smartTablePage.clearEditFields(); + const editedUser = smartTablePage.editUser(user); + smartTablePage.verifyEditedUserData(editedUser); + }); +}); \ No newline at end of file diff --git a/cypress/page-Objects/AuthPage.js b/cypress/page-Objects/AuthPage.js new file mode 100644 index 0000000..a98dfd8 --- /dev/null +++ b/cypress/page-Objects/AuthPage.js @@ -0,0 +1,12 @@ +import { faker } from '@faker-js/faker'; + +class AuthPage { + login() { + cy.get('#input-email').type("somerandomemail@gmail.com"); + cy.get('#input-password').type("12345678"); + cy.get('.custom-checkbox').click(); + cy.get('.appearance-filled').click(); + } +} + +export default AuthPage; \ No newline at end of file diff --git a/cypress/page-Objects/SmartTablePage.js b/cypress/page-Objects/SmartTablePage.js new file mode 100644 index 0000000..506c64d --- /dev/null +++ b/cypress/page-Objects/SmartTablePage.js @@ -0,0 +1,75 @@ +import { faker } from '@faker-js/faker'; + +class SmartTablePage { + createUser(user) { + cy.get('[ng2-st-thead-form-row=""] > :nth-child(2)').should("be.visible").type(user.id.toString()); + cy.get('[ng2-st-thead-form-row=""] > :nth-child(3)').should("be.visible").type(user.firstName); + cy.get('[ng2-st-thead-form-row=""] > :nth-child(4)').should("be.visible").type(user.lastName); + cy.get('[ng2-st-thead-form-row=""] > :nth-child(5)').should("be.visible").type(user.username); + cy.get('[ng2-st-thead-form-row=""] > :nth-child(6)').should("be.visible").type(user.email); + cy.get('[ng2-st-thead-form-row=""] > :nth-child(7)').should("be.visible").type(user.age.toString()); + cy.get('.nb-checkmark').click(); + } + + filterCreatedUser(user) { + cy.get('.ng2-smart-filters > .id').should("be.visible").type(user.id.toString()); + cy.get('.ng2-smart-filters > .firstName').should("be.visible").type(user.firstName); + cy.get('.ng2-smart-filters > .lastName').should("be.visible").type(user.lastName); + cy.get('.ng2-smart-filters > .username').should("be.visible").type(user.username); + cy.get('.ng2-smart-filters > .email').should("be.visible").type(user.email); + cy.get('.ng2-smart-filters > .age').should("be.visible").type(user.age.toString()); + } + + verifyCreatedUserData(newUser) { + cy.get(".ng2-smart-row").should("have.length", 1); + cy.get(':nth-child(2)').should("contain.text", newUser.id); + cy.get(':nth-child(3)').should("contain.text", newUser.firstName); + cy.get(':nth-child(4)').should("contain.text", newUser.lastName); + cy.get(':nth-child(5)').should("contain.text", newUser.username); + cy.get(':nth-child(6)').should("contain.text", newUser.email); + cy.get(':nth-child(7)').should("contain.text", newUser.age); + } + + clearEditFields() { + cy.get('[ng-reflect-name="id"]').clear(); + cy.get('[ng-reflect-name="firstName"]').clear(); + cy.get('[ng-reflect-name="lastName"]').clear(); + cy.get('[ng-reflect-name="username"]').clear(); + cy.get('[ng-reflect-name="email"]').clear(); + cy.get('[ng-reflect-name="age"]').clear(); + } + + editUser(user) { + const editedUser = { + editedId: "edited" + user.id, + editedFirstName: "edited" + user.firstName, + editedLastName: "edited" + user.lastName, + editedUsername: "edited" + user.username, + editedEmail: "edited" + user.email, + editedAge: "edited" + user.age + }; + + cy.get('[ng-reflect-name="id"]').type(editedUser.editedId); + cy.get('[ng-reflect-name="firstName"]').type(editedUser.editedFirstName); + cy.get('[ng-reflect-name="lastName"]').type(editedUser.editedLastName); + cy.get('[ng-reflect-name="username"]').type(editedUser.editedUsername); + cy.get('[ng-reflect-name="email"]').type(editedUser.editedEmail); + cy.get('[ng-reflect-name="age"]').type(editedUser.editedAge); + + cy.get('.ng2-smart-action-edit-save').click(); + + return editedUser; + } + + verifyEditedUserData(user) { + cy.get('.ng2-smart-row > :nth-child(2)').should("contain.text", user.editedId); + cy.get('.ng2-smart-row > :nth-child(3)').should("contain.text", user.editedFirstName); + cy.get('.ng2-smart-row > :nth-child(4)').should("contain.text", user.editedLastName); + cy.get('.ng2-smart-row > :nth-child(5)').should("contain.text", user.editedUsername); + cy.get('.ng2-smart-row > :nth-child(6)').should("contain.text", user.editedEmail); + cy.get('.ng2-smart-row > :nth-child(7)').should("contain.text", user.editedAge); + } + +} + +export default SmartTablePage; \ No newline at end of file diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 698b01a..eb0288e 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -34,4 +34,4 @@ // visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable // } // } -// } \ No newline at end of file +// } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 963a157..01cc535 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@angular/platform-browser-dynamic": "^15.2.10", "@angular/router": "^15.2.10", "@asymmetrik/ngx-leaflet": "3.0.1", + "@faker-js/faker": "^8.4.1", "@nebular/auth": "11.0.1", "@nebular/eva-icons": "11.0.1", "@nebular/security": "11.0.1", @@ -34,6 +35,7 @@ "core-js": "2.5.1", "echarts": "^4.9.0", "eva-icons": "^1.1.3", + "faker": "^6.6.6", "intl": "1.2.5", "ionicons": "2.0.1", "leaflet": "1.2.0", @@ -76,7 +78,7 @@ "@typescript-eslint/parser": "^5.43.0", "codelyzer": "^6.0.2", "conventional-changelog-cli": "1.3.4", - "cypress": "^13.6.6", + "cypress": "^13.7.0", "eslint": "^8.28.0", "husky": "0.13.3", "jasmine-core": "~3.6.0", @@ -6601,6 +6603,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@faker-js/faker": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.4.1.tgz", + "integrity": "sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=6.14.13" + } + }, "node_modules/@fortawesome/fontawesome-free": { "version": "5.15.4", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", @@ -12274,9 +12291,9 @@ "dev": true }, "node_modules/cypress": { - "version": "13.6.6", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.6.tgz", - "integrity": "sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.7.0.tgz", + "integrity": "sha512-UimjRSJJYdTlvkChcdcfywKJ6tUYuwYuk/n1uMMglrvi+ZthNhoRYcxnWgTqUtkl17fXrPAsD5XT2rcQYN1xKA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -14830,6 +14847,11 @@ "node >=0.6.0" ] }, + "node_modules/faker": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/faker/-/faker-6.6.6.tgz", + "integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==" + }, "node_modules/fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", diff --git a/package.json b/package.json index a1fc57d..faeb326 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@angular/platform-browser-dynamic": "^15.2.10", "@angular/router": "^15.2.10", "@asymmetrik/ngx-leaflet": "3.0.1", + "@faker-js/faker": "^8.4.1", "@nebular/auth": "11.0.1", "@nebular/eva-icons": "11.0.1", "@nebular/security": "11.0.1", @@ -55,6 +56,7 @@ "core-js": "2.5.1", "echarts": "^4.9.0", "eva-icons": "^1.1.3", + "faker": "^6.6.6", "intl": "1.2.5", "ionicons": "2.0.1", "leaflet": "1.2.0", @@ -97,7 +99,7 @@ "@typescript-eslint/parser": "^5.43.0", "codelyzer": "^6.0.2", "conventional-changelog-cli": "1.3.4", - "cypress": "^13.6.6", + "cypress": "^13.7.0", "eslint": "^8.28.0", "husky": "0.13.3", "jasmine-core": "~3.6.0",