Skip to content

Commit df2257e

Browse files
committed
First commit
1 parent 6cfbf2e commit df2257e

File tree

6 files changed

+383
-1
lines changed

6 files changed

+383
-1
lines changed

.editorconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This project uses EditorConfig (http://editorconfig.org) to standardize
2+
# tabulation, charset and other attributes of source files. Please head to
3+
# http://editorconfig.org/#download to check if your editor comes with
4+
# EditorConfig bundled or to download a plugin.
5+
6+
root = true
7+
8+
[*]
9+
charset = utf-8
10+
indent_style = tab
11+
indent_size = 4
12+
trim_trailing_whitespace = true
13+
insert_final_newline = true
14+
15+
[{package.json,*.yml}]
16+
indent_style = space
17+
indent_size = 2

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

README.md

Lines changed: 178 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,179 @@
11
# codeceptjs-dbhelper
2-
Database helper for CodeceptJS that uses database-js
2+
> Let your CodeceptJS tests talk to databases
3+
4+
This is a [Helper](https://codecept.io/helpers/) for [CodeceptJS](https://codecept.io/) that allows you to execute queries or commands to databases using [database-js](https://github.com/mlaanderson/database-js). That is, your tests written for CodeceptJS now will be able to access databases easily. **It is especially useful for preparing databases before/after executing test cases.**
5+
6+
## Install
7+
8+
```bash
9+
npm install --save-dev codeceptjs-dbhelper
10+
```
11+
12+
👉 You will also have to install the drivers of [database-js](https://github.com/mlaanderson/database-js) for the desired databases. For instance, whether you want to access a JSON file, just install the JSON driver.
13+
14+
### Available drivers
15+
16+
*Only install those you need*
17+
18+
- Access databases or SQL Server databases
19+
```bash
20+
npm install --save-dev database-js-adodb
21+
```
22+
- CSV files
23+
```bash
24+
npm install --save-dev database-js-csv
25+
```
26+
- Excel files
27+
```bash
28+
npm install --save-dev database-js-xlsx
29+
```
30+
- INI files
31+
```bash
32+
npm install --save-dev database-js-ini
33+
```
34+
- Firebase databases
35+
```bash
36+
npm install --save-dev database-js-firebase
37+
```
38+
- JSON files
39+
```bash
40+
npm install --save-dev database-js-json
41+
```
42+
- MySQL databases
43+
```bash
44+
npm install --save-dev database-js-mysql
45+
```
46+
- PostgreSQL databases
47+
```bash
48+
npm install --save-dev database-js-postgres
49+
```
50+
- SQLite databases
51+
```bash
52+
npm install --save-dev database-js-sqlite
53+
```
54+
55+
56+
## How to configure it
57+
58+
In your `codecept.json`, include **DbHelper** in the property **helpers** :
59+
60+
```js
61+
...
62+
"helpers": {
63+
...
64+
"DbHelper": {
65+
"require": "node_modules/codeceptjs-dbhelper"
66+
}
67+
},
68+
...
69+
```
70+
71+
## How to use it
72+
73+
The object `I` of your tests and events will have access to new methods. [See the API](#api).
74+
75+
76+
### Example 1
77+
78+
```js
79+
BeforeSuite( async( I ) => {
80+
// The first parameter is the key that will hold a reference to the db
81+
I.connect( "testdb", "mysql:///root:mypassword@localhost:3306/testdb" );
82+
} );
83+
84+
AfterSuite( async( I ) => {
85+
await I.removeConnection( "testdb" ); // also disconnects
86+
} );
87+
88+
89+
Before( async( I ) => {
90+
91+
// Delete all the records of the table user
92+
await I.run( "testdb", "DELETE FROM user" );
93+
94+
// Insert some users
95+
await I.run( "testdb", "INSERT INTO user ( username, password ) VALUES ( ?, ? )", "admin", "123456" );
96+
await I.run( "testdb", "INSERT INTO user ( username, password ) VALUES ( ?, ? )", "bob", "654321" );
97+
await I.run( "testdb", "INSERT INTO user ( username, password ) VALUES ( ?, ? )", "alice", "4lic3p4s$" );
98+
99+
} );
100+
101+
102+
// ... your feature ...
103+
104+
// ... your scenarios ...
105+
```
106+
107+
### Example 2
108+
109+
```js
110+
Feature( 'Foo' );
111+
112+
Scenario( 'Bar', async( I ) => {
113+
114+
// Query a user from the database
115+
const results = await I.query( "testdb", "SELECT * FROM user WHERE username = ?", "bob" );
116+
const bob = results[ 0 ];
117+
118+
I.amOnPage( '/login' );
119+
I.fillField( '#username', bob.username );
120+
I.fillField( '#password', bob.password );
121+
I.click( '#ok' );
122+
I.see( 'Welcome' );
123+
} );
124+
```
125+
126+
## API
127+
128+
129+
```js
130+
/**
131+
* Connects to a database by the given connection data.
132+
*
133+
* @param {string|number} key Key used to identify the database
134+
* @param {string|object} conn JDBC-like connection string or a connection object accepted by `database-js`.
135+
* @param {object|undefined} driver Driver object, used by `database-js` (optional).
136+
*/
137+
connect( key, conn, driver );
138+
139+
/**
140+
* Disconnects from a given database by its key.
141+
*
142+
* @param {string|number} key Key used to identify the database
143+
*/
144+
async disconnect( key );
145+
146+
/**
147+
* Disconnects and removes a database connection by its key.
148+
*
149+
* @param {string|number} key Key used to identify the database
150+
*/
151+
async removeConnection( key );
152+
153+
/**
154+
* Queries a database with the given key.
155+
*
156+
* @param {string|number} key Key used to identify the database
157+
* @param {string} command Query
158+
* @param {any[]} params Parameters of the query
159+
*
160+
* @returns {Promise<any[]>} The results of the query.
161+
*/
162+
async query( key, command, ... params );
163+
164+
/**
165+
* Executes a command to the database with the given key.
166+
*
167+
* @param {string|number} key Key used to identify the database
168+
* @param {string} command Command to execute
169+
* @param {any[]} params Parameters of the command
170+
*
171+
* @returns {Promise<any[]>}
172+
*/
173+
async run( key, command, ... params );
174+
```
175+
176+
177+
## License
178+
179+
MIT © [Thiago Delgado Pinto](https://github.com/thiagodp)

index.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
let dbjs = require('database-js'); // npm install database-js --save-dev
2+
3+
/**
4+
* Database helper
5+
*
6+
* @author Thiago Delgado Pinto
7+
*/
8+
class DbHelper extends Helper {
9+
10+
/**
11+
* Constructor
12+
*
13+
* @param {object} config Configuration declared in the CodeceptJS configuration file.
14+
*/
15+
constructor( config ) {
16+
super( config );
17+
const defaultOptions = {};
18+
// Attributes
19+
this.options = Object.assign( defaultOptions, config ); // Copy from config
20+
this.connectionMap = {};
21+
}
22+
23+
/**
24+
* Connects to a database by the given connection data.
25+
*
26+
* @param {string|number} key Key used to identify the database
27+
* @param {string|object} conn JDBC-like connection string or a connection object accepted by `database-js`.
28+
* @param {object|undefined} driver Driver object, used by `database-js` (optional).
29+
*/
30+
connect( key, conn, driver ) {
31+
return this.connectionMap[ key ] = this.createConnection( conn, driver );
32+
}
33+
34+
/**
35+
* Disconnects from a given database by its key.
36+
*
37+
* @param {string|number} key Key used to identify the database
38+
*/
39+
async disconnect( key ) {
40+
let conn = this.connectionMap[ key ];
41+
if ( ! conn ) {
42+
throw this._keyNotFoundError( key );
43+
}
44+
return await conn.close();
45+
}
46+
47+
/**
48+
* Disconnects and removes a database connection by its key.
49+
*
50+
* @param {string|number} key Key used to identify the database
51+
*/
52+
async removeConnection( key ) {
53+
if ( ! this.connectionMap[ key ] ) {
54+
return true;
55+
}
56+
let couldClose = true;
57+
try {
58+
await this.disconnect( key );
59+
} catch ( e ) {
60+
couldClose = false;
61+
}
62+
this.connectionMap[ key ] = undefined;
63+
return couldClose;
64+
}
65+
66+
/**
67+
* Queries a database with the given key.
68+
*
69+
* @param {string|number} key Key used to identify the database
70+
* @param {string} command Query
71+
* @param {any[]} params Parameters of the query
72+
*
73+
* @returns {Promise<any[]>} The results of the query.
74+
*/
75+
async query( key, command, ... params ) {
76+
let conn = this.connectionMap[ key ];
77+
if ( ! conn ) {
78+
throw this._keyNotFoundError( key );
79+
}
80+
let stmt = conn.prepareStatement( command );
81+
if ( ! params ) {
82+
return await stmt.query();
83+
}
84+
return await stmt.query( ... params );
85+
}
86+
87+
/**
88+
* Executes a command to the database with the given key.
89+
*
90+
* @param {string|number} key Key used to identify the database
91+
* @param {string} command Command to execute
92+
* @param {any[]} params Parameters of the command
93+
*
94+
* @returns {Promise<any[]>}
95+
*/
96+
async run( key, command, ... params ) {
97+
let conn = this.connectionMap[ key ];
98+
if ( ! conn ) {
99+
throw this._keyNotFoundError( key );
100+
}
101+
let stmt = conn.prepareStatement( command );
102+
if ( ! params ) {
103+
return await stmt.execute();
104+
}
105+
return await stmt.execute( ... params );
106+
}
107+
108+
/**
109+
* Creates a database connection.
110+
*
111+
* @param {string|object} conn JDBC-like connection string or a connection object accepted by `database-js`.
112+
* @param {object|undefined} driver Driver object, used by `database-js` (optional).
113+
*/
114+
createConnection( conn, driver ) {
115+
return new dbjs.Connection( conn, driver );
116+
}
117+
118+
/**
119+
* Checks whether there is a database with the given key.
120+
*
121+
* @param {string|number} key Key used to identify the database
122+
*/
123+
hasConnection( key ) {
124+
return !! this.connectionMap[ key ];
125+
}
126+
127+
/**
128+
* Get the database connection with the given key.
129+
*
130+
* @param {string|number} key Key used to identify the database
131+
*/
132+
getConnection( key ) {
133+
return this.connectionMap[ key ];
134+
}
135+
136+
/**
137+
* Creates an error related to the case when the given key is not found.
138+
*
139+
* @param {string|number} key Key used to identify the database
140+
*/
141+
_keyNotFoundError( key ) {
142+
return new Error( 'Database not found with the key ' + key );
143+
}
144+
145+
}
146+
147+
module.exports = DbHelper;

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "codeceptjs-dbhelper",
3+
"version": "1.0.0",
4+
"description": "Database helper for CodeceptJS that uses database-js",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/thiagodp/codeceptjs-dbhelper.git"
12+
},
13+
"keywords": [
14+
"codeceptjs",
15+
"database",
16+
"database-js"
17+
],
18+
"author": "thiagodp",
19+
"license": "MIT",
20+
"bugs": {
21+
"url": "https://github.com/thiagodp/codeceptjs-dbhelper/issues"
22+
},
23+
"homepage": "https://github.com/thiagodp/codeceptjs-dbhelper#readme",
24+
"dependencies": {
25+
"database-js": "^3.0.3"
26+
}
27+
}

0 commit comments

Comments
 (0)