Reorder Capybara assertions to confirm state before absence
What does this MR do and why?
Fixes a class of flaky :js feature specs that intermittently time out (30s)
on negative Capybara matchers that run before a positive matcher
confirms the post-action state.
The anti-pattern
After an action that triggers an asynchronous UI re-render (click_button,
click_link, etc.), these specs asserted the absence of the old state
before confirming the new state:
click_button 'Resume'
expect(page).not_to have_button 'Resume' # negative FIRST — waits the full 30s
expect(page).to have_button 'Pause' # positive LASTWhile the component is mid-transition, the old element is still in the DOM, so the negative matcher polls it for the entire Capybara timeout before concluding it's gone — a 30s flake when the re-render is slightly slow.
The fix
Reorder each affected block so a positive matcher confirms the new state first, then the negative absence checks run against an already-settled page:
click_button 'Resume'
expect(page).to have_button 'Pause' # positive first — waits for re-render
expect(page).not_to have_button 'Resume' # negative now resolves instantlyThis follows the testing guide: confirm the page is loaded with a positive matcher before checking for element absence (best practices).
Pure assertion reordering — no expectations were added or removed (43 insertions / 43 deletions across 25 files). The same fix was previously applied to the runner specs in !240917 (merged).
Scope
25 feature specs across CE and EE, covering award emoji toggles, label subscription, admin background migrations, registry protection rules, pipeline cancel, CI editor, LDAP/SAML group links, epic boards, and more. Only the highest-confidence cases (clear state toggle where the negative checks the disappearing old element) are included.
References
Open flaky-test tracking issues (failure::flaky-test, test-health:pass-after-retry)
whose root cause this MR addresses:
- https://gitlab.com/gitlab-org/quality/test-failure-issues/-/issues/9504 —
pipelines_spec.rbpipeline cancel (the exact example reordered here;quarantine::flaky) - https://gitlab.com/gitlab-org/quality/test-failure-issues/-/issues/2681 —
ee/spec/features/epic_boards/epic_boards_spec.rb(severity::1,flakiness::4) - https://gitlab.com/gitlab-org/quality/test-failure-issues/-/issues/5953 —
user_interacts_with_awards_spec.rb
The remaining specs (label subscription, registry protection rules, LDAP/SAML group links, etc.) had no open tracking issue — they are preventive fixes from a code-pattern audit of the same anti-pattern.
How to set up and validate locally
Run any of the touched specs; the reordered examples should pass reliably:
bundle exec rspec spec/features/groups/labels/subscription_spec.rb \
spec/features/admin/admin_sees_background_migrations_spec.rbValidated locally: subscription (group + project), admin_sees_background_migrations,
usage_stats_consent, milestone, user_interacts_with_awards, and the EE
LDAP/SAML group-link specs pass. RuboCop is clean on all 25 files. (Note:
user_comments_on_issue_spec.rb has unrelated pre-existing BrowserConsoleError
failures in its rich-text-editor shared examples — present on clean master and
not touched by this MR.)
Why these regressions weren't caught at authoring time
Added after merge, as context for the GitLab Duo Code Review principle work tracked in gitlab-org/gitlab#603464. Recorded here so it cannot be argued the reviewer drew the conclusion from this description before the analysis existed.
These anti-patterns were introduced before GitLab Duo Code Review had a custom
instruction that flags them, so the reviewer had no rule to catch them when the
code was authored. Timeline on master:
.gitlab/duo/mr-review-instructions.yamlfirst added: 2025-06-18Test Efficiencygroup added (which carries the positive-before-absence rule): 2026-04-20- The specific "confirm the page has loaded with a positive assertion before checking for absence" rule: 2026-06-11
Tracing three of the reordered cases back to the commit that introduced the negative-before-positive order:
| Spec | Introduced by | Authored | Duo absence rule available then? |
|---|---|---|---|
spec/features/groups/labels/subscription_spec.rb |
fix-33991 |
2017-06-26 | No (predates the instructions file by years) |
spec/features/admin/admin_hooks_spec.rb |
579392-webhooks-form-should-redirect-after-editting |
2025-12-09 | No (before the Test Efficiency group) |
spec/features/usage_stats_consent_spec.rb |
remove-sign_in_form_vue-ff |
2026-02-24 | No (before the Test Efficiency group) |
In each case the guidance that now catches the pattern did not yet exist when the code was written — these are regressions Duo could not have flagged at the time, and the rule that detects them was only added later.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.