Skip to content

Fix QAN search page-object race with debounced search - #1188

Closed
claude[bot] wants to merge 1 commit into
mainfrom
claude/elegant-cerf-lgx0vh
Closed

Fix QAN search page-object race with debounced search#1188
claude[bot] wants to merge 1 commit into
mainfrom
claude/elegant-cerf-lgx0vh

Conversation

@claude

@claude claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Failures fixed (investigator)

What failed

The only red job in the run (88 passed, 2 failed, 21 skipped). Both failures are
the same error, at the same page-object line:

Clickable element "//input[contains(@name, "search")]" was not found by text|CSS|XPath
  ✖ I.click("//input[contains(@name, "search")]")   queryAnalyticsData.js:158
  ✔ I.clearField("//input[contains(@name, "search")]") queryAnalyticsData.js:157
  ✔ I.wait(1)                                        queryAnalyticsData.js:156
  ✔ I.waitForVisible("//input[contains(@name, "search")]", 30) queryAnalyticsData.js:155

The field is visible, clearField on it succeeds — and then the very next step
cannot find it at all.

Not a one-off: the same two tests failed the same way on three consecutive
nightlies — 31653305276 (08-13),
31756198073 (08-14),
31852756475 (08-15).

Root cause — our page object, not the product

percona/pmm#5537 (PMM-14848, merged
2026-08-11 — two days before the first red nightly) turned the QAN Overview
search into debounced search-as-you-type:

const debouncedSearch = useMemo(() => debounce((search: string) => {
  handleSearchRef.current({ search });
}, SEARCH_DEBOUNCE_MS /* 300 */), []);

Every value change now issues a search of its own. I.clearField is a value
change, so searchByValue() fires an empty search before it ever gets to the
click, the Overview panel reloads, and the search input is remounted underneath
the pending I.click.

Measured on the reproduction VM

Throwaway Linode VM, perconalab/pmm-server:3-dev-latest (3.9.1-v3-b9a8db278,
so it has #5537), latest-tarball client, pdpgsql + ps + psmdb setups.
Driving the real UI and polling the DOM every 50 ms after a fill('') on the
search input — three runs:

run input gone from DOM at new input mounted at
1 579 ms ~1300 ms
2 496 ms ~1300 ms
3 506 ms ~1300 ms

So there is a ~700-800 ms window in which //input[contains(@name, "search")]
matches nothing — which is exactly the error CI reports.

pr.codecept.js sets waitForAction: 500, so I.click fires ≈500 ms after
I.clearField — straddling the start of that window. In two of the three
measurements the gap was already open at 500 ms. Whether the click lands just
before or just inside the gap is decided by tens of milliseconds, which is why
the nightly's loaded remote server loses it every night while a fresh,
lightly-loaded VM wins it.

Fix

Don't issue a search just to empty the field: drop the pre-click clearField
(Playwright's fill clears the field as part of typing, so I.fillField alone
does the job in one action and one debounce), and settle the panel afterwards.

Verification

Full @qan suite on the same VM, before and after the change (same server, same
setups, runs ~1 h apart):

passing failing pending
main @ 37a003d 48 15 2
this branch 45 18 2

PMM-T1061 and PMM-T1790 pass in both runs. Every baseline failure is still a
failure afterwards (no test was "fixed" by accident) and three more appear:

  • PMM-T215 and PMM-T128 — both hinge on .ant-pagination-item-ellipsis
    (not visible / not found). Whether that element renders depends on how many
    pages of QAN data exist, and the dataset grew between the two runs. The
    baseline's own PMM-T193 failure shows the same drift (expected 100, actual 75 items).
  • PMM-T411 + PMM-T400 + PMM-T414supposed to result in Query with value: 0.05 QPS but the resulted query found is 0.06 QPS. A value that moves while
    the generator keeps running. Notably the search in this test worked; only
    the QPS assertion drifted.

None of the three touch searchByValue() / click() / clearSearchValue(), and
neither run produced a "search input not found" error (the one was not found
in the after-run is the pagination ellipsis above).

What this does not prove. As explained above, this VM wins the race the
nightly loses, so a green run here is not evidence the nightly is fixed. What
is established here is the mechanism (the measured DOM gap) and that removing
the extra search does not regress the @qan suite. Only the next real nightly
can confirm PMM-T1061/PMM-T1790 go green in CI.

Note on PR #1184

#1184's description lists this
exact fix ("fix 1", commit
0b2c040) and names
PMM-T1061/PMM-T1790, but that commit is no longer on its branch — the file
isn't in #1184's diff and main still has the racy sequence. So despite what
#1184 says, nothing open currently fixes these two tests. This PR restores it.


Generated by Claude Code

The QAN Overview search became search-as-you-type (debounced 300ms) in
PMM-14848 (percona/pmm#5537, merged 2026-08-11). The searchByValue()/
click() page-object methods cleared the field before clicking it, and
that clear now fires an empty search of its own, reloading the Overview
panel and remounting the search input. The immediately following
I.click() races that reload and fails with "Clickable element
//input[contains(@name, "search")] was not found" (PMM-T1061, PMM-T1790,
and any @qan spec that searches).

Click the already-loaded grid first and let I.fillField clear+type in a
single action (Playwright fill clears the field), so only one search is
issued, then wait for the panel to settle. Apply the same settle to
clearSearchValue().

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: travagliad <215686151+travagliad@users.noreply.github.com>
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

Closing this — it should never have been opened.

My dedup only covered open percona/pmm-qa PRs; I never checked Jira. There is
already a ticket for this, filed 2026-08-13:
PMM-15336"QAN
overview search input unmounts while typing, losing focus and keystrokes"

(Bug, New, Found by Automation = Yes). It names PMM-T1061 and PMM-T1790 as its
CI casualties.

More importantly, it classifies this correctly — as a product bug — and my
change here contradicts it. PMM-15336's root cause goes one level deeper than
mine:

Overview/components/QanTable/Table.tsx renders the table — headers included —
only in the !loading branch; while loading it renders just a <Spinner/>.
The search input is inside that header.

So the input doesn't merely race a reload: the product deletes its own search
box
on every debounced search and remounts it without focus, dropping whatever
was typed in between. That hits real users, not just CodeceptJS — typing
SELECT, pausing, then continuing leaves you with SELECT and the rest of the
characters gone. The ticket has an A/B against 3.9.0 showing the input was
never unmounted before percona/pmm#5537.

PMM-15336 is explicit that the tests are to stay as they are:

The tests are correct and are deliberately left unchanged — relaxing them would
hide this defect.

That is exactly what this PR would have done. Removing the clearField stops the
tests from ever landing in the unmount window, so the nightly goes green while
users keep losing keystrokes — the CI signal for a live regression, switched off.

The measurements I took stand and agree with the ticket's (search input out of the
DOM ~500 ms after a value change, back ~1.3 s later, on 3.9.1-v3-b9a8db278) — I
just drew the wrong conclusion from them. The fix belongs in
Table.tsx/Search.tsx, keeping the header mounted across loading, per
PMM-15336's suggested direction. Nothing to change in pmm-qa.


Generated by Claude Code

@claude claude Bot closed this Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant