boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Thu, 17 Dec 2015 22:23:41 +0100
changeset 1037 e390a06dbfac
parent 1016 665b10c62f3d
permissions -rw-r--r--
#257171: FXBrowsers.runInBrowser needs to properly set BrwsrCtx
     1 /**
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     9  * The contents of this file are subject to the terms of either the GNU
    10  * General Public License Version 2 only ("GPL") or the Common
    11  * Development and Distribution License("CDDL") (collectively, the
    12  * "License"). You may not use this file except in compliance with the
    13  * License. You can obtain a copy of the License at
    14  * http://www.netbeans.org/cddl-gplv2.html
    15  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    16  * specific language governing permissions and limitations under the
    17  * License.  When distributing the software, include this License Header
    18  * Notice in each file and include the License file at
    19  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    20  * particular file as subject to the "Classpath" exception as provided
    21  * by Oracle in the GPL Version 2 section of the License file that
    22  * accompanied this code. If applicable, add the following below the
    23  * License Header, with the fields enclosed by brackets [] replaced by
    24  * your own identifying information:
    25  * "Portions Copyrighted [year] [name of copyright owner]"
    26  *
    27  * Contributor(s):
    28  *
    29  * The Original Software is NetBeans. The Initial Developer of the Original
    30  * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    31  *
    32  * If you wish your version of this file to be governed by only the CDDL
    33  * or only the GPL Version 2, indicate your decision by adding
    34  * "[Contributor] elects to include this software in this distribution
    35  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    36  * single choice of license, a recipient has the option to distribute
    37  * your version of this file under either the CDDL, the GPL Version 2 or
    38  * to extend the choice of license to its licensees as provided above.
    39  * However, if you add GPL Version 2 code and therefore, elected the GPL
    40  * Version 2 license, then the option applies only if the new code is
    41  * made subject to such option by the copyright holder.
    42  */
    43 package net.java.html.boot.fx;
    44 
    45 import java.net.URL;
    46 import java.util.concurrent.CountDownLatch;
    47 import javafx.application.Application;
    48 import javafx.application.Platform;
    49 import javafx.scene.Scene;
    50 import javafx.scene.layout.BorderPane;
    51 import javafx.scene.web.WebView;
    52 import javafx.stage.Stage;
    53 import net.java.html.BrwsrCtx;
    54 import net.java.html.js.JavaScriptBody;
    55 import static org.testng.Assert.*;
    56 import org.testng.annotations.BeforeClass;
    57 import org.testng.annotations.Test;
    58 
    59 /**
    60  *
    61  * @author Jaroslav Tulach
    62  */
    63 public class FXBrowsersTest {
    64     private static CountDownLatch PROPERTY_SET;
    65 
    66     public FXBrowsersTest() {
    67     }
    68     
    69     @BeforeClass public void initFX() throws Throwable {
    70         new Thread("initFX") {
    71             @Override
    72             public void run() {
    73                 if (Platform.isFxApplicationThread()) {
    74                     new App().start(new Stage());
    75                 } else {
    76                     try {
    77                         App.launch(App.class);
    78                     } catch (IllegalStateException ex) {
    79                         Platform.runLater(this);
    80                     }
    81                 }
    82             }
    83         }.start();
    84         App.CDL.await();
    85     }
    86     
    87     @JavaScriptBody(args = {  }, body = "return true;")
    88     static boolean inJS() {
    89         return false;
    90     }
    91 
    92     @Test
    93     public void brwsrCtxExecute() throws Throwable {
    94         assertFalse(inJS(), "We aren't in JS now");
    95         final CountDownLatch init = new CountDownLatch(1);
    96         final BrwsrCtx[] ctx = { null };
    97         FXBrowsers.runInBrowser(App.getV1(), new Runnable() {
    98             @Override
    99             public void run() {
   100                 assertTrue(inJS(), "We are in JS context now");
   101                 ctx[0] = BrwsrCtx.findDefault(FXBrowsersTest.class);
   102                 init.countDown();
   103             }
   104         });
   105         init.await();
   106 
   107         final CountDownLatch cdl = new CountDownLatch(1);
   108         class R implements Runnable {
   109             @Override
   110             public void run() {
   111                 if (Platform.isFxApplicationThread()) {
   112                     assertTrue(inJS());
   113                     cdl.countDown();
   114                 } else {
   115                     ctx[0].execute(this);
   116                 }
   117             }
   118         }
   119         new Thread(new R(), "Background thread").start();
   120 
   121         cdl.await();
   122     }
   123 
   124     @Test
   125     public void behaviorOfTwoWebViewsAtOnce() throws Throwable {
   126         class R implements Runnable {
   127             Throwable t;
   128 
   129             @Override
   130             public void run() {
   131                 try {
   132                     doTest();
   133                 } catch (Throwable ex) {
   134                     t = ex;
   135                 }
   136             }
   137             
   138             private void doTest() throws Throwable {
   139                 URL u = FXBrowsersTest.class.getResource("/org/netbeans/html/boot/fx/empty.html");
   140                 assertNotNull(u, "URL found");
   141                 FXBrowsers.load(App.getV1(), u, OnPages.class, "first");
   142             }
   143         }
   144         R run = new R();
   145         PROPERTY_SET = new CountDownLatch(2);
   146         Platform.runLater(run);
   147         PROPERTY_SET.await();
   148         
   149         assertEquals(Integer.getInteger("finalFirst"), Integer.valueOf(3), "Three times in view one");
   150         assertEquals(Integer.getInteger("finalSecond"), Integer.valueOf(2), "Two times in view one");
   151 
   152         final CountDownLatch finish = new CountDownLatch(1);
   153         final Object[] three = { 0 };
   154         assertFalse(Platform.isFxApplicationThread());
   155         FXBrowsers.runInBrowser(App.getV1(), new Runnable() {
   156             @Override
   157             public void run() {
   158                 assertTrue(Platform.isFxApplicationThread());
   159                 three[0] = App.getV1().getEngine().executeScript("window.cntBrwsr");
   160                 finish.countDown();
   161             }
   162         });
   163         finish.await();
   164         
   165         assertEquals(three[0], Integer.valueOf(3));
   166     }
   167     
   168     public static class OnPages {
   169         static Class<?> first;
   170         static Object firstWindow;
   171         
   172         public static void first() {
   173             first = OnPages.class;
   174             firstWindow = window();
   175             assertNotNull(firstWindow, "First window found");
   176             
   177             assertEquals(increment(), 1, "Now it is one");
   178             
   179             URL u = FXBrowsersTest.class.getResource("/org/netbeans/html/boot/fx/empty.html");
   180             assertNotNull(u, "URL found");
   181             FXBrowsers.load(App.getV2(), u, new Runnable() {
   182                 @Override
   183                 public void run() {
   184                     OnPages.second("Hello");
   185                 }
   186             });
   187             
   188             assertEquals(increment(), 2, "Now it is two and not influenced by second view");
   189             System.setProperty("finalFirst", "" + increment());
   190             PROPERTY_SET.countDown();
   191         }
   192         
   193         public static void second(String... args) {
   194             assertEquals(args.length, 1, "One string argument");
   195             assertEquals(args[0], "Hello", "It is hello");
   196             assertEquals(first, OnPages.class, "Both views share the same classloader");
   197             
   198             Object window = window();
   199             assertNotNull(window, "Some window found");
   200             assertNotNull(firstWindow, "First window is known");
   201             assertNotSame(firstWindow, window, "The window objects should be different");
   202             
   203             assertEquals(increment(), 1, "Counting starts from zero");
   204             System.setProperty("finalSecond", "" + increment());
   205             PROPERTY_SET.countDown();
   206         }
   207         
   208         @JavaScriptBody(args = {}, body = "return window;")
   209         private static native Object window();
   210         
   211         @JavaScriptBody(args = {}, body = ""
   212             + "if (window.cntBrwsr) return ++window.cntBrwsr;"
   213             + "return window.cntBrwsr = 1;"
   214         )
   215         private static native int increment();
   216     }
   217     
   218     public static class App extends Application {
   219         static final CountDownLatch CDL = new CountDownLatch(1);
   220         private static BorderPane pane;
   221 
   222         /**
   223          * @return the v1
   224          */
   225         static WebView getV1() {
   226             return (WebView)System.getProperties().get("v1");
   227         }
   228 
   229         /**
   230          * @return the v2
   231          */
   232         static WebView getV2() {
   233             return (WebView)System.getProperties().get("v2");
   234         }
   235 
   236         @Override
   237         public void start(Stage stage) {
   238             pane= new BorderPane();
   239             Scene scene = new Scene(pane, 800, 600);
   240             stage.setScene(scene);
   241             
   242             System.getProperties().put("v1", new WebView());
   243             System.getProperties().put("v2", new WebView());
   244 
   245             pane.setCenter(getV1());
   246             pane.setBottom(getV2());
   247 
   248             CDL.countDown();
   249         }
   250         
   251         
   252     }
   253 }