Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/java/src/org/openqa/selenium/Platform.java
3992 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.Arrays;
21
import java.util.Locale;
22
import java.util.regex.Matcher;
23
import java.util.regex.Pattern;
24
import org.jspecify.annotations.Nullable;
25
26
/**
27
* Represents the known and supported Platforms that WebDriver runs on. This is pretty close to the
28
* Operating System, but differs slightly, because this class is used to extract information such as
29
* program locations and line endings.
30
*/
31
// Useful URLs:
32
// http://hg.openjdk.java.net/jdk7/modules/jdk/file/a37326fa7f95/src/windows/native/java/lang/java_props_md.c
33
public enum Platform {
34
35
/** Never returned, but can be used to request a browser running on any version of Windows. */
36
WINDOWS("windows") {
37
@Override
38
public @Nullable Platform family() {
39
return null;
40
}
41
42
@Override
43
public String toString() {
44
return "windows";
45
}
46
},
47
48
/**
49
* For versions of Windows that "feel like" Windows XP. These are ones that store files in
50
* "\Program Files\" and documents under "\\documents and settings\\username"
51
*/
52
XP("Windows Server 2003", "xp", "windows", "winnt", "windows_nt", "windows nt") {
53
@Override
54
public @Nullable Platform family() {
55
return WINDOWS;
56
}
57
58
@Override
59
public String toString() {
60
return "Windows XP";
61
}
62
},
63
64
/** For versions of Windows that "feel like" Windows Vista. */
65
VISTA("windows vista", "Windows Server 2008") {
66
@Override
67
public @Nullable Platform family() {
68
return WINDOWS;
69
}
70
71
@Override
72
public String toString() {
73
return "Windows Vista";
74
}
75
},
76
77
WIN7("windows 7", "win7") {
78
@Override
79
public @Nullable Platform family() {
80
return WINDOWS;
81
}
82
83
@Override
84
public String toString() {
85
return "Windows 7";
86
}
87
},
88
89
/** For versions of Windows that "feel like" Windows 8. */
90
WIN8("Windows Server 2012", "windows 8", "win8") {
91
@Override
92
public @Nullable Platform family() {
93
return WINDOWS;
94
}
95
96
@Override
97
public String toString() {
98
return "Windows 8";
99
}
100
},
101
102
WIN8_1("windows 8.1", "win8.1") {
103
@Override
104
public @Nullable Platform family() {
105
return WINDOWS;
106
}
107
108
@Override
109
public String toString() {
110
return "Windows 8.1";
111
}
112
},
113
114
WIN10("windows 10", "win10") {
115
@Override
116
public @Nullable Platform family() {
117
return WINDOWS;
118
}
119
120
@Override
121
public String toString() {
122
return "Windows 10";
123
}
124
},
125
126
WIN11("windows 11", "win11") {
127
@Override
128
public @Nullable Platform family() {
129
return WINDOWS;
130
}
131
132
@Override
133
public String toString() {
134
return "Windows 11";
135
}
136
},
137
138
MAC("mac", "darwin", "macOS", "mac os x", "os x") {
139
@Override
140
public @Nullable Platform family() {
141
return null;
142
}
143
144
@Override
145
public String toString() {
146
return "mac";
147
}
148
},
149
150
SNOW_LEOPARD("snow leopard", "os x 10.6", "macos 10.6") {
151
@Override
152
public @Nullable Platform family() {
153
return MAC;
154
}
155
156
@Override
157
public String toString() {
158
return "OS X 10.6";
159
}
160
},
161
162
MOUNTAIN_LION("mountain lion", "os x 10.8", "macos 10.8") {
163
@Override
164
public @Nullable Platform family() {
165
return MAC;
166
}
167
168
@Override
169
public String toString() {
170
return "OS X 10.8";
171
}
172
},
173
174
MAVERICKS("mavericks", "os x 10.9", "macos 10.9") {
175
@Override
176
public @Nullable Platform family() {
177
return MAC;
178
}
179
180
@Override
181
public String toString() {
182
return "OS X 10.9";
183
}
184
},
185
186
YOSEMITE("yosemite", "os x 10.10", "macos 10.10") {
187
@Override
188
public @Nullable Platform family() {
189
return MAC;
190
}
191
192
@Override
193
public String toString() {
194
return "OS X 10.10";
195
}
196
},
197
198
EL_CAPITAN("el capitan", "os x 10.11", "macos 10.11") {
199
@Override
200
public @Nullable Platform family() {
201
return MAC;
202
}
203
204
@Override
205
public String toString() {
206
return "OS X 10.11";
207
}
208
},
209
210
SIERRA("sierra", "os x 10.12", "macos 10.12") {
211
@Override
212
public @Nullable Platform family() {
213
return MAC;
214
}
215
216
@Override
217
public String toString() {
218
return "macOS 10.12";
219
}
220
},
221
222
HIGH_SIERRA("high sierra", "os x 10.13", "macos 10.13") {
223
@Override
224
public @Nullable Platform family() {
225
return MAC;
226
}
227
228
@Override
229
public String toString() {
230
return "macOS 10.13";
231
}
232
},
233
234
MOJAVE("mojave", "os x 10.14", "macos 10.14") {
235
@Override
236
public @Nullable Platform family() {
237
return MAC;
238
}
239
240
@Override
241
public String toString() {
242
return "macOS 10.14";
243
}
244
},
245
246
CATALINA("catalina", "os x 10.15", "macos 10.15") {
247
@Override
248
public @Nullable Platform family() {
249
return MAC;
250
}
251
252
@Override
253
public String toString() {
254
return "macOS 10.15";
255
}
256
},
257
258
BIG_SUR("big sur", "os x 11.0", "macos 11.0") {
259
@Override
260
public @Nullable Platform family() {
261
return MAC;
262
}
263
264
@Override
265
public String toString() {
266
return "macOS 11.0";
267
}
268
},
269
270
MONTEREY("monterey", "os x 12.0", "macos 12.0") {
271
@Override
272
public @Nullable Platform family() {
273
return MAC;
274
}
275
276
@Override
277
public String toString() {
278
return "macOS 12.0";
279
}
280
},
281
282
VENTURA("ventura", "os x 13.0", "macos 13.0") {
283
@Override
284
public @Nullable Platform family() {
285
return MAC;
286
}
287
288
@Override
289
public String toString() {
290
return "macOS 13.0";
291
}
292
},
293
294
SONOMA("sonoma", "os x 14.0", "macos 14.0") {
295
@Override
296
public @Nullable Platform family() {
297
return MAC;
298
}
299
300
@Override
301
public String toString() {
302
return "macOS 14.0";
303
}
304
},
305
306
SEQUOIA("sequoia", "os x 15.0", "macos 15.0") {
307
@Override
308
public @Nullable Platform family() {
309
return MAC;
310
}
311
312
@Override
313
public String toString() {
314
return "macOS 15.0";
315
}
316
},
317
318
/** Many platforms have UNIX traits, amongst them LINUX, Solaris and BSD. */
319
UNIX("solaris", "bsd") {
320
@Override
321
public @Nullable Platform family() {
322
return null;
323
}
324
},
325
326
LINUX("linux") {
327
@Override
328
public @Nullable Platform family() {
329
return UNIX;
330
}
331
332
@Override
333
public String toString() {
334
return "linux";
335
}
336
},
337
338
ANDROID("android", "dalvik") {
339
@Override
340
public @Nullable Platform family() {
341
return null;
342
}
343
},
344
345
IOS("iOS") {
346
@Override
347
public @Nullable Platform family() {
348
return null;
349
}
350
},
351
352
/** Never returned, but can be used to request a browser running on any operating system. */
353
ANY("") {
354
@Override
355
public @Nullable Platform family() {
356
return ANY;
357
}
358
359
@Override
360
public boolean is(Platform compareWith) {
361
return this == compareWith;
362
}
363
364
@Override
365
public String toString() {
366
return "any";
367
}
368
};
369
370
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+).*");
371
private static @Nullable Platform current;
372
private final String[] partOfOsName;
373
private int minorVersion = 0;
374
private int majorVersion = 0;
375
376
Platform(String... partOfOsName) {
377
this.partOfOsName = partOfOsName;
378
}
379
380
/**
381
* Get current platform (not necessarily the same as operating system).
382
*
383
* @return current platform
384
*/
385
public static Platform getCurrent() {
386
if (current == null) {
387
current = extractFromSysProperty(System.getProperty("os.name"));
388
389
String version = System.getProperty("os.version", "0.0.0");
390
int major = 0;
391
int minor = 0;
392
393
final Matcher matcher = VERSION_PATTERN.matcher(version);
394
if (matcher.matches()) {
395
try {
396
major = Integer.parseInt(matcher.group(1));
397
minor = Integer.parseInt(matcher.group(2));
398
} catch (NumberFormatException e) {
399
// These things happen
400
}
401
}
402
403
current.majorVersion = major;
404
current.minorVersion = minor;
405
}
406
return current;
407
}
408
409
/**
410
* Extracts platforms based on system properties in Java and uses a heuristic to determine the
411
* most likely operating system. If unable to determine the operating system, it will default to
412
* UNIX.
413
*
414
* @param osName the operating system name to determine the platform of
415
* @return the most likely platform based on given operating system name
416
*/
417
public static Platform extractFromSysProperty(String osName) {
418
return extractFromSysProperty(osName, System.getProperty("os.version"));
419
}
420
421
/**
422
* Extracts platforms based on system properties in Java and uses a heuristic to determine the
423
* most likely operating system. If unable to determine the operating system, it will default to
424
* UNIX.
425
*
426
* @param osName the operating system name to determine the platform of
427
* @param osVersion the operating system version to determine the platform of
428
* @return the most likely platform based on given operating system name and version
429
*/
430
public static Platform extractFromSysProperty(String osName, String osVersion) {
431
osName = osName.toLowerCase(Locale.ENGLISH);
432
// os.name for android is linux
433
if ("dalvik".equalsIgnoreCase(System.getProperty("java.vm.name"))) {
434
return Platform.ANDROID;
435
}
436
// Windows 8 can't be detected by osName alone
437
if (osVersion.equals("6.2") && osName.startsWith("windows nt")) {
438
return WIN8;
439
}
440
// Windows 8 can't be detected by osName alone
441
if (osVersion.equals("6.3") && osName.startsWith("windows nt")) {
442
return WIN8_1;
443
}
444
Platform mostLikely = UNIX;
445
String previousMatch = null;
446
for (Platform os : Platform.values()) {
447
for (String matcher : os.partOfOsName) {
448
if (matcher.isEmpty()) {
449
continue;
450
}
451
matcher = matcher.toLowerCase(Locale.ENGLISH);
452
if (os.isExactMatch(osName, matcher)) {
453
return os;
454
}
455
if (os.isCurrentPlatform(osName, matcher) && isBetterMatch(previousMatch, matcher)) {
456
previousMatch = matcher;
457
mostLikely = os;
458
}
459
}
460
}
461
462
// Default to assuming we're on a UNIX variant (including LINUX)
463
return mostLikely;
464
}
465
466
/**
467
* Gets a platform with the name matching the parameter.
468
*
469
* @param name the platform name
470
* @return the Platform enum value matching the parameter
471
*/
472
public static Platform fromString(String name) {
473
for (Platform platform : values()) {
474
if (platform.toString().equalsIgnoreCase(name)) {
475
return platform;
476
}
477
}
478
479
for (Platform os : Platform.values()) {
480
for (String matcher : os.partOfOsName) {
481
if (name.equalsIgnoreCase(matcher)) {
482
return os;
483
}
484
}
485
}
486
throw new WebDriverException("Unrecognized platform: " + name);
487
}
488
489
/**
490
* Decides whether the previous match is better or not than the current match. If previous match
491
* is null, the newer match is always better.
492
*
493
* @param previous the previous match
494
* @param matcher the newer match
495
* @return true if newer match is better, false otherwise
496
*/
497
private static boolean isBetterMatch(@Nullable String previous, String matcher) {
498
return previous == null || matcher.length() >= previous.length();
499
}
500
501
public String[] getPartOfOsName() {
502
return Arrays.copyOf(partOfOsName, partOfOsName.length);
503
}
504
505
/**
506
* Heuristic for comparing two platforms. If platforms (which is not the same thing as operating
507
* systems) are found to be approximately similar in nature, this will return true. For instance
508
* the LINUX platform is similar to UNIX, and will give a positive result if compared.
509
*
510
* @param compareWith the platform to compare with
511
* @return true if platforms are approximately similar, false otherwise
512
*/
513
public boolean is(Platform compareWith) {
514
return
515
// Any platform is itself
516
this == compareWith
517
||
518
// Any platform is also ANY platform
519
compareWith == ANY
520
||
521
// And any Platform which is not a platform type belongs to the same family
522
(this.family() != null && this.family().is(compareWith));
523
}
524
525
/**
526
* Returns a platform that represents a family for the current platform. For instance the LINUX if
527
* a part of the UNIX family, the XP is a part of the WINDOWS family.
528
*
529
* @return the family platform for the current one, or {@code null} if this {@code Platform}
530
* represents a platform family (such as Windows, or MacOS)
531
*/
532
public abstract @Nullable Platform family();
533
534
private boolean isCurrentPlatform(String osName, String matchAgainst) {
535
return osName.contains(matchAgainst);
536
}
537
538
private boolean isExactMatch(String osName, String matchAgainst) {
539
return matchAgainst.equals(osName);
540
}
541
542
/**
543
* Returns the major version of this platform.
544
*
545
* @return the major version of specified platform
546
*/
547
public int getMajorVersion() {
548
return majorVersion;
549
}
550
551
/**
552
* Returns the minor version of this platform.
553
*
554
* @return the minor version of specified platform
555
*/
556
public int getMinorVersion() {
557
return minorVersion;
558
}
559
}
560
561