console: add tests for manage db page

TODO:

- [x] Test for add sources

- [x] Test for set connection setting

- [x] Test for delete sources

- [x] Test for switch between sources

Co-authored-by: Ikechukwu Eze <22247592+iykekings@users.noreply.github.com>
Co-authored-by: Aleksandra Sikora <9019397+beerose@users.noreply.github.com>
GitOrigin-RevId: 2b31dbb69767cdcacf0cb2b2afde56871c3a2240
This commit is contained in:
Varun Choudhary 2021-03-19 15:17:17 +05:30 committed by hasura-bot
parent 07010ea2a7
commit 845756047a
7 changed files with 223 additions and 1 deletions

View File

@ -17,3 +17,11 @@ export const setPromptValue = (value: string | null) => {
/* eslint-disable-next-line cypress/no-unnecessary-waiting */
cy.wait(7000);
};
// This is works as setPromptValue with no unnecessary waiting
export const setPromptWithCb = (value: string | null, cb: () => void) => {
cy.window().then(win => {
cy.stub(win, 'prompt').returns(value);
cb();
});
};

View File

@ -0,0 +1,119 @@
import { setPromptWithCb } from '../../../helpers/common';
import { baseUrl } from '../../../helpers/dataHelpers';
const config = {
host: 'localhost',
port: '5432',
dbName: 'gql_test',
username: 'gql_test',
password: '',
};
const dbUrl = `postgres://${config.username}:${config.password}@${config.host}:${config.port}/${config.dbName}`;
export const openManageDatabases = () => {
cy.getBySel('sidebar-manage-database').click();
cy.url().should('eq', `${baseUrl}/data/manage`);
};
export const expandAddDatabaseForm = () => {
cy.get('button').contains('Connect Database').click();
cy.url().should('eq', `${baseUrl}/data/manage/connect`);
};
export const expandConnectionSettingsform = () => {
cy.get('a').contains('Connection Settings').click();
};
export const failsOnEmptyFormSubmission = () => {
cy.getBySel('save-database').click();
cy.get('.notification-error').should('be.visible');
};
export const addsNewPostgresDatabaseWithUrl = () => {
cy.getBySel('database-display-name').type('testDB1');
cy.getBySel('database-type').select('postgres');
cy.getBySel('database-url').type(dbUrl);
cy.getBySel('max-connections').type('50');
cy.getBySel('idle-timeout').type('180');
cy.getBySel('retries').type('1');
cy.getBySel('save-database').click();
cy.get('.notification-success')
.should('be.visible')
.and('contain', 'Database added successfully!');
cy.url().should('eq', `${baseUrl}/data/manage`);
};
export const addsNewPgDBWithConParams = () => {
cy.getBySel('sidebar-manage-database').click();
cy.get('button').contains('Connect Database').click();
cy.get("input[type='radio']").eq(0).click();
cy.getBySel('database-display-name').type('testDB2');
cy.getBySel('database-type').select('postgres');
cy.getBySel('host').type(config.host);
cy.getBySel('port').type(config.port);
cy.getBySel('username').type(config.username);
if (config.password) {
cy.getBySel('password').type(config.password);
}
cy.getBySel('database-name').type(config.dbName);
cy.getBySel('save-database').click();
cy.get('.notification-success')
.should('be.visible')
.and('contain', 'Database added successfully!');
cy.url().should('eq', `${baseUrl}/data/manage`);
};
export const addsNewPgDBWithEnvVar = () => {
cy.getBySel('sidebar-manage-database').click();
cy.get('button').contains('Connect Database').click();
cy.get("input[type='radio']").eq(2).click();
cy.getBySel('database-display-name').type('testDB3');
cy.getBySel('database-type').select('postgres');
cy.getBySel('database-url-env').type('HASURA_GRAPHQL_DATABASE_URL');
cy.getBySel('save-database').click();
cy.get('.notification-success')
.should('be.visible')
.and('contain', 'Database added successfully!');
cy.url().should('eq', `${baseUrl}/data/manage`);
};
export const failDuplicateNameDb = () => {
cy.getBySel('sidebar-manage-database').click();
cy.get('button').contains('Connect Database').click();
cy.getBySel('database-display-name').type('testDB1');
cy.getBySel('database-url').type(dbUrl);
cy.getBySel('save-database').click();
cy.get('.notification-error')
.should('be.visible')
.and('contain', 'Add data source failed')
.and('contain', 'source with name "testDB1" already exists');
};
export const deleteTestDBWithUrl = () => {
cy.getBySel('sidebar-manage-database').click();
setPromptWithCb('testDB1', () => {
cy.getBySel('testDB1').find('button').contains('Remove').click();
cy.get('.notification-success')
.should('be.visible')
.and('contain', 'Data source removed successfully!');
cy.window().its('prompt').should('be.called');
});
};
export const deleteTestDBWithConParams = () => {
setPromptWithCb('testDB2', () => {
cy.getBySel('testDB2').find('button').contains('Remove').click();
cy.get('.notification-success')
.should('be.visible')
.and('contain', 'Data source removed successfully!');
cy.window().its('prompt').should('be.called');
});
};
export const deleteTestDDWithEnvVar = () => {
setPromptWithCb('testDB3', () => {
cy.getBySel('testDB3').find('button').contains('Remove').click();
cy.get('.notification-success')
.should('be.visible')
.and('contain', 'Data source removed successfully!');
cy.window().its('prompt').should('be.called');
});
};

View File

@ -0,0 +1,60 @@
import { setMetaData } from '../../validators/validators';
import { getIndexRoute } from '../../../helpers/dataHelpers';
import {
openManageDatabases,
expandAddDatabaseForm,
expandConnectionSettingsform,
failsOnEmptyFormSubmission,
addsNewPostgresDatabaseWithUrl,
failDuplicateNameDb,
addsNewPgDBWithConParams,
addsNewPgDBWithEnvVar,
deleteTestDBWithUrl,
deleteTestDBWithConParams,
deleteTestDDWithEnvVar,
} from './spec';
import { testMode } from '../../../helpers/common';
const setup = () => {
describe('Setup route', () => {
it('Visit the index route', () => {
cy.visit(getIndexRoute()).then(setMetaData);
});
});
};
export const runManageDatabaseTests = () => {
describe('Manage Data sources Tests', () => {
it('Opens Manage Database route', openManageDatabases);
it('Opens Add database form', expandAddDatabaseForm);
it('Expands Connection settings form', expandConnectionSettingsform);
it('Fails on empty form submission', failsOnEmptyFormSubmission);
it(
'Successfully creates a new postgres database with database url',
addsNewPostgresDatabaseWithUrl
);
it(
'Successfully creates a new postgres database with connection parameters',
addsNewPgDBWithConParams
);
it(
'Successfully creates a new postgres database with env variable ',
addsNewPgDBWithEnvVar
);
it('Fails to connect db with duplicate name', failDuplicateNameDb);
it('Successfully deletes test DB added with URL', deleteTestDBWithUrl);
it(
'Successfully deletes test DB added with connection params',
deleteTestDBWithConParams
);
it(
'Successfully deletes test DB added with env variable',
deleteTestDDWithEnvVar
);
});
};
if (testMode !== 'cli') {
setup();
runManageDatabaseTests();
}

View File

@ -23,3 +23,11 @@
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
Cypress.Commands.add('getBySel', (selector, ...args) => {
return cy.get(`[data-test=${selector}]`, ...args);
});
Cypress.Commands.add('getBySelLike', (selector, ...args) => {
return cy.get(`[data-test*=${selector}]`, ...args);
});

View File

@ -1,4 +1,17 @@
// type definition for all custom commands
declare namespace Cypress {
interface Chainable<Subject> {}
interface Chainable<Subject> {
/**
* Custom command to select DOM element by data-test attribute.
* <button data-test="greeting"> </button>
* @example cy.getBySel('greeting')
*/
getBySel(value: string): Chainable<Element>;
/**
* Custom command to select DOM element by data-test* attribute.
* <button data-test="save_me_oh_God"> </button>
* @example cy.getBySelLike('save_me')
*/
getBySelLike(value: string): Chainable<Element>;
}
}

View File

@ -257,6 +257,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
value={connectDBInputState.displayName}
label="Database Display Name"
placeholder="database name"
data-test="database-display-name"
/>
<label
key="Data Source Driver"
@ -274,6 +275,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
className={`form-control ${styles.connect_db_input_pad}`}
data-test="database-type"
>
<option key="postgres" value="postgres">
Postgres
@ -296,6 +298,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
value={connectDBInputState.databaseURLState.dbURL}
placeholder={dbTypePlaceholders[connectDBInputState.dbType]}
disabled={isEditState}
data-test="database-url"
/>
) : null}
{connectionType === connectionTypes.ENV_VAR ? (
@ -309,6 +312,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
value={connectDBInputState.envVarURLState.envVarURL}
data-test="database-url-env"
/>
) : null}
{connectionType === connectionTypes.CONNECTION_PARAMS &&
@ -324,6 +328,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
value={connectDBInputState.connectionParamState.host}
data-test="host"
/>
<LabeledInput
label="Port"
@ -335,6 +340,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
value={connectDBInputState.connectionParamState.port}
data-test="port"
/>
<LabeledInput
label="Username"
@ -346,6 +352,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
value={connectDBInputState.connectionParamState.username}
data-test="username"
/>
<LabeledInput
label="Password"
@ -359,6 +366,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
value={connectDBInputState.connectionParamState.password}
data-test="password"
/>
<LabeledInput
key="connect-db-database-name"
@ -371,6 +379,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
})
}
value={connectDBInputState.connectionParamState.database}
data-test="database-name"
/>
</>
) : null}
@ -412,6 +421,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
}
min="0"
labelInBold
data-test="max-connections"
/>
</div>
<div className={styles.connnection_settings_form_input_layout}>
@ -432,6 +442,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
}
min="0"
labelInBold
data-test="idle-timeout"
/>
</div>
<div className={styles.connnection_settings_form_input_layout}>
@ -452,6 +463,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
}
min="0"
labelInBold
data-test="retries"
/>
</div>
</div>
@ -467,6 +479,7 @@ const ConnectDatabase: React.FC<ConnectDatabaseProps> = props => {
...(loading && { cursor: 'progress' }),
}}
disabled={loading}
data-test="save-database"
>
{!isEditState ? 'Connect Database' : 'Edit Connection'}
</Button>

View File

@ -58,6 +58,7 @@ const DatabaseListItem: React.FC<DatabaseListItemProps> = ({
return (
<div
className={`${styles.flex_space_between} ${styles.add_pad_min} ${styles.db_list_item}`}
data-test={dataSource.name}
>
<div className={styles.display_flex}>
<Button