]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix #11369 (#11403)
authorMaciej PrzepiĆ³ra <maciej@przepiora.me>
Thu, 17 Jan 2019 10:46:49 +0000 (11:46 +0100)
committerSun Zhe <31067185+ZheSun88@users.noreply.github.com>
Thu, 17 Jan 2019 10:46:49 +0000 (12:46 +0200)
Clear contents of iframe clone that is in a Window so that when it's reattached to DOM we don't get 404

client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java
uitest/src/main/java/com/vaadin/tests/components/window/ClosingWindowWithBrowserFrameShouldntGenerate404.java [new file with mode: 0644]
uitest/src/main/resources/sample.pdf [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/window/ClosingWindowWithBrowserFrameShouldntGenerate404Test.java [new file with mode: 0644]

index aa244c7888d4c795e0396d12058cd020e9397072..feb34e502e272beb08701ec8bd2c39e7edf66968 100644 (file)
@@ -326,6 +326,23 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
                 }
                 return newEl;
             }
+
+            if ("iframe".equalsIgnoreCase(old.getTagName())
+                    && old.hasAttribute("src")
+                    && old.getAttribute("src").contains("APP/connector")) {
+                // an iframe reloads when reattached to the DOM, but
+                // unfortunately, when newEl is reattached, server-side
+                // resource (e.g. generated PDF) is already gone, so this will
+                // end up with 404, which might be undesirable.
+                // Instead of the resource that is not available anymore,
+                // let's just use empty iframe.
+                // See
+                // https://github.com/vaadin/framework/issues/11369
+                // for details of the issue this works around
+                Element newEl = old.cloneNode(false).cast();
+                newEl.setAttribute("src", "about:blank");
+                return newEl;
+            }
         }
         Node res = node.cloneNode(false);
         if (node.hasChildNodes()) {
diff --git a/uitest/src/main/java/com/vaadin/tests/components/window/ClosingWindowWithBrowserFrameShouldntGenerate404.java b/uitest/src/main/java/com/vaadin/tests/components/window/ClosingWindowWithBrowserFrameShouldntGenerate404.java
new file mode 100644 (file)
index 0000000..74c7938
--- /dev/null
@@ -0,0 +1,70 @@
+package com.vaadin.tests.components.window;
+
+import com.vaadin.server.StreamResource;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.*;
+import org.apache.commons.io.IOUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ClosingWindowWithBrowserFrameShouldntGenerate404
+        extends AbstractTestUI {
+
+    private VerticalLayout layout;
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        layout = new VerticalLayout();
+
+        Button button = new Button("Click Me", e -> showPdfInAWindow());
+        layout.addComponent(button);
+        addComponent(layout);
+    }
+
+    private void showPdfInAWindow() {
+        try {
+            final String fileName = "sample.pdf";
+            final byte[] bytes = IOUtils
+                    .toByteArray(getClass().getResource("/" + fileName));
+            StreamResource.StreamSource source = new StreamResource.StreamSource() {
+                @Override
+                public InputStream getStream() {
+                    return new ByteArrayInputStream(bytes);
+                }
+            };
+
+            StreamResource resource = new StreamResource(source, fileName);
+
+            resource.setMIMEType("application/pdf");
+            resource.getStream().setParameter("Content-Disposition",
+                    "attachment; filename=" + fileName);
+            resource.setCacheTime(-1);
+
+            // Use browser frame
+            BrowserFrame frame = new BrowserFrame();
+            frame.setSizeFull();
+            frame.setSource(resource);
+            frame.setHeight("650px");
+            Window pdfWindow = new Window("Sample PDF");
+            pdfWindow.center();
+            pdfWindow.setModal(true);
+            pdfWindow.setResizable(false);
+            pdfWindow.setHeight("700px");
+            pdfWindow.setWidth("900px");
+            pdfWindow.setContent(frame);
+
+            pdfWindow.addCloseListener(e -> {
+                layout.addComponent(new Label("PDF was sent"));
+
+            });
+
+            UI.getCurrent().addWindow(pdfWindow);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/uitest/src/main/resources/sample.pdf b/uitest/src/main/resources/sample.pdf
new file mode 100644 (file)
index 0000000..758b45a
Binary files /dev/null and b/uitest/src/main/resources/sample.pdf differ
diff --git a/uitest/src/test/java/com/vaadin/tests/components/window/ClosingWindowWithBrowserFrameShouldntGenerate404Test.java b/uitest/src/test/java/com/vaadin/tests/components/window/ClosingWindowWithBrowserFrameShouldntGenerate404Test.java
new file mode 100644 (file)
index 0000000..a0a32cb
--- /dev/null
@@ -0,0 +1,39 @@
+package com.vaadin.tests.components.window;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.WindowElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.logging.LogEntry;
+
+import java.util.List;
+
+public class ClosingWindowWithBrowserFrameShouldntGenerate404Test
+        extends MultiBrowserTest {
+
+    private static boolean contains404(LogEntry logEntry) {
+        return logEntry.getMessage().contains("404");
+    }
+
+    @Test
+    public void openWindowWithFrame_closeWindow_no404() {
+        openTestURL();
+        $(ButtonElement.class).first().click();
+
+        $(WindowElement.class).first().close();
+
+        $(LabelElement.class).exists();
+
+        List<LogEntry> logs = getDriver().manage().logs().get("browser")
+                .getAll();
+
+        Assert.assertTrue(theresNoLogWith404In(logs));
+    }
+
+    private boolean theresNoLogWith404In(List<LogEntry> logs) {
+        return !logs.stream().anyMatch(
+                ClosingWindowWithBrowserFrameShouldntGenerate404Test::contains404);
+    }
+}