Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/java/src/org/openqa/selenium/MutableCapabilities.java
1865 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
package org.openqa.selenium;
19
20
import java.util.Collections;
21
import java.util.HashSet;
22
import java.util.Map;
23
import java.util.Set;
24
import java.util.TreeMap;
25
import org.jspecify.annotations.NullMarked;
26
import org.jspecify.annotations.Nullable;
27
import org.openqa.selenium.internal.Require;
28
29
@NullMarked
30
public class MutableCapabilities implements Capabilities {
31
32
private static final Set<String> OPTION_KEYS;
33
34
static {
35
HashSet<String> keys = new HashSet<>();
36
keys.add("goog:chromeOptions");
37
keys.add("ms:edgeOptions");
38
keys.add("moz:firefoxOptions");
39
keys.add("se:ieOptions");
40
OPTION_KEYS = Collections.unmodifiableSet(keys);
41
}
42
43
private final Map<String, Object> caps = new TreeMap<>();
44
45
public MutableCapabilities() {
46
// no-arg constructor
47
}
48
49
public MutableCapabilities(Capabilities other) {
50
this(other.asMap());
51
}
52
53
public MutableCapabilities(Map<String, ?> capabilities) {
54
capabilities.forEach(
55
(key, value) -> {
56
if (value != null) {
57
setCapability(key, value);
58
}
59
});
60
}
61
62
/**
63
* Merge two {@link Capabilities} together and return the union of the two as a new {@link
64
* Capabilities} instance. Capabilities from {@code other} will override those in {@code this}.
65
*/
66
@Override
67
public MutableCapabilities merge(Capabilities other) {
68
MutableCapabilities newInstance = new MutableCapabilities(this);
69
if (other != null) {
70
other.asMap().forEach(newInstance::setCapability);
71
}
72
return newInstance;
73
}
74
75
public void setCapability(String capabilityName, boolean value) {
76
setCapability(capabilityName, (Object) value);
77
}
78
79
public void setCapability(String capabilityName, String value) {
80
setCapability(capabilityName, (Object) value);
81
}
82
83
public void setCapability(String capabilityName, Platform value) {
84
setCapability(capabilityName, (Object) value);
85
}
86
87
public void setCapability(String key, @Nullable Object value) {
88
Require.nonNull("Capability name", key);
89
90
// We have to special-case some keys and values because of the popular idiom of calling
91
// something like "capabilities.setCapability(SafariOptions.CAPABILITY, new SafariOptions());"
92
// and this is no longer needed as options are capabilities. There will be a large amount of
93
// legacy code that will always try and follow this pattern, however.
94
if (OPTION_KEYS.contains(key) && value instanceof Capabilities) {
95
((Capabilities) value).asMap().forEach(this::setCapability);
96
return;
97
}
98
99
if (value == null) {
100
caps.remove(key);
101
return;
102
}
103
104
SharedCapabilitiesMethods.setCapability(caps, key, value);
105
}
106
107
@Override
108
public Map<String, Object> asMap() {
109
return Collections.unmodifiableMap(caps);
110
}
111
112
@Override
113
public @Nullable Object getCapability(String capabilityName) {
114
return caps.get(capabilityName);
115
}
116
117
@Override
118
public Set<String> getCapabilityNames() {
119
return Collections.unmodifiableSet(caps.keySet());
120
}
121
122
public Map<String, Object> toJson() {
123
return asMap();
124
}
125
126
@Override
127
public int hashCode() {
128
return SharedCapabilitiesMethods.hashCode(this);
129
}
130
131
@Override
132
public boolean equals(@Nullable Object o) {
133
if (!(o instanceof Capabilities)) {
134
return false;
135
}
136
return SharedCapabilitiesMethods.equals(this, (Capabilities) o);
137
}
138
139
@Override
140
public String toString() {
141
return SharedCapabilitiesMethods.toString(this);
142
}
143
}
144
145