github.com/getgauge/gauge@v1.6.9/execution/stepExecutor.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package execution
     8  
     9  import (
    10  	"github.com/getgauge/gauge-proto/go/gauge_messages"
    11  	"github.com/getgauge/gauge/execution/event"
    12  	"github.com/getgauge/gauge/execution/result"
    13  	"github.com/getgauge/gauge/gauge"
    14  	"github.com/getgauge/gauge/plugin"
    15  	"github.com/getgauge/gauge/runner"
    16  )
    17  
    18  type stepExecutor struct {
    19  	runner               runner.Runner
    20  	pluginHandler        plugin.Handler
    21  	currentExecutionInfo *gauge_messages.ExecutionInfo
    22  	stream               int
    23  }
    24  
    25  // TODO: stepExecutor should not consume both gauge.Step and gauge_messages.ProtoStep. The usage of ProtoStep should be eliminated.
    26  func (e *stepExecutor) executeStep(step *gauge.Step, protoStep *gauge_messages.ProtoStep) *result.StepResult {
    27  	stepRequest := e.createStepRequest(protoStep)
    28  	e.currentExecutionInfo.CurrentStep = &gauge_messages.StepInfo{Step: stepRequest, IsFailed: false}
    29  	stepResult := result.NewStepResult(protoStep)
    30  	for i := range step.GetFragments() {
    31  		stepFragmet := step.GetFragments()[i]
    32  		protoStepFragmet := protoStep.GetFragments()[i]
    33  		if stepFragmet.FragmentType == gauge_messages.Fragment_Parameter && stepFragmet.Parameter.ParameterType == gauge_messages.Parameter_Dynamic {
    34  			stepFragmet.GetParameter().Value = protoStepFragmet.GetParameter().Value
    35  		}
    36  	}
    37  	event.Notify(event.NewExecutionEvent(event.StepStart, step, nil, e.stream, e.currentExecutionInfo))
    38  
    39  	e.notifyBeforeStepHook(stepResult)
    40  	if !stepResult.GetFailed() {
    41  		executeStepMessage := &gauge_messages.Message{MessageType: gauge_messages.Message_ExecuteStep, ExecuteStepRequest: stepRequest}
    42  		stepExecutionStatus := e.runner.ExecuteAndGetStatus(executeStepMessage)
    43  		stepExecutionStatus.Message = append(stepResult.ProtoStepExecResult().GetExecutionResult().Message, stepExecutionStatus.Message...)
    44  		if stepExecutionStatus.GetFailed() {
    45  			e.currentExecutionInfo.CurrentStep.ErrorMessage = stepExecutionStatus.GetErrorMessage()
    46  			e.currentExecutionInfo.CurrentStep.StackTrace = stepExecutionStatus.GetStackTrace()
    47  			setStepFailure(e.currentExecutionInfo)
    48  			stepResult.SetStepFailure()
    49  		} else if stepResult.GetSkippedScenario() {
    50  			e.currentExecutionInfo.CurrentStep.ErrorMessage = stepExecutionStatus.GetErrorMessage()
    51  			e.currentExecutionInfo.CurrentStep.StackTrace = stepExecutionStatus.GetStackTrace()
    52  		}
    53  		stepResult.SetProtoExecResult(stepExecutionStatus)
    54  	}
    55  	e.notifyAfterStepHook(stepResult)
    56  
    57  	event.Notify(event.NewExecutionEvent(event.StepEnd, *step, stepResult, e.stream, e.currentExecutionInfo))
    58  	defer e.currentExecutionInfo.CurrentStep.Reset()
    59  	return stepResult
    60  }
    61  
    62  func (e *stepExecutor) createStepRequest(protoStep *gauge_messages.ProtoStep) *gauge_messages.ExecuteStepRequest {
    63  	stepRequest := &gauge_messages.ExecuteStepRequest{ParsedStepText: protoStep.GetParsedText(), ActualStepText: protoStep.GetActualText(), Stream: int32(e.stream)}
    64  	stepRequest.Parameters = getParameters(protoStep.GetFragments())
    65  	return stepRequest
    66  }
    67  
    68  func (e *stepExecutor) notifyBeforeStepHook(stepResult *result.StepResult) {
    69  	m := &gauge_messages.Message{
    70  		MessageType:                  gauge_messages.Message_StepExecutionStarting,
    71  		StepExecutionStartingRequest: &gauge_messages.StepExecutionStartingRequest{CurrentExecutionInfo: e.currentExecutionInfo, Stream: int32(e.stream)},
    72  	}
    73  	e.pluginHandler.NotifyPlugins(m)
    74  	res := executeHook(m, stepResult, e.runner)
    75  	stepResult.ProtoStep.PreHookMessages = res.Message
    76  	stepResult.ProtoStep.PreHookScreenshotFiles = res.ScreenshotFiles
    77  	if res.GetFailed() {
    78  		setStepFailure(e.currentExecutionInfo)
    79  		handleHookFailure(stepResult, res, result.AddPreHook)
    80  	}
    81  	m.StepExecutionStartingRequest.StepResult = gauge.ConvertToProtoStepResult(stepResult)
    82  	e.pluginHandler.NotifyPlugins(m)
    83  }
    84  
    85  func (e *stepExecutor) notifyAfterStepHook(stepResult *result.StepResult) {
    86  	m := &gauge_messages.Message{
    87  		MessageType:                gauge_messages.Message_StepExecutionEnding,
    88  		StepExecutionEndingRequest: &gauge_messages.StepExecutionEndingRequest{CurrentExecutionInfo: e.currentExecutionInfo, Stream: int32(e.stream)},
    89  	}
    90  
    91  	res := executeHook(m, stepResult, e.runner)
    92  	stepResult.ProtoStep.PostHookMessages = res.Message
    93  	stepResult.ProtoStep.PostHookScreenshotFiles = res.ScreenshotFiles
    94  	if res.GetFailed() {
    95  		setStepFailure(e.currentExecutionInfo)
    96  		handleHookFailure(stepResult, res, result.AddPostHook)
    97  	}
    98  	m.StepExecutionEndingRequest.StepResult = gauge.ConvertToProtoStepResult(stepResult)
    99  	e.pluginHandler.NotifyPlugins(m)
   100  }
   101  
   102