Skip to content

[Regression 2.32][JS] Location.reload() reloads to the wrong address when invoked across frames #297

Description

@atnak

Problem in brief

This following Javascript will reload the "topFrame" frame, but to the wrong address if the code was run from a different frame.

parent.topFrame.location.reload();

Reproducing

frameset.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<frameset rows="150,*">
<frame name="topFrame" src="top.html">
<frame name="bottomFrame" src="bottom.html">
</frameset>
</html>

bottom.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script>
function test() {
  parent.topFrame.location.reload();
}
</script>
</head>
<body>
<button onclick="test()">test</button>
</body>
</html>
  • When the button "test" in the bottom frame is clicked, the topFrame is reloaded.
  • However, the topFrame is reloaded to the new address of "bottom.html" instead of "top.html".
  • Therefore, both the top and bottom frames become "bottom.html".

Details

The problem appears to be due to the use of getWindow(getStartingScope()) here in reload() rather than window_. I do not know what the purpose of getWindow(getStartingScope()) is here but since a location instance holds its own address in window_, I don't know why getStartingScope() is being used instead of window_.

Another place using getStartingScope() is in Location.setHref() and I think it makes more sense.

I think reload() was implemented as setHref(getHref()) in the past and when it was later refactored to the current form, getWindow(getStartingScope()) was copied here incorrectly.

Suggested fix

      * @throws IOException if there is a problem reloading the page
      * @see <a href="/api/browser/proxy?url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fms536342.aspx">MSDN Documentation</a>
      */
     @JsxFunction
     public void reload(final boolean force) throws IOException {
-        final HtmlPage htmlPage = (HtmlPage) getWindow(getStartingScope()).getWebWindow().getEnclosedPage();
+        final HtmlPage htmlPage = (HtmlPage) window_.getWebWindow().getEnclosedPage();
         final WebRequest request = htmlPage.getWebResponse().getWebRequest();
 
         if (getBrowserVersion().hasFeature(JS_LOCATION_RELOAD_REFERRER)) {

Test case

Here's a test that can be used in LocationTest.java.

    /**
     * Tests that location.reload() works correctly when invoked across frames.
     */
    @Test
    public void reloadAcrossFrames() throws Exception {
        try (final WebClient webClient = getWebClient();
                final MockWebConnection webConnection = new MockWebConnection()) {

            final String framesetContent = ""
                + "<html>\n"
                + "  <frameset rows='100,*'>\n"
                + "    <frame name='upper' src='upper.html'/>\n"
                + "    <frame name='lower' src='lower.html'/>\n"
                + "  </frameset>\n"
                + "</html>";

            final String upperContent = "<html><body><h1>upper</h1></body></html>";
            final String lowerContent = ""
                + "<html><head>\n"
                + "<script>\n"
                + "function test() {\n"
                + "  parent.upper.location.reload();\n"
                + "}\n"
                + "</script>\n"
                + "</head>\n"
                + "<body><h1>lower</h1><button onclick=\"test()\">test</button></body></html>";

            webConnection.setResponse(URL_FIRST, framesetContent);
            webConnection.setResponse(new URL(URL_FIRST, "upper.html"), upperContent);
            webConnection.setResponse(new URL(URL_FIRST, "lower.html"), lowerContent);

            webClient.setWebConnection(webConnection);

            webClient.getPage(URL_FIRST);
            assertEquals(3, webClient.getWebWindows().size());

            assertEquals("/upper.html", webClient.getWebWindowByName("upper").getEnclosedPage().getUrl().getFile());
            assertEquals("/lower.html", webClient.getWebWindowByName("lower").getEnclosedPage().getUrl().getFile());

            final HtmlPage p = (HtmlPage)webClient.getWebWindowByName("lower").getEnclosedPage();
            p.<HtmlButton>getFirstByXPath("//button").click();

            assertEquals("/upper.html", webClient.getWebWindowByName("upper").getEnclosedPage().getUrl().getFile());
            assertEquals("/lower.html", webClient.getWebWindowByName("lower").getEnclosedPage().getUrl().getFile());
        }
    }

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions