Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to add console log to allure and spec reporters (fix for #7001) #7134

Merged
merged 12 commits into from
Jul 15, 2021
1 change: 1 addition & 0 deletions packages/wdio-allure-reporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ exports.config = {
- `disableWebdriverScreenshotsReporting` - optional parameter(`false` by default), in order to not attach screenshots to the reporter.
- `useCucumberStepReporter` - optional parameter (`false` by default), set it to true in order to change the report hierarchy when using cucumber. Try it for yourself and see how it looks.
- `disableMochaHooks` - optional parameter (`false` by default), set it to true in order to not fetch the `before/after` stacktrace/screenshot/result hooks into the Allure Reporter.
- `addConsoleLogs` - optional parameter(`false` by default), set to true in order to attach console logs from step to the reporter.

## Supported Allure API
* `addLabel(name, value)` - assign a custom label to test
Expand Down
19 changes: 17 additions & 2 deletions packages/wdio-allure-reporter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Capabilities, Options } from '@wdio/types'

import {
getTestStatus, isEmpty, tellReporter, isMochaEachHooks, getErrorFromFailedTest,
isMochaAllHooks, getLinkByTemplate
isMochaAllHooks, getLinkByTemplate, attachConsoleLogs
} from './utils'
import { events, PASSED, PENDING, SKIPPED, stepStatuses } from './constants'
import {
Expand All @@ -30,13 +30,19 @@ class AllureReporter extends WDIOReporter {
private _config?: Options.Testrunner
private _lastScreenshot?: string
private _options: AllureReporterOptions
private _consoleOutput: string
private _originalStdoutWrite: any
private _addConsoleLogs: boolean

constructor(options: AllureReporterOptions = {}) {
const outputDir = options.outputDir || 'allure-results'
super({
...options,
outputDir,
})
this._addConsoleLogs = false
this._consoleOutput = ''
this._originalStdoutWrite = process.stdout.write.bind(process.stdout)
this._allure = new Allure()
this._capabilities = {}
this._options = options
Expand All @@ -45,6 +51,12 @@ class AllureReporter extends WDIOReporter {
this.registerListeners()

this._lastScreenshot = undefined

let processObj: any = process
if (options.addConsoleLogs || this._addConsoleLogs) processObj.stdout.write = (chunk: any, encoding: any, callback: any) => {
if (typeof chunk === 'string' && !chunk.includes('mwebdriver')) this._consoleOutput += '\t' + chunk
return this._originalStdoutWrite(chunk, encoding, callback)
}
praveendvd marked this conversation as resolved.
Show resolved Hide resolved
}

registerListeners() {
Expand Down Expand Up @@ -127,6 +139,7 @@ class AllureReporter extends WDIOReporter {
}

onTestStart(test: TestStats | HookStats) {
this._consoleOutput = ''
const testTitle = test.currentTest ? test.currentTest : test.title
if (this.isAnyTestRunning() && this._allure.getCurrentTest().name == testTitle) {
// Test already in progress, most likely started by a before each hook
Expand Down Expand Up @@ -192,6 +205,7 @@ class AllureReporter extends WDIOReporter {
}

onTestPass() {
attachConsoleLogs(this._consoleOutput, this._allure)
if (this._options.useCucumberStepReporter) {
return this._allure.endStep('passed')
}
Expand All @@ -216,7 +230,7 @@ class AllureReporter extends WDIOReporter {

this._allure.getCurrentTest().name = test.title
}

attachConsoleLogs(this._consoleOutput, this._allure)
const status = getTestStatus(test, this._config)
while (this._allure.getCurrentSuite().currentStep instanceof Step) {
this._allure.endStep(status)
Expand All @@ -226,6 +240,7 @@ class AllureReporter extends WDIOReporter {
}

onTestSkip(test: TestStats) {
attachConsoleLogs(this._consoleOutput, this._allure)
if (this._options.useCucumberStepReporter) {
this._allure.endStep('canceled')
} else if (!this._allure.getCurrentTest() || this._allure.getCurrentTest().name !== test.title) {
Expand Down
4 changes: 4 additions & 0 deletions packages/wdio-allure-reporter/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export interface AllureReporterOptions {
* with value specified in `addTestId(value)` call parameter. Example `https://example.org/tms/{}`
*/
tmsLinkTemplate?: string
/**
* optional parameter(`false` by default), in order to attach console logs from step to the reporter.
praveendvd marked this conversation as resolved.
Show resolved Hide resolved
*/
addConsoleLogs?: boolean
}

export interface AddLabelEventArgs {
Expand Down
13 changes: 13 additions & 0 deletions packages/wdio-allure-reporter/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Options } from '@wdio/types'
import CompoundError from './compoundError'
import { mochaEachHooks, mochaAllHooks, linkPlaceholder } from './constants'
import type { Status } from './types'
import AllureReporter from './index.js'

/**
* Get allure test status by TestStat object
Expand Down Expand Up @@ -105,3 +106,15 @@ export const getLinkByTemplate = (template: string | undefined, id: string) => {
}
return template.replace(linkPlaceholder, id)
}

/**
*
* @param {string} logs - logs to be attached
* @param {string} allure - allure report object
* @private
*/
export const attachConsoleLogs = (logs: string | undefined, allure: AllureReporter['_allure']) => {
if (logs) allure?.addAttachment('Console Logs',
'<pre style="display: inline-block; background-color:#4d4d4d;color:white;padding:20px;text-shadow:1px 1px 0 #444; min-width:100%; height:auto; min-height: 100%;">'
.concat('.........Console Logs.........\n\n'+logs, '</pre>'), 'text/html')
praveendvd marked this conversation as resolved.
Show resolved Hide resolved
}
29 changes: 27 additions & 2 deletions packages/wdio-allure-reporter/tests/suite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { suiteEnd, suiteStart } from './__fixtures__/suite'
import {
testFailed, testPending, testStart, testFailedWithMultipleErrors,
hookStart, hookFailed, hookStartWithCurrentTest,
testFailedWithAssertionErrorFromExpectWebdriverIO
} from './__fixtures__/testState'
testFailedWithAssertionErrorFromExpectWebdriverIO } from './__fixtures__/testState'
import {
commandStart, commandEnd, commandEndScreenShot, commandStartScreenShot
} from './__fixtures__/command'
import { log } from 'console'

let processOn: any
beforeAll(() => {
Expand Down Expand Up @@ -595,5 +595,30 @@ for (const protocol of ['webdriver', 'devtools']) {
const allureXml = results[0]
expect(allureXml('test-case attachment[title="Screenshot"]')).toHaveLength(1)
})

it('should attach console log', () => {
const allureOptions = {
stdout: true,
outputDir,
disableMochaHooks: true,
addConsoleLogs: true
}
const reporter = new AllureReporter(allureOptions)
reporter.onRunnerStart(runnerStart())
reporter.onSuiteStart(suiteStart())
//this shouldn't be logged
log('Printing to console 1')
reporter.onTestStart(testStart())
//this should be logged
log('Printing to console 2')
reporter.onTestPass()
reporter.onSuiteEnd(suiteEnd())
reporter.onRunnerEnd(runnerEnd())
const results = getResults(outputDir)
expect(results).toHaveLength(1)
const allureXml = results[0]
expect(allureXml('test-case attachment[title="Console Logs"]')).toHaveLength(1)
})

})
}
15 changes: 15 additions & 0 deletions packages/wdio-spec-reporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,19 @@ Default: `false`
onlyFailures: true,
},
]
```

### addConsoleLogs
Set to true to show console logs from steps in final report

Type: `boolean`
Default: `false`

```js
[
"spec",
{
addConsoleLogs: true,
},
]
```
29 changes: 27 additions & 2 deletions packages/wdio-spec-reporter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export default class SpecReporter extends WDIOReporter {
private _indents = 0
private _suiteIndents: Record<string, number> = {}
private _orderedSuites: SuiteStats[] = []
private _consoleOutput = ''
private _consoleLogs: Array<string> = []
praveendvd marked this conversation as resolved.
Show resolved Hide resolved
private _originalStdoutWrite: any = process.stdout.write.bind(process.stdout);
praveendvd marked this conversation as resolved.
Show resolved Hide resolved

private _addConsoleLogs = false

// Keep track of the order that suites were called
private _stateCounts: StateCount = {
Expand Down Expand Up @@ -45,6 +50,11 @@ export default class SpecReporter extends WDIOReporter {
this._sauceLabsSharableLinks = 'sauceLabsSharableLinks' in options
? options.sauceLabsSharableLinks as boolean
: this._sauceLabsSharableLinks
let processObj: any = process
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let processObj: any = process
let processObj = process

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i remove any , i get
image

if (options.addConsoleLogs || this._addConsoleLogs) processObj.stdout.write = (chunk: any, encoding: any, callback: any) => {
if (typeof chunk === 'string' && !chunk.includes('mwebdriver')) this._consoleOutput += chunk
return this._originalStdoutWrite(chunk, encoding, callback)
}
praveendvd marked this conversation as resolved.
Show resolved Hide resolved
}

onSuiteStart (suite: SuiteStats) {
Expand All @@ -67,15 +77,22 @@ export default class SpecReporter extends WDIOReporter {
}
}

onTestStart () {
this._consoleOutput = ''
}

onTestPass () {
this._consoleLogs.push(this._consoleOutput)
this._stateCounts.passed++
}

onTestFail () {
this._consoleLogs.push(this._consoleOutput)
this._stateCounts.failed++
}

onTestSkip () {
this._consoleLogs.push(this._consoleOutput)
this._stateCounts.skipped++
}

Expand All @@ -97,7 +114,7 @@ export default class SpecReporter extends WDIOReporter {
const divider = '------------------------------------------------------------------'

// Get the results
const results = this.getResultDisplay()
const results = this.getResultDisplay(preface)

// If there are no test results then return nothing
if (results.length === 0) {
Expand Down Expand Up @@ -218,7 +235,7 @@ export default class SpecReporter extends WDIOReporter {
* @param {Array} suites Runner suites
* @return {Array} Display output list
*/
getResultDisplay () {
getResultDisplay (preface?: string) {
const output = []
const suites = this.getOrderedSuites()
const specFileReferences: string[] = []
Expand Down Expand Up @@ -265,6 +282,14 @@ export default class SpecReporter extends WDIOReporter {
const table = getFormattedRows(rawTable, testIndent)
output.push(...table)
}

// print console output
const logItem = this._consoleLogs.shift()
if (logItem) {
output.push('')
output.push(testIndent.repeat(2) + '.........Console Logs.........')
output.push(testIndent.repeat(3) + logItem?.replace(/\n/g, '\n'.concat(preface + ' ', testIndent.repeat(3))))
}
}

// Put a line break after each suite (only if tests exist in that suite)
Expand Down
6 changes: 6 additions & 0 deletions packages/wdio-spec-reporter/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export interface SpecReporterOptions {
* @default: false
*/
onlyFailures?: boolean
/**
* Ability to show console logs from steps in report
*
* @default: false
*/
addConsoleLogs?: boolean
}

export interface TestLink {
Expand Down
23 changes: 23 additions & 0 deletions packages/wdio-spec-reporter/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
SUITES_NO_TESTS_WITH_HOOK_ERROR,
SUITES_MULTIPLE_ERRORS
} from './__fixtures__/testdata'
import { log } from 'console'
import { runnerEnd, runnerStart } from '../../wdio-allure-reporter/tests/__fixtures__/runner'
import { suiteEnd, suiteStart } from '../../wdio-allure-reporter/tests/__fixtures__/suite'

const reporter = new SpecReporter({})

Expand Down Expand Up @@ -545,6 +548,26 @@ describe('SpecReporter', () => {
})
})

describe('add console logs', () => {
const options = { addConsoleLogs: true }
beforeEach(() => {
tmpReporter = new SpecReporter(options)
tmpReporter.onRunnerStart(runnerStart())
tmpReporter.onSuiteStart(suiteStart())
tmpReporter.onTestStart()
log('Printing to console spec')

})

it('should get new passed symbol', () => {
tmpReporter.onTestPass()
tmpReporter.onSuiteStart(suiteEnd())
tmpReporter.onRunnerEnd(runnerEnd())
expect(tmpReporter.getResultDisplay()).toContain('Printing to console spec')
praveendvd marked this conversation as resolved.
Show resolved Hide resolved
})

praveendvd marked this conversation as resolved.
Show resolved Hide resolved
})

describe('onlyFailures', () => {
let printReporter = null
const runner = getRunnerConfig({ hostname: 'localhost' })
Expand Down