skip to content

What should a suite send to a hosted browser provider alongside each session's verdict, and why?

level: seniorimportance: must knowfreq 61%

answer

  1. pass or fail alone is not actionable
  2. you can only search what you sent
  3. derive the name, never type it
  4. separate this attempt from the last
  5. a failure message is a place secrets hide

basics

~20 s

Send the verdict, a case name that is stable across runs, something separating this attempt from the last, and a short failure reason. Keep secrets out of all of it: the payload lands on someone else's machine.

solid answer

~50 s

Pass or fail alone makes a row you cannot act on. Add a **stable case name** derived from the identity your framework already computes — not a hand-typed title — because you can only search and group on values you actually sent, and a name that changes with the wording joins nothing. Add something that separates **this attempt** from the last: the pipeline run, and a marker for a re-run, so a retried case does not blur into its own history. Add a **short reason** on failure, the first assertion's message rather than a stack, so the list is triageable without opening anything. Keep the link working both ways by recording the service's session identifier in your own report. And send nothing secret — a raw exception from your driving-test booking suite can carry a token, an address with credentials inside it, or a real person's details.

go deeper

for a junior

Learn the minimum useful payload: a verdict, a case name, and a short reason when it fails. Know that the name should come from code rather than from a title somebody typed into the test.

for a middle

Be ready to explain why the name must be stable and why the run and attempt must be separate values from it. Know that anything you did not send cannot be searched or grouped afterwards.

for a senior

Expect the secrets question. Talk about failure messages as an exfiltration path, about building the reason deliberately rather than from a caught exception, and about keeping the far side's session identifier in your own report.

for a principal

Own the naming scheme before the estate grows. Settle how a case is named, who may change it, and what happens when a suite is restructured, because an annotation already sent should be treated as beyond your reach.

## Why the verdict alone is not enough An annotation that says only *failed* produces a row you cannot act on. The reader already suspects something failed; what they need is **which** case, **which** attempt and **roughly why**, fast enough that opening the run is a decision rather than a reflex. Two constraints shape the whole payload, and both are easy to forget because neither is technical: - you can only search, filter and group on values **you actually sent**; - the payload lands on infrastructure you do not own, so treat every annotation as final. ## A case name that is stable across runs Stable means the same case yields the same name on every run, on every machine, in every shard, in any order. Derive it from the identity your framework already computes — the class or file, the case function, and a key for the parameter row where there is one — rather than from a human title. A title gets reworded, and the moment it does you have two unrelated sets of rows for one case and no way to join them. Some rules that hold up: - **Derive, never type.** A name assembled in code changes only when the code does. - **Make it flat and boring.** Use characters that survive a URL, a search box and a chat message. - **Do not encode the environment in it.** Branch, browser and shard belong in separate values; baked into the name they fragment the case's history. - **Assume it is permanent.** Choose the scheme before the first wide run, not after. ## Something that separates this attempt from the last A stable name groups a case's history; it also makes every attempt look alike. So send a value unique to the run — the pipeline run or build identifier — and, where a case can execute more than once in a run, a marker for the attempt. Without it, a re-run after a flake and the original say the same thing about the same name and nobody can tell which is which. The useful filters come from here too: branch, shard, nightly or change-triggered. What you rarely need to re-send is anything the service already received on the session request — browser, platform, settings. Repeating it is noise you then have to keep in sync. ## A reason short enough to read in a list On failure, send the first assertion's message, trimmed, so that somebody scanning outcomes can sort a run into *the booking confirmation never appeared*, *the slot search timed out* and *the login step broke* without opening a single one. A full stack trace does not do that: too long to read in a list, and usually more about your framework than about the product. | Sent | What it lets a reader do | |---|---| | the verdict | see that something is wrong | | a stable case name | find every run of this case | | the run and attempt | tell this execution from its re-run | | a short reason | triage without opening anything | | your run's address | get from their record back to yours | ## The link home, in both directions The annotation gives you *their record, labelled with your names*. The other half is yours to keep: record the identifier the service minted for the session in your own report, because your test could not have predicted it. Then a failing case reaches whatever the far side kept for it, and their row reaches your pipeline run. Both directions are your responsibility, and each needs one thing written down. ## What not to send This is the part that gets skipped, and the part with consequences. The payload is data you hand to a third party, and a failure message assembled by your harness is an unusually good hiding place for a secret: - an exception whose message carries the endpoint address your suite connected with, credentials and all; - an authorisation token echoed into a message by a helpful client library; - a fixture shaped like a real person's record — a name, a licence number, a date of birth for a driving-test booking; - an internal hostname that says more about your estate than you would put in a public document. The habit that fixes it: build the reason from a **short, deliberate** string rather than from whatever `toString` produced, and redact it the way you redact logs. How long the provider keeps it and who else on the account can read it are separate questions — worth asking only about data that got sent, so the cheapest control is not sending it. ## A checklist worth memorising 1. **Verdict** — reduced to whatever the service accepts. 2. **Stable case name** — derived in code from the case's identity. 3. **Run and attempt** — so this execution is distinguishable from its re-run. 4. **Short reason on failure** — readable in a list, redacted like a log line. 5. **Their session identifier, kept on your side** — so the link works the other way. Send those and a stranger can triage your suite. Send the verdict alone and even you will struggle a fortnight later.

  • Why derive the case name in code rather than let each test declare its own?
    Because a declared name drifts. It gets reworded during a refactor, duplicated by a copy-paste, and forgotten on the next test somebody adds — and each of those quietly splits or merges a case's history on the far side. A name assembled from the identity the framework already computes changes only when the code itself changes, which is visible in review.
  • Should the annotation carry the browser and platform the case ran on?
    Usually not. The service received those on the session request, so re-sending them adds a second copy you must keep in sync and that can disagree with the first. Send what the service could not know: your case identity, your run, your attempt, and your reason. Send what it already has only when you genuinely need it in a different shape.
  • What is the risk in putting a raw exception message into the annotation?
    It is assembled from values your harness was holding, and those include endpoint addresses with credentials inside them, tokens echoed by client libraries, and fixture data shaped like real personal records. Once sent, it sits on a third party's infrastructure. Build the reason from a deliberate short string and redact it the way you redact logs.

A verdict with no stable case name is a signed delivery receipt with nothing written in the address box: the statement is true, it is filed, and it reaches nobody who needed it. The name is the address, which is why it is chosen deliberately and not reworded on a whim.

saying these in an interview costs you the question

  • Sending only pass or fail and calling it reported
  • Using a hand-typed display title as the case name
  • Baking the branch or browser into the case name
  • Pasting a full stack trace in as the failure reason
  • Assuming an annotation can be revised after it is sent
  • Never checking what the failure message actually contains