fix(selenium): Collaborative summary editor loses typed text on blur - #117
Merged
Merged
Conversation
Same Quill microtask race as PR #115 (AI model description): typing into the summary editor then blurring can fire handleSave() before React's onChange commits, wiping the field. The old workaround typed the text twice and asserted the doubled string -- fragile and hid the real bug. enter_summary() now calls BasePage.type_into_rich_editor(), which types once, watches for a few seconds, and retypes only if the editor got wiped. Updated test_prv_010 and test_prv_011 assertions to expect test_summary instead of test_summary + test_summary.
saqibmanan
added a commit
that referenced
this pull request
Sep 24, 2026
…ount orgs (#103) (#120) * fix(selenium): re-find rich editor before typing, and wait for text to land Two defects in type_into_rich_editor, both found from a captured screenshot showing the editor still displaying its placeholder: - The stay-check polled immediately after send_keys, so if Quill had not yet committed the text the first comparison failed and both attempts burned in milliseconds, reporting ''. Wait for the text to appear first, then watch that it stays. - The element was located before scrolling and typed into afterwards. React can swap the editor node in between; keys sent to the detached node are accepted silently while the visible editor stays blank. Re-find immediately before typing and confirm focus actually landed. Also adds save_failure_artifacts() and a per-attempt trace, so the next failure says which branch fired instead of only 'now holds'. * test(provider): capture screenshot + DOM when the Metadata tab wait times out All three Metadata-tab waits are already at 60s, so a further timeout bump is not the answer; two such bumps on the publishers page achieved nothing because the real fault was a wrong tag in the locator, found only once the DOM was captured. Dump the same evidence here. * fix(selenium): restore the JS click on the rich editor, keyed failure artifacts Two corrections to the previous commit on this branch: - It replaced the JS click() with focus(), which regressed test_prv_011 and test_prv_012 from passing to failing. Quill sets its selection range on mousedown/click; with focus but no caret it silently discards everything send_keys types. The per-attempt trace showed focus landing on the correct sole contenteditable editor while the text stayed ''. Click, then focus. The 'detached React node' reasoning in that commit was wrong. - save_failure_artifacts wrote a fixed filename, so each failure overwrote the last. Under -n the artifact you read can belong to a different test entirely, which sent one diagnosis down the wrong path. Key it by test id and PYTEST_XDIST_WORKER. * ci: run provider smoke serially These are write flows against one shared dev backend and they contend on it. Measured on the same branch and target: 4 failed at -n 3 --dist loadfile, all 5 of the same tests passed sequentially. --reruns 2 was active and did not rescue the parallel run. The failures presented as locator breakage -- blank TimeoutExceptions, a Quill editor silently dropping send_keys -- and were contention throughout, which cost several cycles of DOM investigation before -n was changed. ~30 min serial against a 60 min job timeout. * Revert "ci: run provider smoke serially" This reverts commit 1b4d0ea. * fix(provider): give each account its own org (#103) select_org() with no argument fell back to a hardcoded "my test agency". Account 1 can write there and account 2's org_add_permission[0] IS that org, so test_prv_009 (which edits the org profile) ran against the same org row as the create flows. New writable_org fixture pins one org per account slot -- 1 my test agency, 2 test org 2, 3 test org name -- overridable via TEST_ORG_<n> and skipping loudly when the grant is missing, since this provisioning has already drifted twice. select_org() now requires an org name and has no "first available card" fallback; both fallbacks were how a worker silently landed on another worker's org. Measured: test_prv_009 and test_prv_013 go from failing to passing at -n 3. * test(selenium): click_until helper, plus console and network capture click_until clicks and then verifies the click had its expected effect, retrying with a JS click. Failure artifacts now also dump the browser console and GraphQL traffic. Both came out of test_prv_006, where a screenshot alone was a dead end: the "Create New Dataset" modal sat open for 60s with the type selected, the button aria-disabled=false, one matching button in the DOM, an empty console and no toast. The network log is what finally showed no createDataset mutation is ever sent -- the click reaches no handler at all. Still unexplained; the capture is what makes it diagnosable. * fix(selenium): disable Chrome's password-leak bubble ROOT CAUSE of test_prv_006/006b/007. After login Chrome showed "The password that you just used was found in a data breach". That is browser UI, not page content: it renders over the page and takes keyboard focus, swallowing clicks and send_keys. It is invisible to every in-page diagnostic -- Selenium's screenshot captures the viewport not browser chrome, and it appears in neither page_source, the console log nor the network log. So the modal looked perfect while nothing worked: button unique, visible, aria-disabled=false, type card selected, clean console, and no createDataset mutation ever sent. It fires per PASSWORD, so it hit the accounts whose credentials are in a breach corpus and not others. That is why it read as contention under -n, then as account/org-specific, then as headless-only -- three wrong root causes, each from runs where an uncontrolled variable moved with the one being tested. Verified: account 3 headless, the combination that had never passed, went 3/3; the same three at -n 3 also 3/3; full suite 11/12 with the remaining failure unrelated (intermittent logo upload) and passing on rerun. Also pins WINDOW_SIZE as an override, used to rule out a viewport-breakpoint theory along the way. * fix(provider): dataset description via type_into_rich_editor The last enter_description still using a raw click + send_keys; the usecase, collaborative and ai-model summaries moved to the helper in #115-#117. A plain send_keys can leave the Quill editor empty, which test_prv_006 step 5a asserts against ("expected description ... but found ''").
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
handleSave()before React's onChange commits, wiping the field.enter_summary()inpages/provider/create_collaborative_page.pynow calls the sharedBasePage.type_into_rich_editor()helper (type once, watch for wipe, retype if needed) instead of the old click/send_keys/type-twice dance.test_prv_010_ind_create_collaborative.pyandtest_prv_011_org_create_collaborative.pynow assertactual_summary == test_summaryinstead of the doubledtest_summary + test_summary, and the error messages match.Verification
Ran locally against dev (
HOME_URL_DEV=https://dev.civicdataspace.in):Result:
1 passed in 209.06s.Did not touch any UseCase-flow files (test_prv_003/007/008, create_usecase_page.py) -- out of scope, owned by a parallel change.