Skip to content

Commit 5023aca

Browse files
committed
executeScript supports primitiveArray args also
1 parent c90d992 commit 5023aca

2 files changed

Lines changed: 204 additions & 14 deletions

File tree

src/main/java/org/openqa/selenium/htmlunit/HtmlUnitDriver.java

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,14 @@ private Object parseArgumentIntoJavascriptParameter(final Scriptable scope, Obje
915915
|| arg instanceof Number // special case the underlying type
916916
|| arg instanceof String
917917
|| arg instanceof Boolean
918-
|| arg.getClass().isArray()
918+
919+
|| arg instanceof Object[]
920+
|| arg instanceof int[]
921+
|| arg instanceof long[]
922+
|| arg instanceof float[]
923+
|| arg instanceof double[]
924+
|| arg instanceof boolean[]
925+
919926
|| arg instanceof Collection<?> || arg instanceof Map<?, ?>)) {
920927
throw new IllegalArgumentException(
921928
"Argument must be a string, number, boolean or WebElement: " + arg + " (" + arg.getClass() + ")");
@@ -925,39 +932,72 @@ private Object parseArgumentIntoJavascriptParameter(final Scriptable scope, Obje
925932
final HtmlUnitWebElement webElement = (HtmlUnitWebElement) arg;
926933
assertElementNotStale(webElement.getElement());
927934
return webElement.getElement().getScriptableObject();
928-
929935
}
930936
else if (arg instanceof HtmlElement) {
931937
final HtmlElement element = (HtmlElement) arg;
932938
assertElementNotStale(element);
933939
return element.getScriptableObject();
934-
935940
}
936941
else if (arg instanceof Collection<?>) {
937942
final List<Object> list = new ArrayList<>();
938943
for (final Object o : (Collection<?>) arg) {
939944
list.add(parseArgumentIntoJavascriptParameter(scope, o));
940945
}
941946
return Context.getCurrentContext().newArray(scope, list.toArray());
942-
943947
}
944-
else if (arg.getClass().isArray()) {
948+
949+
else if (arg instanceof Object[]) {
945950
final List<Object> list = new ArrayList<>();
946951
for (final Object o : (Object[]) arg) {
947952
list.add(parseArgumentIntoJavascriptParameter(scope, o));
948953
}
949954
return Context.getCurrentContext().newArray(scope, list.toArray());
950-
951955
}
952-
else if (arg instanceof Map<?, ?>) {
953-
final Map<?, ?> argmap = (Map<?, ?>) arg;
954-
final Scriptable map = Context.getCurrentContext().newObject(scope);
955-
for (final Map.Entry<?, ?> entry : argmap.entrySet()) {
956-
map.put((String) entry.getKey(), map, parseArgumentIntoJavascriptParameter(scope, entry.getValue()));
956+
else if (arg instanceof int[]) {
957+
final List<Object> list = new ArrayList<>();
958+
for (final Object o : (int[]) arg) {
959+
list.add(parseArgumentIntoJavascriptParameter(scope, o));
957960
}
958-
return map;
961+
return Context.getCurrentContext().newArray(scope, list.toArray());
962+
}
963+
else if (arg instanceof long[]) {
964+
final List<Object> list = new ArrayList<>();
965+
for (final Object o : (long[]) arg) {
966+
list.add(parseArgumentIntoJavascriptParameter(scope, o));
967+
}
968+
return Context.getCurrentContext().newArray(scope, list.toArray());
969+
}
970+
else if (arg instanceof float[]) {
971+
final List<Object> list = new ArrayList<>();
972+
for (final Object o : (float[]) arg) {
973+
list.add(parseArgumentIntoJavascriptParameter(scope, o));
974+
}
975+
return Context.getCurrentContext().newArray(scope, list.toArray());
976+
}
977+
else if (arg instanceof double[]) {
978+
final List<Object> list = new ArrayList<>();
979+
for (final Object o : (double[]) arg) {
980+
list.add(parseArgumentIntoJavascriptParameter(scope, o));
981+
}
982+
return Context.getCurrentContext().newArray(scope, list.toArray());
983+
}
984+
else if (arg instanceof boolean[]) {
985+
final List<Object> list = new ArrayList<>();
986+
for (final Object o : (boolean[]) arg) {
987+
list.add(parseArgumentIntoJavascriptParameter(scope, o));
988+
}
989+
return Context.getCurrentContext().newArray(scope, list.toArray());
990+
}
959991

992+
else if (arg instanceof Map<?, ?>) {
993+
final Map<?, ?> map = (Map<?, ?>) arg;
994+
final Scriptable obj = Context.getCurrentContext().newObject(scope);
995+
for (final Map.Entry<?, ?> entry : map.entrySet()) {
996+
obj.put((String) entry.getKey(), obj, parseArgumentIntoJavascriptParameter(scope, entry.getValue()));
997+
}
998+
return obj;
960999
}
1000+
9611001
else {
9621002
return arg;
9631003
}

src/test/java/org/openqa/selenium/htmlunit/HtmlUnitDriver2Test.java

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@
1717

1818
package org.openqa.selenium.htmlunit;
1919

20+
import java.math.BigInteger;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
2024
import org.junit.Test;
2125
import org.junit.runner.RunWith;
26+
import org.openqa.selenium.By;
2227
import org.openqa.selenium.JavascriptExecutor;
2328
import org.openqa.selenium.WebDriver;
29+
import org.openqa.selenium.WebElement;
2430
import org.openqa.selenium.htmlunit.junit.BrowserRunner;
31+
import org.openqa.selenium.htmlunit.junit.BrowserRunner.Alerts;
32+
import org.openqa.selenium.htmlunit.junit.BrowserRunner.HtmlUnitNYI;
2533

2634
/**
2735
* General tests for the HtmlUnitDriver.
@@ -33,9 +41,151 @@ public class HtmlUnitDriver2Test extends WebDriverTestCase {
3341

3442
@Test
3543
public void executeScriptWithoutPage() {
36-
final WebDriver driver = getWebDriver();
37-
final String text = (String) ((JavascriptExecutor) driver).executeScript("return 'test';");
44+
final WebDriver webDriver = getWebDriver();
45+
final String text = (String) ((JavascriptExecutor) webDriver).executeScript("return 'test';");
3846

3947
assertEquals("test", text);
4048
}
49+
50+
@Test
51+
@Alerts({"1| [0]HtmlUnit string", "1| [0] string"})
52+
public void executeScriptParamString() throws Exception {
53+
executeScriptParam(getExpectedAlerts()[0], "HtmlUnit");
54+
executeScriptParam(getExpectedAlerts()[1], "");
55+
}
56+
57+
@Test
58+
@Alerts({"1| [0]true boolean", "1| [0]false boolean", "1| [0]true boolean"})
59+
public void executeScriptParamBoolean() throws Exception {
60+
executeScriptParam(getExpectedAlerts()[0], true);
61+
executeScriptParam(getExpectedAlerts()[1], false);
62+
executeScriptParam(getExpectedAlerts()[2], Boolean.TRUE);
63+
}
64+
65+
@Test
66+
@Alerts({"1| [0]4711 number",
67+
"1| [0]-1234567890155 number",
68+
"1| [0]0 number",
69+
"1| [0]3.141592653589793 number",
70+
"1| [0]4444 number"})
71+
@HtmlUnitNYI(
72+
CHROME = {"1| [0]4711 number",
73+
"1| [0]-1234567890155 number",
74+
"1| [0]0 number",
75+
"1| [0]3.141592653589793 number",
76+
"1| [0]4444 bigint"},
77+
EDGE = {"1| [0]4711 number",
78+
"1| [0]-1234567890155 number",
79+
"1| [0]0 number",
80+
"1| [0]3.141592653589793 number",
81+
"1| [0]4444 bigint"},
82+
FF = {"1| [0]4711 number",
83+
"1| [0]-1234567890155 number",
84+
"1| [0]0 number",
85+
"1| [0]3.141592653589793 number",
86+
"1| [0]4444 bigint"},
87+
FF_ESR = {"1| [0]4711 number",
88+
"1| [0]-1234567890155 number",
89+
"1| [0]0 number",
90+
"1| [0]3.141592653589793 number",
91+
"1| [0]4444 bigint"})
92+
public void executeScriptParamNumber() throws Exception {
93+
executeScriptParam(getExpectedAlerts()[0], 4711);
94+
executeScriptParam(getExpectedAlerts()[1], -1234567890155L);
95+
executeScriptParam(getExpectedAlerts()[2], 0f);
96+
executeScriptParam(getExpectedAlerts()[3], Math.PI);
97+
executeScriptParam(getExpectedAlerts()[4], BigInteger.valueOf(4444));
98+
}
99+
100+
@Test
101+
@Alerts({"2| [0]Html string [1]Unit string", "0|"})
102+
public void executeScriptParamSimpleArray() throws Exception {
103+
executeScriptParam(getExpectedAlerts()[0], new String[] {"Html", "Unit"});
104+
executeScriptParam(getExpectedAlerts()[1], new String[] {});
105+
}
106+
107+
@Test
108+
@Alerts({"1| [0]1,-2 array",
109+
"1| [0]1,-2 array",
110+
"1| [0]1,-2 array",
111+
"1| [0]1,-2 array",
112+
"1| [0]false array"})
113+
public void executeScriptParamPrimitiveArray() throws Exception {
114+
executeScriptParam(getExpectedAlerts()[0], new int[] {1, -2});
115+
executeScriptParam(getExpectedAlerts()[1], new long[] {1L, -2L});
116+
executeScriptParam(getExpectedAlerts()[2], new float[] {1f, -2f});
117+
executeScriptParam(getExpectedAlerts()[3], new double[] {1d, -2d});
118+
executeScriptParam(getExpectedAlerts()[4], new boolean[] {false});
119+
}
120+
121+
@Test
122+
@Alerts({"3| [0]Html string [1]17 number [2]true boolean",
123+
"3| [0]Html string [1]42,7 array [2]true boolean"})
124+
public void executeScriptParamMixedArray() throws Exception {
125+
executeScriptParam(getExpectedAlerts()[0], new Object[] {"Html", 17, true});
126+
executeScriptParam(getExpectedAlerts()[1], new Object[] {"Html", new int[] {42, 7}, true});
127+
}
128+
129+
@Test
130+
@Alerts({"1| [0][object Object] object ()",
131+
"1| [0][object Object] object (Html->Unit )",
132+
"1| [0][object Object] object (Zahl->17 )"})
133+
public void executeScriptParamSimpleMap() throws Exception {
134+
Map<String, Object> param = new HashMap<>();
135+
136+
executeScriptParam(getExpectedAlerts()[0], param);
137+
138+
param.put("Html", "Unit");
139+
executeScriptParam(getExpectedAlerts()[1], param);
140+
141+
param = new HashMap<>();
142+
param.put("Zahl", 17);
143+
executeScriptParam(getExpectedAlerts()[2], param);
144+
}
145+
146+
private void executeScriptParam(final Object expected, final Object... params) throws Exception {
147+
final String html = "<html><head><title>Tester</title></head></html>";
148+
final WebDriver webDriver = loadPage2(html);
149+
150+
final String js = "let result = '';\n"
151+
+ "result += arguments.length;\n"
152+
+ "result += '|';\n"
153+
+ "for (let i = 0; i < arguments.length; i++) {\n"
154+
+ " result += ' [' + i + ']' + arguments[i];"
155+
+ " if (Array.isArray(arguments[i])) {\n"
156+
+ " result += ' array';\n"
157+
+ " } else if (Object.getPrototypeOf(arguments[i]) === Map.prototype) {\n"
158+
+ " result += ' map';\n"
159+
+ " } else {\n"
160+
+ " result += ' ' + typeof arguments[i];\n"
161+
+ " if ('object' === typeof arguments[i]) {\n"
162+
+ " result += ' (';\n"
163+
+ " let props = Object.getOwnPropertyNames(arguments[i]);\n"
164+
+ " for (let p = 0; p < props.length; p++) {\n"
165+
+ " result += props[p];\n"
166+
+ " result += '->';\n"
167+
+ " result += arguments[i][props[p]] + ' ';\n"
168+
+ " }\n"
169+
+ " result += ')';\n"
170+
+ " }\n"
171+
+ " }\n"
172+
+ "}\n"
173+
+ "return result;\n";
174+
175+
final String text = (String) ((JavascriptExecutor) webDriver).executeScript(js, params);
176+
assertEquals(expected, text);
177+
}
178+
179+
@Test
180+
public void executeScriptParamWebElement() throws Exception {
181+
final String html = "<html><head><title>Tester</title></head>\n"
182+
+ "<body><div id='myDivId'>diff</div></html>";
183+
final WebDriver webDriver = loadPage2(html);
184+
185+
final WebElement webElement = webDriver.findElement(By.id("myDivId"));
186+
187+
final String js = "return arguments[0].outerHTML;";
188+
final String text = (String) ((JavascriptExecutor) webDriver).executeScript(js, webElement);
189+
assertEquals("<div id=\"myDivId\">diff</div>", text);
190+
}
41191
}

0 commit comments

Comments
 (0)