Skip to content

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

@atnak

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="http://msdn.microsoft.com/en-us/library/ms536342.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());
        }
    }

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