Issue #3616873: Pin the read after a submit to the page that came back
A read taken after pressButton('View cart') could land on the page the submit was pressed from, not the page it brought back.
Both pages carry the same offer card, so waitForElement() matches straight away on the old document, and the handle it returns dies under WebDriver the moment the rebuilt page arrives. That surfaced as WebDriver\Exception\StaleElementReference and said nothing about the offer.
What was measured
Instrumenting the test to stamp the pre-submit document and watch for the stamp to go: in one run of three concurrent runs, pressButton() returned with the old document still in place, for another 71ms. Fourteen samples of the value itself were all 2, arriving within 2 to 226ms, so the quantity the form renders was never wrong; only where it was read from was.
Under heavier load (six concurrent) chromedriver itself times out receiving messages from the renderer, which no test change addresses and which is not this failure.
The change
submitAndWaitForNewPage() stamps the document, presses, and waits for the stamp to be gone before anything is read, so every read after it is pinned to the page that came back. Its poll tolerates the one exception a read can throw as the document is replaced, and it fails with a sentence naming the timeout if no new page arrives.
The read then re-finds the field and asserts on that handle rather than on one taken earlier.
Verification
- the single test, three concurrent runs: green
- the whole class: 12 tests, 100 assertions, green
phpcsDrupalandDrupalPracticeover the project root: 0phpstanlevel 1 overyoyaku_calendar: no errorscspell: nothing new (onlyyoyaku, which is in the project dictionary)
No user-facing string changed, so there is nothing for the French catalog, and docs/metrics.md counts classes and methods, neither of which moved.
Update: the wait moved into a trait
WaitsForTheNextPage in the parent module's tests/src/Traits, beside HoldsOneLine and RecordsQueryCounts, which is how this project shares test helpers. A trait rather than a base class: two of the project's browser tests extend PerformanceTestBase, so a shared parent would have had to fight that.
yoyaku_calendar declares yoyaku:yoyaku, so the import stays inside the module boundary.