Page MenuHomePhabricator

[timebox: 3days] ReviseTone.cy.ts fails with badtoken error
Closed, ResolvedPublic

Description

As shown in https://integration.wikimedia.org/ci/job/quibble-with-gated-extensions-selenium-php83/11543/console and pasted below, the ReviseTone.cy.ts tests can fail with a badtoken error.

Test failure
16:41:46 ────────────────────────────────────────────────────────────────────────────────────────────────────
16:41:46                                                                                                     
16:41:46   Running:  ReviseTone.cy.ts                                                                (6 of 9)
16:41:48 
16:41:48 
16:41:48   Revise Tone
16:41:52     On desktop
16:41:58       βœ“ Shows the Revise Tone Edit Check (8895ms)
16:41:58       - Closes the Editor when declining Edits and suggests a new task
16:41:58       - Shows the Revise Tone Edit Check and tags edits
16:41:58     On mobile
16:42:00       1) "before each" hook for "Shows the Revise Tone Edit Check"
16:42:00         cy:command βœ”  visit	/index.php -> 301: http://127.0.0.1:9413/index.php?title=Main_Page
16:42:00         cy:command βœ”  window	
16:42:00         cy:command βœ”  assert	expected **<window>** to have property **mw**
16:42:00         cy:command βœ”  window	
16:42:00         cy:command βœ”  its	.mw.Api
16:42:00         cy:command βœ”  assert	expected **[Function]** to exist
16:42:00         cy:command βœ”  window	
16:42:00             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
16:42:00                       Status: 200
16:42:00             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
16:42:00                       Status: 200
16:42:00         cy:command βœ”  visit	/index.php -> 301: http://127.0.0.1:9413/index.php?title=Main_Page
16:42:00         cy:command βœ”  window	
16:42:00         cy:command βœ”  its	.mw.Api
16:42:00         cy:command βœ”  assert	expected **[Function]** to exist
16:42:00         cy:command βœ”  window	
16:42:00             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
16:42:00                       Status: 200
16:42:00             cy:xhr ➟  GET http://127.0.0.1:9413/api.php?action=query&format=json&meta=tokens&type=csrf
16:42:00                       Status: 200
16:42:00             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
16:42:00                       Status: 200
16:42:00         cy:command ✘  then	function(){}
16:42:00 
16:42:00 
16:42:00 
16:42:00 
16:42:00   1 passing (11s)
16:42:00   2 pending
16:42:00   1 failing
16:42:00 
16:42:00   1) Revise Tone
16:42:00        On mobile
16:42:00          "before each" hook for "Shows the Revise Tone Edit Check":
16:42:00      Error: badtoken
16:42:00 
16:42:00 Because this error occurred during a `before each` hook we are skipping the remaining tests in the current suite: `Revise Tone`
16:42:00       at $Cy.fail (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:146049:13)
16:42:00       at onError (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:152519:22)
16:42:00       at tryCatcher (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1777:23)
16:42:00       at Promise._settlePromiseFromHandler (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1489:31)
16:42:00       at Promise._settlePromise (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1546:18)
16:42:00       at Promise._settlePromise0 (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1591:10)
16:42:00       at Promise._settlePromises (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1667:18)
16:42:00       at _drainQueueStep (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2377:12)
16:42:00       at _drainQueue (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2370:9)
16:42:00       at Async._drainQueues (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2386:5)
16:42:00       at Async.drainQueues (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2256:14)
16:42:00 
16:42:00 
16:42:00 
16:42:01 
16:42:01   (Results)
16:42:01 
16:42:01   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
16:42:01   β”‚ Tests:        6                                                                                β”‚
16:42:01   β”‚ Passing:      1                                                                                β”‚
16:42:01   β”‚ Failing:      1                                                                                β”‚
16:42:01   β”‚ Pending:      2                                                                                β”‚
16:42:01   β”‚ Skipped:      2                                                                                β”‚
16:42:01   β”‚ Screenshots:  1                                                                                β”‚
16:42:01   β”‚ Video:        true                                                                             β”‚
16:42:01   β”‚ Duration:     11 seconds                                                                       β”‚
16:42:01   β”‚ Spec Ran:     ReviseTone.cy.ts                                                                 β”‚
16:42:01   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
16:42:01 
16:42:01 
16:42:01   (Screenshots)
16:42:01 
16:42:01   -  /workspace/log/GrowthExperiments/ReviseTone.cy.ts/Revise Tone -- Shows the Revis     (1280x720)
16:42:01      e Tone Edit Check -- before each hook (failed).png                                             
16:42:01 
16:42:01 
16:42:01   (Video)
16:42:01 
16:42:01   -  Video output: /workspace/log/GrowthExperiments/ReviseTone.cy.ts.mp4
16:42:01 
16:42:01
....
16:42:22   (Run Finished)
16:42:22 
16:42:22 
16:42:22        Spec                                              Tests  Passing  Failing  Pending  Skipped  
16:42:22   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
16:42:22   β”‚ βœ”  AddALink.cy.ts                           00:27        1        1        -        -        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  AddImage.cy.ts                           00:22        2        2        -        -        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  CommunityConfiguration.cy.ts             00:01        1        1        -        -        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  Homepage.cy.ts                            62ms        1        -        -        1        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  MentorDashboard.cy.ts                    00:11        1        1        -        -        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ–  ReviseTone.cy.ts                         00:11        6        1        1        2        2 β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  TemplateBasedTask.cy.ts                   88ms        1        -        -        1        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  ViewGrowthExperimentsEvents.cy.ts        00:03        1        1        -        -        - β”‚
16:42:22   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
16:42:22   β”‚ βœ”  Impact/Impact.cy.ts                      00:05        1        1        -        -        - β”‚
16:42:22   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
16:42:22     βœ–  1 of 9 failed (11%)                      01:23       15        8        1        4        2

Suggested path forward:

  • if account creation fails, then the account creation method checks if it got a badtoken error, waits 1 second, and then tries again (including a new token)
  • explore if it is feasible to create a test account in the beginning of the cypress test suite and then reuse for several tests where appropriate.

Notes

Event Timeline

Restricted Application added a subscriber: Aklapper. Β· View Herald Transcript
Dreamy_Jazz changed the subtype of this task from "Bug Report" to "Task".Feb 9 2026, 5:27 PM

Seen this happen again in https://integration.wikimedia.org/ci/job/quibble-vendor-mysql-php83-selenium/19600/console:

10:40:29   Running:  ReviseTone.cy.ts                                                                (6 of 9)
10:40:31 
10:40:31 
10:40:31   Revise Tone
10:40:34     On desktop
10:40:36       1) "before each" hook for "Shows the Revise Tone Edit Check"
10:40:36         cy:command βœ”  visit	/index.php -> 301: http://127.0.0.1:9413/index.php?title=Main_Page
10:40:36         cy:command βœ”  window	
10:40:36         cy:command βœ”  assert	expected **<window>** to have property **mw**
10:40:36         cy:command βœ”  window	
10:40:36         cy:command βœ”  its	.mw.Api
10:40:36         cy:command βœ”  assert	expected **[Function]** to exist
10:40:36         cy:command βœ”  window	
10:40:36             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
10:40:36                       Status: 200
10:40:36             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
10:40:36                       Status: 200
10:40:36         cy:command βœ”  visit	/index.php -> 301: http://127.0.0.1:9413/index.php?title=Main_Page
10:40:36         cy:command βœ”  window	
10:40:36         cy:command βœ”  its	.mw.Api
10:40:36         cy:command βœ”  assert	expected **[Function]** to exist
10:40:36         cy:command βœ”  window	
10:40:36             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
10:40:36                       Status: 200
10:40:36             cy:xhr ➟  GET http://127.0.0.1:9413/api.php?action=query&format=json&meta=tokens&type=csrf
10:40:36                       Status: 200
10:40:36             cy:xhr ➟  POST http://127.0.0.1:9413/api.php
10:40:36                       Status: 200
10:40:36         cy:command ✘  then	function(){}
10:40:36 
10:40:36 
10:40:36 
10:40:37 
10:40:37   0 passing (5s)
10:40:37   1 failing
10:40:37 
10:40:37   1) Revise Tone
10:40:37        On desktop
10:40:37          "before each" hook for "Shows the Revise Tone Edit Check":
10:40:37      Error: badtoken
10:40:37 
10:40:37 Because this error occurred during a `before each` hook we are skipping the remaining tests in the current suite: `Revise Tone`
10:40:37       at $Cy.fail (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:146049:13)
10:40:37       at onError (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:152519:22)
10:40:37       at tryCatcher (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1777:23)
10:40:37       at Promise._settlePromiseFromHandler (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1489:31)
10:40:37       at Promise._settlePromise (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1546:18)
10:40:37       at Promise._settlePromise0 (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1591:10)
10:40:37       at Promise._settlePromises (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:1667:18)
10:40:37       at _drainQueueStep (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2377:12)
10:40:37       at _drainQueue (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2370:9)
10:40:37       at Async._drainQueues (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2386:5)
10:40:37       at Async.drainQueues (http://127.0.0.1:9413/__cypress/runner/cypress_runner.js:2256:14)
10:40:37 
10:40:37 
10:40:37 
10:40:38 
10:40:38   (Results)
10:40:38 
10:40:38   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
10:40:38   β”‚ Tests:        6                                                                                β”‚
10:40:38   β”‚ Passing:      0                                                                                β”‚
10:40:38   β”‚ Failing:      1                                                                                β”‚
10:40:38   β”‚ Pending:      0                                                                                β”‚
10:40:38   β”‚ Skipped:      5                                                                                β”‚
10:40:38   β”‚ Screenshots:  1                                                                                β”‚
10:40:38   β”‚ Video:        true                                                                             β”‚
10:40:38   β”‚ Duration:     5 seconds                                                                        β”‚
10:40:38   β”‚ Spec Ran:     ReviseTone.cy.ts                                                                 β”‚
10:40:38   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Not sure how much there is to do here. The test creates a new account via the API. Sometimes the CI wiki has a bad day and refuses the token it handed out, or it handed out a bad token.

I guess we could implement some retry logic? But my assumption is that this is downstream from a CI being overloaded or similar.

Michael renamed this task from ReviseTone.cy.ts fails with badtoken error to [timebox: 3days] ReviseTone.cy.ts fails with badtoken error.Mar 23 2026, 2:39 PM

Change #1273843 had a related patch set uploaded (by Michael Große; author: Michael Große):

[mediawiki/extensions/GrowthExperiments@master] test(Cypress): retry failing tests

https://gerrit.wikimedia.org/r/1273843

Change #1273844 had a related patch set uploaded (by Michael Große; author: Michael Große):

[mediawiki/extensions/GrowthExperiments@master] test(Cypress): reuse logins to speed up tests

https://gerrit.wikimedia.org/r/1273844

Looking into it, I don't think anything is wrong with our tests. It just seems that sometimes core is forgetting the correct token, for whatever reason. postWithToken in resources/src/mediawiki.api/index.js even has retry code for specifically that:

			return this.getToken( tokenType, assertParams ).then( ( token ) => {
				params.token = token;
				// This call will return immediately if the abort was triggered
				// while the token request was running.
				return this.post( params, ajaxOptions ).catch( ( code, ...args ) => {
					if ( code === 'badtoken' ) {
						this.badToken( tokenType );
						// Try again, once
						params.token = undefined;
						return this.getToken( tokenType, assertParams ).then( ( t ) => {
							params.token = t;
							return this.post( params, ajaxOptions );
						} );
					}

					// Let caller handle the error code
					return $.Deferred().reject( code, ...args );
				} );
			} ).promise( abortable );

Let's just retry. This should give us more chances to get it right.

Also, there is another change to reuse logins between some tests. On balance across runs of these jobs in CI, that should hopefully offset any delays that we may incur from rarely flaky tests.

Change #1273843 merged by jenkins-bot:

[mediawiki/extensions/GrowthExperiments@master] test(Cypress): retry failing tests

https://gerrit.wikimedia.org/r/1273843

Change #1273844 merged by jenkins-bot:

[mediawiki/extensions/GrowthExperiments@master] test(Cypress): reuse logins to speed up tests

https://gerrit.wikimedia.org/r/1273844

Change #1275981 had a related patch set uploaded (by Michael Große; author: Michael Große):

[mediawiki/extensions/GrowthExperiments@master] test(Cypress): fix two overlooked shared sessions

https://gerrit.wikimedia.org/r/1275981

Change #1275981 merged by jenkins-bot:

[mediawiki/extensions/GrowthExperiments@master] test(Cypress): fix two overlooked shared sessions

https://gerrit.wikimedia.org/r/1275981

Nothing to QA here.