Skip to content

Commit 6bc5a58

Browse files
authored
[java] Merge capabilities of slot with the new session request capabilities (#11369)
1 parent 8815c27 commit 6bc5a58

File tree

2 files changed

+408
-20
lines changed

2 files changed

+408
-20
lines changed

java/src/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutator.java

Lines changed: 116 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
import org.openqa.selenium.Capabilities;
2323
import org.openqa.selenium.ImmutableCapabilities;
2424
import org.openqa.selenium.PersistentCapabilities;
25-
25+
import java.util.ArrayList;
2626
import java.util.HashMap;
27+
import java.util.List;
2728
import java.util.Map;
2829
import java.util.Objects;
2930
import java.util.function.Function;
@@ -56,33 +57,128 @@ public Capabilities apply(Capabilities capabilities) {
5657
}
5758

5859
String browserName = capabilities.getBrowserName().toLowerCase();
59-
if (!BROWSER_OPTIONS.containsKey(browserName)) {
60-
return capabilities;
61-
}
62-
6360
String options = BROWSER_OPTIONS.get(browserName);
64-
if (!slotStereotype.asMap().containsKey(options)) {
65-
return capabilities;
61+
if (slotStereotype.asMap().containsKey(options) && capabilities.asMap().containsKey(options)) {
62+
63+
@SuppressWarnings("unchecked")
64+
Map<String, Object>
65+
stereotypeOptions =
66+
(Map<String, Object>) slotStereotype.asMap().get(options);
67+
68+
@SuppressWarnings("unchecked")
69+
Map<String, Object> capsOptions = (Map<String, Object>) capabilities.asMap().get(options);
70+
71+
// Merge top level capabilities, excluding browser specific options.
72+
// This will overwrite the browser options too, but it does not matter since we tackle it separately just after this.
73+
Map<String, Object> toReturn = new HashMap<>(slotStereotype.merge(capabilities).asMap());
74+
75+
// Merge browser specific stereotype and capabilities options
76+
switch (browserName.toLowerCase()) {
77+
case "chrome":
78+
case "microsoftedge":
79+
case "msedge":
80+
toReturn.put(options, mergeChromiumOptions(stereotypeOptions, capsOptions));
81+
break;
82+
case "firefox":
83+
toReturn.put(options, mergeFirefoxOptions(stereotypeOptions, capsOptions));
84+
break;
85+
default:
86+
break;
87+
}
88+
89+
return new ImmutableCapabilities(toReturn);
6690
}
6791

68-
@SuppressWarnings("unchecked")
69-
Map<String, Object> stereotypeOptions = (Map<String, Object>) slotStereotype.asMap().get(options);
92+
return slotStereotype.merge(capabilities);
93+
}
7094

71-
Map<String, Object> toReturn = new HashMap<>(capabilities.asMap());
95+
private Map<String, Object> mergeChromiumOptions(Map<String, Object> stereotypeOptions,
96+
Map<String, Object> capsOptions) {
97+
Map<String, Object> toReturn = new HashMap<>(stereotypeOptions);
7298

73-
if (!toReturn.containsKey(options)) {
74-
toReturn.put(options, stereotypeOptions);
75-
return new ImmutableCapabilities(toReturn);
99+
for (String name : capsOptions.keySet()) {
100+
if (name.equals("args")) {
101+
List<String> arguments =
102+
(List<String>) (capsOptions.getOrDefault(("args"), new ArrayList<>()));
103+
104+
List<String> stereotypeArguments =
105+
(List<String>) (stereotypeOptions.getOrDefault(("args"), new ArrayList<>()));
106+
107+
arguments.forEach(arg -> {
108+
if (!stereotypeArguments.contains(arg)) {
109+
stereotypeArguments.add(arg);
110+
}
111+
});
112+
toReturn.put("args", stereotypeArguments);
113+
}
114+
115+
if (name.equals("extensions")) {
116+
List<String> extensionList = (List<String>) (capsOptions.get(("extensions")));
117+
118+
List<String> stereotypeExtensions =
119+
(List<String>) (stereotypeOptions.getOrDefault(("extensions"), new ArrayList<>()));
120+
121+
extensionList.forEach(extension -> {
122+
if (!stereotypeExtensions.contains(extension)) {
123+
stereotypeExtensions.add(extension);
124+
}
125+
});
126+
127+
toReturn.put("extensions", stereotypeExtensions);
128+
}
129+
130+
if (!name.equals("binary") && !name.equals("extensions") && !name.equals("args")) {
131+
toReturn.put(name, capsOptions.get(name));
132+
}
76133
}
77134

78-
@SuppressWarnings("unchecked")
79-
Map<String, Object> capsOptions = (Map<String, Object>) toReturn.get(options);
80-
stereotypeOptions.forEach((key, value) -> {
81-
if (!capsOptions.containsKey(key)) {
82-
capsOptions.put(key, value);
135+
return toReturn;
136+
}
137+
138+
private Map<String, Object> mergeFirefoxOptions(Map<String, Object> stereotypeOptions,
139+
Map<String, Object> capsOptions) {
140+
Map<String, Object> toReturn = new HashMap<>(stereotypeOptions);
141+
142+
for (String name : capsOptions.keySet()) {
143+
if (name.equals("args")) {
144+
List<String>
145+
arguments =
146+
(List<String>) (capsOptions.getOrDefault(("args"), new ArrayList<>()));
147+
List<String> stereotypeArguments =
148+
(List<String>) (stereotypeOptions.getOrDefault(("args"), new ArrayList<>()));
149+
arguments.forEach(arg -> {
150+
if (!stereotypeArguments.contains(arg)) {
151+
stereotypeArguments.add(arg);
152+
}
153+
});
154+
toReturn.put("args", stereotypeArguments);
155+
}
156+
157+
if (name.equals("prefs")) {
158+
Map<String, Object> prefs =
159+
(Map<String, Object>) (capsOptions.getOrDefault(("prefs"), new HashMap<>()));
160+
161+
Map<String, Object> stereotypePrefs =
162+
(Map<String, Object>) (stereotypeOptions.getOrDefault(("prefs"), new HashMap<>()));
163+
164+
stereotypePrefs.putAll(prefs);
165+
toReturn.put("prefs", stereotypePrefs);
166+
}
167+
168+
if (name.equals("profile")) {
169+
String rawProfile =
170+
(String) capsOptions.get("profile");
171+
172+
toReturn.put("profile", rawProfile);
173+
}
174+
175+
if (name.equals("log")) {
176+
Map<String, Object> logLevelMap =
177+
(Map<String, Object>) capsOptions.get("log");
178+
toReturn.put("log", logLevelMap);
83179
}
84-
});
180+
}
85181

86-
return new ImmutableCapabilities(toReturn);
182+
return toReturn;
87183
}
88184
}

0 commit comments

Comments
 (0)