Repository navigation
goto: keep the app path when the base url has a query or hash (#108) - #116
Conversation
|
@greptileai review |
|
@greptile review |
[Medium impact] Changes how the goto step resolves relative URLs. Preserve base URL credentials before merging; relative navigation can otherwise fail on protected sites. FindingsFix with agent prompt### Issue 1
src/browser/steps.ts:179
`resolveUrl` rebuilds the base using `parsed.origin`, which excludes its username and password. For example, `https://user:pass@host/app` plus `/login` now becomes `https://host/app/login`; previously the credentials stayed.
If a spec supplies credentials through its base URL without a separate `auth` block, relative navigation can no longer open the protected page. Build the directory URL from `parsed` without discarding its credentials.
### Issue 2
src/browser/steps.ts:180-181
`resolveUrl` treats an explicitly empty query or hash as missing. With base `https://host/app?x=1#section`, `/login?` restores `?x=1`, and `/login#` restores `#section`. Users cannot clear the inherited query options or hash route this way.
The URL getters return an empty string for both absent and explicitly empty values. Check whether the target supplied each delimiter before copying the base value, and add tests for empty overrides.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
|
| const directory = parsed.pathname.endsWith('/') ? parsed.pathname : `${parsed.pathname}/`; | ||
| const relative = target.startsWith('/') ? target.slice(1) : target; | ||
| return new URL(relative, baseWithSlash).toString(); | ||
| const resolved = new URL(relative, `${parsed.origin}${directory}`); |
There was a problem hiding this comment.
Relative navigation drops credentials
resolveUrl rebuilds the base using parsed.origin, which excludes its username and password. For example, https://user:pass@host/app plus /login now becomes https://host/app/login; previously the credentials stayed.
If a spec supplies credentials through its base URL without a separate auth block, relative navigation can no longer open the protected page. Build the directory URL from parsed without discarding its credentials.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/browser/steps.ts
Line: 179
Comment:
**Relative navigation drops credentials**
`resolveUrl` rebuilds the base using `parsed.origin`, which excludes its username and password. For example, `https://user:pass@host/app` plus `/login` now becomes `https://host/app/login`; previously the credentials stayed.
If a spec supplies credentials through its base URL without a separate `auth` block, relative navigation can no longer open the protected page. Build the directory URL from `parsed` without discarding its credentials.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Fixed in 5041210: a relative goto keeps the user name and password from the base url.
| if (!resolved.search) resolved.search = parsed.search; | ||
| if (!resolved.hash) resolved.hash = parsed.hash; |
There was a problem hiding this comment.
Empty overrides keep base values
resolveUrl treats an explicitly empty query or hash as missing. With base https://host/app?x=1#section, /login? restores ?x=1, and /login# restores #section. Users cannot clear the inherited query options or hash route this way.
The URL getters return an empty string for both absent and explicitly empty values. Check whether the target supplied each delimiter before copying the base value, and add tests for empty overrides.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/browser/steps.ts
Line: 180-181
Comment:
**Empty overrides keep base values**
`resolveUrl` treats an explicitly empty query or hash as missing. With base `https://host/app?x=1#section`, `/login?` restores `?x=1`, and `/login#` restores `#section`. Users cannot clear the inherited query options or hash route this way.
The URL getters return an empty string for both absent and explicitly empty values. Check whether the target supplied each delimiter before copying the base value, and add tests for empty overrides.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Fixed in 5041210: an empty query or hash in the target clears that part of the base url.
… and hash Co-authored-by: Gabe <gpavanello@thefork.com>
…hash Co-authored-by: Gabe <gpavanello@thefork.com>
84d2727 to
5041210
Compare
|
@greptileai review |
Step 1/3 of quality/108-goto-query. Previous: none. Next: quality/107-useid-fragment.
Part of #108
Intent
A relative
gotostays under the base path. A base query or hash stays unless the target has its own. Credentials in the base url stay.%%{init: {'theme': 'neutral'}}%% flowchart TD base["base url with query or hash"] --> resolve["resolveUrl"] target["relative target"] --> resolve resolve --> path["keep the base directory"] path --> carry["copy query and hash unless the target has a ? or #"] carry --> page["page loads under the base path"]Drift
None.
Decisions
?or#in the target clears that part of the base url. Door: two-way.data:orhttps:, stays unchanged. Door: two-way.Evidence
Before:
http://host/app?x=1+/login→http://host/login.http://host/app#section+/login→http://host/login. Fail-first: expectedhttp://host/app/login?x=1, actualhttp://host/login.After:
http://host/app?x=1+/login→http://host/app/login?x=1.#section→http://host/app/login#section. Browser goto fromhttp://127.0.0.1:45659/app?from=e2eloadedhttp://127.0.0.1:45659/app/login?from=e2e, titleApp login, search?from=e2e.npm run verify: 578 pass, 0 fail. docs ok 18. Baseline was 577 pass, 0 fail. Live e2e did not finish:Connection error: fetch failed.Review round 1
Before:
https://user:pass@host/app+/loginbecamehttps://host/app/login./login?kept?x=1./login#kept#section. Fail-first: 3 fail, 1 pass.After: the credential url stays
https://user:pass@host/app/login./login?becomeshttps://host/app/login?#section./login#becomeshttps://host/app/login?x=1#.npm run verify: 581 pass, 0 fail. Head5041210. The branch was rebased onto main after #115 merged, so verify ran on the commits before the rebase.Reading map
src/browser/steps.test.ts(new test),scripts/gates.test.mjs(e2e floor 38 to 39).e2e/goto-base-query.yaml.resolveUrlis now exported fromsrc/browser/steps.ts.Stack
Step 1/3 of quality/108-goto-query. Previous: none. Next: quality/107-useid-fragment.