From 7c7ea5972e0d03778cf54ea077e96a87ffb4b928 Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Thu, 8 Feb 2024 10:43:25 -0600 Subject: [PATCH 01/10] correct the customApiIntercept `loading` case `req.reply()` was not returning an empty response, it was returning the actual response from the server. this led to the "loading" state being present momentarily before the actual response was returned. we are now forcing the loading state to remain, as the mock intends. --- cypress/support/commands.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cypress/support/commands.js b/cypress/support/commands.js index dcf2c9a3..d2f3d9ff 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -23,6 +23,7 @@ // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) + import { scientistApiBaseURL } from './e2e' // add a command to login that uses a session, so the user will remain logged in throughout the test file vs. needing to log in before each example. @@ -44,10 +45,10 @@ Cypress.Commands.add('login', (username, password) => { Cypress.Commands.add('customApiIntercept', ({ action, alias, data, defaultFixture, emptyFixture, error, errorCaseStatusCode, loading, requestURL }) => { - cy.intercept(action, scientistApiBaseURL + requestURL, (req) => { + cy.intercept(action, `${scientistApiBaseURL}${requestURL}`, (req) => { switch (true) { // reply with an empty response: both data and error will be undefined. - case loading: req.reply() + case loading: req.reply({}) break // error will be defined @@ -66,4 +67,4 @@ Cypress.Commands.add('customApiIntercept', ({ break } }).as(alias || 'customIntercept') -}) \ No newline at end of file +}) From f9d4eae97e304ef9bedd9e1ad16295338650238a Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Thu, 8 Feb 2024 10:50:35 -0600 Subject: [PATCH 02/10] fix the first home spec made the cypress config file more dynamic. it also will allow us to correctly intercept api calls in our `customApiIntercept` command. update the "featured services list is loading" test check that we in fact have 3 placeholder items, as the description states. --- cypress.config.js | 11 ++++++++--- cypress/e2e/home.cy.js | 11 ++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 529841c3..3ff5cbdc 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -23,12 +23,17 @@ module.exports = defineConfig({ env: { TEST_SCIENTIST_USER: 'test@test.com', TEST_SCIENTIST_PW: '!test1234', - NEXT_PUBLIC_PROVIDER_NAME: 'acme', - NEXT_PUBLIC_PROVIDER_ID: '572' + NEXT_PUBLIC_PROVIDER_NAME: process.env.NEXT_PUBLIC_PROVIDER_NAME, + NEXT_PUBLIC_PROVIDER_ID: process.env.NEXT_PUBLIC_PROVIDER_ID, + NEXT_PUBLIC_TOKEN: process.env.NEXT_PUBLIC_TOKEN, + // importing the `API_PER_PAGE` variable from the constants file throws + // errors since this file doesn't follow ES6 syntax. if the value is + // changed in constants, it needs to be updated here too + API_PER_PAGE: 2000, }, reporter: 'junit', reporterOptions: { mochaFile: 'cypress/results/results-[hash].xml', toConsole: true, }, -}); +}) diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index cff47a0a..5d97967f 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -5,11 +5,10 @@ describe('Viewing Home page', () => { let featuredServices beforeEach(() => { - // Intercept the response from the endpoint to view all requests cy.customApiIntercept({ action: 'GET', alias: 'useAllWares', - requestURL: `/providers/${Cypress.env('NEXT_PUBLIC_PROVIDER_ID')}/wares.json`, + requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}`, data: featuredServices, defaultFixture: 'services/wares.json', emptyFixture: 'services/no-wares.json', @@ -19,13 +18,11 @@ describe('Viewing Home page', () => { cy.visit('/') }) - context('featured services list is loading', () => { - before(() => { - loading = true - }) + before(() => loading = true) + it('should show 3 placeholder cards loading', () => { - cy.get('p.placeholder-glow').should('be.visible').then(() => { + cy.get('p.placeholder-glow').should('have.length', 3).then(() => { cy.log('Loading text displays correctly.') }) }) From 940b731ef061bd95ea77471e1b89c9d71de908b4 Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Thu, 8 Feb 2024 13:11:06 -0600 Subject: [PATCH 03/10] refactor the home page specs changed up the specs to fit the flow of the home page. also moving two specs from the browse page to the home page since that's where the requests originate from. --- cypress.config.js | 1 + cypress/e2e/browse.cy.js | 41 ++--------------- cypress/e2e/home.cy.js | 95 +++++++++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 68 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 3ff5cbdc..736d283e 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -26,6 +26,7 @@ module.exports = defineConfig({ NEXT_PUBLIC_PROVIDER_NAME: process.env.NEXT_PUBLIC_PROVIDER_NAME, NEXT_PUBLIC_PROVIDER_ID: process.env.NEXT_PUBLIC_PROVIDER_ID, NEXT_PUBLIC_TOKEN: process.env.NEXT_PUBLIC_TOKEN, + CYPRESS_SEARCH_QUERY: 'test', // importing the `API_PER_PAGE` variable from the constants file throws // errors since this file doesn't follow ES6 syntax. if the value is // changed in constants, it needs to be updated here too diff --git a/cypress/e2e/browse.cy.js b/cypress/e2e/browse.cy.js index dd0e64f0..aee53206 100644 --- a/cypress/e2e/browse.cy.js +++ b/cypress/e2e/browse.cy.js @@ -19,10 +19,10 @@ describe('Browsing', () => { emptyFixture: 'services/no-wares.json', }, ] - + beforeEach(() => { // Intercept the responses from the endpoint to view all requests. - // Even though this is to the same endpoint, the call happens on each page twice, + // Even though this is to the same endpoint, the call happens on each page twice, // once when the page loads with all the wares, and again after any search is performed. // this makes it necessary to create an intercept for each time the call is made. intercepts.forEach((intercept) => { @@ -103,39 +103,4 @@ describe('Browsing', () => { }) }) }) - - describe('from the home page', () => { - beforeEach(() => { - wares = true - // Intercept the api call being made on the homepage - cy.customApiIntercept({ - action: 'GET', - alias: 'useAllWares', - requestURL: `/providers/${Cypress.env('NEXT_PUBLIC_PROVIDER_ID')}/wares.json`, - data: wares, - defaultFixture: 'services/wares.json', - loading, - error - }) - cy.visit('/') - }) - - context('a search is completed successfully and', () => { - it('navigates to "/browse" with a blank query', () => { - cy.get('button.search-button').click() - cy.url().should('include', '/browse') - cy.url().should('not.include', '?') - cy.get('input.search-bar').should('have.value', '') - cy.get(".card[data-cy='item-card']").should('be.visible') - }) - - it('navigates to "/browse" with a query term', () => { - cy.get('input.search-bar').type('test') - cy.get('button.search-button').click() - cy.url().should('include', '/browse?q=test') - cy.get('input.search-bar').should('have.value', 'test') - cy.get(".card[data-cy='item-card']").should('be.visible') - }) - }) - }) -}) \ No newline at end of file +}) diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index 5d97967f..3aee8309 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -1,4 +1,4 @@ -describe('Viewing Home page', () => { +describe('Navigating to the home page', () => { // declare variables that can be used to change how the response is intercepted. let loading let error @@ -18,47 +18,82 @@ describe('Viewing Home page', () => { cy.visit('/') }) - context('featured services list is loading', () => { - before(() => loading = true) - - it('should show 3 placeholder cards loading', () => { - cy.get('p.placeholder-glow').should('have.length', 3).then(() => { - cy.log('Loading text displays correctly.') + describe('renders a search bar', () => { + it('with no query', () => { + cy.get("form[data-cy='search-bar']").should('exist').then(() => { + cy.log('Search bar renders successfully.') }) }) - }) - context('error while making a request to the api', () => { - before(() => { - loading = false - error = true + it('able to navigate to "/browse" with a blank query', () => { + cy.get('button.search-button').click() + cy.url().should('include', '/browse') + cy.url().should('not.include', '?') + cy.get('input.search-bar').should('have.value', '') + cy.get(".card[data-cy='item-card']").should('be.visible') }) - it('should show an error message.', () => { - cy.get("div[role='alert']").should('be.visible').then(() => { - cy.log('Successfully hits an error.') - }) + + it('able to navigate to "/browse" with a valid query term', () => { + cy.get('input.search-bar').type(Cypress.env('CYPRESS_SEARCH_QUERY')) + cy.get('button.search-button').click() + cy.url().should('include', `/browse?q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`) + cy.get('input.search-bar').should('have.value', Cypress.env('CYPRESS_SEARCH_QUERY')) + cy.get(".card[data-cy='item-card']").should('be.visible') + }) + + it('able to navigate to "/browse" with an invalid query term', () => { + cy.get('input.search-bar').type('test') + cy.get('button.search-button').click() + cy.url().should('include', '/browse?q=test') + cy.get('input.search-bar').should('have.value', 'test') + cy.get(".card[data-cy='item-card']").should('be.visible') }) }) - context('home page components are loading successfully, &', () => { - before(() => { - featuredServices = true - error = false + describe('renders a text box', () => { + it('showing the about text.', () => { + cy.get("section[data-cy='about-us-section']").should('exist').then(() => { + cy.log('Abouttext renders successfully.') + }) }) - it('should show the search bar.', () => { - cy.get("form[data-cy='search-bar']").should('exist').then(() => { - cy.log('Search bar renders successfully.') + }) + + describe('makes a call to the api', () => { + context('which when returns an error', () => { + before(() => { + loading = false + error = true + }) + + it('shows an error message', () => { + // why would we get an error? + cy.get("div[role='alert']").should('be.visible').then(() => { + cy.log('Successfully hits an error.') + }) }) }) - it('should show the about text.', () => { - cy.get("section[data-cy='about-us-section']").should('exist').then(() => { - cy.log('Abouttext renders successfully.') + + context('which when returns no error or data', () => { + before(() => loading = true) + + it('shows 3 placeholder cards loading', () => { + cy.get('p.placeholder-glow').should('have.length', 3).then(() => { + cy.log('Loading text displays correctly.') + }) }) }) - it('should show the featured services cards.', () => { - cy.get("div[data-cy='item-group']").should('exist').then(() => { - cy.log('Status bar renders successfully.') + + context('which when returns data', () => { + before(() => { + featuredServices = true + error = false + }) + + it('shows the featured services cards', () => { + cy.get("div[data-cy='item-group']").should('exist').then(() => { + cy.log('Status bar renders successfully.') + }) }) }) }) -}) \ No newline at end of file +}) From 41119301e6bc0c295018d763fad87063e61e31da Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Thu, 8 Feb 2024 15:21:14 -0600 Subject: [PATCH 04/10] correctly testing for a search with no query --- cypress/e2e/home.cy.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index 3aee8309..dc414437 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -3,6 +3,8 @@ describe('Navigating to the home page', () => { let loading let error let featuredServices + let requestURL + let data beforeEach(() => { cy.customApiIntercept({ @@ -25,7 +27,23 @@ describe('Navigating to the home page', () => { }) }) - it('able to navigate to "/browse" with a blank query', () => { + context('able to navigate to "/browse"', () => { + const testSetup = ({ data, requestURL }) => { + cy.customApiIntercept({ + action: 'GET', + alias: 'useFilteredWares', + requestURL, + data, + defaultFixture: 'services/wares.json', + }) + } + + it('with a blank query', () => { + testSetup({ + requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=`, + data: true + }) + cy.get('button.search-button').click() cy.url().should('include', '/browse') cy.url().should('not.include', '?') From 733458a951da38ff520034b0bc071051ce48de5a Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Thu, 8 Feb 2024 16:00:11 -0600 Subject: [PATCH 05/10] all search bar tests from the home e2e spec pass --- cypress/e2e/home.cy.js | 43 ++++++++++++------- cypress/fixtures/services/filtered-wares.json | 22 ++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 cypress/fixtures/services/filtered-wares.json diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index dc414437..0ac61ca7 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -1,22 +1,21 @@ describe('Navigating to the home page', () => { // declare variables that can be used to change how the response is intercepted. - let loading let error let featuredServices - let requestURL - let data + let loading beforeEach(() => { cy.customApiIntercept({ action: 'GET', alias: 'useAllWares', - requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}`, data: featuredServices, defaultFixture: 'services/wares.json', emptyFixture: 'services/no-wares.json', + error, loading, - error + requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}`, }) + cy.visit('/') }) @@ -28,20 +27,22 @@ describe('Navigating to the home page', () => { }) context('able to navigate to "/browse"', () => { - const testSetup = ({ data, requestURL }) => { + const testSetup = ({ data, defaultFixture, requestURL }) => { cy.customApiIntercept({ action: 'GET', alias: 'useFilteredWares', - requestURL, data, - defaultFixture: 'services/wares.json', + defaultFixture, + emptyFixture: 'services/no-wares.json', + requestURL, }) } it('with a blank query', () => { testSetup({ requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=`, - data: true + data: true, + defaultFixture: 'services/wares.json', }) cy.get('button.search-button').click() @@ -51,7 +52,13 @@ describe('Navigating to the home page', () => { cy.get(".card[data-cy='item-card']").should('be.visible') }) - it('able to navigate to "/browse" with a valid query term', () => { + it('with a valid query term', () => { + testSetup({ + requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`, + data: true, + defaultFixture: 'services/filtered-wares.json', + }) + cy.get('input.search-bar').type(Cypress.env('CYPRESS_SEARCH_QUERY')) cy.get('button.search-button').click() cy.url().should('include', `/browse?q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`) @@ -59,12 +66,18 @@ describe('Navigating to the home page', () => { cy.get(".card[data-cy='item-card']").should('be.visible') }) - it('able to navigate to "/browse" with an invalid query term', () => { - cy.get('input.search-bar').type('test') + it('with an invalid query term', () => { + const invalidQuery = 'asdfghjk' + testSetup({ + requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=${invalidQuery}`, + }) + + cy.get('input.search-bar').type(invalidQuery) cy.get('button.search-button').click() - cy.url().should('include', '/browse?q=test') - cy.get('input.search-bar').should('have.value', 'test') - cy.get(".card[data-cy='item-card']").should('be.visible') + cy.url().should('include', `/browse?q=${invalidQuery}`) + cy.get('input.search-bar').should('have.value', invalidQuery) + cy.get("p[data-cy='no-results']").should('contain', `Your search for ${invalidQuery} returned no results`) + }) }) }) diff --git a/cypress/fixtures/services/filtered-wares.json b/cypress/fixtures/services/filtered-wares.json new file mode 100644 index 00000000..4ac43915 --- /dev/null +++ b/cypress/fixtures/services/filtered-wares.json @@ -0,0 +1,22 @@ +{ + "ware_refs": [ + { + "id": 3456, + "slug": "test-ware", + "name": "Test Ware", + "snippet": "Here is a test ware snippet.", + "urls": { + "promo_image": "https://y.yarn.co/193fa4ae-a245-4f7a-ac9d-64bbebb18c8d_screenshot.jpg" + } + }, + { + "id": 4567, + "slug": "another-test-ware", + "name": "Another Test Ware", + "snippet": "Another test snippet.", + "urls": { + "promo_image": "https://cdn.drawception.com/images/panels/2017/7-2/jtqKRKSpyj-6.png" + } + } + ] +} From 531182c43afaf6663d5d9bc8d31ec304859b6f8c Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Thu, 8 Feb 2024 17:42:32 -0600 Subject: [PATCH 06/10] formatting --- cypress/e2e/home.cy.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index 0ac61ca7..519cfad9 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -45,12 +45,12 @@ describe('Navigating to the home page', () => { defaultFixture: 'services/wares.json', }) - cy.get('button.search-button').click() - cy.url().should('include', '/browse') - cy.url().should('not.include', '?') - cy.get('input.search-bar').should('have.value', '') - cy.get(".card[data-cy='item-card']").should('be.visible') - }) + cy.get('button.search-button').click() + cy.url().should('include', '/browse') + cy.url().should('not.include', '?') + cy.get('input.search-bar').should('have.value', '') + cy.get(".card[data-cy='item-card']").should('be.visible') + }) it('with a valid query term', () => { testSetup({ @@ -59,12 +59,12 @@ describe('Navigating to the home page', () => { defaultFixture: 'services/filtered-wares.json', }) - cy.get('input.search-bar').type(Cypress.env('CYPRESS_SEARCH_QUERY')) - cy.get('button.search-button').click() - cy.url().should('include', `/browse?q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`) - cy.get('input.search-bar').should('have.value', Cypress.env('CYPRESS_SEARCH_QUERY')) - cy.get(".card[data-cy='item-card']").should('be.visible') - }) + cy.get('input.search-bar').type(Cypress.env('CYPRESS_SEARCH_QUERY')) + cy.get('button.search-button').click() + cy.url().should('include', `/browse?q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`) + cy.get('input.search-bar').should('have.value', Cypress.env('CYPRESS_SEARCH_QUERY')) + cy.get(".card[data-cy='item-card']").should('be.visible') + }) it('with an invalid query term', () => { const invalidQuery = 'asdfghjk' From 611356021a088010c45fcd9075f1b77a42d834d1 Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Mon, 12 Feb 2024 13:20:01 -0600 Subject: [PATCH 07/10] properly throw errors from fetcher although we were catching the error in `#fetcher`, we weren't returning it as an error. it was being returned to the caller as the `data` value. this means none of our `isError` checks for GET requests were working properly. with this commit, we're throwing the error so that we are handling it on the view correctly. --- utils/api/base.js | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/api/base.js b/utils/api/base.js index b16c0ab1..1ae2a445 100644 --- a/utils/api/base.js +++ b/utils/api/base.js @@ -11,6 +11,7 @@ export const fetcher = (url, token) => { .then(res => res.data) .catch(error => { Sentry.captureException(error) + throw error }) } From fd52f079f61d2976c233d0871c490fda5bf4e3bb Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Mon, 12 Feb 2024 13:23:55 -0600 Subject: [PATCH 08/10] correctly accounting for errors on the home page spec we're testing for an invalid access token now. the `customApiIntercept` command is also simplified. --- cypress/e2e/home.cy.js | 21 ++++++++++++-------- cypress/support/commands.js | 38 +++++++++++++------------------------ 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index 519cfad9..dd7b79f0 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -1,16 +1,14 @@ describe('Navigating to the home page', () => { // declare variables that can be used to change how the response is intercepted. + let data let error - let featuredServices let loading beforeEach(() => { cy.customApiIntercept({ action: 'GET', alias: 'useAllWares', - data: featuredServices, - defaultFixture: 'services/wares.json', - emptyFixture: 'services/no-wares.json', + data: 'services/wares.json', error, loading, requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}`, @@ -90,17 +88,24 @@ describe('Navigating to the home page', () => { }) describe('makes a call to the api', () => { - context('which when returns an error', () => { + context('which when given an invalid access token', () => { before(() => { - loading = false - error = true + data = undefined + error = { + response: { + data: { + message: 'No access token provided.', + }, + status: 403, + }, + } }) it('shows an error message', () => { - // why would we get an error? cy.get("div[role='alert']").should('be.visible').then(() => { cy.log('Successfully hits an error.') }) + cy.get("div[role='alert']").contains('No access token provided.') }) }) diff --git a/cypress/support/commands.js b/cypress/support/commands.js index d2f3d9ff..2f7d033f 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -30,12 +30,12 @@ import { scientistApiBaseURL } from './e2e' // source: https://github.com/nextauthjs/next-auth/discussions/2053#discussioncomment-1191016 Cypress.Commands.add('login', (username, password) => { cy.session([username, password], () => { - cy.intercept("/api/auth/session", { fixture: "session.json" }).as("session"); + cy.intercept('/api/auth/session', { fixture: 'session.json' }).as('session') - // Set the cookie for cypress. - // It has to be a valid cookie so next-auth can decrypt it and confirm its validity. - // This cookie also may need to be refreshed intermittently if it expires - cy.setCookie("next-auth.session-token", Cypress.env('TEST_SESSION_COOKIE')); + // Set the cookie for cypress. + // It has to be a valid cookie so next-auth can decrypt it and confirm its validity. + // This cookie also may need to be refreshed intermittently if it expires + cy.setCookie('next-auth.session-token', Cypress.env('TEST_SESSION_COOKIE')) }) }) @@ -43,28 +43,16 @@ Cypress.Commands.add('login', (username, password) => { // required params are action, defaultFixture, requestURL // optional params such as data, loading, and error can be passed depending on the creation of test cases that are related to that specific api call Cypress.Commands.add('customApiIntercept', ({ - action, alias, data, defaultFixture, emptyFixture, error, errorCaseStatusCode, loading, requestURL + action, alias, data, error, loading, requestURL }) => { cy.intercept(action, `${scientistApiBaseURL}${requestURL}`, (req) => { - switch (true) { - // reply with an empty response: both data and error will be undefined. - case loading: req.reply({}) - break - - // error will be defined - case error: req.reply({ statusCode: errorCaseStatusCode || 500 }) - break - - // reply with a request body- default status code is 200 - case data: req.reply({ fixture: defaultFixture }) - break - - // reply with the empty fixture is there is one, and the default as a backup. Allows us to isolate one api call at a time that may potentially respond with empty data. - case !data: req.reply({ fixture: emptyFixture || defaultFixture }) - break - - default: req.reply({ fixture: defaultFixture }) - break + const response = { + data: { fixture: data }, + error: { ...error }, + loading: {}, } + console.log({ response }) + + return req.reply(response[data || error || loading]) }).as(alias || 'customIntercept') }) From 808b8383ae151bd4f59b0aefafe5c3f17f07f1ae Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Mon, 12 Feb 2024 15:01:37 -0600 Subject: [PATCH 09/10] all 7 home specs are passing also further simplified the `customApiIntercept` function. --- cypress/e2e/home.cy.js | 41 ++++++++++++------------------------- cypress/support/commands.js | 27 +++++++++++++++--------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/cypress/e2e/home.cy.js b/cypress/e2e/home.cy.js index dd7b79f0..5bc8e0f9 100644 --- a/cypress/e2e/home.cy.js +++ b/cypress/e2e/home.cy.js @@ -1,17 +1,14 @@ describe('Navigating to the home page', () => { // declare variables that can be used to change how the response is intercepted. - let data + let data = 'services/wares.json' let error - let loading beforeEach(() => { cy.customApiIntercept({ - action: 'GET', alias: 'useAllWares', - data: 'services/wares.json', + data, error, - loading, - requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}`, + requestURL: '/wares.json?per_page=2000', }) cy.visit('/') @@ -27,20 +24,17 @@ describe('Navigating to the home page', () => { context('able to navigate to "/browse"', () => { const testSetup = ({ data, defaultFixture, requestURL }) => { cy.customApiIntercept({ - action: 'GET', alias: 'useFilteredWares', data, - defaultFixture, - emptyFixture: 'services/no-wares.json', + error, requestURL, }) } it('with a blank query', () => { testSetup({ - requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=`, - data: true, - defaultFixture: 'services/wares.json', + data: 'services/wares.json', + requestURL: '/wares.json?per_page=2000&q=', }) cy.get('button.search-button').click() @@ -52,9 +46,8 @@ describe('Navigating to the home page', () => { it('with a valid query term', () => { testSetup({ - requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`, - data: true, - defaultFixture: 'services/filtered-wares.json', + data: 'services/filtered-wares.json', + requestURL: `/wares.json?per_page=2000&q=${Cypress.env('CYPRESS_SEARCH_QUERY')}`, }) cy.get('input.search-bar').type(Cypress.env('CYPRESS_SEARCH_QUERY')) @@ -67,7 +60,8 @@ describe('Navigating to the home page', () => { it('with an invalid query term', () => { const invalidQuery = 'asdfghjk' testSetup({ - requestURL: `/wares.json?per_page=${Cypress.env('API_PER_PAGE')}&q=${invalidQuery}`, + data: 'services/no-wares.json', + requestURL: `/wares.json?per_page=2000&q=${invalidQuery}`, }) cy.get('input.search-bar').type(invalidQuery) @@ -92,12 +86,10 @@ describe('Navigating to the home page', () => { before(() => { data = undefined error = { - response: { - data: { - message: 'No access token provided.', - }, - status: 403, + body: { + message: 'No access token provided.', }, + statusCode: 403, } }) @@ -110,8 +102,6 @@ describe('Navigating to the home page', () => { }) context('which when returns no error or data', () => { - before(() => loading = true) - it('shows 3 placeholder cards loading', () => { cy.get('p.placeholder-glow').should('have.length', 3).then(() => { cy.log('Loading text displays correctly.') @@ -120,11 +110,6 @@ describe('Navigating to the home page', () => { }) context('which when returns data', () => { - before(() => { - featuredServices = true - error = false - }) - it('shows the featured services cards', () => { cy.get("div[data-cy='item-group']").should('exist').then(() => { cy.log('Status bar renders successfully.') diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 2f7d033f..9ab32faa 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -39,20 +39,27 @@ Cypress.Commands.add('login', (username, password) => { }) }) -// intercepts requests and creates potential cases for loading, error, data, and empty data -// required params are action, defaultFixture, requestURL -// optional params such as data, loading, and error can be passed depending on the creation of test cases that are related to that specific api call +/** + * This command intercepts requests and returns the given stubbed response + * + * @param {string} alias - the alias to give the intercept (convention is to + * use the function name) + * @param {string} data - the fixture to return as the response data + * @param {object} error - the error object to return as the response error + * @param {string} requestURL - the URL to intercept + * + * @returns {object} - the stubbed response + */ Cypress.Commands.add('customApiIntercept', ({ - action, alias, data, error, loading, requestURL + alias, data, error, requestURL }) => { - cy.intercept(action, `${scientistApiBaseURL}${requestURL}`, (req) => { + cy.intercept(`${scientistApiBaseURL}${requestURL}`, (req) => { const response = { - data: { fixture: data }, - error: { ...error }, - loading: {}, + data: data && { fixture: data }, + error, } - console.log({ response }) - return req.reply(response[data || error || loading]) + // falling back to an empty object mimics the loading state + return req.reply(response.data || response.error || {}) }).as(alias || 'customIntercept') }) From 11f0bc942d35d065321776769dfb9b1b1ab8627a Mon Sep 17 00:00:00 2001 From: Alisha Evans Date: Tue, 13 Feb 2024 10:28:56 -0600 Subject: [PATCH 10/10] remove now irrelevant code --- cypress.config.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 736d283e..93a4fccd 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -27,10 +27,6 @@ module.exports = defineConfig({ NEXT_PUBLIC_PROVIDER_ID: process.env.NEXT_PUBLIC_PROVIDER_ID, NEXT_PUBLIC_TOKEN: process.env.NEXT_PUBLIC_TOKEN, CYPRESS_SEARCH_QUERY: 'test', - // importing the `API_PER_PAGE` variable from the constants file throws - // errors since this file doesn't follow ES6 syntax. if the value is - // changed in constants, it needs to be updated here too - API_PER_PAGE: 2000, }, reporter: 'junit', reporterOptions: {