diff --git a/cypress/fixtures/profile.json b/cypress/fixtures/profile.json new file mode 100644 index 0000000..b6c355c --- /dev/null +++ b/cypress/fixtures/profile.json @@ -0,0 +1,5 @@ +{ + "id": 8739, + "name": "Jane", + "email": "jane@example.com" +} \ No newline at end of file diff --git a/cypress/fixtures/users.json b/cypress/fixtures/users.json new file mode 100644 index 0000000..79b699a --- /dev/null +++ b/cypress/fixtures/users.json @@ -0,0 +1,232 @@ +[ + { + "id": 1, + "name": "Leanne Graham", + "username": "Bret", + "email": "Sincere@april.biz", + "address": { + "street": "Kulas Light", + "suite": "Apt. 556", + "city": "Gwenborough", + "zipcode": "92998-3874", + "geo": { + "lat": "-37.3159", + "lng": "81.1496" + } + }, + "phone": "1-770-736-8031 x56442", + "website": "hildegard.org", + "company": { + "name": "Romaguera-Crona", + "catchPhrase": "Multi-layered client-server neural-net", + "bs": "harness real-time e-markets" + } + }, + { + "id": 2, + "name": "Ervin Howell", + "username": "Antonette", + "email": "Shanna@melissa.tv", + "address": { + "street": "Victor Plains", + "suite": "Suite 879", + "city": "Wisokyburgh", + "zipcode": "90566-7771", + "geo": { + "lat": "-43.9509", + "lng": "-34.4618" + } + }, + "phone": "010-692-6593 x09125", + "website": "anastasia.net", + "company": { + "name": "Deckow-Crist", + "catchPhrase": "Proactive didactic contingency", + "bs": "synergize scalable supply-chains" + } + }, + { + "id": 3, + "name": "Clementine Bauch", + "username": "Samantha", + "email": "Nathan@yesenia.net", + "address": { + "street": "Douglas Extension", + "suite": "Suite 847", + "city": "McKenziehaven", + "zipcode": "59590-4157", + "geo": { + "lat": "-68.6102", + "lng": "-47.0653" + } + }, + "phone": "1-463-123-4447", + "website": "ramiro.info", + "company": { + "name": "Romaguera-Jacobson", + "catchPhrase": "Face to face bifurcated interface", + "bs": "e-enable strategic applications" + } + }, + { + "id": 4, + "name": "Patricia Lebsack", + "username": "Karianne", + "email": "Julianne.OConner@kory.org", + "address": { + "street": "Hoeger Mall", + "suite": "Apt. 692", + "city": "South Elvis", + "zipcode": "53919-4257", + "geo": { + "lat": "29.4572", + "lng": "-164.2990" + } + }, + "phone": "493-170-9623 x156", + "website": "kale.biz", + "company": { + "name": "Robel-Corkery", + "catchPhrase": "Multi-tiered zero tolerance productivity", + "bs": "transition cutting-edge web services" + } + }, + { + "id": 5, + "name": "Chelsey Dietrich", + "username": "Kamren", + "email": "Lucio_Hettinger@annie.ca", + "address": { + "street": "Skiles Walks", + "suite": "Suite 351", + "city": "Roscoeview", + "zipcode": "33263", + "geo": { + "lat": "-31.8129", + "lng": "62.5342" + } + }, + "phone": "(254)954-1289", + "website": "demarco.info", + "company": { + "name": "Keebler LLC", + "catchPhrase": "User-centric fault-tolerant solution", + "bs": "revolutionize end-to-end systems" + } + }, + { + "id": 6, + "name": "Mrs. Dennis Schulist", + "username": "Leopoldo_Corkery", + "email": "Karley_Dach@jasper.info", + "address": { + "street": "Norberto Crossing", + "suite": "Apt. 950", + "city": "South Christy", + "zipcode": "23505-1337", + "geo": { + "lat": "-71.4197", + "lng": "71.7478" + } + }, + "phone": "1-477-935-8478 x6430", + "website": "ola.org", + "company": { + "name": "Considine-Lockman", + "catchPhrase": "Synchronised bottom-line interface", + "bs": "e-enable innovative applications" + } + }, + { + "id": 7, + "name": "Kurtis Weissnat", + "username": "Elwyn.Skiles", + "email": "Telly.Hoeger@billy.biz", + "address": { + "street": "Rex Trail", + "suite": "Suite 280", + "city": "Howemouth", + "zipcode": "58804-1099", + "geo": { + "lat": "24.8918", + "lng": "21.8984" + } + }, + "phone": "210.067.6132", + "website": "elvis.io", + "company": { + "name": "Johns Group", + "catchPhrase": "Configurable multimedia task-force", + "bs": "generate enterprise e-tailers" + } + }, + { + "id": 8, + "name": "Nicholas Runolfsdottir V", + "username": "Maxime_Nienow", + "email": "Sherwood@rosamond.me", + "address": { + "street": "Ellsworth Summit", + "suite": "Suite 729", + "city": "Aliyaview", + "zipcode": "45169", + "geo": { + "lat": "-14.3990", + "lng": "-120.7677" + } + }, + "phone": "586.493.6943 x140", + "website": "jacynthe.com", + "company": { + "name": "Abernathy Group", + "catchPhrase": "Implemented secondary concept", + "bs": "e-enable extensible e-tailers" + } + }, + { + "id": 9, + "name": "Glenna Reichert", + "username": "Delphine", + "email": "Chaim_McDermott@dana.io", + "address": { + "street": "Dayna Park", + "suite": "Suite 449", + "city": "Bartholomebury", + "zipcode": "76495-3109", + "geo": { + "lat": "24.6463", + "lng": "-168.8889" + } + }, + "phone": "(775)976-6794 x41206", + "website": "conrad.com", + "company": { + "name": "Yost and Sons", + "catchPhrase": "Switchable contextually-based project", + "bs": "aggregate real-time technologies" + } + }, + { + "id": 10, + "name": "Clementina DuBuque", + "username": "Moriah.Stanton", + "email": "Rey.Padberg@karina.biz", + "address": { + "street": "Kattie Turnpike", + "suite": "Suite 198", + "city": "Lebsackbury", + "zipcode": "31428-2261", + "geo": { + "lat": "-38.2386", + "lng": "57.2232" + } + }, + "phone": "024-648-3804", + "website": "ambrose.net", + "company": { + "name": "Hoeger LLC", + "catchPhrase": "Centralized empowering task-force", + "bs": "target end-to-end models" + } + } +] \ No newline at end of file diff --git a/cypress/integration/examples/pages/app/login.spec.js b/cypress/integration/examples/pages/app/login.spec.js index 598ece0..f234927 100644 --- a/cypress/integration/examples/pages/app/login.spec.js +++ b/cypress/integration/examples/pages/app/login.spec.js @@ -1,14 +1,30 @@ /// +import LoginScreenPageObject from '../../../../../src/components/screens/app/LoginScreen/LoginScreen.pageObject'; + describe('/pages/app/login/', () => { - it('preencha os campos e vá para a página /app/profile', () => { - cy.visit('/app/login/'); + describe('when fill and submit a form login request', () => { + it('go to the profile page', () => { + // Pré Teste + cy.intercept('https://instalura-api-git-master-omariosouto.vercel.app') + .as('userLogin'); - cy.get('#formCadastro input[name="usuario"]').type('diogo05'); - cy.get('#formCadastro input[name="senha"]').type('diogo05'); + // Cenário + const loginScreen = new LoginScreenPageObject(cy); + loginScreen + .fillLoginForm({ user: 'diogo05', password: 'diogo05' }) + .submitLoginForm(); - cy.get('#formCadastro button[type="submit"]').click(); + // Asserções + cy.url().should('include', '/app/profile'); - cy.url().should('include', '/app/profile'); + cy.wait('@userLogin') + .then((intercept) => { + const { token } = intercept.response.body.data; + cy.getCookie('APP_TOKEN') + .should('exist') + .should('have.property', 'value', token); + }); + }); }); }); diff --git a/cypress/screenshots/examples/cypress_api.spec.js/Cypress.config() -- Get and set configuration options (failed).png b/cypress/screenshots/examples/cypress_api.spec.js/Cypress.config() -- Get and set configuration options (failed).png new file mode 100644 index 0000000..4cb646d Binary files /dev/null and b/cypress/screenshots/examples/cypress_api.spec.js/Cypress.config() -- Get and set configuration options (failed).png differ diff --git a/cypress/screenshots/examples/misc.spec.js/my-image.png b/cypress/screenshots/examples/misc.spec.js/my-image.png new file mode 100644 index 0000000..34500d6 Binary files /dev/null and b/cypress/screenshots/examples/misc.spec.js/my-image.png differ diff --git a/cypress/screenshots/examples/network_requests.spec.js/Network Requests -- cy.request() - make an XHR request (failed).png b/cypress/screenshots/examples/network_requests.spec.js/Network Requests -- cy.request() - make an XHR request (failed).png new file mode 100644 index 0000000..4fa364b Binary files /dev/null and b/cypress/screenshots/examples/network_requests.spec.js/Network Requests -- cy.request() - make an XHR request (failed).png differ diff --git a/cypress/screenshots/examples/network_requests.spec.js/Network Requests -- cy.request() - verify response using BDD syntax (failed).png b/cypress/screenshots/examples/network_requests.spec.js/Network Requests -- cy.request() - verify response using BDD syntax (failed).png new file mode 100644 index 0000000..e74dbc9 Binary files /dev/null and b/cypress/screenshots/examples/network_requests.spec.js/Network Requests -- cy.request() - verify response using BDD syntax (failed).png differ diff --git a/cypress/screenshots/examples/pages/app/login.spec.js/pagesapplogin -- when fill and submit a form login request -- go to the profile page (failed).png b/cypress/screenshots/examples/pages/app/login.spec.js/pagesapplogin -- when fill and submit a form login request -- go to the profile page (failed).png new file mode 100644 index 0000000..a8f0162 Binary files /dev/null and b/cypress/screenshots/examples/pages/app/login.spec.js/pagesapplogin -- when fill and submit a form login request -- go to the profile page (failed).png differ diff --git a/package-lock.json b/package-lock.json index 959e08f..fb4e59c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "framer-motion": "^3.7.0", "lodash": "^4.17.20", "next": "latest", + "nookies": "^2.5.2", "prop-types": "^15.7.2", "react": "^16.8.0", "react-dom": "^16.8.0", @@ -2712,6 +2713,14 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -7457,6 +7466,15 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==" }, + "node_modules/nookies": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/nookies/-/nookies-2.5.2.tgz", + "integrity": "sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA==", + "dependencies": { + "cookie": "^0.4.1", + "set-cookie-parser": "^2.4.6" + } + }, "node_modules/noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -8837,6 +8855,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "optional": true }, + "node_modules/set-cookie-parser": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", + "integrity": "sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==" + }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -12803,6 +12826,11 @@ } } }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -16509,6 +16537,15 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==" }, + "nookies": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/nookies/-/nookies-2.5.2.tgz", + "integrity": "sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA==", + "requires": { + "cookie": "^0.4.1", + "set-cookie-parser": "^2.4.6" + } + }, "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -17572,6 +17609,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "optional": true }, + "set-cookie-parser": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", + "integrity": "sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==" + }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", diff --git a/package.json b/package.json index 7098458..0a29dc7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "start": "next start", "lint": "eslint --ignore-path .gitignore .", "commit": "cz", - "test:integration:open": "cypress open" + "test:integration:open": "cypress open", + "test:integration": "cypress run --headless" }, "dependencies": { "@commitlint/cli": "^12.0.1", @@ -19,6 +20,7 @@ "framer-motion": "^3.7.0", "lodash": "^4.17.20", "next": "latest", + "nookies": "^2.5.2", "prop-types": "^15.7.2", "react": "^16.8.0", "react-dom": "^16.8.0", diff --git a/src/components/screens/app/LoginScreen/LoginScreen.pageObject.js b/src/components/screens/app/LoginScreen/LoginScreen.pageObject.js new file mode 100644 index 0000000..cad9ba9 --- /dev/null +++ b/src/components/screens/app/LoginScreen/LoginScreen.pageObject.js @@ -0,0 +1,20 @@ +export default class LoginScreenPageObject { + constructor(cy) { + this.cy = cy; + + this.cy.visit('/app/login'); + } + + fillLoginForm({ user, password }) { + this.cy.get('#formCadastro input[name="usuario"]').type(user); + this.cy.get('#formCadastro input[name="senha"]').type(password); + + return this; + } + + submitLoginForm() { + this.cy.get('#formCadastro button[type="submit"]').click(); + + return this; + } +} diff --git a/src/infra/env/isStagingEnv.js b/src/infra/env/isStagingEnv.js new file mode 100644 index 0000000..1d0d96d --- /dev/null +++ b/src/infra/env/isStagingEnv.js @@ -0,0 +1,5 @@ +const isServer = typeof window === 'undefined'; + +export const isStagingEnv = isServer + ? process.env.NODE_ENV === 'development' + : globalThis.location.href.includes('localhost'); diff --git a/src/services/login/loginService.js b/src/services/login/loginService.js index ba2ed09..58728b1 100644 --- a/src/services/login/loginService.js +++ b/src/services/login/loginService.js @@ -1,3 +1,6 @@ +import { setCookie, destroyCookie } from 'nookies'; +import { isStagingEnv } from '../../infra/env/isStagingEnv'; + async function HttpClient(url, { headers, body, ...options }) { return fetch(url, { headers: { @@ -11,20 +14,39 @@ async function HttpClient(url, { headers, body, ...options }) { if (respostaDoServer.ok) { return respostaDoServer.json(); } - throw new Error('Falha em pegar os dados do servidor :('); }); } +const BASE_URL = isStagingEnv + // Back End de DEV + ? 'https://instalura-api-git-master-omariosouto.vercel.app' +// Back End de PROD + : 'https://instalura-api.omariosouto.vercel.app'; + export const loginService = { async login({ username, password }) { - return HttpClient('https://instalura-api.omariosouto.vercel.app/api/login', { + return HttpClient(`${BASE_URL}/api/login`, { method: 'POST', body: { - username, - password, + username, // 'omariosouto' + password, // 'senhasegura' }, }) - .then((respostaConvertida) => respostaConvertida); + .then((respostaConvertida) => { + const { token } = respostaConvertida.data; + const DAY_IN_SECONDS = 86400; + // Salvar o Token + setCookie(null, 'APP_TOKEN', token, { + path: '/', + maxAge: DAY_IN_SECONDS * 7, + }); + return { + token, + }; + }); + }, + logout() { + destroyCookie(null, 'APP_TOKEN'); }, };