mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-22 01:46:58 +01:00
add more website tests, support functions, login
This commit is contained in:
parent
e5c19482ab
commit
72090d778b
@ -5,9 +5,13 @@ describe('Login tests', () => {
|
|||||||
defaultCommandTimeout: 10000,
|
defaultCommandTimeout: 10000,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
|
cy.visit('/login');
|
||||||
cy.dataCy('button-profile').click();
|
cy.getDataTest('input-username').find('input').type(Cypress.env('umami_user'));
|
||||||
cy.dataCy('item-logout').click();
|
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');
|
cy.url().should('eq', Cypress.config().baseUrl + '/login');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,37 +1,91 @@
|
|||||||
describe('Website tests', () => {
|
describe('Website tests', () => {
|
||||||
|
Cypress.session.clearAllSavedSessions();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
|
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', () => {
|
it('Add a website', () => {
|
||||||
cy.dataCy('button-website-add').click();
|
// add website
|
||||||
|
cy.visit('/settings/websites');
|
||||||
|
cy.getDataTest('button-website-add').click();
|
||||||
cy.contains(/Add website/i).should('be.visible');
|
cy.contains(/Add website/i).should('be.visible');
|
||||||
cy.dataCy('input-name').click().type('Test Website', {
|
cy.getDataTest('input-name').find('input').wait(500).type('Add test', { delay: 50 });
|
||||||
delay: 100,
|
cy.getDataTest('input-domain').find('input').wait(500).type('addtest.com', { delay: 50 });
|
||||||
});
|
cy.getDataTest('button-submit').click();
|
||||||
cy.dataCy('input-domain').click().type('testwebsite.com');
|
cy.get('td[label="Name"]').should('contain.text', 'Add test');
|
||||||
cy.dataCy('button-submit').click();
|
cy.get('td[label="Domain"]').should('contain.text', 'addtest.com');
|
||||||
cy.get('td[label="Name"]').should('contain.text', 'Test Website');
|
|
||||||
cy.get('td[label="Domain"]').should('contain.text', 'testwebsite.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', () => {
|
it.only('Edit a website', () => {
|
||||||
cy.dataCy('link-button-edit').first().click();
|
// prep data
|
||||||
cy.contains(/Tracking code/i).should('be.visible');
|
cy.addWebsite('Update test', 'updatetest.com');
|
||||||
cy.get('div')
|
cy.visit('/settings/websites');
|
||||||
.contains(/Tracking code/i)
|
|
||||||
.click();
|
|
||||||
cy.get('textarea').should('contain.text', Cypress.config().baseUrl + '/script2.js');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test tracking script content', () => {
|
// edit website
|
||||||
cy.dataCy('link-button-edit').first().click();
|
cy.getDataTest('link-button-edit').first().click();
|
||||||
cy.contains(/Tracking code/i).should('be.visible');
|
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')
|
cy.get('div')
|
||||||
.contains(/Tracking code/i)
|
.contains(/Tracking code/i)
|
||||||
.click();
|
.click();
|
||||||
cy.get('textarea').should('contain.text', Cypress.config().baseUrl + '/script.js');
|
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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,24 +1,57 @@
|
|||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
|
import { uuid } from '../../src/lib/crypto';
|
||||||
|
|
||||||
Cypress.Commands.add('dataCy', (value: string) => {
|
Cypress.Commands.add('getDataTest', (value: string) => {
|
||||||
return cy.get(`[data-cy=${value}]`);
|
return cy.get(`[data-test=${value}]`);
|
||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('login', (username: string, password: string) => {
|
Cypress.Commands.add('login', (username: string, password: string) => {
|
||||||
cy.session(
|
cy.session([username, password], () => {
|
||||||
[username, password],
|
cy.request({
|
||||||
() => {
|
method: 'POST',
|
||||||
cy.visit('/login');
|
url: '/api/auth/login',
|
||||||
cy.dataCy('input-username').type(username);
|
body: {
|
||||||
cy.dataCy('input-password').type(password);
|
username,
|
||||||
cy.dataCy('button-submit').click();
|
password,
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + '/dashboard');
|
|
||||||
},
|
|
||||||
{
|
|
||||||
validate: () => {
|
|
||||||
cy.visit('/profile');
|
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
);
|
.then(response => {
|
||||||
cy.visit('/dashboard');
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
16
cypress/support/index.d.ts
vendored
16
cypress/support/index.d.ts
vendored
@ -3,14 +3,24 @@
|
|||||||
declare namespace Cypress {
|
declare namespace Cypress {
|
||||||
interface Chainable {
|
interface Chainable {
|
||||||
/**
|
/**
|
||||||
* Custom command to select DOM element by data-cy attribute.
|
* Custom command to select DOM element by data-test attribute.
|
||||||
* @example cy.dataCy('greeting')
|
* @example cy.getDataTest('greeting')
|
||||||
*/
|
*/
|
||||||
dataCy(value: string): Chainable<JQuery<HTMLElement>>;
|
getDataTest(value: string): Chainable<JQuery<HTMLElement>>;
|
||||||
/**
|
/**
|
||||||
* Custom command to login user into the app.
|
* Custom command to login user into the app.
|
||||||
* @example cy.login('admin', 'password)
|
* @example cy.login('admin', 'password)
|
||||||
*/
|
*/
|
||||||
login(username: string, password: string): Chainable<JQuery<HTMLElement>>;
|
login(username: string, password: string): Chainable<JQuery<HTMLElement>>;
|
||||||
|
/**
|
||||||
|
* Custom command to create a website
|
||||||
|
* @example cy.addWebsite('test', 'test.com')
|
||||||
|
*/
|
||||||
|
addWebsite(name: string, domain: string): Chainable<JQuery<HTMLElement>>;
|
||||||
|
/**
|
||||||
|
* Custom command to create a website
|
||||||
|
* @example cy.deleteWebsite('02d89813-7a72-41e1-87f0-8d668f85008b')
|
||||||
|
*/
|
||||||
|
deleteWebsite(websiteId: string): Chainable<JQuery<HTMLElement>>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export function WebsiteAddButton({ teamId, onSave }: { teamId: string; onSave?:
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalTrigger>
|
<ModalTrigger>
|
||||||
<Button data-cy="button-website-add" variant="primary">
|
<Button data-test="button-website-add" variant="primary">
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Plus />
|
<Icons.Plus />
|
||||||
</Icon>
|
</Icon>
|
||||||
|
@ -39,7 +39,7 @@ export function WebsiteAddForm({
|
|||||||
<Form onSubmit={handleSubmit} error={error}>
|
<Form onSubmit={handleSubmit} error={error}>
|
||||||
<FormRow label={formatMessage(labels.name)}>
|
<FormRow label={formatMessage(labels.name)}>
|
||||||
<FormInput
|
<FormInput
|
||||||
data-cy="input-name"
|
data-test="input-name"
|
||||||
name="name"
|
name="name"
|
||||||
rules={{ required: formatMessage(labels.required) }}
|
rules={{ required: formatMessage(labels.required) }}
|
||||||
>
|
>
|
||||||
@ -48,7 +48,7 @@ export function WebsiteAddForm({
|
|||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow label={formatMessage(labels.domain)}>
|
<FormRow label={formatMessage(labels.domain)}>
|
||||||
<FormInput
|
<FormInput
|
||||||
data-cy="input-domain"
|
data-test="input-domain"
|
||||||
name="domain"
|
name="domain"
|
||||||
rules={{
|
rules={{
|
||||||
required: formatMessage(labels.required),
|
required: formatMessage(labels.required),
|
||||||
@ -59,7 +59,7 @@ export function WebsiteAddForm({
|
|||||||
</FormInput>
|
</FormInput>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormButtons flex>
|
<FormButtons flex>
|
||||||
<SubmitButton data-cy="button-submit" variant="primary" disabled={false}>
|
<SubmitButton data-test="button-submit" variant="primary" disabled={false}>
|
||||||
{formatMessage(labels.save)}
|
{formatMessage(labels.save)}
|
||||||
</SubmitButton>
|
</SubmitButton>
|
||||||
{onClose && (
|
{onClose && (
|
||||||
|
@ -36,7 +36,7 @@ export function WebsitesTable({
|
|||||||
<>
|
<>
|
||||||
{allowEdit && (
|
{allowEdit && (
|
||||||
<LinkButton href={renderTeamUrl(`/settings/websites/${websiteId}`)}>
|
<LinkButton href={renderTeamUrl(`/settings/websites/${websiteId}`)}>
|
||||||
<Icon data-cy="link-button-edit">
|
<Icon data-test="link-button-edit">
|
||||||
<Icons.Edit />
|
<Icons.Edit />
|
||||||
</Icon>
|
</Icon>
|
||||||
<Text>{formatMessage(labels.edit)}</Text>
|
<Text>{formatMessage(labels.edit)}</Text>
|
||||||
|
@ -66,7 +66,9 @@ export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?:
|
|||||||
description={formatMessage(messages.deleteWebsiteWarning)}
|
description={formatMessage(messages.deleteWebsiteWarning)}
|
||||||
>
|
>
|
||||||
<ModalTrigger>
|
<ModalTrigger>
|
||||||
<Button variant="danger">{formatMessage(labels.delete)}</Button>
|
<Button data-test="button-delete" variant="danger">
|
||||||
|
{formatMessage(labels.delete)}
|
||||||
|
</Button>
|
||||||
<Modal title={formatMessage(labels.deleteWebsite)}>
|
<Modal title={formatMessage(labels.deleteWebsite)}>
|
||||||
{(close: () => void) => (
|
{(close: () => void) => (
|
||||||
<WebsiteDeleteForm websiteId={websiteId} onSave={handleSave} onClose={close} />
|
<WebsiteDeleteForm websiteId={websiteId} onSave={handleSave} onClose={close} />
|
||||||
|
@ -27,15 +27,20 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa
|
|||||||
return (
|
return (
|
||||||
<Form ref={ref} onSubmit={handleSubmit} error={error} values={website}>
|
<Form ref={ref} onSubmit={handleSubmit} error={error} values={website}>
|
||||||
<FormRow label={formatMessage(labels.websiteId)}>
|
<FormRow label={formatMessage(labels.websiteId)}>
|
||||||
<TextField value={website?.id} readOnly allowCopy />
|
<TextField data-test="text-field-websiteId" value={website?.id} readOnly allowCopy />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow label={formatMessage(labels.name)}>
|
<FormRow label={formatMessage(labels.name)}>
|
||||||
<FormInput name="name" rules={{ required: formatMessage(labels.required) }}>
|
<FormInput
|
||||||
|
data-test="input-name"
|
||||||
|
name="name"
|
||||||
|
rules={{ required: formatMessage(labels.required) }}
|
||||||
|
>
|
||||||
<TextField />
|
<TextField />
|
||||||
</FormInput>
|
</FormInput>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow label={formatMessage(labels.domain)}>
|
<FormRow label={formatMessage(labels.domain)}>
|
||||||
<FormInput
|
<FormInput
|
||||||
|
data-test="input-domain"
|
||||||
name="domain"
|
name="domain"
|
||||||
rules={{
|
rules={{
|
||||||
required: formatMessage(labels.required),
|
required: formatMessage(labels.required),
|
||||||
@ -49,7 +54,9 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa
|
|||||||
</FormInput>
|
</FormInput>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormButtons>
|
<FormButtons>
|
||||||
<SubmitButton variant="primary">{formatMessage(labels.save)}</SubmitButton>
|
<SubmitButton data-test="button-submit" variant="primary">
|
||||||
|
{formatMessage(labels.save)}
|
||||||
|
</SubmitButton>
|
||||||
</FormButtons>
|
</FormButtons>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
@ -43,7 +43,7 @@ export function LoginForm() {
|
|||||||
<Form className={styles.form} onSubmit={handleSubmit} error={getMessage(error)}>
|
<Form className={styles.form} onSubmit={handleSubmit} error={getMessage(error)}>
|
||||||
<FormRow label={formatMessage(labels.username)}>
|
<FormRow label={formatMessage(labels.username)}>
|
||||||
<FormInput
|
<FormInput
|
||||||
data-cy="input-username"
|
data-test="input-username"
|
||||||
name="username"
|
name="username"
|
||||||
rules={{ required: formatMessage(labels.required) }}
|
rules={{ required: formatMessage(labels.required) }}
|
||||||
>
|
>
|
||||||
@ -52,7 +52,7 @@ export function LoginForm() {
|
|||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow label={formatMessage(labels.password)}>
|
<FormRow label={formatMessage(labels.password)}>
|
||||||
<FormInput
|
<FormInput
|
||||||
data-cy="input-password"
|
data-test="input-password"
|
||||||
name="password"
|
name="password"
|
||||||
rules={{ required: formatMessage(labels.required) }}
|
rules={{ required: formatMessage(labels.required) }}
|
||||||
>
|
>
|
||||||
@ -61,7 +61,7 @@ export function LoginForm() {
|
|||||||
</FormRow>
|
</FormRow>
|
||||||
<FormButtons>
|
<FormButtons>
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
data-cy="button-submit"
|
data-test="button-submit"
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
variant="primary"
|
variant="primary"
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
|
@ -25,7 +25,7 @@ export function ProfileButton() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PopupTrigger>
|
<PopupTrigger>
|
||||||
<Button data-cy="button-profile" variant="quiet">
|
<Button data-test="button-profile" variant="quiet">
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Profile />
|
<Icons.Profile />
|
||||||
</Icon>
|
</Icon>
|
||||||
@ -41,7 +41,7 @@ export function ProfileButton() {
|
|||||||
<Text>{formatMessage(labels.profile)}</Text>
|
<Text>{formatMessage(labels.profile)}</Text>
|
||||||
</Item>
|
</Item>
|
||||||
{!cloudMode && (
|
{!cloudMode && (
|
||||||
<Item data-cy="item-logout" key="logout" className={styles.item}>
|
<Item data-test="item-logout" key="logout" className={styles.item}>
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Logout />
|
<Icons.Logout />
|
||||||
</Icon>
|
</Icon>
|
||||||
|
Loading…
Reference in New Issue
Block a user