DEV Community

2SD Technologies Limited
2SD Technologies Limited

Posted on

How do you decide two buttons are the same button?

Every UI test rests on a claim that sounds trivial and is not: this element, on this page today, is the same element I recorded last week.

Selectors are how we usually make that claim, and they make it by proxy. #checkout-btn does not mean "the button that completes the purchase". It means "whatever has that id", and the relationship between the two is a convention somebody upheld until a release did not.

So the question worth asking is not how to write more durable selectors. It is what would have to be true for a tool to decide, after a change, that two elements are the same thing.

Why the obvious answers do not survive

Use stable test ids. Correct, and it is the best advice in this article -- data-testid attributes owned by the team, treated as API rather than decoration, will prevent most of this. It is also advice that arrives too late for the suite you already have, and it does not survive a component library upgrade that rewrites the markup underneath your attributes, or a third-party checkout widget you do not control, or the two hundred tests written before the convention existed.

Use XPath from a stable ancestor. This trades one fragility for a worse one. A path encodes structure, and structure is the thing most likely to change: one wrapper div for a new layout mode and every path below it is wrong.

Use the accessible name. Much better, and genuinely durable, right up to the point where the copy changes. "Continue" becomes "Continue to payment" in a conversion experiment, and a test keyed on visible text is now keyed on a marketing decision.

Each is right about something. None is right alone, and that is the actual shape of the problem: element identity is not carried by any single attribute. It is distributed across several, each of which is individually unreliable and collectively quite informative.

Identity as a scoring problem

Which suggests treating it the way you would treat any other fuzzy-matching problem: capture several independent signals at record time, and after a change, score candidates against them rather than requiring an exact match on one.

The signals worth capturing are the ones that tend to change independently of each other:

  • Role. Is it still a button -- not a link, not a div with a click handler? Role is the most stable of the four, because changing it usually means changing behaviour.
  • Label. The visible text a person would actually click. Unstable under copy changes, but strong evidence when it matches.
  • Position. The same place in the same form, expressed relative to its container rather than in pixels. Survives restyling; does not survive reordering.
  • Neighbours. The fields either side of it. This one is underrated: a checkout button whose preceding sibling is still the card-number field is probably still the checkout button, even if its id, text and position all moved.

No single one of those is worth much. A candidate matching three of four, where the fourth is the one that plausibly changed in this release, is worth a great deal.

The part that decides whether any of this is a good idea

Here is where scoring becomes dangerous rather than clever, and it is worth being blunt about it, because this is the difference between a useful mechanism and a liability.

A scorer must be able to decline.

If the implementation always returns its best candidate, you have built something that converts failures into passes. The test was red because the button genuinely vanished; the scorer finds something button-shaped nearby, clicks it, and the suite goes green. You have not fixed a test. You have removed a signal, and you will not find out until production.

So the behaviour under uncertainty is the whole design, not an edge case:

  1. A confidence threshold, below which the run fails -- and fails as a missing element, with the candidates it considered and their scores, not as a generic assertion error.
  2. Every accepted match recorded as a change, in the run output, with the old identity and the new one side by side. A relocation is an event, not an implementation detail.
  3. A way to see those events without going looking for them. If reviewing relocations is an optional screen somebody has to remember to open, nobody opens it, and you are back to silent passes with extra steps.

The uncomfortable implication is that a tool making this claim should sometimes be more alarming than a brittle one, not less: it should fail loudly in exactly the cases a naive selector would also have failed, and the difference should show up only where the evidence is genuinely strong.

What to ask, and what to do if you are not buying anything

If you are evaluating something that advertises self-healing, two questions get to the bottom of it quickly. Ask to see a low-confidence case -- not a demo of a successful relocation, but what happens when the tool is unsure. And ask where accepted relocations appear, and whether anyone on the team has looked at that list this month.

If you are not buying anything, the useful takeaway is smaller and free: when a test fails on a missing element, the debugging information you want is not "selector not found". It is what else was on the page that nearly matched, and why it was rejected. Most frameworks will not tell you that, but you can usually capture it yourself in a failure hook -- dump the candidates with the same role, and their labels, before you throw. It turns a class of ten-minute investigations into ten-second ones, and it costs about twenty lines.

Disclosure

2SD Technologies builds TAI, a testing platform, and relocation-by-scoring is how it handles interface changes. The reason this article spends more words on declining to match than on matching is that we think it is the only part of the idea that is contentious -- the scoring is straightforward engineering, and the threshold is where a vendor's judgement is either sound or expensive for you.

Happy to show you the low-confidence case against your own application, if it would be useful: info@2sdtechnologies.com

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.