import { describe, it, expect, afterEach, beforeAll, vi } from 'vitest'
import type { CommandArgs } from '@wdio/type'
import process from 'node:process'
import { Status } from 'allure-js-commons'
import CompoundError from '../src/compoundError.js'
import {
getTestStatus,
isEmpty,
isEachTypeHooks,
getErrorFromFailedTest,
isAllTypeHooks,
getLinkByTemplate,
findLast,
isScreenshotCommand,
getSuiteLabels,
isBeforeEachTypeHook,
} from '../src/utils.js'
import { suiteStart } from './__fixtures__/suite.js'
import { linkPlaceholder } from '../src/constants.js'
describe('utils', () => {
let processEmit: any
beforeAll(() => {
processEmit = process.emit.bind(process)
process.emit = vi.fn() as any
})
afterEach(() => {
process.emit = processEmit
})
describe('isScreenshotCommand', () => {
it('isScreenshotCommand', () => {
expect(isScreenshotCommand({ endpoint: '/session/id/screenshot' } as CommandArgs)).toEqual(true)
expect(isScreenshotCommand({ endpoint: '/wdu/hub/session/id/screenshot' } as CommandArgs)).toEqual(true)
expect(isScreenshotCommand({ endpoint: '/session/id/click' } as CommandArgs)).toEqual(false)
expect(isScreenshotCommand({ command: 'takeScreenshot' } as CommandArgs)).toEqual(true)
expect(isScreenshotCommand({ command: 'elementClick' } as CommandArgs)).toEqual(false)
expect(isScreenshotCommand({ endpoint: '/session/id/element/id/screenshot' } as CommandArgs)).toEqual(true)
})
})
describe('getTestStatus', () => {
it('return status for jasmine', () => {
const config: any = { framework: 'jasmine' }
expect(getTestStatus({} as any, config)).toEqual(Status.FAILED)
})
it('broken for test with no error', () => {
const config: any = { framework: 'mocha' }
expect(getTestStatus({} as any, config)).toEqual(Status.BROKEN)
})
it('failed for AssertionError', () => {
const config: any = { framework: 'mocha' }
const test = { error: { name: 'Error', message: 'AssertionError' } }
expect(getTestStatus(test as any, config)).toEqual(Status.FAILED)
})
it('failed for AssertionError stacktrace', () => {
const config: any = { framework: 'mocha' }
const test = { error: { stack: 'AssertionError' } }
expect(getTestStatus(test as any, config)).toEqual(Status.FAILED)
})
it('broken for not AssertionError', () => {
const config: any = { framework: 'mocha' }
const test = { error: { name: 'MyError' } }
expect(getTestStatus(test as any, config)).toEqual(Status.BROKEN)
})
it('broken for error without stacktrace', () => {
const config: any = { framework: 'mocha' }
const test = { error: {} }
expect(getTestStatus(test as any, config)).toEqual(Status.BROKEN)
})
it('failed status for not AssertionError stacktrace', () => {
const config: any = { framework: 'mocha' }
const test = { error: { stack: 'MyError stack trace' } }
expect(getTestStatus(test as any, config)).toEqual(Status.BROKEN)
})
})
it('isMochaEachHooks filter hook by title', () => {
expect(isEachTypeHooks('"before all" hook')).toEqual(false)
expect(isEachTypeHooks('"after all" hook')).toEqual(false)
expect(isEachTypeHooks('"before each" hook')).toEqual(true)
expect(isEachTypeHooks('"after each" hook')).toEqual(true)
})
it('isMochaBeforeEachHook filter hook by title', () => {
expect(isBeforeEachTypeHook('"before all" hook')).toEqual(false)
expect(isBeforeEachTypeHook('"after all" hook')).toEqual(false)
expect(isBeforeEachTypeHook('"before each" hook')).toEqual(true)
expect(isBeforeEachTypeHook('"after each" hook')).toEqual(false)
})
describe('isEmpty', () => {
it('should filter empty objects', () => {
expect(isEmpty({})).toEqual(true)
expect(isEmpty([])).toEqual(true)
expect(isEmpty(undefined)).toEqual(true)
expect(isEmpty(null)).toEqual(true)
expect(isEmpty('')).toEqual(true)
})
})
describe('isMochaHooks', () => {
it('should filter hook by title', () => {
expect(isEachTypeHooks('"before all" hook')).toEqual(false)
expect(isEachTypeHooks('"after all" hook')).toEqual(false)
expect(isEachTypeHooks('"before each" hook')).toEqual(true)
expect(isEachTypeHooks('"after each" hook')).toEqual(true)
expect(isAllTypeHooks('"before all" hook')).toEqual(true)
expect(isAllTypeHooks('"after all" hook')).toEqual(true)
expect(isAllTypeHooks('"before each" hook')).toEqual(false)
expect(isAllTypeHooks('"after each" hook')).toEqual(false)
})
})
describe('getErrorFromFailedTest', () => {
it('should handle test with no error object', () => {
const testStat = {}
expect(getErrorFromFailedTest(testStat as any)).toBeUndefined()
})
it('should return just the error property when there is no errors property', () => {
const testStat = {
error: new Error('Everything is Broken Forever'),
}
expect(getErrorFromFailedTest(testStat as any)!.message).toBe(
'Everything is Broken Forever'
)
})
it('should return a single error when there is an errors array with one error', () => {
const testStat = {
errors: [new Error('Everything is Broken Forever')],
error: new Error('Everything is Broken Forever'),
}
expect(getErrorFromFailedTest(testStat as any)!.message).toBe(
'Everything is Broken Forever'
)
})
it('should return a CompoundError of the errors when there is more than one error', () => {
const testStat = {
errors: [
new Error('Everything is Broken Forever'),
new Error('Additional things are broken'),
],
error: new Error('Everything is Broken Forever'),
}
const error = getErrorFromFailedTest(
testStat as any
) as CompoundError
expect(error instanceof CompoundError).toBe(true)
expect(error.innerErrors).toEqual(testStat.errors)
})
})
describe('getLinkByTemplate', () => {
const template = 'https://youtrack.jetbrains.com/issue/{}'
const id = 'JIRA-42'
it('should return link with task id', () => {
const link = getLinkByTemplate(template, id)
expect(link).toEqual(
'https://youtrack.jetbrains.com/issue/JIRA-42'
)
})
it('should return id if template is not a string', () => {
expect(getLinkByTemplate(undefined, id)).toEqual(id)
expect(getLinkByTemplate({} as any, id)).toEqual(id)
})
it('should throw error if template is invalid', () => {
const template = 'foo'
expect(() => getLinkByTemplate(template, id)).toThrow(
`The link template "${template}" must contain ${linkPlaceholder} substring.`
)
})
})
describe('findLast', () => {
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
it('should return last matched element', () => {
expect(findLast(arr, (el) => el % 2 === 0)).toEqual(8)
})
it('should return undefind when nothing matched', () => {
expect(findLast(arr, (el) => el === 10)).toEqual(undefined)
})
})
describe('getSuiteLabels', () => {
describe('suite stats with tags', () => {
it('returns allure labels', () => {
expect(
getSuiteLabels({
...suiteStart(),
tags: [
{
name: '@foo=bar',
}
]
})
).toEqual([
{
name: 'foo',
value: 'bar',
},
])
})
})
describe('suite stats with invalid tags', () => {
it('returns empty array', () => {
expect(
getSuiteLabels({
...suiteStart(),
tags: [
{
name: 'foo bar',
},
{
name: 'foo,bar',
}
]
})
).toEqual([])
})
})
describe('suite stats without tags', () => {
it('returns empty array', () => {
expect(getSuiteLabels({ ...suiteStart(), tags: undefined })).toEqual(
[]
)
})
})
})
})