Make WordPress Core

Opened 32 hours ago

Last modified 22 hours ago

#65982 new defect (bug)

tests/e2e/specs/install.test.js fails permanently after its first successful run (leftover wp_e2e_* tables never dropped)

Reported by: theanamhossain Owned by:
Priority: normal Milestone: 7.2
Component: Build/Test Tools Version: 6.6
Severity: normal Keywords: has-patch
Cc: Focuses:

Description

install.test.js tricks WordPress into "not installed" mode by swapping
$table_prefix to wp_e2e_ in wp-config.php for the duration of the
test (beforeEach), then reverting it (afterEach). The test then runs the
full installer under that prefix.

The problem: afterEach only restores wp-config.php — it never drops
the wp_e2e_* tables the install wizard just created. So:

  1. First run against a clean DB: passes, but leaves a fully-installed wp_e2e_options, wp_e2e_users, etc. behind.
  2. Every subsequent run: beforeEach flips the prefix to wp_e2e_ again, but WordPress now finds those tables already there and considers itself installed, so / never redirects to /wp-admin/install.php. The test then fails deterministically on every future run until someone manually drops the tables.

Steps to reproduce:

  1. npm run env:start
  2. npx wp-scripts test-playwright --config tests/e2e/playwright.config.js tests/e2e/specs/install.test.js (passes)
  3. Run the exact same command again. (fails: "Expected pattern: /wp-admin\/install\.php$/, Received string: http://localhost:8889/")

Separately, there's a secondary timing issue: the single page.goto('/')
right after the config swap can occasionally observe a not-yet-updated
view of wp-config.php (looks like Docker bind-mount write propagation
lag on some hosts), causing an occasional failure even with a clean DB.
Retrying the navigation itself (not just polling the already-loaded
page's URL, which is all toHaveURL's built-in retry does) papers over
this reliably.

Attached patch:

  • Drops the wp_e2e_* tables in afterEach via wp eval (routed through WP's own $wpdb/mysqli connection rather than wp-cli's db query, which shells out to the mysql binary and can hit unrelated SSL/client issues on some hosts).
  • Wraps the initial navigation + redirect assertion in expect(...).toPass() so the navigation itself retries, not just the URL check.

Verified fix: ran the test 5 times back-to-back after patching — all 5
passed. Before the patch, only the very first run of a fresh DB would
pass; every run after that failed permanently.

Attachments (2)

before-patch-failure.png (1.0 MB ) - added by theanamhossain 32 hours ago.
install-test-e2e-flake.diff (2.0 KB ) - added by theanamhossain 32 hours ago.
Patch: drop leftover wp_e2e_ tables and retry install-page navigation.

Download all attachments as: .zip

Change History (7)

@theanamhossain
32 hours ago

Patch: drop leftover wp_e2e_ tables and retry install-page navigation.

#1 @theanamhossain
31 hours ago

Isolation data - three consecutive runs of each variant, wp_e2e_* tables
dropped before each:

  trunk (unpatched)          1 passed / 2 failed
  retry navigation only      0 passed / 3 failed
  table drop only            2 passed / 1 failed
  both changes               3 passed / 0 failed

The two changes address two independent failure modes. The leftover
wp_e2e_* tables cause a deterministic failure on any run following a
successful install - retrying alone can't recover, since the site really
is installed. Separately, the test rewrites wp-config.php on the host and
navigates immediately, so on Docker for Mac the container can serve a
request using the pre-write config; that accounts for the failures from an
otherwise clean database. Neither change is sufficient on its own.

Last edited 31 hours ago by theanamhossain (previous) (diff)

#2 @jorbin
30 hours ago

  • Milestone Awaiting Review7.2
  • Version trunk6.6

Thank you @theanamhossain and welcome to WordPress Core trac!

Would you be able to create a PR on https://github.com/WordPress/wordpress-develop with these changes so that we can see the tests run?

Tests were added in e58430 (#61240) which happened during 6.6. Updating the version accordingly.

#3 @theanamhossain
23 hours ago

Sure @jorbin
Allow me sometime to do that.
I will add my comment here, once I create a pull in wordpress-develop branch.
Thanks.

This ticket was mentioned in PR #13302 on WordPress/wordpress-develop by @theanamhossain.


22 hours ago
#4

  • Keywords has-unit-tests added

afterEach in tests/e2e/specs/install.test.js reverted wp-config.php's table prefix but never dropped the wp_e2e_* tables the test's own install wizard creates. As a result:

  • The first run against a clean database passes, but leaves a fully-installed wp_e2e_options, wp_e2e_users, etc. behind.
  • Every run after that flips the prefix to wp_e2e_ again, WordPress finds those tables already present, and the test never reaches /wp-admin/install.php — it fails deterministically on every subsequent run until someone manually drops the tables.

### This PR:

  • Drops the wp_e2e_* tables in afterEach via wp eval, routed through WP's own $wpdb/mysqli connection rather than wp-cli's db query, which shells out to the mysql binary and can hit unrelated SSL/client issues on some hosts.
  • Wraps the initial navigation + redirect assertion in expect(...).toPass() so the navigation itself retries, not just the URL check. A single page.goto('/') right after the config swap can occasionally observe a not-yet-updated wp-config.php on some hosts (consistent with Docker bind-mount write propagation lag).

### Testing

Isolation data — three consecutive runs of each variant, with wp_e2e_* tables dropped before each:

trunk (unpatched)          1 passed / 2 failed
retry navigation only      0 passed / 3 failed
table drop only            2 passed / 1 failed
both changes                3 passed / 0 failed

Both changes are independently necessary — neither one alone is sufficient to make the test reliably repeatable.

Trac ticket: https://core.trac.wordpress.org/ticket/65982

### Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Sonnet 5
Used for: Diagnosing the root cause (including tracing a Playwright network trace and DB state to rule out a false lead), drafting the fix, and building the A/B isolation harness used to produce the testing data above. I reviewed the diagnosis, ran and verified the fix and the isolation tests myself, and take responsibility for the change.

#5 @theanamhossain
22 hours ago

  • Keywords has-unit-tests removed

Hello @jorbin
Here is pull I create -
https://github.com/WordPress/wordpress-develop/pull/13302
Let me know you feedback from your side.
If I need to do anything else for this, please let me know.
Since I am new here, I might not aware about all the thing.
Correct me if I am wrong.
Appreciate your time and help on this.
Thanks.

Note: See TracTickets for help on using tickets.