cucumber / cucumber-jvm

Cucumber for the JVM
https://cucumber.io
MIT License
2.69k stars 2.02k forks source link

Make it possible to use `Scenario` without a hook #2903

Open mpkorstanje opened 4 days ago

mpkorstanje commented 4 days ago

šŸ¤” What's the problem you're trying to solve?

Currently when using a Scenario to attach file or log information to a report it is necessary to use a before hook to get the scenario object:

public class Attachments {

    Scenario scenario;

    @Before
    public void before(Scenario scenario) {
        this.scenario = scenario;
    }

    @When("the string {string} is attached as {string}")
    public void theStringIsAttachedAs(String text, String contentType) {
        scenario.attach(text, contentType, null);
    }

This is quite cumbersome.

āœØ What's your proposed solution?

When executing a step definition, Cucumber knows what the currently active scenario is. So we can in theory use something like

    @When("the string {string} is attached as {string}")
    public void theStringIsAttachedAs(String text, String contentType) {
        Scenario.current().attach(text, contentType, null);
    }

Or with a static import.

    @When("the string {string} is attached as {string}")
    public void theStringIsAttachedAs(String text, String contentType) {
        currentScenario().attach(text, contentType, null);
    }

Cucumber would internally use a ThreadLocal to store the current active test case. This does come with the problem that it may be invoked on a different thread by accident (e.g. when using Awaitility) but with a clear error message I reckon the worst of this can be avoided.

ā› Have you considered any alternatives or workarounds?

No response

šŸ“š Any additional context?

This will be required once https://github.com/cucumber/compatibility-kit/issues/83 is resolved to pass the acceptance test (or some filtering to ignore these extra messages).

orcunbalcilar commented 3 days ago

A wrapper/proxy class at runtime for the desired class ?