From 72090d778b991b00e91a55fe974f48b3b10ef964 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Fri, 1 Mar 2024 13:00:59 -0800 Subject: [PATCH] add more website tests, support functions, login --- cypress/e2e/login.cy.ts | 10 +- cypress/e2e/website.cy.ts | 98 ++++++++++++++----- cypress/support/e2e.ts | 67 +++++++++---- cypress/support/index.d.ts | 16 ++- .../settings/websites/WebsiteAddButton.tsx | 2 +- .../settings/websites/WebsiteAddForm.tsx | 6 +- .../settings/websites/WebsitesTable.tsx | 2 +- .../websites/[websiteId]/WebsiteData.tsx | 4 +- .../websites/[websiteId]/WebsiteEditForm.tsx | 13 ++- src/app/login/LoginForm.tsx | 6 +- src/components/input/ProfileButton.tsx | 4 +- 11 files changed, 169 insertions(+), 59 deletions(-) diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts index 5c833113..288d5c51 100644 --- a/cypress/e2e/login.cy.ts +++ b/cypress/e2e/login.cy.ts @@ -5,9 +5,13 @@ describe('Login tests', () => { defaultCommandTimeout: 10000, }, () => { - cy.login(Cypress.env('umami_user'), Cypress.env('umami_password')); - cy.dataCy('button-profile').click(); - cy.dataCy('item-logout').click(); + cy.visit('/login'); + cy.getDataTest('input-username').find('input').type(Cypress.env('umami_user')); + cy.getDataTest('input-password').find('input').type(Cypress.env('umami_password')); + cy.getDataTest('button-submit').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); + cy.getDataTest('button-profile').click(); + cy.getDataTest('item-logout').click(); cy.url().should('eq', Cypress.config().baseUrl + '/login'); }, ); diff --git a/cypress/e2e/website.cy.ts b/cypress/e2e/website.cy.ts index 86f703eb..feec39de 100644 --- a/cypress/e2e/website.cy.ts +++ b/cypress/e2e/website.cy.ts @@ -1,37 +1,91 @@ describe('Website tests', () => { + Cypress.session.clearAllSavedSessions(); + beforeEach(() => { cy.login(Cypress.env('umami_user'), Cypress.env('umami_password')); - cy.get('a[href="/settings"]').click(); - cy.url().should('include', '/settings/websites'); }); - it.skip('Add a website', () => { - cy.dataCy('button-website-add').click(); + it('Add a website', () => { + // add website + cy.visit('/settings/websites'); + cy.getDataTest('button-website-add').click(); cy.contains(/Add website/i).should('be.visible'); - cy.dataCy('input-name').click().type('Test Website', { - delay: 100, - }); - cy.dataCy('input-domain').click().type('testwebsite.com'); - cy.dataCy('button-submit').click(); - cy.get('td[label="Name"]').should('contain.text', 'Test Website'); - cy.get('td[label="Domain"]').should('contain.text', 'testwebsite.com'); + cy.getDataTest('input-name').find('input').wait(500).type('Add test', { delay: 50 }); + cy.getDataTest('input-domain').find('input').wait(500).type('addtest.com', { delay: 50 }); + cy.getDataTest('button-submit').click(); + cy.get('td[label="Name"]').should('contain.text', 'Add test'); + cy.get('td[label="Domain"]').should('contain.text', 'addtest.com'); + + // clean-up data + cy.getDataTest('link-button-edit').first().click(); + cy.contains(/Details/i).should('be.visible'); + cy.getDataTest('text-field-websiteId') + .find('input') + .then($input => { + const websiteId = $input[0].value; + cy.deleteWebsite(websiteId); + }); + cy.visit('/settings/websites'); + cy.contains('Add test').should('not.exist'); }); - it('Test tracking script content', () => { - cy.dataCy('link-button-edit').first().click(); - cy.contains(/Tracking code/i).should('be.visible'); - cy.get('div') - .contains(/Tracking code/i) - .click(); - cy.get('textarea').should('contain.text', Cypress.config().baseUrl + '/script2.js'); - }); + it.only('Edit a website', () => { + // prep data + cy.addWebsite('Update test', 'updatetest.com'); + cy.visit('/settings/websites'); - it('Test tracking script content', () => { - cy.dataCy('link-button-edit').first().click(); - cy.contains(/Tracking code/i).should('be.visible'); + // edit website + cy.getDataTest('link-button-edit').first().click(); + cy.contains(/Details/i).should('be.visible'); + cy.getDataTest('input-name') + .find('input') + .wait(500) + .clear() + .type('Updated website', { delay: 50 }); + cy.getDataTest('input-domain') + .find('input') + .wait(500) + .clear() + .type('updatedwebsite.com', { delay: 50 }); + cy.getDataTest('button-submit').click({ force: true }); + cy.getDataTest('input-name').find('input').should('have.value', 'Updated website'); + cy.getDataTest('input-domain').find('input').should('have.value', 'updatedwebsite.com'); + + // verify tracking script cy.get('div') .contains(/Tracking code/i) .click(); cy.get('textarea').should('contain.text', Cypress.config().baseUrl + '/script.js'); + + // clean-up data + cy.get('div') + .contains(/Details/i) + .click(); + cy.contains(/Details/i).should('be.visible'); + cy.getDataTest('text-field-websiteId') + .find('input') + .then($input => { + const websiteId = $input[0].value; + cy.deleteWebsite(websiteId); + }); + cy.visit('/settings/websites'); + cy.contains('Add test').should('not.exist'); + }); + + it('Delete a website', () => { + // prep data + cy.addWebsite('Delete test', 'deletetest.com'); + cy.visit('/settings/websites'); + + // delete website + cy.getDataTest('link-button-edit').first().click(); + cy.contains(/Data/i).should('be.visible'); + cy.get('div').contains(/Data/i).click(); + cy.contains(/All website data will be deleted./i).should('be.visible'); + cy.getDataTest('button-delete').click(); + cy.contains(/Type DELETE in the box below to confirm./i).should('be.visible'); + cy.get('input[name="confirm"').type('DELETE'); + cy.get('button[type="submit"]').click(); + cy.contains('Delete test').should('not.exist'); }); }); diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index faca6903..2c45142b 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -1,24 +1,57 @@ /// +import { uuid } from '../../src/lib/crypto'; -Cypress.Commands.add('dataCy', (value: string) => { - return cy.get(`[data-cy=${value}]`); +Cypress.Commands.add('getDataTest', (value: string) => { + return cy.get(`[data-test=${value}]`); }); Cypress.Commands.add('login', (username: string, password: string) => { - cy.session( - [username, password], - () => { - cy.visit('/login'); - cy.dataCy('input-username').type(username); - cy.dataCy('input-password').type(password); - cy.dataCy('button-submit').click(); - cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); - }, - { - validate: () => { - cy.visit('/profile'); + cy.session([username, password], () => { + cy.request({ + method: 'POST', + url: '/api/auth/login', + body: { + username, + password, }, - }, - ); - cy.visit('/dashboard'); + }) + .then(response => { + Cypress.env('authorization', `bearer ${response.body.token}`); + window.localStorage.setItem('umami.auth', JSON.stringify(response.body.token)); + }) + .its('status') + .should('eq', 200); + }); +}); + +Cypress.Commands.add('addWebsite', (name: string, domain: string) => { + cy.request({ + method: 'POST', + url: '/api/websites', + headers: { + 'Content-Type': 'application/json', + Authorization: Cypress.env('authorization'), + }, + body: { + id: uuid(), + createdBy: '41e2b680-648e-4b09-bcd7-3e2b10c06264', + name: name, + domain: domain, + }, + }).then(response => { + expect(response.status).to.eq(200); + }); +}); + +Cypress.Commands.add('deleteWebsite', (websiteId: string) => { + cy.request({ + method: 'DELETE', + url: `/api/websites/${websiteId}`, + headers: { + 'Content-Type': 'application/json', + Authorization: Cypress.env('authorization'), + }, + }).then(response => { + expect(response.status).to.eq(200); + }); }); diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts index 1da81f1a..90cca19b 100644 --- a/cypress/support/index.d.ts +++ b/cypress/support/index.d.ts @@ -3,14 +3,24 @@ declare namespace Cypress { interface Chainable { /** - * Custom command to select DOM element by data-cy attribute. - * @example cy.dataCy('greeting') + * Custom command to select DOM element by data-test attribute. + * @example cy.getDataTest('greeting') */ - dataCy(value: string): Chainable>; + getDataTest(value: string): Chainable>; /** * Custom command to login user into the app. * @example cy.login('admin', 'password) */ login(username: string, password: string): Chainable>; + /** + * Custom command to create a website + * @example cy.addWebsite('test', 'test.com') + */ + addWebsite(name: string, domain: string): Chainable>; + /** + * Custom command to create a website + * @example cy.deleteWebsite('02d89813-7a72-41e1-87f0-8d668f85008b') + */ + deleteWebsite(websiteId: string): Chainable>; } } diff --git a/src/app/(main)/settings/websites/WebsiteAddButton.tsx b/src/app/(main)/settings/websites/WebsiteAddButton.tsx index 5dd60b76..e534461c 100644 --- a/src/app/(main)/settings/websites/WebsiteAddButton.tsx +++ b/src/app/(main)/settings/websites/WebsiteAddButton.tsx @@ -15,7 +15,7 @@ export function WebsiteAddButton({ teamId, onSave }: { teamId: string; onSave?: return ( - + {(close: () => void) => ( diff --git a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx index dac7a8d4..15538661 100644 --- a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx +++ b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx @@ -27,15 +27,20 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa return ( - + - + - {formatMessage(labels.save)} + + {formatMessage(labels.save)} + ); diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx index 03192413..3101bf48 100644 --- a/src/app/login/LoginForm.tsx +++ b/src/app/login/LoginForm.tsx @@ -43,7 +43,7 @@ export function LoginForm() {
@@ -52,7 +52,7 @@ export function LoginForm() { @@ -61,7 +61,7 @@ export function LoginForm() { -