Agent to integrate NightwatchJS with ReportPortal.
- More about NightwatchJS
- More about ReportPortal
Install the agent in your project:
npm install --save-dev @reportportal/agent-js-nightwatch
Create rp.json file with reportportal configuration:
{
"token": "00000000-0000-0000-0000-000000000000",
"endpoint": "https://your.reportportal.server/api/v1",
"project": "YourReportPortalProjectName",
"launch": "YourLauncherName",
"attributes": [
{
"key": "YourKey",
"value": "YourValue"
},
{
"value": "YourValue"
}
],
"description": "Your launch description",
"rerun": true,
"rerunOf": "launchUuid of already existed launch",
"mode": "DEFAULT",
"debug": false,
"parallelRun": true
}
Parameter | Description |
---|---|
token | User's Report Portal token from which you want to send requests. It can be found on the profile page of this user. |
endpoint | URL of your server. For example 'https://server:8080/api/v1'. |
launch | Name of launch at creation. |
project | The name of the project in which the launches will be created. |
rerun | Default: false. Enable rerun |
rerunOf | UUID of launch you want to rerun. If not specified, report portal will update the latest launch with the same name |
mode | Launch mode. Allowable values DEFAULT (by default) or DEBUG. |
debug | This flag allows seeing the logs of the client-javascript. Useful for debugging. |
parallelRun | Default: false. Indicates if tests running in parallel (uses for post-factum-reporter) |
This agent supports two types of reporting:
- Post-factum reporting
- Real-time reporting
This reporter sends results of test executions to Report Portal when all tests have been finished.
-
Create reporter.js file with code like:
const { PostFactumReporter } = require('@reportportal/agent-js-nightwatch'); const config = require('./rp.json'); const reporter = new PostFactumReporter(config); module.exports = { write : (results, options, done) => { return reporter.startReporting(results, done); } };
-
Create the
nightwatch.conf.js
configuration file. -
Run your tests with --config and --reporter options specified:
nightwatch --config ./nightwatch.conf.js --reporter ./reporter.js
This reporter sends results of test executions to Report Portal during tests run.
Since Nightwatch does not initially support real-time test report results, this approach requires a bit more preparation.
Since tests in nightwatch can be run sequentially or in parallel, each of the execution methods requires its own small preparation steps.
Each run type supports the Reporting API to use it directly in tests.
-
Create the
nightwatch.conf.js
configuration file. -
Create the
reporter
instance like:const { RealTimeReporter, ReportingAPI } = require('@reportportal/agent-js-nightwatch'); const config = require('./rp.json'); const rpReporter = new RealTimeReporter(config);
-
Add global
before
andafter
hook handlers:
Start and finish launch here.
Also to use Reporting API it must be initialized inbefore
hook and destroyed inafter
hook.module.exports = { // ...your config, globals: { before: function (done) { ReportingAPI.init(); const launchParams = { // launch params from rp.json can be overwritten here description: 'Awesome launch', attributes: [{ key: 'status', value: 'passed' }], }; rpReporter.startLaunch(launchParams); done(); }, after: function (done) { rpReporter.finishLaunch(); ReportingAPI.destroy(); done(); }, } }
-
Now you able to use agent API in tests to report results in real time (see the API reference).
No other preparations are required from the test definitions.
-
Create the
nightwatch.conf.js
configuration file. -
Add global
before
andafter
hook handlers:
Start and finish launch here.
Also you createrpReporter
instance inside thebefore
hook body, because the reporter must be created ONLY ONCE for the main process.const { RealTimeReporter } = require('@reportportal/agent-js-nightwatch'); const config = require('./rp.json'); let rpReporter; module.exports = { // ...your config, globals: { before: function (done) { rpReporter = new RealTimeReporter(config); const launchParams = { // launch params from rp.json can be overwritten here description: 'Awesome launch', attributes: [{ key: 'status', value: 'passed' }], }; rpReporter.startLaunch(launchParams); done(); }, after: function (done) { rpReporter.finishLaunch(); done(); }, } }
-
To start using the Reporting API in tests, you must initialize and destroy the API in EACH test suite:
const { ReportingAPI } = require('@reportportal/agent-js-nightwatch'); ReportingAPI.init(); describe('Suite name', function() { after((browser, done) => { browser.end(() => { ReportingAPI.destroy(); done(); }); }); });
-
Now you able to use agent API in tests to report results in real time (see the API reference).
The API provide methods for starting and finishing test items and hooks.
ReportingAPI.startSuite(suiteStartObj);
where suiteStartObj = { name: string, attributes: Array<Attribute>, description: string }
required: name
Example:
describe('Suite name', function() {
before((browser, done) => {
const suiteStartObj = {
name: 'Suite name',
attributes: [{ key: 'suite', value: 'any' }],
description: 'Suite description',
};
ReportingAPI.startSuite(suiteStartObj);
done();
});
});
ReportingAPI.finishSuite(suiteName);
required: suiteName
Example:
describe('Suite name', function() {
after((browser, done) => {
ReportingAPI.finishSuite('Suite name');
browser.end(() => {
done();
});
});
});
ReportingAPI.startTestCase(currentTest, parentName);
where currentTest = browser.currentTest
object
required: currentTest
parentName
required only for parallel run
Example:
describe('Suite name', function() {
beforeEach((browser) => {
ReportingAPI.startTestCase(browser.currentTest, 'Suite name');
});
});
ReportingAPI.finishTestCase(currentTest);
where currentTest = browser.currentTest
object
required: currentTest
Example:
describe('Suite name', function() {
afterEach((browser) => {
ReportingAPI.finishTestCase(browser.currentTest);
});
});
ReportingAPI.startBeforeSuite(parentName);
ReportingAPI.finishBeforeSuite(data);
where data = { name: string, status: string, attributes: Array<Attribute>, description: string }
where status
must be one of the following: passed, failed, stopped, skipped, interrupted, cancelled, info, warn
Example:
describe('Suite name', function() {
before((browser, done) => {
ReportingAPI.startBeforeSuite();
// beforeSuite related actions
ReportingAPI.finishBeforeSuite();
ReportingAPI.startSuite({ name: 'Suite name' });
done();
});
});
ReportingAPI.startAfterSuite(parentName);
ReportingAPI.finishAfterSuite(data);
where data = { name: string, status: string, attributes: Array<Attribute>, description: string }
where status
must be one of the following: passed, failed, stopped, skipped, interrupted, cancelled, info, warn
Example:
describe('Suite name', function() {
after((browser, done) => {
ReportingAPI.finishSuite('Suite name');
ReportingAPI.startAfterSuite();
// afterSuite related actions
ReportingAPI.finishAfterSuite();
browser.end(() => {
done();
});
});
});
ReportingAPI.startBeforeTestCase(parentName);
required: parentName
ReportingAPI.finishBeforeTestCase(data);
where data = { name: string, status: string, attributes: Array<Attribute>, description: string }
where status
must be one of the following: passed, failed, stopped, skipped, interrupted, cancelled, info, warn
Example:
describe('Suite name', function() {
beforeEach((browser) => {
ReportingAPI.startBeforeTestCase('Suite name');
// beforeEach related actions
ReportingAPI.finishBeforeTestCase();
ReportingAPI.startTestCase(browser.currentTest, 'Suite name');
});
});
ReportingAPI.startAfterTestCase(parentName);
required: parentName
ReportingAPI.finishAfterTestCase(data);
where data = { name: string, status: string, attributes: Array<Attribute>, description: string }
where status
must be one of the following: passed, failed, stopped, skipped, interrupted, cancelled, info, warn
Example:
describe('Suite name', function() {
afterEach((browser) => {
ReportingAPI.finishTestCase(browser.currentTest);
ReportingAPI.startAfterTestCase('Suite name');
// afterEach related actions
ReportingAPI.finishAfterTestCase();
});
});
The API provide methods for attaching data (logs, attributes, description, testCaseId, status).
Add attributes(tags) to the current test or for provided by name. Should be called inside of corresponding test.
ReportingAPI.addAttributes(attributes: Array<Attribute>, itemName?: string);
required: attributes
itemName
required only for parallel run
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
ReportingAPI.addAttributes([{ key: 'check', value: 'success' }]);
});
});
Append text description to the current test or for provided by name. Should be called inside of corresponding test.
ReportingAPI.addDescription(text: string, itemName?: string);
required: text
itemName
required only for parallel run
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
ReportingAPI.addDescription('Item description');
});
});
Set test case id to the current test or for provided by name. Should be called inside of corresponding test.
ReportingAPI.setTestCaseId(id: string, itemName?: string);
required: id
itemName
required only for parallel run
If testCaseId not specified, it will be generated automatically.
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
ReportingAPI.setTestCaseId('itemTestCaseId');
});
});
Send logs to report portal for the current test or for provided by name. Should be called inside of corresponding test.
ReportingAPI.log(level: LOG_LEVELS, message: string, file?: Attachment, itemName?: string);
required: level
, message
itemName
required only for parallel run
where level
can be one of the following: TRACE, DEBUG, WARN, INFO, ERROR, FATAL
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
const attachment = {
name: 'Cities',
type: FILE_TYPES.JSON,
content: fs.readFileSync(path.resolve(__dirname, '../data', 'cities.json')),
};
ReportingAPI.log('INFO', 'Log with attachment', attachment);
});
});
Send logs with corresponding level to report portal for the current test or for provided by name. Should be called inside of corresponding test.
ReportingAPI.logInfo(message: string, file?: Attachment, itemName?: string);
ReportingAPI.logDebug(message: string, file?: Attachment, itemName?: string);
ReportingAPI.logWarn(message: string, file?: Attachment, itemName?: string);
ReportingAPI.logError(message: string, file?: Attachment, itemName?: string);
ReportingAPI.logTrace(message: string, file?: Attachment, itemName?: string);
ReportingAPI.logFatal(message: string, file?: Attachment, itemName?: string);
required: message
itemName
required only for parallel run
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
ReportingAPI.logInfo('Log message');
ReportingAPI.logDebug('Log message');
ReportingAPI.logWarn('Log message');
ReportingAPI.logError('Log message');
ReportingAPI.logTrace('Log message');
ReportingAPI.logFatal('Log message');
});
});
Send logs to report portal for the current launch. Should be called inside of the any test.
ReportingAPI.launchLog(level: LOG_LEVELS, message: string, file?: Attachment);
required: level
, message
where level
can be one of the following: TRACE, DEBUG, WARN, INFO, ERROR, FATAL
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
const attachment = {
name: 'Cities',
type: FILE_TYPES.JSON,
content: fs.readFileSync(path.resolve(__dirname, '../data', 'cities.json')),
};
ReportingAPI.launchLog('INFO', 'Log with attachment for launch', attachment);
});
});
Send logs with corresponding level to report portal for the current launch. Should be called inside of the any test.
ReportingAPI.launchLogInfo(message: string, file?: Attachment);
ReportingAPI.launchLogDebug(message: string, file?: Attachment);
ReportingAPI.launchLogWarn(message: string, file?: Attachment);
ReportingAPI.launchLogError(message: string, file?: Attachment);
ReportingAPI.launchLogTrace(message: string, file?: Attachment);
ReportingAPI.launchLogFatal(message: string, file?: Attachment);
required: message
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
ReportingAPI.launchLogInfo('Log message');
ReportingAPI.launchLogDebug('Log message');
ReportingAPI.launchLogWarn('Log message');
ReportingAPI.launchLogError('Log message');
ReportingAPI.launchLogTrace('Log message');
ReportingAPI.launchLogFatal('Log message');
});
});
Assign corresponding status to the current test item or for provided by name.
ReportingAPI.setStatus(status: string, itemName?: string);
required: status
itemName
required only for parallel run
where status
must be one of the following: passed, failed, stopped, skipped, interrupted, cancelled, info, warn
Example:
describe('Suite name', function() {
test('ecosia.org test', function(browser) {
ReportingAPI.setStatus('passed', browser.currentTest.name);
});
});
setStatusFailed, setStatusPassed, setStatusSkipped, setStatusStopped, setStatusInterrupted, setStatusCancelled, setStatusInfo, setStatusWarn
Assign corresponding status to the current test item or for provided by name.
ReportingAPI.setStatusFailed(itemName?: string);
ReportingAPI.setStatusPassed(itemName?: string);
ReportingAPI.setStatusSkipped(itemName?: string);
ReportingAPI.setStatusStopped(itemName?: string);
ReportingAPI.setStatusInterrupted(itemName?: string);
ReportingAPI.setStatusCancelled(itemName?: string);
ReportingAPI.setStatusInfo(itemName?: string);
ReportingAPI.setStatusWarn(itemName?: string);
required: message
itemName
required only for parallel run
Example:
describe('Suite name', function() {
test('ecosia.org test', function() {
ReportingAPI.setStatusFailed('Log message');
ReportingAPI.setStatusPassed('Log message');
ReportingAPI.setStatusSkipped('Log message');
ReportingAPI.setStatusStopped('Log message');
ReportingAPI.setStatusInterrupted('Log message');
ReportingAPI.setStatusCancelled('Log message');
ReportingAPI.setStatusInfo('Log message');
ReportingAPI.setStatusWarn('Log message');
});
});
Do not forget to specify custom commands path in your nightwatch.conf.js
file:
module.exports = {
// ...your config,
custom_commands_path: ['./node_modules/@reportportal/agent-js-nightwatch/build/commands'],
}
Send log with corresponding level to report portal for the current test or for provided by name. Should be called inside of corresponding test.
browser.rpLog(message: string, level: string, itemName?: string);
required: message, level = 'INFO'
itemName
required only for parallel run
where level
can be one of the following: TRACE, DEBUG, WARN, INFO, ERROR, FATAL
Example:
describe('Suite name', function() {
test('ecosia.org test', function(browser) {
browser
.url('https://www.ecosia.org/')
.rpLog('Log message')
.end();
});
});
Send log with screenshot attachment with provided name to report portal for the current test or for provided by name. Should be called inside of corresponding test.
browser.rpSaveScreenshot(fileName: string, itemName?: string, callback?: function);
required: fileName
itemName
required only for parallel run
Example:
describe('Suite name', function() {
test('ecosia.org test', function(browser) {
browser
.url('https://www.ecosia.org/')
.rpSaveScreenshot('rpTestScreen.jpg')
.end();
});
});
Send log with screenshot attachment to report portal for the current test or for provided by name. Should be called inside of corresponding test.
browser.rpScreenshot(itemName?: string, callback?: function);
itemName
required only for parallel run
Example:
describe('Suite name', function() {
test('ecosia.org test', function(browser) {
browser
.url('https://www.ecosia.org/')
.rpScreenshot()
.end();
});
});
To integrate with Sauce Labs just add attributes for the test case:
[{
"key": "SLID",
"value": "# of the job in Sauce Labs"
}, {
"key": "SLDC",
"value": "EU (your job region in Sauce Labs)"
}]