blob: 41482fbd4843cb08c231c327bf7569b78ceb0f42 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2020 Equo
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Guillermo Zunino, Equo - initial implementation
********************************************************************************/
package org.eclipse.swt.tests.junit;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Automated Test Suite for class org.eclipse.swt.browser.Browser
*
* @see org.eclipse.swt.browser.Browser
*/
public class Test_org_eclipse_swt_browser_Chromium extends Test_org_eclipse_swt_browser_Browser {
@BeforeClass
public static void setChromiumStyle() {
System.setProperty("org.eclipse.swt.browser.DefaultType", "chromium");
}
@AfterClass
public static void setDefaultStyle() {
System.clearProperty("org.eclipse.swt.browser.DefaultType");
}
@Before
public void setup() {
debug_show_browser = true;
debug_show_browser_timeout_seconds = 1;
}
/**
* Test that execute works works in callback BrowserFunction multiple times.
*/
@Test
public void test_BrowserFunction_callback_and_execute() {
AtomicBoolean javaCallbackExecuted = new AtomicBoolean(false);
AtomicInteger callCount = new AtomicInteger(0);
new BrowserFunction(browser, "callFunc") {
@Override
public Object function(Object[] arguments) {
System.out.println("callFunc BrowserFunc " +callCount.get() + " " + arguments[0]);
browser.execute("doSomething()");
if (arguments != null && arguments.length == 1 && "de".equals(arguments[0])) {
callCount.incrementAndGet();
return "{\"Reset\":\"Zur0cksetzen\"}";
}
callCount.incrementAndGet();
return "{\"Reset\":\"Reset\"}";
}
};
new BrowserFunction(browser, "finishedSomething") {
@Override
public Object function(Object[] arguments) {
System.out.println("finishedSomething BrowserFunc " + callCount.get() + " " + arguments[0]);
callCount.incrementAndGet();
browser.execute("doSomething1()");
javaCallbackExecuted.set(true);
return null;
}
};
browser.setText("<html>\n" +
"<body>\n" +
"\n" +
" English\n" +
" <div id=\"english\"></div>\n" +
" German\n" +
" <div id=\"german\"></div>\n" +
"\n" +
" <script>\n" +
" console.log('callFunc(en)')\n" +
" var en = callFunc('en');\n" +
" console.log('en json received');\n" +
" var enResult = JSON.parse(en);\n" +
" console.log('en json parsed')\n" +
" document.getElementById('english').innerHTML = \"Success: \" + enResult.Reset;\n" +
" console.log('html updated')\n" +
" \n" +
" console.log('callFunc(de)');\n" +
" var de = callFunc('de');\n" +
" console.log('de json received');\n" +
" var deResult = JSON.parse(de);\n" +
" console.log('de json parsed');\n" +
" document.getElementById('german').innerHTML = \"Success: \" + deResult.Reset;\n" +
" console.log('html updated 2');\n" +
" \n" +
" // functions needed for demonstration of issue 31\n" +
" function doSomething() {\n" +
" console.log('Doin something');\n" +
" var tmp = 0;\n" +
" for (var i = 0; i < 10000; i++) {\n" +
" tmp = tmp + 1 * 2;\n" +
" }\n" +
" console.log('Finished something');\n" +
" finishedSomething('a');\n" +
" }\n" +
" function doSomething1() {\n" +
" console.log('Doin something1');\n" +
" var tmp = 0;\n" +
" for (var i = 0; i < 10000; i++) {\n" +
" tmp = tmp + 1 * 2;\n" +
" }\n" +
" console.log('Finished something1');\n" +
" }\n" +
" </script>\n" +
"</body>\n" +
"</html>");
shell.open();
boolean passed = waitForPassCondition(() -> javaCallbackExecuted.get() && callCount.get() == 4);
String message = "A javascript callback should work. But something went wrong. Call count: " + callCount.get();
assertTrue(message, passed);
}
/**
* Test that javascript can call java, java returns a String back to javascript.
*
* It's a bit tricky to tell if javascript actually received the correct value from java.
* Solution: make a second function/callback that is called with the value that javascript received from java.
*
* Logic:
* 1) Java registers function callCustomFunction() by setting html body.
* 2) which in turn calls JavascriptCallback, which returns value string back to javascript.
* 3) javascript then calls JavascriptCallback_javascriptReceivedJavaString() and passes it value received from java.
* 4) Java validates that the correct value was passed to javascript and was passed back to java.
*
* loosely based on Snippet307.
*/
@Test
public void test_BrowserFunction_callback_with_javaReturningString () {
AtomicReference<String> returnString = new AtomicReference<>();
class JavascriptCallback extends BrowserFunction { // Note: Local class defined inside method.
JavascriptCallback(Browser browser, String name) {
super(browser, name);
}
@Override
public Object function(Object[] arguments) {
return "a � string";
}
}
class JavascriptCallback_javascriptReceivedJavaString extends BrowserFunction { // Note: Local class defined inside method.
JavascriptCallback_javascriptReceivedJavaString(Browser browser, String name) {
super(browser, name);
}
@Override
public Object function(Object[] arguments) {
System.out.println("JavascriptCallback_javascriptReceivedJavaString");
String returnVal = (String) arguments[0];
returnString.set(returnVal); // 4)
return null;
}
}
String htmlWithScript = "<html><head>\n"
+ "<script language=\"JavaScript\">\n"
+ "function callCustomFunction() {\n" // Define a javascript function.
+ " document.body.style.backgroundColor = 'red'\n"
+ " var retVal = jsCallbackToJava()\n" // 2)
+ " console.log('val:' + retVal)\n" // This calls the javafunction that we registered. Set HTML body to return value.
+ " document.write(retVal)\n" // This calls the javafunction that we registered. Set HTML body to return value.
+ " jsSuccess(retVal)\n" // 3)
+ "}"
+ "</script>\n"
+ "</head>\n"
+ "<body> If you see this, javascript did not receive anything from Java. This page should just be a string </body>\n"
+ "</html>\n";
// 1)
browser.setText(htmlWithScript);
new JavascriptCallback(browser, "jsCallbackToJava");
new JavascriptCallback_javascriptReceivedJavaString(browser, "jsSuccess");
browser.addProgressListener(callCustomFunctionUponLoad);
shell.open();
boolean passed = waitForPassCondition(() -> "a � string".equals(returnString.get()));
String message = "Java should have returned something back to javascript. But something went wrong";
assertTrue(message, passed);
}
/**
* Test that javascript can call java, java returns an mixed array back to javascript.
*
* It's a bit tricky to tell if javascript actually received the correct value from java.
* Solution: make a second function/callback that is called with the value that javascript received from java.
*
* Logic:
* 1) Java registers function callCustomFunction() by setting html body.
* 2) which in turn calls JavascriptCallback, which returns mixed array value back to javascript.
* 3) javascript then calls JavascriptCallback_javascriptReceivedJavaArray() and passes it value received from java.
* 4) Java validates that the correct value was passed to javascript and was passed back to java.
*
* loosely based on Snippet307.
*/
@Test
public void test_BrowserFunction_callback_with_javaReturningArray () {
AtomicReferenceArray<Object> returnArray = new AtomicReferenceArray<>(3);
class JavascriptCallback extends BrowserFunction { // Note: Local class defined inside method.
JavascriptCallback(Browser browser, String name) {
super(browser, name);
}
@Override
public Object function(Object[] arguments) {
return new Object[] {"a String", 42, true};
}
}
class JavascriptCallback_javascriptReceivedJavaArray extends BrowserFunction { // Note: Local class defined inside method.
JavascriptCallback_javascriptReceivedJavaArray(Browser browser, String name) {
super(browser, name);
}
@Override
public Object function(Object[] arguments) {
Object[] returnVal = (Object[]) arguments[0];
returnArray.set(0, returnVal[0]);
returnArray.set(1, returnVal[1]);
returnArray.set(2, returnVal[2]);
return null;
}
}
String htmlWithScript = "<html><head>\n"
+ "<script language=\"JavaScript\">\n"
+ "function callCustomFunction() {\n" // Define a javascript function.
+ " document.body.style.backgroundColor = 'red'\n"
+ " var retVal = jsCallbackToJava()\n" // 2)
+ " document.write(retVal)\n" // This calls the javafunction that we registered. Set HTML body to return value.
+ " jsSuccess(retVal)\n" // 3)
+ "}"
+ "</script>\n"
+ "</head>\n"
+ "<body> If you see this, javascript did not receive anything from Java. This page should just be '{\"a String\", 42, true}' </body>\n"
+ "</html>\n";
// 1)
browser.setText(htmlWithScript);
new JavascriptCallback(browser, "jsCallbackToJava");
new JavascriptCallback_javascriptReceivedJavaArray(browser, "jsSuccess");
browser.addProgressListener(callCustomFunctionUponLoad);
shell.open();
boolean passed = waitForPassCondition(() ->
"a String".equals(returnArray.get(0)) && Double.valueOf(42.0d).equals(returnArray.get(1)) && Boolean.valueOf((boolean) returnArray.get(2)) == true);
String message = "Java should have returned something back to javascript. But something went wrong";
assertTrue(message, passed);
}
}