|
32 | 32 | import org.openqa.selenium.json.JsonOutput; |
33 | 33 | import org.openqa.selenium.remote.service.DriverService; |
34 | 34 |
|
| 35 | +import java.lang.reflect.Method; |
| 36 | +import java.lang.reflect.Modifier; |
35 | 37 | import java.net.URI; |
36 | 38 | import java.net.URISyntaxException; |
37 | 39 | import java.util.ArrayList; |
@@ -81,32 +83,90 @@ public Map<Capabilities, Collection<SessionFactory>> getSessionFactories( |
81 | 83 |
|
82 | 84 | Map<WebDriverInfo, Collection<SessionFactory>> allDrivers = discoverDrivers(maxSessions, factoryFactory); |
83 | 85 |
|
84 | | - // If drivers have been specified, use those. |
85 | | - List<String> drivers = config.getAll("node", "drivers").orElse(new ArrayList<>()).stream() |
86 | | - .map(String::toLowerCase) |
87 | | - .collect(Collectors.toList()); |
88 | | - |
89 | 86 | ImmutableMultimap.Builder<Capabilities, SessionFactory> sessionFactories = ImmutableMultimap.builder(); |
90 | 87 |
|
91 | | - if (!drivers.isEmpty()) { |
92 | | - allDrivers.entrySet().stream() |
93 | | - .filter(entry -> drivers.contains(entry.getKey().getDisplayName().toLowerCase())) |
94 | | - .sorted(Comparator.comparing(entry -> entry.getKey().getDisplayName().toLowerCase())) |
95 | | - .peek(this::report) |
96 | | - .forEach(entry -> sessionFactories.putAll(entry.getKey().getCanonicalCapabilities(), entry.getValue())); |
| 88 | + addDriverFactoriesFromConfig(sessionFactories); |
| 89 | + addSpecificDrivers(allDrivers, sessionFactories); |
| 90 | + addDetectedDrivers(allDrivers, sessionFactories); |
| 91 | + |
| 92 | + return sessionFactories.build().asMap(); |
| 93 | + } |
| 94 | + |
| 95 | + private void addDriverFactoriesFromConfig(ImmutableMultimap.Builder<Capabilities, SessionFactory> sessionFactories) { |
| 96 | + Optional<List<String>> additionalDriverFactories = config.getAll("node", "driver-factories"); |
| 97 | + if (!additionalDriverFactories.isPresent()) { |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + List<String> allConfigs = additionalDriverFactories.get(); |
| 102 | + if (allConfigs.size() % 2 != 0) { |
| 103 | + throw new ConfigException("Expected each driver class to be mapped to a config"); |
| 104 | + } |
| 105 | + |
| 106 | + for (int i = 0; i < allConfigs.size(); i++) { |
| 107 | + SessionFactory sessionFactory = createSessionFactory(allConfigs.get(i)); |
| 108 | + i++; |
| 109 | + if (i == allConfigs.size()) { |
| 110 | + throw new ConfigException("Unable to find JSON config"); |
| 111 | + } |
| 112 | + Capabilities stereotype = JSON.toType(allConfigs.get(i), Capabilities.class); |
| 113 | + |
| 114 | + sessionFactories.put(stereotype, sessionFactory); |
| 115 | + } |
| 116 | + } |
| 117 | + |
| 118 | + private SessionFactory createSessionFactory(String clazz) { |
| 119 | + LOG.fine(String.format("Creating %s as instance of %s", clazz, SessionFactory.class)); |
| 120 | + |
| 121 | + try { |
| 122 | + // Use the context class loader since this is what the `--ext` |
| 123 | + // flag modifies. |
| 124 | + Class<?> ClassClazz = Class.forName(clazz, true, Thread.currentThread().getContextClassLoader()); |
| 125 | + Method create = ClassClazz.getMethod("create", Config.class); |
| 126 | + |
| 127 | + if (!Modifier.isStatic(create.getModifiers())) { |
| 128 | + throw new IllegalArgumentException(String.format( |
| 129 | + "Class %s's `create(Config)` method must be static", clazz)); |
| 130 | + } |
| 131 | + |
| 132 | + if (!SessionFactory.class.isAssignableFrom(create.getReturnType())) { |
| 133 | + throw new IllegalArgumentException(String.format( |
| 134 | + "Class %s's `create(Config)` method must be static", clazz)); |
| 135 | + } |
97 | 136 |
|
98 | | - return sessionFactories.build().asMap(); |
| 137 | + return (SessionFactory) create.invoke(null, config); |
| 138 | + } catch (NoSuchMethodException e) { |
| 139 | + throw new IllegalArgumentException(String.format( |
| 140 | + "Class %s must have a static `create(Config)` method", clazz)); |
| 141 | + } catch (ReflectiveOperationException e) { |
| 142 | + throw new IllegalArgumentException("Unable to find class: " + clazz, e); |
99 | 143 | } |
| 144 | + } |
100 | 145 |
|
| 146 | + private void addDetectedDrivers( |
| 147 | + Map<WebDriverInfo, Collection<SessionFactory>> allDrivers, |
| 148 | + ImmutableMultimap.Builder<Capabilities, SessionFactory> sessionFactories) { |
101 | 149 | if (!config.getBool("node", "detect-drivers").orElse(false)) { |
102 | | - return sessionFactories.build().asMap(); |
| 150 | + return; |
103 | 151 | } |
104 | 152 |
|
105 | 153 | allDrivers.entrySet().stream() |
106 | 154 | .peek(this::report) |
107 | 155 | .forEach(entry -> sessionFactories.putAll(entry.getKey().getCanonicalCapabilities(), entry.getValue())); |
| 156 | + } |
108 | 157 |
|
109 | | - return sessionFactories.build().asMap(); |
| 158 | + private void addSpecificDrivers( |
| 159 | + Map<WebDriverInfo, Collection<SessionFactory>> allDrivers, |
| 160 | + ImmutableMultimap.Builder<Capabilities, SessionFactory> sessionFactories) { |
| 161 | + List<String> drivers = config.getAll("node", "drivers").orElse(new ArrayList<>()).stream() |
| 162 | + .map(String::toLowerCase) |
| 163 | + .collect(Collectors.toList()); |
| 164 | + |
| 165 | + allDrivers.entrySet().stream() |
| 166 | + .filter(entry -> drivers.contains(entry.getKey().getDisplayName().toLowerCase())) |
| 167 | + .sorted(Comparator.comparing(entry -> entry.getKey().getDisplayName().toLowerCase())) |
| 168 | + .peek(this::report) |
| 169 | + .forEach(entry -> sessionFactories.putAll(entry.getKey().getCanonicalCapabilities(), entry.getValue())); |
110 | 170 | } |
111 | 171 |
|
112 | 172 | private Map<WebDriverInfo, Collection<SessionFactory>> discoverDrivers( |
|
0 commit comments