changeset 11127:ce2b158a0afe

8207772: File API and FileReader should be supported in WebView Reviewed-by: kcr, arajkumar, mschoene
author mbilla
date Tue, 11 Dec 2018 23:23:35 +0530
parents fa76dfc055eb
children 32a30b0adafc
files modules/javafx.web/src/main/java/com/sun/javafx/webkit/UIClientImpl.java modules/javafx.web/src/main/java/com/sun/javafx/webkit/drt/DumpRenderTree.java modules/javafx.web/src/main/java/com/sun/javafx/webkit/drt/UIClientImpl.java modules/javafx.web/src/main/java/com/sun/webkit/FileSystem.java modules/javafx.web/src/main/native/Source/WebCore/platform/FileSystem.h modules/javafx.web/src/main/native/Source/WebCore/platform/java/FileSystemJava.cpp modules/javafx.web/src/main/native/Tools/DumpRenderTree/java/DumpRenderTree.cpp modules/javafx.web/src/shims/java/com/sun/javafx/webkit/UIClientImplShim.java modules/javafx.web/src/shims/java/com/sun/webkit/WebPageShim.java modules/javafx.web/src/test/addExports modules/javafx.web/src/test/java/test/javafx/scene/web/FileReaderTest.java modules/javafx.web/src/test/resources/test/html/BinaryFile.dat modules/javafx.web/src/test/resources/test/html/HelloWorld.txt modules/javafx.web/src/test/resources/test/html/readAsText.html
diffstat 14 files changed, 531 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.web/src/main/java/com/sun/javafx/webkit/UIClientImpl.java	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/java/com/sun/javafx/webkit/UIClientImpl.java	Tue Dec 11 23:23:35 2018 +0530
@@ -69,6 +69,8 @@
     private final Accessor accessor;
     private FileChooser chooser;
     private static final Map<String, FileExtensionInfo> fileExtensionMap = new HashMap<>();
+    // for testing purposes only
+    private static String[] chooseFiles = null;
 
     private static class FileExtensionInfo {
         private String description;
@@ -220,7 +222,15 @@
         return false;
     }
 
+    // for testing purposes only
+    static void test_setChooseFiles(String[] files) {
+        chooseFiles = files;
+    }
+
     @Override public String[] chooseFile(String initialFileName, boolean multiple, String mimeFilters) {
+        if (chooseFiles != null) {
+            return chooseFiles;
+        }
         // get the toplevel window
         Window win = null;
         WebView view = accessor.getView();
--- a/modules/javafx.web/src/main/java/com/sun/javafx/webkit/drt/DumpRenderTree.java	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/java/com/sun/javafx/webkit/drt/DumpRenderTree.java	Tue Dec 11 23:23:35 2018 +0530
@@ -157,6 +157,10 @@
         return testString;
     }
 
+    protected String getTestURL() {
+        return testPath;
+    }
+
 /*
     private static boolean isDebug()
     {
@@ -323,6 +327,7 @@
     private static native boolean dumpChildFramesAsText();
     private static native boolean dumpBackForwardList();
     protected static native boolean shouldStayOnPageAfterHandlingBeforeUnload();
+    protected static native String[] openPanelFiles();
 
     private final class DRTLoadListener implements LoadListenerClient {
         @Override
--- a/modules/javafx.web/src/main/java/com/sun/javafx/webkit/drt/UIClientImpl.java	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/java/com/sun/javafx/webkit/drt/UIClientImpl.java	Tue Dec 11 23:23:35 2018 +0530
@@ -31,6 +31,7 @@
 import com.sun.webkit.graphics.WCImage;
 import com.sun.webkit.graphics.WCRectangle;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -182,7 +183,26 @@
      */
     @Override
     public String[] chooseFile(String initialFileName, boolean multiple, String mimeFilters) {
-        throw new UnsupportedOperationException("Not supported yet");
+        if (DumpRenderTree.drt.complete()) {
+            return null;
+        }
+        DumpRenderTree.out.printf("OPEN FILE PANEL\n");
+        String[] openPanelFiles = DumpRenderTree.drt.openPanelFiles();
+        if (openPanelFiles == null || openPanelFiles.length == 0) {
+            return null;
+        }
+
+        final File testURLFile = new File(DumpRenderTree.drt.getTestURL());
+        String testURLFileParent = testURLFile.getParent();
+        if (multiple) {
+            String[] result = new String[openPanelFiles.length];
+            for (int i = 0; i < openPanelFiles.length; i++) {
+                result[i] = new File(testURLFileParent, openPanelFiles[i]).getAbsolutePath();
+            }
+            return result;
+        } else {
+            return new String[] { new File(testURLFileParent, openPanelFiles[0]).getAbsolutePath() };
+        }
     }
 
     /**
--- a/modules/javafx.web/src/main/java/com/sun/webkit/FileSystem.java	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/java/com/sun/webkit/FileSystem.java	Tue Dec 11 23:23:35 2018 +0530
@@ -27,8 +27,12 @@
 
 import com.sun.javafx.logging.PlatformLogger;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import static java.lang.String.format;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Paths;
@@ -52,6 +56,41 @@
         return new File(path).exists();
     }
 
+    private static RandomAccessFile fwkOpenFile(String path, String mode) {
+        try {
+            return new RandomAccessFile(path, mode);
+        } catch (FileNotFoundException | SecurityException ex) {
+            logger.fine(format("Error while creating RandomAccessFile for file [%s]", path), ex);
+        }
+        return null;
+    }
+
+    private static void fwkCloseFile(RandomAccessFile raf) {
+        try {
+            raf.close();
+        } catch (IOException ex) {
+            logger.fine(format("Error while closing RandomAccessFile for file [%s]", raf), ex);
+        }
+    }
+
+    private static int fwkReadFromFile(RandomAccessFile raf, ByteBuffer byteBuffer) {
+        try {
+            FileChannel fc = raf.getChannel();
+            return fc.read(byteBuffer);
+        } catch (IOException ex) {
+            logger.fine(format("Error while reading RandomAccessFile for file [%s]", raf), ex);
+        }
+        return -1;
+    }
+
+    private static void fwkSeekFile(RandomAccessFile raf, long pos) {
+        try {
+            raf.seek(pos);
+        } catch (IOException ex) {
+            logger.fine(format("Error while seek RandomAccessFile for file [%s]", raf), ex);
+        }
+    }
+
     private static long fwkGetFileSize(String path) {
         try {
             File file = new File(path);
--- a/modules/javafx.web/src/main/native/Source/WebCore/platform/FileSystem.h	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/FileSystem.h	Tue Dec 11 23:23:35 2018 +0530
@@ -71,6 +71,9 @@
 // FIXME: -1 is INVALID_HANDLE_VALUE, defined in <winbase.h>. Chromium tries to
 // avoid using Windows headers in headers.  We'd rather move this into the .cpp.
 const PlatformFileHandle invalidPlatformFileHandle = reinterpret_cast<HANDLE>(-1);
+#elif PLATFORM(JAVA)
+typedef JGObject PlatformFileHandle;
+const PlatformFileHandle invalidPlatformFileHandle { nullptr };
 #else
 typedef int PlatformFileHandle;
 const PlatformFileHandle invalidPlatformFileHandle = -1;
--- a/modules/javafx.web/src/main/native/Source/WebCore/platform/java/FileSystemJava.cpp	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/java/FileSystemJava.cpp	Tue Dec 11 23:23:35 2018 +0530
@@ -232,21 +232,68 @@
     return String();
 }
 
-PlatformFileHandle openFile(const String&, FileOpenMode)
+PlatformFileHandle openFile(const String& path, FileOpenMode mode)
 {
-    notImplemented();
-    return invalidPlatformFileHandle;
+    if (mode != FileOpenMode::Read) {
+        return invalidPlatformFileHandle;
+    }
+    JNIEnv* env = WebCore_GetJavaEnv();
+    static jmethodID mid = env->GetStaticMethodID(
+            GetFileSystemClass(env),
+            "fwkOpenFile",
+            "(Ljava/lang/String;Ljava/lang/String;)Ljava/io/RandomAccessFile;");
+    ASSERT(mid);
+
+    PlatformFileHandle result = env->CallStaticObjectMethod(
+            GetFileSystemClass(env),
+            mid,
+            (jstring)path.toJavaString(env), (jstring)(env->NewStringUTF("r")));
+
+    CheckAndClearException(env);
+    return result ? result : invalidPlatformFileHandle;
 }
 
-void closeFile(PlatformFileHandle&)
+void closeFile(PlatformFileHandle& handle)
 {
-    notImplemented();
+    if (isHandleValid(handle)) {
+        JNIEnv* env = WebCore_GetJavaEnv();
+        static jmethodID mid = env->GetStaticMethodID(
+                GetFileSystemClass(env),
+                "fwkCloseFile",
+                "(Ljava/io/RandomAccessFile;)V");
+        ASSERT(mid);
+
+        env->CallStaticVoidMethod(
+                GetFileSystemClass(env),
+                mid, (jobject)handle);
+        CheckAndClearException(env);
+        handle = invalidPlatformFileHandle;
+    }
 }
 
-int readFromFile(PlatformFileHandle, char*, int)
+int readFromFile(PlatformFileHandle handle, char* data, int length)
 {
-    notImplemented();
-    return -1;
+    if (length < 0 || !isHandleValid(handle) || data == nullptr) {
+        return -1;
+    }
+    JNIEnv* env = WebCore_GetJavaEnv();
+    static jmethodID mid = env->GetStaticMethodID(
+            GetFileSystemClass(env),
+            "fwkReadFromFile",
+            "(Ljava/io/RandomAccessFile;Ljava/nio/ByteBuffer;)I");
+    ASSERT(mid);
+
+    int result = env->CallStaticIntMethod(
+            GetFileSystemClass(env),
+            mid,
+            (jobject)handle,
+            (jobject)(env->NewDirectByteBuffer(data, length)));
+    CheckAndClearException(env);
+
+    if (result < 0) {
+        return -1;
+    }
+    return result;
 }
 
 int writeToFile(PlatformFileHandle, const char*, int)
@@ -274,10 +321,28 @@
     return String(env, result);
 }
 
-long long seekFile(PlatformFileHandle, long long, FileSeekOrigin)
+long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin)
 {
-    notImplemented();
-    return (long long)(-1);
+    // we always get positive value for offset from webkit.
+    // Below check for offset < 0 might be redundant?
+    if (offset < 0 || !isHandleValid(handle)) {
+        return -1;
+    }
+    JNIEnv* env = WebCore_GetJavaEnv();
+    static jmethodID mid = env->GetStaticMethodID(
+            GetFileSystemClass(env),
+            "fwkSeekFile",
+            "(Ljava/io/RandomAccessFile;J)V");
+    ASSERT(mid);
+
+    env->CallStaticVoidMethod(
+            GetFileSystemClass(env),
+            mid,
+            (jobject)handle, (jlong)offset);
+    if (CheckAndClearException(env)) {
+        offset = -1;
+    }
+    return offset;
 }
 
 std::optional<int32_t> getFileDeviceId(const CString&)
--- a/modules/javafx.web/src/main/native/Tools/DumpRenderTree/java/DumpRenderTree.cpp	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/main/native/Tools/DumpRenderTree/java/DumpRenderTree.cpp	Tue Dec 11 23:23:35 2018 +0530
@@ -135,6 +135,20 @@
     return bool_to_jbool(gTestRunner->shouldStayOnPageAfterHandlingBeforeUnload());
 }
 
+JNIEXPORT jobjectArray JNICALL Java_com_sun_javafx_webkit_drt_DumpRenderTree_openPanelFiles
+    (JNIEnv* env, jclass)
+{
+    ASSERT(gTestRunner);
+    const auto& openFiles = gTestRunner->openPanelFiles();
+    static JGClass stringCls = env->FindClass("java/lang/String");
+    ASSERT(stringCls);
+    jobjectArray files = env->NewObjectArray(openFiles.size(), stringCls, env->NewStringUTF(""));
+    for (auto i = 0; i < openFiles.size(); i++) {
+        env->SetObjectArrayElement(files, i, env->NewStringUTF(openFiles[i].c_str()));
+    }
+    return files;
+}
+
 #ifdef __cplusplus
 }
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/javafx.web/src/shims/java/com/sun/javafx/webkit/UIClientImplShim.java	Tue Dec 11 23:23:35 2018 +0530
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.webkit;
+
+public class UIClientImplShim {
+
+    public static void test_setChooseFiles(String[] files) {
+        UIClientImpl.test_setChooseFiles(files);
+    }
+}
--- a/modules/javafx.web/src/shims/java/com/sun/webkit/WebPageShim.java	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/shims/java/com/sun/webkit/WebPageShim.java	Tue Dec 11 23:23:35 2018 +0530
@@ -26,6 +26,7 @@
 package com.sun.webkit;
 
 import com.sun.webkit.WebPage;
+import com.sun.webkit.event.WCMouseEvent;
 import com.sun.webkit.graphics.WCGraphicsContext;
 import com.sun.webkit.graphics.WCGraphicsManager;
 import com.sun.webkit.graphics.WCPageBackBuffer;
@@ -60,4 +61,21 @@
         page.print(gc, pageNo, w);
         page.endPrinting();
     }
+
+    public static void click(WebPage page, int x, int y) {
+        WCMouseEvent mousePressEvent =
+                new WCMouseEvent(WCMouseEvent.MOUSE_PRESSED, WCMouseEvent.BUTTON1,
+                    1, x, y,
+                    x, y,
+                    System.currentTimeMillis(),
+                    false, false, false, false, false);
+        WCMouseEvent mouseReleaseEvent =
+                new WCMouseEvent(WCMouseEvent.MOUSE_RELEASED, WCMouseEvent.BUTTON1,
+                    1, x, y,
+                    x, y,
+                    System.currentTimeMillis(),
+                    false, false, false, false, false);
+        page.dispatchMouseEvent(mousePressEvent);
+        page.dispatchMouseEvent(mouseReleaseEvent);
+    }
 }
--- a/modules/javafx.web/src/test/addExports	Fri Dec 07 11:24:41 2018 +0100
+++ b/modules/javafx.web/src/test/addExports	Tue Dec 11 23:23:35 2018 +0530
@@ -47,8 +47,10 @@
 --add-exports javafx.graphics/com.sun.scenario.effect.light=ALL-UNNAMED
 --add-exports javafx.graphics/com.sun.scenario=ALL-UNNAMED
 #
+--add-exports javafx.web/com.sun.javafx.scene.web=ALL-UNNAMED
+--add-exports javafx.web/com.sun.javafx.webkit=ALL-UNNAMED
 --add-exports javafx.web/com.sun.webkit=ALL-UNNAMED
 --add-exports javafx.web/com.sun.webkit.dom=ALL-UNNAMED
---add-exports javafx.web/com.sun.javafx.scene.web=ALL-UNNAMED
+--add-exports javafx.web/com.sun.webkit.event=ALL-UNNAMED
+--add-exports javafx.web/com.sun.webkit.network=ALL-UNNAMED
 --add-exports javafx.web/com.sun.webkit.text=ALL-UNNAMED
---add-exports javafx.web/com.sun.webkit.network=ALL-UNNAMED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/javafx.web/src/test/java/test/javafx/scene/web/FileReaderTest.java	Tue Dec 11 23:23:35 2018 +0530
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.javafx.scene.web;
+
+import com.sun.javafx.webkit.UIClientImplShim;
+import com.sun.webkit.WebPage;
+import com.sun.webkit.WebPageShim;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+import java.util.concurrent.CountDownLatch;
+import javafx.concurrent.Worker.State;
+import javafx.scene.web.WebEngineShim;
+
+import static javafx.concurrent.Worker.State.SUCCEEDED;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import netscape.javascript.JSObject;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FileReaderTest extends TestBase {
+    private final WebPage page = WebEngineShim.getPage(getEngine());
+    private String[] fileList = { new File("src/test/resources/test/html/HelloWorld.txt").getAbsolutePath() };
+    private CountDownLatch latch;
+    private State getLoadState() {
+        return submit(() -> getEngine().getLoadWorker().getState());
+    }
+
+    private String getScriptString(String readAPI, String slice, boolean abort) {
+        String scriptContent = String.format("<script type='text/javascript'>" +
+                                    "var result;" +
+                                    "window.addEventListener('click', (e) => {" +
+                                        "document.getElementById('file').click();" +
+                                    "});" +
+                                    "function readFile()" +
+                                    "{" +
+                                        "file = event.target.files[0];" +
+                                        "var reader = new FileReader();" +
+                                        "reader.onloadstart = () => {" +
+                                        "%s" +
+                                        "};" +
+                                        "reader.onload = () => {" +
+                                            "result = reader.result;" +
+                                            "latch.countDown();" +
+                                        "};" +
+                                        "reader.onerror = () => {" +
+                                            "result = 'failed due to error';" +
+                                            "latch.countDown();" +
+                                        "};" +
+                                        "reader." + readAPI + "(file" + slice + ");" +
+                                    "}" +
+                               "</script>" +
+                               "<body> <input type='file' id='file' onchange='readFile()'/></body>", (abort ? "reader.abort();" : ""));
+        return scriptContent;
+    }
+
+    @Before
+    public void before() {
+        latch = new CountDownLatch(1);
+        UIClientImplShim.test_setChooseFiles(fileList);
+    }
+
+    private void loadFileReaderTestScript(String testScript) {
+        loadContent(testScript);
+        testLatch(latch);
+    }
+
+    private void testLatch(CountDownLatch latch) {
+        assertTrue("Page load is not finished yet", getLoadState() == SUCCEEDED);
+        assertNotNull("Document should not be null", getEngine().getDocument());
+        submit(() -> {
+            final JSObject window = (JSObject) getEngine().executeScript("window");
+            assertNotNull(window);
+            window.setMember("latch", latch);
+            // we send a dummy mouse click event at (0,0) to simulate click on file chooser button.
+            WebPageShim.click(page, 0, 0);
+        });
+
+        try {
+            latch.await();
+        } catch (InterruptedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    @Test public void testReadAsTextWithoutSlice() {
+        loadFileReaderTestScript(getScriptString("readAsText", "", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "Hello World", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTextWithSlice() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice()", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "Hello World", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithValidStartAndEnd() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(3, 7)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "lo W", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithEndAsFileLength() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(3, file.length)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "lo World", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithOnlyStartAsFileLength() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(file.length)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "Hello World", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithStartAsNegetiveValue() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(-7, file.length)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "o World", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithStartAsFileLength() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(file.length, 3)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "Hel", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithEndAsNegetiveValue() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(file.length, -3)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "Hello Wo", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithEndAsBeyondFileLength() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(file.length, -100)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithBeginAsValidValue() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(6)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "World", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithOnlyStartAsNegetiveValue() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(-3)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "rld", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testReadAsTexWithSliceWithStartAndEndAsNegetiveValues() {
+        loadFileReaderTestScript(getScriptString("readAsText", ".slice(-3, -7)", false));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "", getEngine().executeScript("window.result"));
+        });
+    }
+
+    @Test public void testreadAsBinaryString() throws FileNotFoundException, IOException {
+        String binaryFile[] = { new File("src/test/resources/test/html/BinaryFile.dat").getAbsolutePath() };
+        UIClientImplShim.test_setChooseFiles(binaryFile);
+        loadFileReaderTestScript(getScriptString("readAsBinaryString", "", false));
+        FileInputStream in = new FileInputStream(binaryFile[0]);
+        final byte[] expectedBinaryData = in.readAllBytes();
+        assertNotNull("BinaryFile content should not be null", expectedBinaryData);
+        submit(() -> {
+            try {
+                final String obj = (String) getEngine().executeScript("window.result");
+                // setting encoding scheme to ISO-8859-1 for binary data as webkit uses the same.
+                final byte[] binBytes = obj.getBytes("ISO-8859-1");
+                assertNotNull("BinaryFile content read should not be null", binBytes);
+                assertArrayEquals("Unexpected file content received", expectedBinaryData, binBytes);
+            } catch (UnsupportedEncodingException ex) {
+                throw new AssertionError(ex);
+            }
+        });
+    }
+
+    @Test public void testreadAsArrayBuffer() throws FileNotFoundException, IOException {
+        loadFileReaderTestScript(getScriptString("readAsArrayBuffer", "", false));
+        try (FileInputStream in = new FileInputStream(fileList[0])) {
+            final byte[] expectedArrayBuffer = in.readAllBytes();
+            submit(() -> {
+                final JSObject obj = (JSObject) getEngine().executeScript("new Uint8Array(window.result)");
+                assertEquals(String.format("%s length must be equal in both Java & JavaScript", fileList),
+                                       expectedArrayBuffer.length, obj.getMember("length"));
+                for (int i = 0; i < expectedArrayBuffer.length; i++) {
+                    assertEquals("Unexpected file content received", expectedArrayBuffer[i], ((Number)(obj.getSlot(i))).byteValue());
+                }
+            });
+        } catch (IOException ex){
+            throw new AssertionError(ex);
+        }
+    }
+
+    @Test public void testreadAsDataURL() throws FileNotFoundException, IOException {
+        loadFileReaderTestScript(getScriptString("readAsDataURL", "", false));
+        try (FileInputStream in = new FileInputStream(fileList[0])) {
+            final byte[] expectedArrayBuffer = in.readAllBytes();
+            submit(() -> {
+                try {
+                    String encodedData = (String) getEngine().executeScript("window.result");
+                    assertNotNull("window.result must have base64 encoded data", encodedData);
+                    assertEquals("Base64 EncodedData is not same as window.result",
+                                   "data:text/plain;base64,SGVsbG8gV29ybGQ=", encodedData);
+                    encodedData = encodedData.split(",")[1];
+                    assertNotNull(encodedData);
+                    final byte[] decodedData = Base64.getDecoder().decode(encodedData);
+                    assertNotNull("Base64 decoded data must be valid", decodedData);
+                    assertEquals("Base64 DecodedData is not same as File Content",
+                        new String(expectedArrayBuffer, "utf-8"), new String(decodedData, "utf-8"));
+                } catch (UnsupportedEncodingException e) {
+                    throw new AssertionError(e);
+                }
+            });
+        } catch (IOException ex){
+            throw new AssertionError(ex);
+        }
+    }
+
+    @Test public void testAbort() {
+        loadFileReaderTestScript(getScriptString("readAsText", "", true));
+        submit(() -> {
+            assertEquals("Unexpected file content received", "failed due to error",
+                          getEngine().executeScript("window.result"));
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/javafx.web/src/test/resources/test/html/BinaryFile.dat	Tue Dec 11 23:23:35 2018 +0530
@@ -0,0 +1,1 @@
+
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/javafx.web/src/test/resources/test/html/HelloWorld.txt	Tue Dec 11 23:23:35 2018 +0530
@@ -0,0 +1,1 @@
+Hello World
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/javafx.web/src/test/resources/test/html/readAsText.html	Tue Dec 11 23:23:35 2018 +0530
@@ -0,0 +1,38 @@
+<html>
+<head>
+<title>Title of the document</title>
+
+<script type="text/javascript">
+var result = null;
+var file;
+window.addEventListener('click', (e) => {
+	document.getElementById('file').click();
+	test.print("onclick.." + e);
+
+});
+function ReadFile() {
+  file = event.target.files[0];
+  test.print("file.." + file);
+  var reader = new FileReader();
+     reader.onload = function () { 
+      document.getElementById('results').innerText='loaded:' + reader.result;
+	  result = reader.result;
+	  test.print("result..." + result);
+	  latch.countDown();
+     };
+  reader.onerror = function () { 
+    document.getElementById('results').innerText='Error:' + reader.result;
+	result = reader.result;
+	latch.countDown();
+  };
+  reader.readAsText(file);
+}
+</script>
+</head>
+
+<body>
+<input type="file" id="file" name="file" onchange="ReadFile()" multiple />
+<div>File Contents</div><div id='results'><div>
+<br/>
+</body>
+</html>