Skip to content

Commit bed411d

Browse files
authored
[bidi][java] Add execute script high-level API (#14330)
Related to #13992
1 parent f4ef7be commit bed411d

File tree

4 files changed

+452
-0
lines changed

4 files changed

+452
-0
lines changed

java/src/org/openqa/selenium/bidi/script/LocalValue.java

+84
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@
1717

1818
package org.openqa.selenium.bidi.script;
1919

20+
import java.math.BigInteger;
21+
import java.time.Instant;
22+
import java.util.ArrayList;
23+
import java.util.HashMap;
24+
import java.util.HashSet;
2025
import java.util.List;
2126
import java.util.Map;
2227
import java.util.Set;
28+
import org.openqa.selenium.json.Json;
2329

2430
public abstract class LocalValue {
2531

32+
private static Json JSON = new Json();
33+
2634
enum SpecialNumberType {
2735
NAN("NaN"),
2836
MINUS_ZERO("-0"),
@@ -123,4 +131,80 @@ public static LocalValue remoteReference(String handle, String sharedId) {
123131
public static LocalValue remoteReference(RemoteReference.Type type, String id) {
124132
return new RemoteReference(type, id);
125133
}
134+
135+
public static LocalValue getArgument(Object arg) {
136+
LocalValue localValue = null;
137+
138+
if (arg instanceof String) {
139+
switch ((String) arg) {
140+
case "undefined":
141+
localValue = undefinedValue();
142+
break;
143+
case "null":
144+
localValue = nullValue();
145+
break;
146+
case "-Infinity":
147+
localValue = numberValue(SpecialNumberType.MINUS_INFINITY);
148+
break;
149+
case "Infinity":
150+
localValue = numberValue(SpecialNumberType.INFINITY);
151+
break;
152+
case "NaN":
153+
localValue = numberValue(SpecialNumberType.NAN);
154+
break;
155+
case "-0":
156+
localValue = numberValue(SpecialNumberType.MINUS_ZERO);
157+
break;
158+
default:
159+
localValue = stringValue((String) arg);
160+
break;
161+
}
162+
} else if (arg instanceof Number) {
163+
if (arg instanceof Integer || arg instanceof Long) {
164+
localValue = numberValue(((Number) arg).longValue());
165+
} else if (arg instanceof Double || arg instanceof Float) {
166+
localValue = numberValue(((Number) arg).doubleValue());
167+
} else if (arg instanceof BigInteger) {
168+
localValue = bigIntValue(arg.toString());
169+
}
170+
} else if (arg instanceof Boolean) {
171+
localValue = booleanValue((Boolean) arg);
172+
} else if (arg instanceof Instant) {
173+
localValue = dateValue(((Instant) arg).toString());
174+
} else if (arg instanceof Map) {
175+
Map<Object, LocalValue> map = new HashMap<>();
176+
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) arg).entrySet()) {
177+
Object key =
178+
(entry.getKey() instanceof String) ? entry.getKey() : getArgument(entry.getKey());
179+
map.put(key, getArgument(entry.getValue()));
180+
}
181+
localValue = mapValue(map);
182+
} else if (arg instanceof List) {
183+
List<LocalValue> values = new ArrayList<>();
184+
((List<Object>) arg).forEach(value -> values.add(getArgument(value)));
185+
localValue = arrayValue(values);
186+
} else if (arg instanceof Set) {
187+
Set<LocalValue> values = new HashSet<>();
188+
((Set<Object>) arg).forEach(value -> values.add(getArgument(value)));
189+
localValue = setValue(values);
190+
} else if (arg instanceof RegExpValue) {
191+
localValue = (RegExpValue) arg;
192+
} else {
193+
String json = JSON.toJson(arg);
194+
Map<Object, Object> objectMap = JSON.toType(json, Map.class);
195+
196+
Map<Object, LocalValue> map = new HashMap<>();
197+
198+
for (Map.Entry<Object, Object> entry : objectMap.entrySet()) {
199+
Object key =
200+
(entry.getKey() instanceof String) ? entry.getKey() : getArgument(entry.getKey());
201+
map.put(key, getArgument(entry.getValue()));
202+
}
203+
localValue = objectValue(map);
204+
205+
return localValue;
206+
}
207+
208+
return localValue;
209+
}
126210
}

java/src/org/openqa/selenium/remote/RemoteScript.java

+35
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,28 @@
2222

2323
import java.io.IOException;
2424
import java.io.InputStream;
25+
import java.util.ArrayList;
26+
import java.util.Arrays;
2527
import java.util.List;
2628
import java.util.Map;
29+
import java.util.Optional;
2730
import java.util.function.Consumer;
2831
import org.openqa.selenium.Beta;
2932
import org.openqa.selenium.By;
3033
import org.openqa.selenium.WebDriver;
34+
import org.openqa.selenium.WebDriverException;
3135
import org.openqa.selenium.WebElement;
3236
import org.openqa.selenium.bidi.BiDi;
3337
import org.openqa.selenium.bidi.HasBiDi;
3438
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
3539
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
3640
import org.openqa.selenium.bidi.module.LogInspector;
3741
import org.openqa.selenium.bidi.script.ChannelValue;
42+
import org.openqa.selenium.bidi.script.EvaluateResult;
43+
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
44+
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
45+
import org.openqa.selenium.bidi.script.LocalValue;
46+
import org.openqa.selenium.bidi.script.RemoteValue;
3847
import org.openqa.selenium.json.Json;
3948

4049
@Beta
@@ -131,4 +140,30 @@ public String pin(String script) {
131140
public void unpin(String id) {
132141
this.script.removePreloadScript(id);
133142
}
143+
144+
@Override
145+
public RemoteValue execute(String script, Object... args) {
146+
String browsingContextId = this.driver.getWindowHandle();
147+
148+
List<LocalValue> arguments = new ArrayList<>();
149+
150+
Arrays.stream(args).forEach(arg -> arguments.add(LocalValue.getArgument(arg)));
151+
152+
EvaluateResult result =
153+
this.script.callFunctionInBrowsingContext(
154+
browsingContextId,
155+
script,
156+
true,
157+
Optional.of(arguments),
158+
Optional.empty(),
159+
Optional.empty());
160+
161+
if (result.getResultType().equals(EvaluateResult.Type.SUCCESS)) {
162+
return ((EvaluateResultSuccess) result).getResult();
163+
} else {
164+
throw new WebDriverException(
165+
"Error while executing script: "
166+
+ ((EvaluateResultExceptionValue) result).getExceptionDetails().getText());
167+
}
168+
}
134169
}

java/src/org/openqa/selenium/remote/Script.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.openqa.selenium.Beta;
2222
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
2323
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
24+
import org.openqa.selenium.bidi.script.RemoteValue;
2425

2526
@Beta
2627
public interface Script {
@@ -40,4 +41,6 @@ public interface Script {
4041
String pin(String script);
4142

4243
void unpin(String id);
44+
45+
RemoteValue execute(String script, Object... args);
4346
}

0 commit comments

Comments
 (0)