diff --git a/src/api.js b/src/api.js index 5ae6a88..8f9ba13 100644 --- a/src/api.js +++ b/src/api.js @@ -18,7 +18,7 @@ class API { */ async checkConnect () { try { - return this.handleResponse(await this.client.get('/user')); + return this.handleResponse(await this.client.get('/users')); } catch (error) { if(this.displayDebugLogs === true){ @@ -35,7 +35,7 @@ class API { */ async createLaunch (projectName, options) { try { - return this.handleResponse(await this.client.post(`/${projectName}/launch`, options)); + return this.handleResponse(await this.client.post(`/v1/${projectName}/launch`, options)); } catch (error) { return this.handleError(error); @@ -50,7 +50,7 @@ class API { */ async finishLaunch (projectName, launchId, options) { try { - return this.handleResponse(await this.client.put(`/${projectName}/launch/${launchId}/finish`, options)); + return this.handleResponse(await this.client.put(`/v1/${projectName}/launch/${launchId}/finish`, options)); } catch (error) { return this.handleError(error); @@ -65,7 +65,7 @@ class API { */ async forceStopLaunch (projectName, launchId, options) { try { - return this.handleResponse(await this.client.put(`/${projectName}/launch/${launchId}/stop`, options)); + return this.handleResponse(await this.client.put(`/v1/${projectName}/launch/${launchId}/stop`, options)); } catch (error) { return this.handleError(error); @@ -79,7 +79,7 @@ class API { */ async createTestItem (projectName, options) { try { - return this.handleResponse(await this.client.post(`/${projectName}/item`, options)); + return this.handleResponse(await this.client.post(`/v1/${projectName}/item`, options)); } catch (error) { return this.handleError(error); @@ -94,7 +94,7 @@ class API { */ async createChildTestItem (projectName, parentItem, options) { try { - return this.handleResponse(await this.client.post(`/${projectName}/item/${parentItem}`, options)); + return this.handleResponse(await this.client.post(`/v1/${projectName}/item/${parentItem}`, options)); } catch (error) { return this.handleError(error); @@ -109,7 +109,7 @@ class API { */ async finishTestItem (projectName, testItemId, options) { try { - return this.handleResponse(await this.client.put(`/${projectName}/item/${testItemId}`, options)); + return this.handleResponse(await this.client.put(`/v1/${projectName}/item/${testItemId}`, options)); } catch (error) { return this.handleError(error); @@ -159,19 +159,52 @@ class API { headers: { 'Content-type': `multipart/form-data; boundary=${MULTIPART_BOUNDARY}`, 'Authorization': `Bearer ${this.token}` } }); - await instance.post(`${this.baseURL}/${projectName}/log`, this.buildMultiPartStream([options], { + await instance.post(`${this.baseURL}/v1/${projectName}/log`, this.buildMultiPartStream([options], { name: options.file.name, type: 'image/png', content: fs.readFileSync(fullPath) }, MULTIPART_BOUNDARY)); } - else this.handleResponse(await this.client.post(`/${projectName}/log`, options)); + else this.handleResponse(await this.client.post(`/v1/${projectName}/log`, options)); } catch (error) { this.handleError(error); } } + async getLaunches(projectName) { + try { + const response = await this.client.get(`/v1/${projectName}/launch/latest`); + return this.handleResponse(response).content; + } + catch (error) { + return this.handleError(error); + } + } + + async getItems(projectName, launchId) { + try { + const response = await this.client.get(`/v1/${projectName}/item?filter.eq.launchId=${launchId}&isLatest=false&launchesLimit=0`)//filter.eq.launchId=${launchId}&isLatest=false&launchesLimit=0`); + return this.handleResponse(response).content; + } + catch (error) { + return this.handleError(error); + } + } + + async getItemLogs(projectName, itemId, logLevel='info') { + try { + const response = await this.client.post(`/v1/${projectName}/log/under`, { + itemIds: [itemId], + logLevel: logLevel + }); + return this.handleResponse(response)[itemId]; + } + catch (error) { + return this.handleError(error); + } + } + /** * Retrieving all logs in a project * @param {*} projectName The name of the project @@ -179,7 +212,7 @@ class API { */ async getLogs(projectName) { try { - const response = await this.client.get(`/${projectName}/log`); + const response = await this.client.get(`/v1/${projectName}/log`); return this.handleResponse(response); } catch (error) { diff --git a/src/index.js b/src/index.js index b92121e..b4cf762 100644 --- a/src/index.js +++ b/src/index.js @@ -78,12 +78,13 @@ exports['default'] = () => { async reportLogs(testId, level, message, time, attachment) { if(message !== undefined) { const isJSON = this.reporter.client.isJSON(message) || Array.isArray(message); + const isException = isJSON && JSON.parse(message).errMsg !== undefined //If the log is a stacktrace, and we want to focus on printing the error message itself. - if(isJSON && JSON.parse(message).errMsg !== undefined) message = JSON.parse(message).errMsg; + if(isException) message = JSON.parse(message).errMsg; //If the log is a JS Object else if(isJSON) message = JSON.parse(message); else if(typeof message === 'object') message = `"${message}"`; - message = this.reporter.client.isJSON(message) ? JSON.stringify(message): message; + message = isJSON ? JSON.stringify(message): message; } await this.reporter.sendTestLogs(testId, level, message, time, attachment); }, diff --git a/src/report-portal.js b/src/report-portal.js index 1ad219a..0aa575a 100644 --- a/src/report-portal.js +++ b/src/report-portal.js @@ -17,7 +17,7 @@ class ReportPortal { this.client = new RPClient({ protocol: (cliArguments.rprotocol) ? cliArguments.rprotocol: 'https', domain: cliArguments.rdomain, - apiPath: '/api/v1', + apiPath: '/api', token: cliArguments.rtoken, }); this.connected = true; diff --git a/src/uat.js b/src/uat.js index 29256e1..128a03e 100644 --- a/src/uat.js +++ b/src/uat.js @@ -87,6 +87,30 @@ class UAT { return this.handleError(error); } } + + async getApiKeys(token, userId) { + try { + this.setApiToken(token); + const response = await this.client.get(`api/users/${userId}/api-keys`) + console.log(response); + return this.handleResponse(response).items; + } + catch (error) { + return this.handleError(error); + } + } + + async createApiToken(token, userId, name) { + try { + this.setApiToken(token); + const response = await this.client.post(`api/users/${userId}/api-keys`, {name: name}) + console.log(response); + return this.handleResponse(response); + } + catch (error) { + return this.handleError(error); + } + } /** * Checking if item is a valid JSON diff --git a/tests/integration/integration.executor.ts b/tests/integration/integration.executor.ts index 2884b04..c1a8fc5 100644 --- a/tests/integration/integration.executor.ts +++ b/tests/integration/integration.executor.ts @@ -9,16 +9,21 @@ describe('Performing Integration testing', async function() { this.timeout(10 * 60 * 60 * 60); before(async () => { loadArguments(); - const client = new UAT({ + let client = new UAT({ protocol: 'http', domain: 'localhost:8080', apiPath: '/uat', }); - const token = await client.getApiToken('superadmin', 'erebus'); + const token = await client.getApiToken('default', '1q2w3e'); console.log(`Got the following token: ${JSON.stringify(token)}`) - const apiToken = await client.generateApiToken(token.access_token); - console.log(`Generated the following report portal token: ${apiToken.access_token}`) - cliArguments.rtoken = token.access_token; + client = new UAT({ + protocol: 'http', + domain: 'localhost:8080', + apiPath: '/', + }); + const apiToken = await client.createApiToken(token.access_token, 1, 'testing'+new Date().getTime() ); + console.log(`Generated the following report portal token: ${JSON.stringify(apiToken)}`) + cliArguments.rtoken = apiToken.api_key; console.log(`List of arguments: ${JSON.stringify(cliArguments)}`) testcafeServer = await createTestCafe('localhost', 1337, 1338); }); @@ -30,6 +35,7 @@ describe('Performing Integration testing', async function() { }); it('Running TestCafe Tests', async () => { + cliArguments.rlaunch="TestCafe Tests" const runner = testcafeServer.createRunner(); const failedCount = await runner .src(['tests/integration/integration.testcafe.ts']) @@ -40,6 +46,7 @@ describe('Performing Integration testing', async function() { console.log('Tests failed: ' + failedCount); }); it('Retry mechanism Tests', async () => { + cliArguments.rlaunch="Retry mechanism Tests" const runner = testcafeServer.createRunner(); const failedCount = await runner .src(['tests/integration/integration.retry.testcafe.ts']) diff --git a/tests/integration/integration.testcafe.ts b/tests/integration/integration.testcafe.ts index 8a703a0..f55e50d 100644 --- a/tests/integration/integration.testcafe.ts +++ b/tests/integration/integration.testcafe.ts @@ -1,5 +1,12 @@ import { t } from 'testcafe'; import { cliArguments } from 'cli-argument-parser'; +declare global { + interface TestController { + testRun: { + name: string; + }; + } +} const API = require('../../src/api.js'); let api: typeof API; fixture `First fixture` @@ -8,42 +15,51 @@ fixture `First fixture` api = new API({ protocol: 'http', domain: 'localhost:8080', - apiPath: '/api/v1', + apiPath: '/api', token: cliArguments.rtoken, }) }); test('Taking screenshot', async () => { - await logAndVerify('About to take a screenshot'); + await logAndVerify('Taking screenshot', 'About to take a screenshot'); await t.takeScreenshot() - await logAndVerify('The screenshot was succesfully taken!'); + await logAndVerify('Taking screenshot', 'The screenshot was succesfully taken!'); }) test('Negative testing, verifying Error display', async () => { - await logAndVerify('About to fail..'); - await logAndVerify(`${{obj: 'X', obj2: { x: 'Y'}}}`) - await logAndVerify({obj: 'X', obj2: { x: 'Y'}}) + await logAndVerify('Negative testing, verifying Error display', 'About to fail..'); + await logAndVerify('Negative testing, verifying Error display', `${{obj: 'X', obj2: { x: 'Y'}}}`) + await logAndVerify('Negative testing, verifying Error display', {obj: 'X', obj2: { x: 'Y'}}) await t.expect('X').eql('Y', 'OMG'); - await logAndVerify('The test failed!'); + await logAndVerify('Negative testing, verifying Error display', 'The test failed!'); }) fixture `Second fixture` test.skip('Skipping the test', async () => { - await logAndVerify('The test is skipped. This log shoud not be appearing.'); + await logAndVerify('Skipping the test', 'The test is skipped. This log shoud not be appearing.'); }) test('Basic print', async () => { - await logAndVerify('Printing the test contents'); + await logAndVerify('Basic print', 'Printing the test contents'); }) /** * Logging a message via console.log and verifying it exists in report portal * @param logMsg The log message */ -async function logAndVerify(logMsg: any) { - console.log(logMsg); +async function logAndVerify(testName: string, logMsg: any) { + const message = typeof logMsg !== 'string' ? JSON.stringify(logMsg): logMsg + console.log(message); await sleepInSeconds(5 * 1000); - let logs = await api.getLogs(cliArguments.rproject); - let log = logs.content.filter(l => l.message === logMsg); - process.stdout.write(`\n[Test logs]: Found ${log.length} occurances for message '${logMsg}'\n`); - await t.expect(log.length).gte(1, `Log appearances for '${logMsg}'`); + let launches = await api.getLaunches(cliArguments.rproject); + launches = launches.filter(l => l.name === cliArguments.rlaunch) + const launchId = launches[0].id; + const items = await api.getItems(cliArguments.rproject, launchId, testName) + + const item = items.find(item => item.name === testName && item.type === 'TEST') + const logs = await api.getItemLogs(cliArguments.rproject, item.id) + + const filteredLogs = logs.filter(l => l.message === message); + + process.stdout.write(`\n[Test logs]: Found ${filteredLogs.length} occurances for message '${message}'\n`); + await t.expect(filteredLogs.length).gte(1, `Log appearances for '${message}'`); } /**