cucumber / cucumber-js

Cucumber for JavaScript
https://cucumber.io
MIT License
5.04k stars 1.09k forks source link

Register custom handler to intercept URL of published report #1797

Open aslakhellesoy opened 3 years ago

aslakhellesoy commented 3 years ago

Is your feature request related to a problem? Please describe.

I would like to capture the URL of the published report so I can notify an external system with the report URL.

Describe the solution you'd like

I want to be able to register a function that will be called with the URL of the published report - something like this:

import { registerPublishListener } from '@cucumber/cucumber'

registerPublishListener(async function (reportUrl: string) {
   // Do something with the URL, for example send it to Slack
})

Describe alternatives you've considered

Redirecting STDERR to a file, then parse it with a shell script and send the message. That's quite a roundabout way of doing this.

Additional context

This is requested by a user of Cucumber Reports. See similar request here: https://github.com/cucumber/cucumber-jvm/issues/2324

tooky commented 3 years ago

I thought I'd take a little look at this. I added a failing scenario in 2118d280f4a06dcbd42b8df2efeaa45cac919e91.

As I started to dig into the code I think that the displayed banner is actually returned by the server receiving the HTTP message stream and then written as is to STDERR, see https://github.com/cucumber/cucumber-js/blob/6e958f100bd86d354c501ff9bfefa16f088925dc/src/cli/index.ts#L102-L108.

@aslakhellesoy were you thinking that this resonse string should be parsed by Cucumber and the URL passed to the listener? This seems error prone.

Alternatively, we could send the entire response body to the listener and leave the parsing up to the listener implementation?

Should we consider changing the reports protocol to return more than just a message string?

davidjgoss commented 2 years ago

I did some experimenting with this today and raised a draft https://github.com/cucumber/cucumber-js/pull/1950 with my progress.

As @tooky noted we don't have a definitive way to get the published URL. I did a scrappy implementation that takes the PUT URL and splits the identifier out of the path, but that's probably no better than parsing it out of the console message on balance.

@aslakhellesoy could we make a non-breaking change to the reports API so that with a Accept: application/json header in the initial GET request it will instead return a JSON representation something like:

{
  "url": "https://reports.cucumber.io/reports/XXXX-XXXX-XXXX-XXXX-XXXX",
  "message": "<terminal-formatted message as it is now>"
}

This would not break existing usages but would allow us to address this issue in newer ones.

mattwynne commented 2 years ago

We could also send the report URL in a custom header.