cucumber / cucumber-ruby-wire

Wire protocol plugin for Cucumber
MIT License
7 stars 11 forks source link

Return embeddings stored in success & fail responses #20

Closed Sigill closed 3 years ago

Sigill commented 5 years ago

Summary

In order to let cucumber formatters access embeddings transferred in wire responses, embeddings have to be returned by the Invoke event handler.

Motivation and Context

I'm looking into cucumber-cpp for my company. We need to be able to embed text or images into the reports, but that feature is not available when using the wire protocol.

This patch is the 3rd of a series of 4, respectively impacting cucumber-ruby, cucumber-ruby-core, cucumber-ruby-wire and cucumber-cpp.

Basically, the idea is to allow embeddings to be specified in the success or fail responses sent through the wire protocol. E.g.:

["success",{"embeddings":[{"label":"Embedded text","mime_type":"text/plain","src":"Some text"}]}]
["fail",{"embeddings":[{"label":"Embedded image","mime_type":"image/png;base64","src":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="}],"message":"There was no  banana"}]

The embeddings will then be stored in the step Result in order to be accessible by the formatter.

The patch on cucumber-ruby (cucumber/cucumber-ruby#1354) will let formatters access embeddings stored in a step result. The patch on cucumber-ruby-core (cucumber/cucumber-ruby-core#170) will store in the step result the embeddings returned by the step invocation. The patch on cucumber-ruby-wire (cucumber/cucumber-ruby-wire#20) will allow the embeddings stored in the wire response to be returned by the wire-based step invocation process. The patch on cucumber-cpp (cucumber/cucumber-cpp#223) will allow C++ steps to send embeddings through wire responses.

Note: embeddings were not considered to be useful for pending steps, but support should be possible if required.

Details

In the current implementation, it's not possible to access data from the wire response as nothing is returned from the wire invocation when a step succeed (a step is considered successful by default, an exception needs to be raised in case of failing or pending step).

Successful step

Cucumber::Core::Test::Runner::RunningTestCase::Status::Base.execute
  Cucumber::Core::Test::Step.execute
    Cucumber::Core::Test::Action.execute
      block -> Cucumber::StepMatch.invoke
        Cucumber::Wire::StepDefinition.invoke
          Cucumber::Wire::Protocol.invoke
            Cucumber::Wire::Protocol::Requests::Invoke.execute
              Cucumber::Wire::RequestHandler.execute
                Cucumber::Wire::Connection.call_remote
                  Cucumber::Wire::DataPacket reponse = // parsed packet
                  Cucumber::Wire::DataPacket.handle_with
                    Cucumber::Wire::DataPacket.handle_success // noop
                  // response discarded
      Cucumber::Core::Test::Action.passed -> return Cucumber::Core::Test::Result::Passed
  Cucumber::Core::Test::Result::Passed.describe_to(Cucumber::Core::Test::Runner::RunningTestCase)
    Cucumber::Core::Test::Runner::RunningTestCase.passed
      Cucumber::Core::Test::Runner::RunningTestCase@status = Cucumber::Core::Test::Runner::RunningTestCase::Status::Passing

Failing step

Cucumber::Core::Test::Runner::RunningTestCase::Status::Base.execute
  Cucumber::Core::Test::Step.execute
    Cucumber::Core::Test::Action.execute
      block -> Cucumber::StepMatch.invoke
        Cucumber::Wire::StepDefinition.invoke
          Cucumber::Wire::Protocol.invoke
            Cucumber::Wire::Protocol::Requests::Invoke.execute
              Cucumber::Wire::RequestHandler.execute
                Cucumber::Wire::Connection.call_remote
                  Cucumber::Wire::DataPacket reponse = // parsed packet
                  Cucumber::Wire::DataPacket.handle_with
                    Cucumber::Wire::RequestHandler.handle_fail -> throw Cucumber::Wire::Exception // error message (from response) embedded in exception
                  // response discarded
      Rescue in Cucumber::Core::Test::Action.execute
        Cucumber::Core::Test::Action.failed -> return Cucumber::Core::Test::Result::Failed
  Cucumber::Core::Test::Result::Failed.describe_to(Cucumber::Core::Test::Runner::RunningTestCase)
    Cucumber::Core::Test::Runner::RunningTestCase.failed
      Cucumber::Core::Test::Runner::RunningTestCase@status = Cucumber::Core::Test::Runner::RunningTestCase::Status::Failing

This patch make the request handler responsible for step invocations return a PassedInvokeResult/FailedInvokeResult object describing the step result (status, embeddings).

Those changes should be backward compatible.

How Has This Been Tested?

No test in that repository, but I just discovered there is a FakeWireServer, I need to see if I can do something with it. Suggestions are welcomed.

Types of changes

Checklist: