1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import abilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; 17import { SysTestKit } from '../kit/SysTestKit'; 18 19import { TAG, PrintTag } from '../../Constant'; 20import { Core } from '../../core'; 21import { SuiteService } from '../service/SuiteService'; 22import { SpecService } from '../service/SpecService'; 23import { StaticSpec } from '../service/StaticSpec'; 24import { ReportAttrIF, TestcaseSummaryIF } from '../../interface'; 25import { ConfigService } from '../config/configService'; 26 27class OhReport { 28 public delegator: abilityDelegatorRegistry.AbilityDelegator; 29 public abilityDelegatorArguments: abilityDelegatorRegistry.AbilityDelegatorArgs; 30 public id: string; 31 public index: int; 32 public duration: long; 33 public currentThreadName: string; 34 public coreContext: Core | null; 35 public suiteService: SuiteService | null; 36 public specService: SpecService | null; 37 private taskDoneTime: number; 38 constructor(attr: ReportAttrIF) { 39 this.delegator = attr.delegator; 40 this.abilityDelegatorArguments = attr.abilityDelegatorArguments; 41 this.id = 'report'; 42 this.index = 0; 43 this.duration = 0; 44 this.currentThreadName = 'mainThread'; 45 this.coreContext = null; 46 this.suiteService = null; 47 this.specService = null; 48 } 49 50 init(coreContext: Core) { 51 this.coreContext = coreContext; 52 const suite = coreContext.getDefaultService('suite'); 53 if (suite !== null) { 54 this.suiteService = suite as SuiteService; 55 } 56 const spec = coreContext.getDefaultService('spec'); 57 if (spec !== null) { 58 this.specService = spec as SpecService; 59 } 60 } 61 62 taskStart() {} 63 64 async taskDone() { 65 const suite = this.suiteService; 66 if (suite) { 67 const summary = suite.getSummary(); 68 if (this.abilityDelegatorArguments !== null && summary !== null) { 69 this.taskDoneTime = new Date().getTime(); 70 let message = 71 '\n' + `${PrintTag.OHOS_REPORT_RESULT}: stream=Tests run: ` + summary.total + ', Failure: ' + summary.failure; 72 message += ', Error: ' + summary.error; 73 message += ', Pass: ' + summary.pass; 74 message += ', Ignore: ' + summary.ignore; 75 const core = this.coreContext; 76 if (core) { 77 const specService = core.getDefaultService('spec'); 78 if (specService !== null) { 79 const spec = specService as SpecService; 80 const num = spec.skipSpecNum; 81 if (Number(num) > 0) { 82 message += ', SkipSpec: ' + num; 83 } 84 } 85 } 86 87 message += '\n' + `${PrintTag.OHOS_REPORT_CODE}: ` + (summary.failure > 0 ? -1 : 0) + '\n'; 88 let isHasError = summary.failure > 0 || summary.error > 0; 89 if (core) { 90 const config = core.getDefaultService('config'); 91 if (config !== null) { 92 const cf = config as ConfigService; 93 if (cf.isBreakOnError() && isHasError) { 94 message += 95 '\n' + 96 `${PrintTag.OHOS_REPORT_RESULT}: breakOnError model, Stopping whole test suite if one specific test case failed or error` + 97 '\n'; 98 } 99 } 100 } 101 102 message += `${PrintTag.OHOS_REPORT_STATUS}: taskconsuming=` + summary.duration + '\n'; 103 console.info(`${message}`); 104 await SysTestKit.print(message); 105 } 106 console.info(`${TAG}report print success`); 107 this.delegator.finishTest('your test finished!!!', 0); 108 } 109 } 110 111 incorrectFormat() { 112 const core = this.coreContext; 113 if (core) { 114 const config = core.getDefaultService('config'); 115 if (config !== null) { 116 const configService = config as ConfigService; 117 if (configService.filterValid.length !== 0) { 118 const value = configService.filterValid; 119 const message = 'this param ' + value.join(',') + ' is invalid' + '\n'; 120 this.delegator.finishTest(message, 0); 121 } 122 } 123 } 124 } 125 126 incorrectTestSuiteFormat() { 127 const core = this.coreContext; 128 if (core) { 129 const config = core.getDefaultService('config'); 130 if (config !== null) { 131 const configService = config as ConfigService; 132 if (configService.filterXdescribe.length !== 0) { 133 let value = configService.filterXdescribe; 134 let message = 'xdescribe ' + value.join(',') + ' should not contain it' + '\n'; 135 this.delegator.finishTest(message, 0); 136 } 137 } 138 } 139 } 140 141 async suiteStart() { 142 if (this.abilityDelegatorArguments !== null) { 143 const suite = this.suiteService; 144 if (suite) { 145 let specArr = new Array<StaticSpec>(); 146 suite.getAllChildSuiteNum(suite.getCurrentRunningSuite(), specArr); 147 let message = '\n' + `${PrintTag.OHOS_REPORT_SUM}: ` + specArr.length; 148 suite.setCurrentRunningSuiteDesc(suite.getRootSuite(), suite.getCurrentRunningSuite(), ''); 149 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: class=` + suite.getCurrentRunningSuiteDesc() + '\n'; 150 if (suite.currentRunningSuite.isSkip) { 151 message += `${PrintTag.OHOS_REPORT_STATUS}: skipReason=` + suite.currentRunningSuite.skipReason + '\n'; 152 } 153 console.info(`${message}`); 154 await SysTestKit.print(message); 155 console.info(`${TAG}${suite.getCurrentRunningSuite().description} suiteStart print success`); 156 } 157 } 158 } 159 160 async suiteDone() { 161 if (this.abilityDelegatorArguments !== null) { 162 const suite = this.suiteService; 163 if (suite) { 164 const currentRunningSuite = suite.getCurrentRunningSuite(); 165 suite.setCurrentRunningSuiteDesc(suite.getRootSuite(), currentRunningSuite, ''); 166 let message = '\n' + `${PrintTag.OHOS_REPORT_STATUS}: class=` + suite.getCurrentRunningSuiteDesc(); 167 if (suite.currentRunningSuite.isSkip && suite.currentRunningSuite.skipReason !== '') { 168 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: skipReason=` + suite.currentRunningSuite.skipReason; 169 } 170 const isPromiseError = currentRunningSuite.isPromiseError; 171 if (isPromiseError) { 172 message += 173 '\n' + `${PrintTag.OHOS_REPORT_STATUS}: shortMsg=Promise(async, await) in describe is not allowed!`; 174 } 175 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: suiteconsuming=` + currentRunningSuite.duration; 176 const hookError = currentRunningSuite.hookError; 177 if (hookError) { 178 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: ${hookError.message}`; 179 } 180 message += '\n'; 181 console.info(`${message}`); 182 await SysTestKit.print(message); 183 console.info(`${TAG}${currentRunningSuite.description} suiteDone print success`); 184 } 185 } 186 } 187 188 async specStart() { 189 if (this.abilityDelegatorArguments !== null) { 190 const specService = this.specService; 191 const suiteService = this.suiteService; 192 if (specService) { 193 const curSpec = specService.currentRunningSpec; 194 if (curSpec) { 195 if (suiteService) { 196 const staticSpec = curSpec as StaticSpec; 197 let message = '\n' + `${PrintTag.OHOS_REPORT_STATUS}: class=` + suiteService.getCurrentRunningSuiteDesc(); 198 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: current=` + ++this.index; 199 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: id=JS`; 200 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: numtests=` + specService.getTestTotal(); 201 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: stream=`; 202 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: test=` + staticSpec.description; 203 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS_CODE}: 1` + '\n'; 204 if (staticSpec.isSkip) { 205 message += `${PrintTag.OHOS_REPORT_STATUS}: skipReason=` + staticSpec.skipReason + '\n'; 206 } 207 console.info(`${message}`); 208 await SysTestKit.print(message); 209 console.info(`${TAG}${staticSpec.description} specStart start print success`); 210 } 211 } 212 } 213 } 214 } 215 216 async specDone() { 217 if (this.abilityDelegatorArguments !== null) { 218 const specService = this.specService; 219 const suiteService = this.suiteService; 220 if (specService) { 221 if (suiteService) { 222 let message = '\n' + `${PrintTag.OHOS_REPORT_STATUS}: class=` + suiteService.getCurrentRunningSuiteDesc(); 223 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: current=` + this.index; 224 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: id=JS`; 225 message += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: numtests=` + specService.getTestTotal(); 226 let messageStack = ''; 227 let messageCode = ''; 228 const currentRunningSpec = specService.currentRunningSpec; 229 if (currentRunningSpec) { 230 const error = currentRunningSpec.error; 231 const fail = currentRunningSpec.fail; 232 if (error) { 233 let errorStack = ''; 234 const stack = error.stack; 235 if (stack) { 236 errorStack = stack.slice(0, -1); 237 } 238 let errorMsg = ''; 239 const message = error.message; 240 if (message) { 241 errorMsg = message; 242 } 243 messageStack = `${PrintTag.OHOS_REPORT_STATUS}: stack=` + errorStack; 244 messageCode += `${PrintTag.OHOS_REPORT_STATUS}: stream=`; 245 messageCode += 246 currentRunningSpec.expectMsg !== '' 247 ? `message: ${currentRunningSpec.expectMsg}, Error in ${currentRunningSpec.description}, ${errorMsg}` 248 : `Error in ${currentRunningSpec.description}, ${errorMsg}`; 249 messageCode += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: test=` + currentRunningSpec.description; 250 messageCode += '\n' + `${PrintTag.OHOS_REPORT_STATUS_CODE}: -1` + '\n'; 251 } else if (fail) { 252 let failStack = ''; 253 const fStack = fail.stack; 254 if (fStack) { 255 failStack = fStack.slice(0, -1); 256 } 257 let failMsg = ''; 258 if (fail.message) { 259 failMsg = fail.message; 260 } 261 messageStack += `${PrintTag.OHOS_REPORT_STATUS}: stack=` + failStack; 262 messageCode += `${PrintTag.OHOS_REPORT_STATUS}: stream=`; 263 messageCode += 264 currentRunningSpec.expectMsg !== '' 265 ? `message: ${currentRunningSpec.expectMsg}, Error in ${currentRunningSpec.description}, ${failMsg}` 266 : `Error in ${currentRunningSpec.description}, ${failMsg}`; 267 messageCode += '\n' + `${PrintTag.OHOS_REPORT_STATUS}: test=` + currentRunningSpec.description; 268 messageCode += '\n' + `${PrintTag.OHOS_REPORT_STATUS_CODE}: -2` + '\n'; 269 } else { 270 messageStack += `${PrintTag.OHOS_REPORT_STATUS}: stream=`; 271 messageCode += `${PrintTag.OHOS_REPORT_STATUS}: test=` + currentRunningSpec.description; 272 messageCode += '\n' + `${PrintTag.OHOS_REPORT_STATUS_CODE}: 0` + '\n'; 273 messageCode += currentRunningSpec.isSkip 274 ? `${PrintTag.OHOS_REPORT_STATUS}: skipReason=` + currentRunningSpec.skipReason + '\n' 275 : ''; 276 } 277 messageCode += `${PrintTag.OHOS_REPORT_STATUS}: consuming=` + currentRunningSpec.duration + '\n'; 278 } else { 279 messageCode += '\n'; 280 } 281 await SysTestKit.print(message); 282 await SysTestKit.print(messageStack); 283 await SysTestKit.print(messageCode); 284 if (currentRunningSpec) { 285 console.info(`${TAG}${currentRunningSpec.description} specDone end print success`); 286 } 287 } 288 } 289 } 290 } 291} 292 293export { OhReport }; 294