Best Cerberus-source code snippet using org.cerberus.engine.execution.impl.ExecutionRunService.updateExecution
Source:ExecutionRunService.java
...201 || execution.getApplicationObj().getType().equalsIgnoreCase(Application.TYPE_FAT))) {202 MessageGeneral mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_PREPARINGROBOTSERVER);203 mes.setDescription(mes.getDescription().replace("%IP%", execution.getRobotHost()));204 execution.setResultMessage(mes);205 updateExecutionWebSocketOnly(execution, true);206 // Decoding Robot capabilities.207 if (execution.getRobotObj() != null) {208 List<RobotCapability> caps = execution.getRobotObj().getCapabilities();209 List<RobotCapability> capsDecoded = new ArrayList<>();210 for (RobotCapability cap : caps) {211 String capDecoded = "";212 try {213 answerDecode = variableService.decodeStringCompletly(cap.getCapability(), execution, null, false);214 capDecoded = answerDecode.getItem();215 if (!(answerDecode.isCodeStringEquals("OK"))) {216 // If anything wrong with the decode --> we stop here with decode message in the action result.217 LOG.debug("{}TestCase interrupted due to decode 'Robot Capability key' Error.", logPrefix);218 throw new CerberusException(new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_CAPABILITYDECODE)219 .resolveDescription("MES", answerDecode.getMessageDescription())220 .resolveDescription("FIELD", "")221 .resolveDescription("AREA", "Robot Capability key : " + cap.getCapability()));222 }223 } catch (CerberusEventException cex) {224 LOG.warn(cex);225 }226 String valDecoded = "";227 try {228 answerDecode = variableService.decodeStringCompletly(cap.getValue(), execution, null, false);229 valDecoded = answerDecode.getItem();230 if (!(answerDecode.isCodeStringEquals("OK"))) {231 // If anything wrong with the decode --> we stop here with decode message in the action result.232 LOG.debug("{}TestCase interrupted due to decode 'Robot Capability value' Error.", logPrefix);233 throw new CerberusException(new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_CAPABILITYDECODE)234 .resolveDescription("MES", answerDecode.getMessageDescription())235 .resolveDescription("FIELD", "")236 .resolveDescription("AREA", "Robot Capability value : " + cap.getValue()));237 }238 } catch (CerberusEventException cex) {239 LOG.warn(cex);240 }241 capsDecoded.add(robotCapabilityFactory.create(cap.getId(), cap.getRobot(), capDecoded, valDecoded));242 }243 execution.getRobotObj().setCapabilitiesDecoded(capsDecoded);244 }245 mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_STARTINGROBOTSERVER);246 mes.setDescription(mes.getDescription().replace("%IP%", execution.getRobotHost()));247 execution.setResultMessage(mes);248 updateExecution(execution, true);249 if (execution.getRobotHost().isEmpty()) {250 mes = new MessageGeneral(MessageGeneralEnum.VALIDATION_FAILED_SELENIUM_EMPTYORBADIP);251 mes.setDescription(mes.getDescription().replace("%IP%", execution.getRobotHost()));252 LOG.debug("{}{}", logPrefix, mes.getDescription());253 throw new CerberusException(mes);254 } else {255 //Start Robot server (Selenium/Appium/Sikuli)256 LOG.debug("{}Starting Robot Server.", logPrefix);257 try {258 this.robotServerService.startServer(execution);259 LOG.debug("{}Robot Server Started.", logPrefix);260 } catch (CerberusException ex) {261 // No need to report exception message as it will be catched and reported later262 throw new CerberusException(ex.getMessageError(), ex);263 }264 // Start video265 try {266 if (Video.recordVideo(execution.getVideo())) {267 videoRecorder = VideoRecorder.getInstance(execution, recorderService);268 videoRecorder.beginRecordVideo();269 }270 } catch (UnsupportedOperationException ex) {271 LOG.info(ex.getMessage()); // log only message that application type is not supported272 }273 }274 }275 // For BrowserStack and LambdaTest, we try to enrich the Tag with build hash.276 switch (execution.getRobotProvider()) {277 case TestCaseExecution.ROBOTPROVIDER_BROWSERSTACK:278 case TestCaseExecution.ROBOTPROVIDER_LAMBDATEST:279 //TODO Why this variable has been declared ?280 String newBuildHash = tagService.enrichTagWithCloudProviderBuild(execution.getRobotProvider(), execution.getSystem(), execution.getTag(), execution.getRobotExecutorObj().getHostUser(), execution.getRobotExecutorObj().getHostPassword());281 Tag newTag = tagService.convert(tagService.readByKey(execution.getTag()));282 execution.setTagObj(newTag);283 break;284 }285 // Get used SeleniumCapabilities (empty if application is not GUI)286 LOG.debug("{}Getting Selenium capabitities for GUI applications.", logPrefix);287 if (execution.getApplicationObj().getType().equalsIgnoreCase(Application.TYPE_GUI) && !execution.getManualExecution().equals("Y")) {288 try {289 Capabilities caps = this.robotServerService.getUsedCapabilities(execution.getSession());290 execution.setVersion(caps.getVersion());291 execution.setPlatform(caps.getPlatform().toString());292 } catch (Exception ex) {293 LOG.error("{}Exception on Selenium getting Used Capabilities.", logPrefix, ex);294 }295 LOG.debug("{}Selenium capabitities loaded.", logPrefix);296 } else if ((execution.getApplicationObj().getType().equalsIgnoreCase(Application.TYPE_APK) || execution.getApplicationObj().getType().equalsIgnoreCase(Application.TYPE_IPA)) && !execution.getManualExecution().equals("Y")) {297 //do nothing, and keep the robot name298 } else if (!execution.getManualExecution().equals("Y")) {299 // If Selenium is not needed, the selenium and browser info is set to empty.300 execution.setSeleniumIP("");301 execution.setSeleniumPort("");302 execution.setBrowser("");303 execution.setVersion("");304 execution.setPlatform("");305 execution.setRobotDecli("");306 LOG.debug("{}No Selenium capabitities loaded because application not (GUI,IPA,APK) : {}", logPrefix, execution.getApplicationObj().getType());307 }308 execution.setRobotDecli(execution.getRobotDecli().replace("%BROWSER%", execution.getBrowser()));309 execution.setRobotDecli(execution.getRobotDecli().replace("%BROWSERVERSION%", execution.getVersion()));310 execution.setRobotDecli(execution.getRobotDecli().replace("%PLATFORM%", execution.getPlatform()));311 //Load Pre TestCase information312 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_LOADINGDETAILEDDATA));313 updateExecutionWebSocketOnly(execution, true);314 LOG.debug("{}Loading Pre-testcases.", logPrefix);315 List<TestCase> preTests = testCaseService.getTestCaseForPrePostTesting(Test.TEST_PRETESTING, execution.getTestCaseObj().getApplication(), execution.getCountry(),316 execution.getSystem(), execution.getCountryEnvParam().getBuild(), execution.getCountryEnvParam().getRevision());317 List<TestCaseStep> preTestCaseStepList = new ArrayList<>();318 //Load Pre TestCase with Step dependencies (Actions/Control)319 if (preTests != null && !preTests.isEmpty()) {320 LOG.debug("{}Loaded PreTest List. {} found", logPrefix, preTests.size());321 LOG.debug("{}Pre-testcases Loaded.", logPrefix);322 LOG.debug("{}Loading all Steps information (Actions & Controls) of all Pre-testcase.", logPrefix);323 for (TestCase myTCase : preTests) {324 preTestCaseStepList.addAll(this.loadTestCaseService.loadTestCaseStep(myTCase));325 LOG.debug("{}Pre testcase : {} - {} Loaded With all Step(s) found.", logPrefix, myTCase.getTest(), myTCase.getTestcase());326 }327 LOG.debug("{}All Steps information (Actions & Controls) of all Pre-testcase Loaded.", logPrefix);328 } else {329 LOG.debug("{}No Pre-testcases found.", logPrefix);330 }331 //Load Post TestCase information332 LOG.debug("{}Loading Post-testcases.", logPrefix);333 List<TestCase> postTests = testCaseService.getTestCaseForPrePostTesting(Test.TEST_POSTTESTING, execution.getTestCaseObj().getApplication(), execution.getCountry(),334 execution.getSystem(), execution.getCountryEnvParam().getBuild(), execution.getCountryEnvParam().getRevision());335 List<TestCaseStep> postTestCaseStepList = new ArrayList<>();336 // Load Post TestCase with Step dependencies (Actions/Control)337 if (postTests != null && !postTests.isEmpty()) {338 LOG.debug("{}Loaded PostTest List. {} found.", logPrefix, postTests.size());339 LOG.debug("{}Post-testcases Loaded.", logPrefix);340 LOG.debug("{}Loading all Steps information (Actions & Controls) of all Post-testcase.", logPrefix);341 for (TestCase myTCase : postTests) {342 postTestCaseStepList.addAll(this.loadTestCaseService.loadTestCaseStep(myTCase));343 LOG.debug("{}Post testcase : {}-{} Loaded With all Step(s) found.", logPrefix, myTCase.getTest(), myTCase.getTestcase());344 }345 LOG.debug("{}All Steps information (Actions & Controls) of all Post-testcase Loaded.", logPrefix);346 } else {347 LOG.debug("{}No Post-testcases found.", logPrefix);348 }349 // Load Main TestCase with Step dependencies (Actions/Control)350 LOG.debug("{}Loading all Steps information of Main testcase.", logPrefix);351 List<TestCaseStep> testCaseStepList;352 testCaseStepList = this.loadTestCaseService.loadTestCaseStep(execution.getTestCaseObj());353 execution.getTestCaseObj().setSteps(testCaseStepList);354 LOG.debug("{}Steps information of Main testcase Loaded : {} Step(s) found.", logPrefix, execution.getTestCaseObj().getSteps().size());355 // Load All properties of the testcase356 LOG.debug("{}Loading all Properties.", logPrefix);357 List<TestCaseCountryProperties> tcProperties = new ArrayList<>();358 try {359 tcProperties = testCaseCountryPropertiesService.findAllWithDependencies(execution.getTest(), execution.getTestCase(), execution.getCountry(),360 execution.getSystem(), execution.getCountryEnvParam().getBuild(), execution.getCountryEnvParam().getRevision());361 execution.setTestCaseCountryPropertyList(tcProperties);362 } catch (CerberusException ex) {363 LOG.warn("Exception getting all the properties : ", ex);364 }365 LOG.debug("{}All Properties Loaded. {} property(ies) found : {}", logPrefix, tcProperties.size(), tcProperties);366 // Load All Execution Data of testcases that this execution depends367 LOG.debug("{}Loading all Execution Data of the execution from queue dependencies.", logPrefix);368 this.testCaseExecutionDataService.loadTestCaseExecutionDataFromDependencies(execution);369 /*370 * Start Execution of the steps/Actions/controls Iterate Steps.371 * mainExecutionTestCaseStepList will contain the list of steps to372 * execute for both pretest and test. This is where we schedule the373 * execution of the steps using mainExecutionTestCaseStepList374 * object.375 */376 LOG.debug("{}Starting the execution with step iteration.", logPrefix);377 List<TestCaseStep> mainExecutionTestCaseStepList;378 mainExecutionTestCaseStepList = new ArrayList<>();379 mainExecutionTestCaseStepList.addAll(preTestCaseStepList);380 mainExecutionTestCaseStepList.addAll(testCaseStepList);381 mainExecutionTestCaseStepList.addAll(postTestCaseStepList);382 // Open Kafka Consumer383 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_LOADINGKAFKACONSUMERS));384 updateExecutionWebSocketOnly(execution, true);385 execution.setKafkaLatestOffset(kafkaService.getAllConsumers(mainExecutionTestCaseStepList, execution));386 // Initialize the global TestCaseExecution Data List387 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_TESTEXECUTING));388 updateExecution(execution, true);389 // Evaluate the condition at the step level.390 AnswerItem<Boolean> conditionAnswerTc;391 boolean conditionDecodeError = false;392 // If execution is not manual, evaluate the condition at the step level393 if (!execution.getManualExecution().equals("Y")) {394 try {395 answerDecode = variableService.decodeStringCompletly(execution.getConditionVal1(), execution, null, false);396 execution.setConditionVal1(answerDecode.getItem());397 if (!(answerDecode.isCodeStringEquals("OK"))) {398 // If anything wrong with the decode --> we stop here with decode message in the action result.399 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_DECODE)400 .resolveDescription("MES", answerDecode.getMessageDescription())401 .resolveDescription("AREA", "TestCase Condition Value1"));402 execution.setEnd(new Date().getTime());403 LOG.debug("{}TestCase interrupted due to decode 'TestCase Condition Value1' Error.", logPrefix);404 conditionDecodeError = true;405 }406 } catch (CerberusEventException cex) {407 LOG.warn(cex);408 }409 try {410 answerDecode = variableService.decodeStringCompletly(execution.getConditionVal2(), execution, null, false);411 execution.setConditionVal2(answerDecode.getItem());412 if (!(answerDecode.isCodeStringEquals("OK"))) {413 // If anything wrong with the decode --> we stop here with decode message in the action result.414 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_DECODE)415 .resolveDescription("MES", answerDecode.getMessageDescription())416 .resolveDescription("AREA", "TestCase Condition Value2"));417 execution.setEnd(new Date().getTime());418 LOG.debug("{}TestCase interrupted due to decode 'TestCase Condition Value2' Error.", logPrefix);419 conditionDecodeError = true;420 }421 } catch (CerberusEventException cex) {422 LOG.warn(cex);423 }424 try {425 answerDecode = variableService.decodeStringCompletly(execution.getConditionVal3(), execution, null, false);426 execution.setConditionVal3(answerDecode.getItem());427 if (!(answerDecode.isCodeStringEquals("OK"))) {428 // If anything wrong with the decode --> we stop here with decode message in the action result.429 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_DECODE)430 .resolveDescription("MES", answerDecode.getMessageDescription())431 .resolveDescription("AREA", "TestCase Condition Value3"));432 execution.setEnd(new Date().getTime());433 LOG.debug("{}TestCase interrupted due to decode 'TestCase Condition Value3Error.", logPrefix);434 conditionDecodeError = true;435 }436 } catch (CerberusEventException cex) {437 LOG.warn(cex);438 }439 }440 if (!conditionDecodeError) {441 conditionAnswerTc = this.conditionService.evaluateCondition(execution.getConditionOperator(),442 execution.getConditionVal1(), execution.getConditionVal2(), execution.getConditionVal3(),443 execution, execution.getConditionOptions());444 boolean doExecuteTestCase = conditionAnswerTc.getItem();445 if (doExecuteTestCase || execution.getManualExecution().equals("Y")) {446 boolean doStepStopExecution = false;447 for (TestCaseStep step : mainExecutionTestCaseStepList) {448 ConditionOperatorEnum testcaseStepConditionEnum = ConditionOperatorEnum.getConditionOperatorEnumFromString(step.getConditionOperator());449 // exeMod management : We trigger Forced Step no matter if previous step execution asked to stop.450 if (!doStepStopExecution || step.isExecutionForced()) {451 // init the index of the step in case we loop.452 int stepIndex = 1;453 boolean doExecuteNextStep = false;454 TestCaseStepExecution stepExecution;455 int maxloop = parameterService.getParameterIntegerByKey("cerberus_loopstep_max", execution.getApplicationObj().getSystem(), 20);456 // Step Loop management.457 do {458 // Start Execution of TestCaseStep459 LOG.debug("{}Start execution of testcasestep", logPrefix);460 long startStep = new Date().getTime();461 //Create and Register TestCaseStepExecution462 MessageEvent stepMess = new MessageEvent(MessageEventEnum.STEP_PENDING)463 .resolveDescription("STEP", String.valueOf(step.getSort()))464 .resolveDescription("STEPINDEX", String.valueOf(stepIndex));465 stepExecution = factoryTestCaseStepExecution.create(466 runID, step.getTest(), step.getTestcase(),467 step.getStepId(), stepIndex, step.getSort(), step.getLoop(), step.getConditionOperator(), step.getConditionValue1(), step.getConditionValue2(), step.getConditionValue3(), step.getConditionValue1(), step.getConditionValue2(), step.getConditionValue3(), null,468 startStep, startStep, startStep, startStep, new BigDecimal("0"), null, stepMess, step, execution,469 step.isUsingLibraryStep(), step.getLibraryStepTest(), step.getLibraryStepTestcase(), step.getLibraryStepStepId(), step.getDescription());470 stepExecution.setLoop(step.getLoop());471 stepExecution.setConditionOptions(step.getConditionOptionsActive());472 testCaseStepExecutionService.insertTestCaseStepExecution(stepExecution, execution.getSecrets());473 stepExecution.setExecutionResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_TESTSTARTED));474 // We populate the TestCaseStep inside the execution List475 execution.addStepExecutionList(stepExecution);476 // determine if step is executed (doExecuteStep) and if we trigger a new step execution after (doExecuteNextStep)477 boolean doExecuteStep = true;478 boolean descriptionOrConditionStepDecodeError = false;479 boolean conditionStepError = false;480 AnswerItem<Boolean> conditionAnswer = new AnswerItem<>(new MessageEvent(MessageEventEnum.CONDITIONEVAL_FAILED_UNKNOWNCONDITION));481 if (!((stepExecution.getLoop().equals(TestCaseStep.LOOP_DOWHILECONDITIONTRUE)482 || stepExecution.getLoop().equals(TestCaseStep.LOOP_DOWHILECONDITIONFALSE))483 && stepIndex == 1)) {484 // We don't decode value1, value2 and value3 if loop condition is a doWhile in order to prevent error message on condition that will not be executed.485 if (!descriptionOrConditionStepDecodeError) {486 try {487 answerDecode = variableService.decodeStringCompletly(stepExecution.getConditionValue1(), execution, null, false);488 stepExecution.setConditionValue1(answerDecode.getItem());489 if (!(answerDecode.isCodeStringEquals("OK"))) {490 stepExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));491 stepExecution.setStepResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Condition Value1"));492 stepExecution.setReturnMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Condition Value1").getDescription());493 stepExecution.setReturnCode(answerDecode.getResultMessage().getCodeString());494 stepExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());495 stepExecution.setEnd(new Date().getTime());496 LOG.debug("{}Step interrupted due to decode 'Step Condition Value1' Error.", logPrefix);497 descriptionOrConditionStepDecodeError = true;498 }499 } catch (CerberusEventException cex) {500 LOG.warn(cex);501 }502 }503 if (!descriptionOrConditionStepDecodeError) {504 try {505 answerDecode = variableService.decodeStringCompletly(stepExecution.getConditionValue2(), execution, null, false);506 stepExecution.setConditionValue2(answerDecode.getItem());507 if (!(answerDecode.isCodeStringEquals("OK"))) {508 stepExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));509 stepExecution.setStepResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Condition Value2"));510 stepExecution.setReturnMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Condition Value2").getDescription());511 stepExecution.setReturnCode(answerDecode.getResultMessage().getCodeString());512 stepExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());513 stepExecution.setEnd(new Date().getTime());514 LOG.debug("{}Step interrupted due to decode 'Step Condition Value2' Error.", logPrefix);515 descriptionOrConditionStepDecodeError = true;516 }517 } catch (CerberusEventException cex) {518 LOG.warn(cex);519 }520 }521 if (!descriptionOrConditionStepDecodeError) {522 try {523 answerDecode = variableService.decodeStringCompletly(stepExecution.getConditionValue3(), execution, null, false);524 stepExecution.setConditionValue3(answerDecode.getItem());525 if (!(answerDecode.isCodeStringEquals("OK"))) {526 stepExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));527 stepExecution.setStepResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Condition Value3"));528 stepExecution.setReturnMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Condition Value3").getDescription());529 stepExecution.setReturnCode(answerDecode.getResultMessage().getCodeString());530 stepExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());531 stepExecution.setEnd(new Date().getTime());532 LOG.debug("{}Step interrupted due to decode 'Step Condition Value3' Error.", logPrefix);533 descriptionOrConditionStepDecodeError = true;534 }535 } catch (CerberusEventException cex) {536 LOG.warn(cex);537 }538 }539 }540 if (!descriptionOrConditionStepDecodeError) {541 try {542 answerDecode = variableService.decodeStringCompletly(stepExecution.getDescription(), execution, null, false);543 stepExecution.setDescription(answerDecode.getItem());544 if (!(answerDecode.isCodeStringEquals("OK"))) {545 stepExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));546 stepExecution.setStepResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Description"));547 stepExecution.setReturnMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Step Description").getDescription());548 stepExecution.setReturnCode(answerDecode.getResultMessage().getCodeString());549 stepExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());550 stepExecution.setEnd(new Date().getTime());551 LOG.debug("{}Step interrupted due to decode 'Step Description' Error.", logPrefix);552 descriptionOrConditionStepDecodeError = true;553 }554 } catch (CerberusEventException cex) {555 LOG.warn(cex);556 }557 }558 if (stepExecution.getLoop().equals(TestCaseStep.LOOP_ONCEIFCONDITIONFALSE)559 || stepExecution.getLoop().equals(TestCaseStep.LOOP_ONCEIFCONDITIONTRUE)560 || stepExecution.getLoop().equals(TestCaseStep.LOOP_WHILECONDITIONFALSEDO)561 || stepExecution.getLoop().equals(TestCaseStep.LOOP_WHILECONDITIONTRUEDO)562 || stepExecution.getLoop().isEmpty()563 || stepIndex > 1) {564 if (!(descriptionOrConditionStepDecodeError)) {565 conditionAnswer = this.conditionService.evaluateCondition(566 stepExecution.getConditionOperator(),567 stepExecution.getConditionValue1(), stepExecution.getConditionValue2(), stepExecution.getConditionValue3(),568 execution, stepExecution.getConditionOptions());569 doExecuteStep = conditionAnswer.getItem();570 if (conditionAnswer.getResultMessage().getMessage().getCodeString().equals("PE")) {571 // There were no error when performing the condition evaluation.572 switch (stepExecution.getLoop()) {573 case TestCaseStep.LOOP_ONCEIFCONDITIONFALSE:574 doExecuteStep = !doExecuteStep;575 doExecuteNextStep = false;576 break;577 case TestCaseStep.LOOP_ONCEIFCONDITIONTRUE:578 case "":579 doExecuteNextStep = false;580 break;581 case TestCaseStep.LOOP_WHILECONDITIONFALSEDO:582 case TestCaseStep.LOOP_DOWHILECONDITIONFALSE:583 doExecuteStep = !doExecuteStep;584 doExecuteNextStep = doExecuteStep;585 break;586 case TestCaseStep.LOOP_WHILECONDITIONTRUEDO:587 case TestCaseStep.LOOP_DOWHILECONDITIONTRUE:588 doExecuteNextStep = doExecuteStep;589 break;590 default:591 doExecuteNextStep = false;592 }593 } else {594 // Error when performing the condition evaluation. We force no execution (false)595 MessageGeneral mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_CONDITION);596 mes.setDescription(mes.getDescription()597 .replace("%AREA%", "step ")598 .replace("%COND%", stepExecution.getConditionOperator())599 .replace("%MES%", conditionAnswer.getResultMessage().getDescription()));600 execution.setResultMessage(mes);601 stepExecution.setExecutionResultMessage(mes);602 stepExecution.setStepResultMessage(new MessageEvent(MessageEventEnum.CONDITION_TESTCASESTEP_FAILED)603 .resolveDescription("AREA", "")604 .resolveDescription("COND", stepExecution.getConditionOperator())605 .resolveDescription("MESSAGE", conditionAnswer.getResultMessage().getDescription())606 );607 stepExecution.setEnd(new Date().getTime());608 LOG.debug("{}Step interrupted due to condition error.", logPrefix);609 conditionStepError = true;610 doExecuteNextStep = false;611 doExecuteStep = false;612 }613 } else {614 // If anything wrong with the decode --> we stop here with decode message in the action result.615 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_DECODE)616 .resolveDescription("AREA", "Step")617 .resolveDescription("MES", answerDecode.getMessageDescription()));618 execution.setEnd(new Date().getTime());619 LOG.debug("{}TestCase interrupted due to decode Error.", logPrefix);620 // There was an error on decode so we stop everything.621 if (execution.getManualExecution().equals("Y")) {622 doExecuteNextStep = true;623 doExecuteStep = true;624 } else {625 doExecuteNextStep = false;626 doExecuteStep = false;627 }628 }629 } else if (stepExecution.getLoop().equals(TestCaseStep.LOOP_DOWHILECONDITIONFALSE)630 || stepExecution.getLoop().equals(TestCaseStep.LOOP_DOWHILECONDITIONTRUE)) {631 // First Step execution for LOOP_DOWHILECONDITIONTRUE and LOOP_DOWHILECONDITIONFALSE --> We force the step execution and activate the next step execution.632 // We also force the condition message to always true with success.633 doExecuteStep = true;634 doExecuteNextStep = true;635 conditionAnswer.setResultMessage(new MessageEvent(MessageEventEnum.CONDITIONEVAL_TRUE_ALWAYS));636 } else {637 // First Step execution for Unknown Loop --> We force the step execution only once (default behaviour).638 doExecuteStep = true;639 doExecuteNextStep = false;640 conditionAnswer.setResultMessage(new MessageEvent(MessageEventEnum.CONDITIONEVAL_FAILED_UNKNOWNLOOP).resolveDescription("LOOP", stepExecution.getLoop()));641 }642 // Execute Step643 LOG.debug("{}Executing step : {} - {} - Step {} - Index {}",644 logPrefix, stepExecution.getTest(), stepExecution.getTestCase(), stepExecution.getStepId(), stepExecution.getStepId());645 if (doExecuteStep) {646 // We execute the step647 stepExecution = this.executeStep(stepExecution, execution);648 /*649 * Updating Execution Result Message only if650 * execution result message of the step is651 * not PE or OK.652 */653 if ((!(stepExecution.getExecutionResultMessage().equals(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_TESTSTARTED))))654 && (!(stepExecution.getExecutionResultMessage().equals(new MessageGeneral(MessageGeneralEnum.EXECUTION_OK))))) {655 execution.setResultMessage(stepExecution.getExecutionResultMessage());656 }657 if (stepExecution.getStepResultMessage().equals(new MessageEvent(MessageEventEnum.STEP_PENDING))) {658 stepExecution.setStepResultMessage(new MessageEvent(MessageEventEnum.STEP_SUCCESS));659 }660 /*661 * We test here is execution is manual and662 * operator needs to evaluate the condition663 * manually. If this is the case, we add the664 * comment inside the description.665 */666 if (execution.getManualExecution().equals("Y") && testcaseStepConditionEnum.isOperatorEvaluationRequired()) {667 stepExecution.setDescription(stepExecution.getDescription() + " - " + conditionAnswer.getMessageDescription());668 }669 testCaseStepExecutionService.updateTestCaseStepExecution(stepExecution, execution.getSecrets());670 if (stepExecution.isStopExecution()) {671 break;672 }673 } else if ((!descriptionOrConditionStepDecodeError) && (!conditionStepError)) { // We don't execute the step and record a generic execution.674 // Register Step in database675 LOG.debug("{}Registering Step : {}", logPrefix, stepExecution.getStepId());676 // We change the Step message only if the Step is not executed due to condition.677 MessageEvent stepMes = new MessageEvent(MessageEventEnum.CONDITION_TESTCASESTEP_NOTEXECUTED);678 stepExecution.setStepResultMessage(stepMes);679 stepExecution.setReturnMessage(stepExecution.getReturnMessage()680 .replace("%COND%", stepExecution.getConditionOperator())681 .replace("%LOOP%", stepExecution.getLoop())682 .replace("%MESSAGE%", conditionAnswer.getResultMessage().getDescription())683 );684 stepExecution.setEnd(new Date().getTime());685 this.testCaseStepExecutionService.updateTestCaseStepExecution(stepExecution, execution.getSecrets());686 LOG.debug("{}Registered Step", logPrefix);687 } else {688 // Not executed because decode error or failed condition.689 stepExecution.setEnd(new Date().getTime());690 stepExecution.setStopExecution(true);691 this.testCaseStepExecutionService.updateTestCaseStepExecution(stepExecution, execution.getSecrets());692 LOG.debug("{}Registered Step", logPrefix);693 }694 // Log TestCaseStepExecution695 if ((execution.getVerbose() > 0) && parameterService.getParameterBooleanByKey("cerberus_executionlog_enable", execution.getSystem(), false)) {696 LOG.info(stepExecution.toJson(false, true, execution.getSecrets()));697 }698 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.699 updateExecutionWebSocketOnly(execution, false);700 stepIndex++;701 } while (doExecuteNextStep && stepIndex <= maxloop);702 // Step execution boolean is considered for next step execution only if current step was not forced or forced and failed.703 if (!step.isExecutionForced() || stepExecution.isStopExecution()) {704 doStepStopExecution = stepExecution.isStopExecution();705 }706 }707 }708 /*709 * If at that time the execution is still PE, we move it to710 * OK. It means that no issue were met.711 */712 if ((execution.getResultMessage() == null) || (execution.getResultMessage().equals(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_TESTSTARTED)))) {713 execution.setResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_OK));714 }715 // We notify external robot provider of end of execution status.716 switch (execution.getRobotProvider()) {717 case TestCaseExecution.ROBOTPROVIDER_BROWSERSTACK:718 browserstackService.setSessionStatus(execution.getSystem(), execution.getRobotSessionID(), execution.getControlStatus(), execution.getControlMessage(), execution.getRobotExecutorObj().getHostUser(), execution.getRobotExecutorObj().getHostPassword());719 break;720 case TestCaseExecution.ROBOTPROVIDER_KOBITON:721 kobitonService.setSessionStatus(execution.getSystem(), execution.getRobotSessionID(), execution.getControlStatus(), execution.getControlMessage(), execution.getRobotExecutorObj().getHostUser(), execution.getRobotExecutorObj().getHostPassword());722 break;723 case TestCaseExecution.ROBOTPROVIDER_LAMBDATEST:724 lambdaTestService.setSessionStatus(execution.getSession(), execution.getControlStatus());725 // We also set the exeid at that stage.726 String session1 = lambdaTestService.getTestID(execution.getTagObj().getLambdaTestBuild(), execution.getRobotSessionID(), execution.getRobotExecutorObj().getHostUser(), execution.getRobotExecutorObj().getHostPassword(), execution.getSystem());727 execution.setRobotProviderSessionID(session1);728 break;729 }730 } else { // We don't execute the testcase linked with condition.731 MessageGeneral mes;732 // Update Execution status from condition733 if (conditionAnswerTc.getResultMessage().getMessage().getCodeString().equals("PE")) {734 mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_NE_CONDITION);735 } else {736 mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_CONDITION);737 }738 mes.setDescription(mes.getDescription().replace("%COND%", execution.getConditionOperator())739 .replace("%MES%", conditionAnswerTc.getResultMessage().getDescription()));740 execution.setResultMessage(mes);741 }742 }743 } catch (CerberusException ex) {744 // If an exception is found, set the execution to FA and print the exception (only in debug mode)745 MessageGeneral messageFin = new MessageGeneral(MessageGeneralEnum.EXECUTION_FA);746 messageFin.setDescription(messageFin.getDescription() + " " + ex.getMessageError().getDescription());747 execution.setResultMessage(messageFin);748 LOG.debug("{}Exception found Executing Test {} : {}", logPrefix, execution.getId(), ex.getMessageError().getDescription());749 } catch (Exception ex) {750 // If an exception is found, set the execution to FA and print the exception751 MessageGeneral messageFin = new MessageGeneral(MessageGeneralEnum.EXECUTION_FA);752 messageFin.setDescription(messageFin.getDescription() + " " + ex.getMessage());753 execution.setResultMessage(messageFin);754 execution.setControlMessage(execution.getControlMessage() + " Exception: " + ex);755 LOG.error("{}Exception found Executing Test {}", logPrefix, execution.getId(), ex);756 } finally {757 // We stop the server session here (selenium for ex.).758 try {759 if (videoRecorder != null) {760 videoRecorder.endRecordVideo();761 }762 execution = this.stopTestCase(execution);763 } catch (Exception ex) {764 LOG.error("{}Exception Stopping Test {} Exception: {}", logPrefix, execution.getId(), ex.toString(), ex);765 }766 // Log Execution767 if ((execution.getVerbose() > 0) && parameterService.getParameterBooleanByKey("cerberus_executionlog_enable", execution.getSystem(), false)) {768 LOG.info(execution.toJson(false));769 }770 // Clean memory771 try {772 executionUUID.removeExecutionUUID(execution.getExecutionUUID());773 LOG.debug("{}Clean ExecutionUUID", logPrefix);774 } catch (Exception ex) {775 LOG.error("{}Exception cleaning Memory: {}", logPrefix, ex.toString(), ex);776 }777 // Credit Limit increase778 sessionCounter.incrementCreditLimitNbExe();779 long durationinSecond = (execution.getEnd() - execution.getStart()) / 1000;780 if ((durationinSecond > 0) && (durationinSecond <= 1000000)) {781 sessionCounter.incrementCreditLimitSecondExe((int) durationinSecond);782 }783 // Log execution is finished784 LOG.info("Execution Finished : UUID={} ID={} RC={} TestName={}.{}.{}.{}.{}_{}_{}",785 execution.getExecutionUUID(),786 execution.getId(),787 execution.getControlStatus(),788 execution.getEnvironment(),789 execution.getCountry(),790 execution.getBuild(),791 execution.getRevision(),792 execution.getTest(),793 execution.getTestCase(),794 execution.getTestCaseObj().getDescription().replace(".", ""));795 // Retry management, in case the result is not (OK or NE), we execute the job again reducing the retry to 1.796 boolean willBeRetried = retriesService.manageRetries(execution);797 // Updating queue to done status only for execution from queue798 if (execution.getQueueID() != 0) {799 executionQueueService.updateToDone(execution.getQueueID(), "", runID);800 }801 // Trigger the necessary Event for WebHook and notification management.802 eventService.triggerEvent(EventHook.EVENTREFERENCE_EXECUTION_END, execution, null, null, null);803 if (!willBeRetried) {804 eventService.triggerEvent(EventHook.EVENTREFERENCE_EXECUTION_END_LASTRETRY, execution, null, null, null);805 }806 // JIRA XRay Connector is triggered at the end of every execution..807 if (!willBeRetried) {808 xRayService.createXRayTestExecution(execution);809 }810 /*811 * After every execution finished, <br>812 * if the execution has a tag that has a campaign associated <br>813 * and no more executions are in the queue, <br>814 * we trigger : <br>815 * 1/ The update of the EndExeQueue of the tag <br>816 * 2/ We notify the Distribution List with execution report status817 */818 tagService.manageCampaignEndOfExecution(execution.getTag());819 /*820 * Dependency management, At the end of the execution, we RELEASE821 * the corresponding dependencies and put corresponding Queue822 * entries to QUEUED status.823 */824 if (!willBeRetried) {825 testCaseExecutionQueueDepService.manageDependenciesEndOfExecution(execution);826 }827 // After every execution finished we try to trigger more from the queue;-).828 executionThreadPoolService.executeNextInQueueAsynchroneously(false);829 }830 return execution;831 }832 // Update Execution status and eventually push the new value to websocket.833 private void updateExecution(TestCaseExecution execution, boolean forcePush) {834 try {835 testCaseExecutionService.updateTCExecution(execution);836 } catch (CerberusException ex) {837 LOG.warn(ex);838 }839 updateExecutionWebSocketOnly(execution, forcePush);840 }841 private void updateExecutionWebSocketOnly(TestCaseExecution execution, boolean forcePush) {842 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.843 if (execution.isCerberus_featureflipping_activatewebsocketpush()) {844 TestCaseExecutionEndPoint.getInstance().send(execution, forcePush);845 }846 }847 @Override848 public TestCaseExecution stopTestCase(TestCaseExecution execution) {849 // Stop Execution850 LOG.debug("{} - Stop the execution {} UUID: {}", execution.getId(), execution.getId(), execution.getExecutionUUID());851 try {852 this.stopExecutionRobotAndProxy(execution);853 } catch (Exception ex) {854 LOG.warn("Exception Stopping Execution {} Exception : {}", execution.getId(), ex.toString(), ex);855 }856 // Saving TestCaseExecution object.857 execution.setEnd(new Date().getTime());858 try {859 testCaseExecutionService.updateTCExecution(execution);860 } catch (CerberusException ex) {861 LOG.warn("Exception updating Execution : {} Exception: {}", execution.getId(), ex.toString());862 }863 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.864 if (execution.isCerberus_featureflipping_activatewebsocketpush()) {865 TestCaseExecutionEndPoint.getInstance().send(execution, true);866 TestCaseExecutionEndPoint.getInstance().end(execution);867 }868 return execution;869 }870 private TestCaseStepExecution executeStep(TestCaseStepExecution stepExecution, TestCaseExecution execution) {871 long runID = stepExecution.getId();872 String logPrefix = runID + " - ";873 AnswerItem<String> answerDecode;874 // Initialise the Step Data List.875 List<TestCaseExecutionData> myStepDataList = new ArrayList<>();876 stepExecution.setTestCaseExecutionDataList(myStepDataList);877 // Initialise the Data List used to enter the action.878 // Iterate Actions879 List<TestCaseStepAction> testCaseStepActionList = stepExecution.getTestCaseStep().getActions();880 LOG.debug("{}Getting list of actions of the step. {} action(s) to perform.", logPrefix, testCaseStepActionList.size());881 for (TestCaseStepAction testCaseStepAction : testCaseStepActionList) {882 // Start Execution of TestCaseStepAction883 long startAction = new Date().getTime();884 DateFormat df = new SimpleDateFormat(DateUtil.DATE_FORMAT_TIMESTAMP);885 long startLongAction = Long.parseLong(df.format(startAction));886 // Create and Register TestCaseStepActionExecution.887 TestCaseStepActionExecution actionExecution = factoryTestCaseStepActionExecution.create(888 stepExecution.getId(), testCaseStepAction.getTest(), testCaseStepAction.getTestcase(),889 testCaseStepAction.getStepId(), stepExecution.getIndex(), testCaseStepAction.getActionId(), testCaseStepAction.getSort(), null, null,890 testCaseStepAction.getConditionOperator(), testCaseStepAction.getConditionValue1(), testCaseStepAction.getConditionValue2(), testCaseStepAction.getConditionValue3(),891 testCaseStepAction.getConditionValue1(), testCaseStepAction.getConditionValue2(), testCaseStepAction.getConditionValue3(),892 testCaseStepAction.getAction(), testCaseStepAction.getValue1(), testCaseStepAction.getValue2(), testCaseStepAction.getValue3(), testCaseStepAction.getValue1(),893 testCaseStepAction.getValue2(), testCaseStepAction.getValue3(),894 (testCaseStepAction.isFatal() ? "Y" : "N"), startAction, startAction, startLongAction, startLongAction, new MessageEvent(MessageEventEnum.ACTION_PENDING),895 testCaseStepAction.getDescription(), testCaseStepAction, stepExecution);896 actionExecution.setOptions(testCaseStepAction.getOptionsActive());897 actionExecution.setConditionOptions(testCaseStepAction.getConditionOptionsActive());898 this.testCaseStepActionExecutionService.insertTestCaseStepActionExecution(actionExecution, execution.getSecrets());899 // We populate the TestCase Action List900 stepExecution.addActionExecutionList(actionExecution);901 // If execution is not manual, evaluate the condition at the action level902 AnswerItem<Boolean> conditionAnswer;903 boolean conditionDecodeError = false;904 if (!execution.getManualExecution().equals("Y")) {905 try {906 answerDecode = variableService.decodeStringCompletly(actionExecution.getConditionVal1(), execution, null, false);907 actionExecution.setConditionVal1(answerDecode.getItem());908 if (!(answerDecode.isCodeStringEquals("OK"))) {909 // If anything wrong with the decode --> we stop here with decode message in the action result.910 actionExecution.setActionResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Action Condition Value1"));911 actionExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));912 actionExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());913 actionExecution.setEnd(new Date().getTime());914 LOG.debug("{}Action interrupted due to decode 'Action Condition Value1' Error.", logPrefix);915 conditionDecodeError = true;916 }917 } catch (CerberusEventException cex) {918 LOG.warn(cex);919 }920 try {921 answerDecode = variableService.decodeStringCompletly(actionExecution.getConditionVal2(), execution, null, false);922 actionExecution.setConditionVal2(answerDecode.getItem());923 if (!(answerDecode.isCodeStringEquals("OK"))) {924 // If anything wrong with the decode --> we stop here with decode message in the action result.925 actionExecution.setActionResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Action Condition Value2"));926 actionExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));927 actionExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());928 actionExecution.setEnd(new Date().getTime());929 LOG.debug("{}Action interrupted due to decode 'Action Condition Value2' Error.", logPrefix);930 conditionDecodeError = true;931 }932 } catch (CerberusEventException cex) {933 LOG.warn(cex);934 }935 try {936 answerDecode = variableService.decodeStringCompletly(actionExecution.getConditionVal3(), execution, null, false);937 actionExecution.setConditionVal3(answerDecode.getItem());938 if (!(answerDecode.isCodeStringEquals("OK"))) {939 // If anything wrong with the decode --> we stop here with decode message in the action result.940 actionExecution.setActionResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Action Condition Value3"));941 actionExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));942 actionExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());943 actionExecution.setEnd(new Date().getTime());944 LOG.debug("{}Action interrupted due to decode 'Action Condition Value3' Error.", logPrefix);945 conditionDecodeError = true;946 }947 } catch (CerberusEventException cex) {948 LOG.warn(cex);949 }950 }951 if (!(conditionDecodeError)) {952 ConditionOperatorEnum actionConditionOperatorEnum = ConditionOperatorEnum.getConditionOperatorEnumFromString(actionExecution.getConditionOperator());953 conditionAnswer = this.conditionService.evaluateCondition(actionExecution.getConditionOperator(),954 actionExecution.getConditionVal1(), actionExecution.getConditionVal2(), actionExecution.getConditionVal3(),955 execution, actionExecution.getConditionOptions());956 boolean doExecuteAction = conditionAnswer.getItem();957 if (execution.getManualExecution().equals("Y") && actionConditionOperatorEnum.isOperatorEvaluationRequired()) {958 actionExecution.setDescription(actionExecution.getDescription() + " - " + conditionAnswer.getMessageDescription());959 }960 // If condition OK or if manual execution, then execute the action961 if (conditionAnswer.getResultMessage().getMessage().getCodeString().equals("PE")962 || execution.getManualExecution().equals("Y")) {963 // Execute or not the action here.964 if (doExecuteAction || execution.getManualExecution().equals("Y")) {965 LOG.debug("Executing action : {} with val1 : {} and val2 : {} and val3 : {}",966 actionExecution.getAction(),967 actionExecution.getValue1(),968 actionExecution.getValue2(),969 actionExecution.getValue3());970 // We execute the Action971 actionExecution = this.executeAction(actionExecution, execution);972 // If Action or property reported to stop the testcase, we stop it and update the step with the message.973 stepExecution.setStopExecution(actionExecution.isStopExecution());974 if ((!(actionExecution.getExecutionResultMessage().equals(new MessageGeneral(MessageGeneralEnum.EXECUTION_OK))))975 && (!(actionExecution.getExecutionResultMessage().equals(new MessageGeneral(MessageGeneralEnum.EXECUTION_PE_TESTEXECUTING))))) {976 stepExecution.setExecutionResultMessage(actionExecution.getExecutionResultMessage());977 stepExecution.setStepResultMessage(actionExecution.getActionResultMessage());978 }979 if (actionExecution.isStopExecution()) {980 break;981 }982 } else {983 // We don't execute the action and record a generic execution.984 // Record Screenshot, PageSource985 actionExecution.addFileList(recorderService.recordExecutionInformationAfterStepActionAndControl(actionExecution, null));986 LOG.debug("Registering Action : {}", actionExecution.getAction());987 // We change the Action message only if the action is not executed due to condition.988 MessageEvent actionMes = new MessageEvent(MessageEventEnum.CONDITION_TESTCASEACTION_NOTEXECUTED);989 actionExecution.setActionResultMessage(actionMes);990 actionExecution.setReturnMessage(actionExecution.getReturnMessage()991 .replace("%COND%", actionExecution.getConditionOperator())992 .replace("%MESSAGE%", conditionAnswer.getResultMessage().getDescription())993 );994 actionExecution.setEnd(new Date().getTime());995 this.testCaseStepActionExecutionService.updateTestCaseStepActionExecution(actionExecution, execution.getSecrets());996 LOG.debug("{}Registered Action", logPrefix);997 }998 } else {999 // Error when performing the condition evaluation. We force no execution (false)1000 MessageGeneral mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_CONDITION);1001 mes.setDescription(mes.getDescription()1002 .replace("%COND%", actionExecution.getConditionOperator())1003 .replace("%AREA%", "action ")1004 .replace("%MES%", conditionAnswer.getResultMessage().getDescription()));1005 actionExecution.setExecutionResultMessage(mes);1006 stepExecution.setExecutionResultMessage(actionExecution.getExecutionResultMessage());1007 actionExecution.setActionResultMessage(new MessageEvent(MessageEventEnum.CONDITION_TESTCASEACTION_FAILED)1008 .resolveDescription("AREA", "")1009 .resolveDescription("COND", actionExecution.getConditionOperator())1010 .resolveDescription("MESSAGE", conditionAnswer.getResultMessage().getDescription()));1011 stepExecution.setStepResultMessage(new MessageEvent(MessageEventEnum.CONDITION_TESTCASESTEP_FAILED)1012 .resolveDescription("AREA", "action ")1013 .resolveDescription("COND", actionExecution.getConditionOperator())1014 .resolveDescription("MESSAGE", conditionAnswer.getResultMessage().getDescription()));1015 if (actionExecution.isFatal().equals("N")) {1016 actionExecution.setStopExecution(false);1017 MessageEvent actionMes = actionExecution.getActionResultMessage();1018 actionMes.setDescription(actionExecution.getActionResultMessage().getDescription() + " -- Execution forced to continue.");1019 actionExecution.setActionResultMessage(actionMes);1020 } else {1021 actionExecution.setStopExecution(true);1022 }1023 stepExecution.setStopExecution(actionExecution.isStopExecution());1024 actionExecution.setEnd(new Date().getTime());1025 this.testCaseStepActionExecutionService.updateTestCaseStepActionExecution(actionExecution, execution.getSecrets());1026 LOG.debug("{}Action interrupted due to condition error.", logPrefix);1027 // We stop any further Action execution.1028 if (actionExecution.isStopExecution()) {1029 break;1030 }1031 }1032 } else {1033 actionExecution.setEnd(new Date().getTime());1034 stepExecution.setExecutionResultMessage(actionExecution.getExecutionResultMessage());1035 stepExecution.setStepResultMessage(actionExecution.getActionResultMessage());1036 stepExecution.setStopExecution(actionExecution.isStopExecution());1037 this.testCaseStepActionExecutionService.updateTestCaseStepActionExecution(actionExecution, execution.getSecrets());1038 LOG.debug("{}Registered Action", logPrefix);1039 if (actionExecution.isStopExecution()) {1040 break;1041 }1042 }1043 // Log TestCaseStepActionExecution1044 if ((execution.getVerbose() > 0) && parameterService.getParameterBooleanByKey("cerberus_executionlog_enable", execution.getSystem(), false)) {1045 LOG.info(actionExecution.toJson(false, true, execution.getSecrets()));1046 }1047 }1048 stepExecution.setEnd(new Date().getTime());1049 this.testCaseStepExecutionService.updateTestCaseStepExecution(stepExecution, execution.getSecrets());1050 updateExecutionWebSocketOnly(execution, false);1051 return stepExecution;1052 }1053 private TestCaseStepActionExecution executeAction(TestCaseStepActionExecution actionExecution, TestCaseExecution execution) {1054 LOG.debug("Starting execute Action : {}", actionExecution.getAction());1055 AnswerItem<String> answerDecode;1056 // If execution is not manual, do action and record files1057 if (!execution.getManualExecution().equals("Y")) {1058 actionExecution = this.actionService.doAction(actionExecution);1059 // Record Screenshot, PageSource1060 try {1061 actionExecution.addFileList(recorderService.recordExecutionInformationAfterStepActionAndControl(actionExecution, null));1062 } catch (Exception ex) {1063 LOG.warn("Unable to record Screenshot/PageSource : {}", ex.toString(), ex);1064 }1065 } else {1066 // If execution manual, set Action result message as notExecuted1067 actionExecution.setActionResultMessage(new MessageEvent(MessageEventEnum.ACTION_WAITINGFORMANUALEXECUTION));1068 actionExecution.setExecutionResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_WE));1069 actionExecution.setEnd(new Date().getTime());1070 }1071 // Register Action in database1072 LOG.debug("Registering Action : {}", actionExecution.getAction());1073 this.testCaseStepActionExecutionService.updateTestCaseStepActionExecution(actionExecution, execution.getSecrets());1074 LOG.debug("Registered Action");1075 if (actionExecution.isStopExecution()) {1076 return actionExecution;1077 }1078 // If Action setXXContent is not executed, we don't execute the corresponding controls.1079 if (actionExecution.getActionResultMessage().getCodeString().equals("NE")1080 && (actionExecution.getAction().equals(TestCaseStepAction.ACTION_SETNETWORKTRAFFICCONTENT)1081 || actionExecution.getAction().equals(TestCaseStepAction.ACTION_SETSERVICECALLCONTENT)1082 || actionExecution.getAction().equals(TestCaseStepAction.ACTION_SETCONSOLECONTENT)1083 || actionExecution.getAction().equals(TestCaseStepAction.ACTION_SETCONTENT))) {1084 return actionExecution;1085 }1086 //As controls are associated with an action, the current state for the action is stored in order to restore it1087 //if some property is not defined for the country1088 MessageEvent actionMessage = actionExecution.getActionResultMessage();1089 MessageGeneral executionResultMessage = actionExecution.getExecutionResultMessage();1090 // Iterate Control1091 List<TestCaseStepActionControl> tcsacList = actionExecution.getTestCaseStepAction().getControls();1092 for (TestCaseStepActionControl control : tcsacList) {1093 // Start Execution of TestCAseStepActionControl1094 long startControl = new Date().getTime();1095 DateFormat df = new SimpleDateFormat(DateUtil.DATE_FORMAT_TIMESTAMP);1096 long startLongControl = Long.parseLong(df.format(startControl));1097 // Create and Register TestCaseStepActionControlExecution1098 LOG.debug("Creating TestCaseStepActionControlExecution");1099 TestCaseStepActionControlExecution controlExecution1100 = factoryTestCaseStepActionControlExecution.create(actionExecution.getId(), control.getTest(), control.getTestcase(),1101 control.getStepId(), actionExecution.getIndex(), control.getActionId(), control.getControlId(), control.getSort(),1102 null, null,1103 control.getConditionOperator(), control.getConditionValue1(), control.getConditionValue2(), control.getConditionValue3(), control.getConditionValue1(), control.getConditionValue2(), control.getConditionValue3(),1104 control.getControl(), control.getValue1(), control.getValue2(), control.getValue3(), control.getValue1(), control.getValue2(),1105 control.getValue3(), (control.isFatal() ? "Y" : "N"), startControl, startControl, startLongControl, startLongControl,1106 control.getDescription(), actionExecution, new MessageEvent(MessageEventEnum.CONTROL_PENDING));1107 controlExecution.setConditionOptions(control.getConditionOptionsActive());1108 controlExecution.setOptions(control.getOptionsActive());1109 this.testCaseStepActionControlExecutionService.insertTestCaseStepActionControlExecution(controlExecution, execution.getSecrets());1110 LOG.debug("Executing control : {} type : {}", controlExecution.getControlId(), controlExecution.getControl());1111 // We populate the TestCase Control List1112 actionExecution.addTestCaseStepActionExecutionList(controlExecution);1113 // Evaluate the condition at the control level.1114 AnswerItem<Boolean> conditionAnswer;1115 boolean conditionDecodeError = false;1116 if (!execution.getManualExecution().equals("Y")) {1117 try {1118 answerDecode = variableService.decodeStringCompletly(controlExecution.getConditionVal1(), execution, null, false);1119 controlExecution.setConditionVal1(answerDecode.getItem());1120 if (!(answerDecode.isCodeStringEquals("OK"))) {1121 // If anything wrong with the decode --> we stop here with decode message in the action result.1122 controlExecution.setControlResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Control Condition Value1"));1123 controlExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));1124 controlExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());1125 controlExecution.setEnd(new Date().getTime());1126 LOG.debug("Control interrupted due to decode 'Control Condition Value1' Error.");1127 conditionDecodeError = true;1128 }1129 } catch (CerberusEventException cex) {1130 LOG.warn(cex);1131 }1132 try {1133 answerDecode = variableService.decodeStringCompletly(controlExecution.getConditionVal2(), execution, null, false);1134 controlExecution.setConditionVal2(answerDecode.getItem());1135 if (!(answerDecode.isCodeStringEquals("OK"))) {1136 // If anything wrong with the decode --> we stop here with decode message in the action result.1137 controlExecution.setControlResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Control Condition Value2"));1138 controlExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));1139 controlExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());1140 controlExecution.setEnd(new Date().getTime());1141 LOG.debug("Control interrupted due to decode 'Control Condition Value2' Error.");1142 conditionDecodeError = true;1143 }1144 } catch (CerberusEventException cex) {1145 LOG.warn(cex);1146 }1147 try {1148 answerDecode = variableService.decodeStringCompletly(controlExecution.getConditionVal3(), execution, null, false);1149 controlExecution.setConditionVal3(answerDecode.getItem());1150 if (!(answerDecode.isCodeStringEquals("OK"))) {1151 // If anything wrong with the decode --> we stop here with decode message in the action result.1152 controlExecution.setControlResultMessage(answerDecode.getResultMessage().resolveDescription("FIELD", "Control Condition Value3"));1153 controlExecution.setExecutionResultMessage(new MessageGeneral(answerDecode.getResultMessage().getMessage()));1154 controlExecution.setStopExecution(answerDecode.getResultMessage().isStopTest());1155 controlExecution.setEnd(new Date().getTime());1156 LOG.debug("Control interrupted due to decode 'Control Condition Value3' Error.");1157 conditionDecodeError = true;1158 }1159 } catch (CerberusEventException cex) {1160 LOG.warn(cex);1161 }1162 }1163 if (!(conditionDecodeError)) {1164 ConditionOperatorEnum controlConditionOperatorEnum = ConditionOperatorEnum.getConditionOperatorEnumFromString(controlExecution.getConditionOperator());1165 conditionAnswer = this.conditionService.evaluateCondition(controlExecution.getConditionOperator(),1166 controlExecution.getConditionVal1(), controlExecution.getConditionVal2(), controlExecution.getConditionVal3(),1167 execution, controlExecution.getConditionOptions());1168 boolean doExecuteControl = conditionAnswer.getItem();1169 if (execution.getManualExecution().equals("Y") && controlConditionOperatorEnum.isOperatorEvaluationRequired()) {1170 controlExecution.setDescription(controlExecution.getDescription() + " - " + conditionAnswer.getMessageDescription());1171 }1172 // If condition OK or if manual execution, then execute the control1173 if (conditionAnswer.getResultMessage().getMessage().getCodeString().equals("PE")1174 || execution.getManualExecution().equals("Y")) {1175 if (doExecuteControl || execution.getManualExecution().equals("Y")) {1176 // We execute the control1177 controlExecution = executeControl(controlExecution, execution);1178 /*1179 * We update the Action with the execution message and1180 * stop flag from the control. We update the status only1181 * if the control is not OK. This is to prevent moving1182 * the status to OK when it should stay KO when a1183 * control failed previously.1184 */1185 actionExecution.setStopExecution(controlExecution.isStopExecution());1186 if (!(controlExecution.getControlResultMessage().equals(new MessageEvent(MessageEventEnum.CONTROL_SUCCESS)))) {1187 //NA is a special case of not having success while calculating the property; the action shouldn't be stopped1188 if (controlExecution.getControlResultMessage().equals(new MessageEvent(MessageEventEnum.PROPERTY_FAILED_NO_PROPERTY_DEFINITION))) {1189 // restores the messages' information if the property is not defined for the country1190 actionExecution.setActionResultMessage(actionMessage);1191 actionExecution.setExecutionResultMessage(executionResultMessage);1192 } else {1193 actionExecution.setExecutionResultMessage(controlExecution.getExecutionResultMessage());1194 actionExecution.setActionResultMessage(controlExecution.getControlResultMessage());1195 }1196 }1197 //If Control report stopping the testcase, we stop it.1198 if (controlExecution.isStopExecution()) {1199 break;1200 }1201 } else { // We don't execute the control and record a generic execution.1202 //Record Screenshot, PageSource1203 controlExecution.addFileList(recorderService.recordExecutionInformationAfterStepActionAndControl(controlExecution.getTestCaseStepActionExecution(), controlExecution));1204 // Register Control in database1205 LOG.debug("Registering Control : {}", controlExecution.getControlId());1206 // We change the Action message only if the action is not executed due to condition.1207 MessageEvent controlMes = new MessageEvent(MessageEventEnum.CONDITION_TESTCASECONTROL_NOTEXECUTED);1208 controlExecution.setControlResultMessage(controlMes);1209 controlExecution.setReturnMessage(controlExecution.getReturnMessage()1210 .replace("%COND%", controlExecution.getConditionOperator())1211 .replace("%MESSAGE%", conditionAnswer.getResultMessage().getDescription())1212 );1213 controlExecution.setEnd(new Date().getTime());1214 this.testCaseStepActionControlExecutionService.updateTestCaseStepActionControlExecution(controlExecution, execution.getSecrets());1215 LOG.debug("Registered Control");1216 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.1217 updateExecutionWebSocketOnly(execution, false);1218 }1219 } else {1220 // Error when performing the condition evaluation. We force no execution (false)1221 MessageGeneral mes = new MessageGeneral(MessageGeneralEnum.EXECUTION_FA_CONDITION);1222 mes.setDescription(mes.getDescription()1223 .replace("%COND%", controlExecution.getConditionOperator())1224 .replace("%AREA%", "control ")1225 .replace("%MES%", conditionAnswer.getResultMessage().getDescription()));1226 controlExecution.setExecutionResultMessage(mes);1227 actionExecution.setExecutionResultMessage(mes);1228 controlExecution.setControlResultMessage(new MessageEvent(MessageEventEnum.CONDITION_TESTCASECONTROL_FAILED)1229 .resolveDescription("AREA", "")1230 .resolveDescription("COND", controlExecution.getConditionOperator())1231 .resolveDescription("MESSAGE", conditionAnswer.getResultMessage().getDescription()));1232 actionExecution.setActionResultMessage(new MessageEvent(MessageEventEnum.CONDITION_TESTCASEACTION_FAILED)1233 .resolveDescription("AREA", "control ")1234 .resolveDescription("COND", controlExecution.getConditionOperator())1235 .resolveDescription("MESSAGE", conditionAnswer.getResultMessage().getDescription()));1236 controlExecution.setEnd(new Date().getTime());1237 this.testCaseStepActionControlExecutionService.updateTestCaseStepActionControlExecution(controlExecution, execution.getSecrets());1238 LOG.debug("Control interrupted due to condition error.");1239 // We stop any further Control execution.1240 break;1241 }1242 } else {1243 controlExecution.setEnd(new Date().getTime());1244 actionExecution.setExecutionResultMessage(controlExecution.getExecutionResultMessage());1245 actionExecution.setActionResultMessage(controlExecution.getControlResultMessage());1246 this.testCaseStepActionControlExecutionService.updateTestCaseStepActionControlExecution(controlExecution, execution.getSecrets());1247 LOG.debug("Registered Control");1248 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.1249 updateExecutionWebSocketOnly(execution, false);1250 }1251 // log TestCaseStepActionControlExecution1252 if ((execution.getVerbose() > 0) && parameterService.getParameterBooleanByKey("cerberus_executionlog_enable", execution.getSystem(), false)) {1253 LOG.info(controlExecution.toJson(false, true, execution.getSecrets()));1254 }1255 }1256 /*1257 * All controls of the actions are done. We now put back the1258 * AppTypeEngine value to the one from the application. and also put1259 * back the last service called content and format.1260 */1261 execution.setAppTypeEngine(execution.getApplicationObj().getType());1262 if (execution.getLastServiceCalled() != null) {1263 execution.getLastServiceCalled().setResponseHTTPBody(execution.getOriginalLastServiceCalled());1264 execution.getLastServiceCalled().setResponseHTTPBodyContentType(execution.getOriginalLastServiceCalledContent());1265 execution.getLastServiceCalled().setRecordTraceFile(true);1266 }1267 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.1268 updateExecutionWebSocketOnly(execution, false);1269 LOG.debug("Finished execute Action : {}", actionExecution.getAction());1270 return actionExecution;1271 }1272 private TestCaseStepActionControlExecution executeControl(TestCaseStepActionControlExecution controlExecution, TestCaseExecution execution) {1273 // If execution is not manual, do control and record files1274 if (!execution.getManualExecution().equals("Y")) {1275 controlExecution = this.controlService.doControl(controlExecution);1276 // Record Screenshot, PageSource1277 controlExecution.addFileList(recorderService.recordExecutionInformationAfterStepActionAndControl(controlExecution.getTestCaseStepActionExecution(), controlExecution));1278 } else {1279 // If execution manual, set Control result message as notExecuted1280 controlExecution.setControlResultMessage(new MessageEvent(MessageEventEnum.CONTROL_WAITINGEXECUTION));1281 controlExecution.setExecutionResultMessage(new MessageGeneral(MessageGeneralEnum.EXECUTION_WE));1282 controlExecution.setEnd(new Date().getTime());1283 }1284 // Register Control in database1285 LOG.debug("Registering Control : {}", controlExecution.getControlId());1286 this.testCaseStepActionControlExecutionService.updateTestCaseStepActionControlExecution(controlExecution, execution.getSecrets());1287 LOG.debug("Registered Control");1288 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.1289 updateExecutionWebSocketOnly(execution, false);1290 return controlExecution;1291 }1292 private TestCaseExecution stopExecutionRobotAndProxy(TestCaseExecution execution) {1293 switch (execution.getApplicationObj().getType()) {1294 case Application.TYPE_GUI:1295 case Application.TYPE_APK:1296 case Application.TYPE_IPA:1297 try {1298 this.robotServerService.stopServer(execution);1299 LOG.debug("Stop server for execution {}", execution.getId());1300 } catch (WebDriverException exception) {1301 LOG.warn("Selenium/Appium didn't manage to close connection for execution {}", execution.getId(), exception);1302 }1303 break;1304 case Application.TYPE_FAT:1305 LOG.debug("Stop Sikuli server for execution {} closing application {}", execution.getId(), execution.getCountryEnvironmentParameters().getIp());1306 if (!StringUtil.isNullOrEmpty(execution.getCountryEnvironmentParameters().getIp())) {1307 this.sikuliService.doSikuliActionCloseApp(execution.getSession(), execution.getCountryEnvironmentParameters().getIp());1308 }1309 LOG.debug("Ask Sikuli to clean execution {}", execution.getId());1310 this.sikuliService.doSikuliEndExecution(execution.getSession());1311 break;1312 default:1313 }1314 // Stopping remote proxy.1315 try {1316 this.executorService.stopRemoteProxy(execution);1317 LOG.debug("Stop Cerberus Executor Proxy for execution {}", execution.getId());1318 } catch (Exception exception) {1319 LOG.warn("Exception on Cerberus Executor Proxy stop for execution {}", execution.getId(), exception);1320 }1321 // Websocket --> we refresh the corresponding Detail Execution pages attached to this execution.1322 updateExecutionWebSocketOnly(execution, false);1323 return execution;1324 }1325 @Override1326 @Async1327 public TestCaseExecution executeTestCaseAsynchronously(TestCaseExecution execution) throws CerberusException {1328 try {1329 return executeTestCase(execution);1330 } catch (CerberusException ex) {1331 throw new CerberusException(ex.getMessageError());1332 }1333 }1334}...
updateExecution
Using AI Code Generation
1import org.cerberus.engine.execution.impl.ExecutionRunService2import org.cerberus.engine.execution.impl.bean.ExecutionRun3import org.cerberus.engine.execution.impl.bean.ExecutionRunStatus4import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatus5import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResult6import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControl7import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessage8import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescription9import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImage10import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageBase6411import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshot12import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase6413import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64Screenshot14import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnail15import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnailThumbnail16import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnailThumbnailThumbnail17import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnailThumbnailThumbnailThumbnail18import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnailThumbnailThumbnailThumbnailThumbnail19import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnailThumbnailThumbnailThumbnailThumbnailThumbnail20import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecutionStatusResultControlMessageDescriptionImageScreenshotBase64ScreenshotThumbnailThumbnailThumbnailThumbnailThumbnailThumbnailThumbnail21import org.cerberus.engine.execution.impl.bean.ExecutionRunStepActionControlExecution
updateExecution
Using AI Code Generation
1ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);2executionRunService.updateExecution(executionUUID, newStatus);3ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);4executionRunService.updateExecution(executionUUID, newStatus);5ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);6executionRunService.updateExecution(executionUUID, newStatus);7ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);8executionRunService.updateExecution(executionUUID, newStatus);9ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);10executionRunService.updateExecution(executionUUID, newStatus);11ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);12executionRunService.updateExecution(executionUUID, newStatus);13ExecutionRunService executionRunService = AppContext.getInstance().getBean(ExecutionRunService.class);14executionRunService.updateExecution(executionUUID, newStatus);
updateExecution
Using AI Code Generation
1import org.cerberus.engine.execution.impl.ExecutionRunService;2import org.cerberus.engine.execution.impl.ExecutionRunServiceTest;3import org.cerberus.engine.execution.impl.ExecutionRunServiceTestCase;4ExecutionRunService executionRunService = ExecutionRunService.getInstance();5ExecutionRunServiceTest executionRunServiceTest = ExecutionRunServiceTest.getInstance();6ExecutionRunServiceTestCase executionRunServiceTestCase = ExecutionRunServiceTestCase.getInstance();7executionRunService.updateExecution(executionId, executionStatus, executionMessage, executionVerbose, executionScreenshot, executionDescription);8import org.cerberus.engine.execution.impl.ExecutionRunService;9import org.cerberus.engine.execution.impl.ExecutionRunServiceTest;10import org.cerberus.engine.execution.impl.ExecutionRunServiceTestCase;11ExecutionRunService executionRunService = ExecutionRunService.getInstance();12ExecutionRunServiceTest executionRunServiceTest = ExecutionRunServiceTest.getInstance();13ExecutionRunServiceTestCase executionRunServiceTestCase = ExecutionRunServiceTestCase.getInstance();14executionRunServiceTestCase.updateExecution(executionId, executionStatus, executionMessage, executionVerbose, executionScreenshot, executionDescription);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!