Link to wp-admin alongside the site URL after the dev server starts - #250
Merged
Merged
Conversation
The front end, wp-admin and Adminer all hang off the same base URL. Deriving them in one place keeps the join testable and correct whether or not the base ends in a slash. Part of WordPress#248.
The app printed "Log in with admin / password" under the site link without giving anywhere to log in — reaching the admin meant editing the URL by hand. Adds a wp-admin link in both places the URL appears: the setup checklist step and the site page. Open Adminer now derives its URL from the same module, replacing an inline join whose slash guard replaced a trailing slash with a trailing slash and so did nothing. Part of WordPress#248.
Twelve tests on the module itself, plus two that read index.jsx as source: index.jsx cannot be loaded without a DOM, so the wiring is checked the way pr-state.test.cjs checks its row. Both source assertions were mutation-tested — bypassing adminUrl on one anchor, and deleting one link, each turn the suite red. Part of WordPress#248.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds external wp-admin links wherever a running site URL appears and centralizes site destination URL construction.
Changes:
- Adds tested helpers for wp-admin and Adminer URLs.
- Adds wp-admin links to setup and site views.
- Routes Adminer through the shared helper.
Review findings: 1 [fix here] · 0 [follow-up]
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/renderer/index.jsx |
Adds wp-admin links and uses the Adminer URL helper. |
src/renderer/site-urls.cjs |
Defines shared site URL builders. |
test/site-urls.test.cjs |
Tests URL construction and renderer wiring. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Collaborator
|
Thanks @amitraj2203 for your contribution. |
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.
Why
Once the dev server is running the app shows the site's front-end URL and, directly under it,
Log in with admin / password— credentials for a screen it gives no way to reach. Most of what a contributor does next happens in the admin: checking a setting, reproducing a ticket, switching a theme. Today that means editing the URL by hand.What changes
A wp-admin link beside the site URL, in both places the URL appears — the setup checklist step and the site page — so it is there whether a contributor is still in setup or returning to a site they have used before.
The URLs are derived in a new
src/renderer/site-urls.cjsrather than built at the call site.index.jsxcannot be loaded without a DOM, so a join written there is untestable; the module keeps it reachable bynode --test.Open Adminernow derives its URL from that same module. Its old inline join guarded the trailing slash with.replace(/\/$/, '/'), which swaps a trailing slash for a trailing slash and so does nothing — harmless today only because the server URL happens to always end in one. Copying that pattern for wp-admin would have duplicated it.Not in this PR: moving
Open Adminerdown onto the same line as the links — that is #249, deliberately separate.How to test this
Platforms: any.
Starting state: a site with its dev server running.
http://127.0.0.1:<port>/ · wp-admin.admin/password.What must not have happened: the link must open in your browser, not inside the app window — a link that navigates the Electron window replaces the UI with a web page and there is no way back.
Open Adminermust not have broken: it was rerouted through the new module, so a wrong URL there would be a silent regression of an existing feature.Risks and limitations
The rendered links are not covered by an automated test — no DOM test infrastructure exists in this repo, which is the tradeoff #216 chose. Two tests read
index.jsxas source text to pin the wiring instead, and the visible behaviour was checked by hand against a running server.index.jsx:2079applies the same no-op slash guard beforesetServerUrl. Left alone as out of scope; noted below.Related
Fixes #248. See also #249, which moves
Open Admineronto this row.Design decisions and alternatives considered
Why a module for what looks like string concatenation. The repo's convention is that renderer logic lives in a
src/renderer/*.cjsmodule with its own test —trac-ticket.cjsis the closest precedent, also a URL builder. Inline would have been shorter and untestable.Why the join is defensive when the base is always the same.
server-runner.jsbuilds the URL ashttp://127.0.0.1:${port}/, so it has always ended in a slash. The module strips and rejoins anyway, because the old code's apparent guard against the other case did nothing, and a helper that silently depends on an invariant it does not enforce is how…:8881wp-admingets shipped later.Why the wp-admin path keeps its trailing slash. WordPress redirects
/wp-adminto/wp-admin/; asking for the canonical form skips a round trip.Departure from the issue. #248 suggests copying the
Open Adminerpattern. That pattern contains the no-op guard described above, so it was fixed and shared instead of copied — one extra hunk, outside the issue's literal scope.Review outcome (required — see AGENTS.md)
3 [fix here]— 2 fixed, 1 deferred. Lint clean; 780 tests pass on both system Node and Electron's Node.Ran per
.github/instructions/code-review.instructions.md, with the judgement pass in a fresh context rather than the session that wrote the change.Fixed — 🟡 tests: the regression guard could not fire. It searched
index.jsxfor the old.replace(/\/$/, '/')but required a space after the comma, which the repo does not write. Green while a live instance of the pattern sat in the file it read. Replaced with assertions that neither'wp-adminnor'adminer.php'appears as a literal inindex.jsx— concatenating a path by hand was the actual bug, and a missing literal cannot be spelled differently.Fixed — 🟡 tests: the wiring the PR adds was unasserted. The source assertions checked the label count and the Adminer call, but nothing tied the anchors'
hreftoadminUrl. Rewriting a link ashref={serverUrl + 'wp-admin'}would have kept them green while bypassing the tested module. Added anhref={adminUrl(count.Both new assertions were mutation-tested rather than assumed: bypassing
adminUrlon one anchor, and deleting one link, each turn the suite red.Deferred — 🔵 architecture:
index.jsx:2079.url.replace(/\/$/,'/')beforesetServerUrlis the same no-op, andmain.js:2403already trims the parsed value. Pre-existing and outside this issue; left for a separate change. The test guard no longer depends on it either way.Verified and not findings:
serverUrlonly ever holdshttp://127.0.0.1:${port}/;Open Admineris observably unchanged;openExternalstill validates throughexternal-url.js; nothing new crosses IPC.Also applied from the review's style notes: both links now use an
aria-hiddenseparator, rather than one bare interpunct that a screen reader would announce.Implementation notes
Three commits, each green on its own: the module, the call sites, then the tests. The tests read
index.jsxand assert its contents, so they land last — committing them earlier would leave a red commit mid-branch.site-urls.cjsexportssiteUrl(base, path)plusadminUrlandadminerUrl.siteUrlreturns''for a missing or non-string base, so the renderer's existingserverUrl ? … : nullguards keep working on the derived value instead of producing a link relative to the app itself.Screenshots or recording
Screen.Recording.2026-08-11.at.11.07.08.AM.mov