diff --git a/src/core/frames/frame_controller.ts b/src/core/frames/frame_controller.ts
index 53a585331..e4287c570 100644
--- a/src/core/frames/frame_controller.ts
+++ b/src/core/frames/frame_controller.ts
@@ -99,7 +99,7 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest
}
async loadResponse(fetchResponse: FetchResponse) {
- if (fetchResponse.redirected) {
+ if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) {
this.sourceURL = fetchResponse.response.url
}
diff --git a/src/tests/fixtures/frames.html b/src/tests/fixtures/frames.html
index acfc17257..ed74efa3f 100644
--- a/src/tests/fixtures/frames.html
+++ b/src/tests/fixtures/frames.html
@@ -19,6 +19,9 @@
Frames
Frames: #frame
+
Navigate #frame from within
Navigate #frame from within with a[data-turbo-action="advance"]
diff --git a/src/tests/functional/form_submission_tests.ts b/src/tests/functional/form_submission_tests.ts
index 519cd04f4..9df835722 100644
--- a/src/tests/functional/form_submission_tests.ts
+++ b/src/tests/functional/form_submission_tests.ts
@@ -359,6 +359,9 @@ export class FormSubmissionTests extends TurboDriveTestCase {
const otherEvents = await this.eventLogChannel.read()
this.assert.equal(otherEvents.length, 0, "no more events")
+
+ const src = await (await this.querySelector("#frame")).getAttribute("src") || ""
+ this.assert.equal((new URL(src)).pathname, "/src/tests/fixtures/frames/frame.html")
}
async "test frame POST form targetting frame toggles submitter's [disabled] attribute"() {
@@ -387,6 +390,9 @@ export class FormSubmissionTests extends TurboDriveTestCase {
const otherEvents = await this.eventLogChannel.read()
this.assert.equal(otherEvents.length, 0, "no more events")
+
+ const src = await (await this.querySelector("#frame")).getAttribute("src") || ""
+ this.assert.equal((new URL(src)).pathname, "/src/tests/fixtures/frames/frame.html")
}
async "test frame GET form targetting frame toggles submitter's [disabled] attribute"() {
@@ -529,6 +535,7 @@ export class FormSubmissionTests extends TurboDriveTestCase {
this.assert.ok(await this.hasSelector("#frame form.redirect"))
this.assert.equal(await message.getVisibleText(), "Hello!")
this.assert.equal(await this.pathname, "/src/tests/fixtures/form.html")
+ this.assert.notOk(await this.propertyForSelector("#frame", "src"), "does not change frame's src")
}
async "test frame form submission with HTTP verb other than GET or POST"() {
diff --git a/src/tests/functional/frame_tests.ts b/src/tests/functional/frame_tests.ts
index d853021da..043742b02 100644
--- a/src/tests/functional/frame_tests.ts
+++ b/src/tests/functional/frame_tests.ts
@@ -302,6 +302,22 @@ export class FrameTests extends TurboDriveTestCase {
this.assert.notOk(await this.nextAttributeMutationNamed("html", "aria-busy"), "removes aria-busy from the ")
}
+ async "test navigating a frame with a form[method=get] that does not redirect still updates the [src]"() {
+ await this.clickSelector("#frame-form-get-no-redirect")
+ await this.nextEventNamed("turbo:before-fetch-request")
+ await this.nextEventNamed("turbo:before-fetch-response")
+ await this.nextEventOnTarget("frame", "turbo:frame-render")
+ await this.nextEventOnTarget("frame", "turbo:frame-load")
+ await this.noNextEventNamed("turbo:before-fetch-request")
+
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
+ this.assert.equal(await (await this.querySelector("h1")).getVisibleText(), "Frames")
+ this.assert.equal(await (await this.querySelector("#frame h2")).getVisibleText(), "Frame: Loaded")
+ this.assert.equal(await this.pathname, "/src/tests/fixtures/frames.html")
+ }
+
async "test navigating turbo-frame[data-turbo-action=advance] from within pushes URL state"() {
await this.clickSelector("#add-turbo-action-to-frame")
await this.clickSelector("#link-frame")
@@ -309,7 +325,9 @@ export class FrameTests extends TurboDriveTestCase {
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
@@ -321,7 +339,9 @@ export class FrameTests extends TurboDriveTestCase {
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
@@ -333,7 +353,9 @@ export class FrameTests extends TurboDriveTestCase {
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
@@ -345,7 +367,9 @@ export class FrameTests extends TurboDriveTestCase {
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
@@ -357,7 +381,9 @@ export class FrameTests extends TurboDriveTestCase {
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
@@ -369,7 +395,9 @@ export class FrameTests extends TurboDriveTestCase {
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
@@ -380,7 +408,7 @@ export class FrameTests extends TurboDriveTestCase {
await this.clickSelector("#link-frame")
await this.nextEventNamed("turbo:load")
await this.goBack()
- await this.nextBody
+ await this.nextEventNamed("turbo:load")
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
@@ -388,6 +416,7 @@ export class FrameTests extends TurboDriveTestCase {
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frames: #frame")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames.html")
+ this.assert.equal(await this.propertyForSelector("#frame", "src"), null)
}
async "test navigating back then forward after pushing URL state from a turbo-frame[data-turbo-action=advance] restores the frames next contents"() {
@@ -395,13 +424,15 @@ export class FrameTests extends TurboDriveTestCase {
await this.clickSelector("#link-frame")
await this.nextEventNamed("turbo:load")
await this.goBack()
- await this.nextBody
+ await this.nextEventNamed("turbo:load")
await this.goForward()
- await this.nextBody
+ await this.nextEventNamed("turbo:load")
const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
+ const src = await this.attributeForSelector("#frame", "src") ?? ""
+ this.assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute")
this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
diff --git a/src/tests/functional/navigation_tests.ts b/src/tests/functional/navigation_tests.ts
index a02f64500..5e349f95d 100644
--- a/src/tests/functional/navigation_tests.ts
+++ b/src/tests/functional/navigation_tests.ts
@@ -7,12 +7,12 @@ export class NavigationTests extends TurboDriveTestCase {
async "test navigating renders a progress bar"() {
await this.remote.execute(() => window.Turbo.setProgressBarDelay(0))
- await this.clickSelector("#same-origin-unannotated-link")
+ await this.clickSelector("#delayed-link")
await this.waitUntilSelector(".turbo-progress-bar")
this.assert.ok(await this.hasSelector(".turbo-progress-bar"), "displays progress bar")
- await this.nextBody
+ await this.nextEventNamed("turbo:load")
await this.waitUntilNoSelector(".turbo-progress-bar")
this.assert.notOk(await this.hasSelector(".turbo-progress-bar"), "hides progress bar")