Skip to content

Commit c525a11

Browse files
navin772diemol
andauthored
[java]: add websocket-port test and --connect-existing check (#15462)
* add check for ``--connect-existing` * add firefox test for BiDi multiple sessions * run `format.sh` * use `WebDriverBuilder` for driver * add `connectToExisting` and `withWebSocketPort` methods --------- Co-authored-by: Diego Molina <[email protected]>
1 parent 1c18799 commit c525a11

File tree

2 files changed

+114
-7
lines changed

2 files changed

+114
-7
lines changed

java/src/org/openqa/selenium/firefox/GeckoDriverService.java

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ public static class Builder
147147
private @Nullable FirefoxDriverLogLevel logLevel;
148148
private @Nullable Boolean logTruncate;
149149
private @Nullable File profileRoot;
150+
private @Nullable Integer marionettePort;
151+
private @Nullable Integer websocketPort;
150152

151153
@Override
152154
public int score(Capabilities capabilities) {
@@ -204,6 +206,31 @@ public GeckoDriverService.Builder withProfileRoot(@Nullable File root) {
204206
return this;
205207
}
206208

209+
/**
210+
* Configures geckodriver to connect to an existing Firefox instance via the specified
211+
* Marionette port.
212+
*
213+
* @param marionettePort The port where Marionette is listening on the existing Firefox
214+
* instance.
215+
* @return A self reference.
216+
*/
217+
public GeckoDriverService.Builder connectToExisting(int marionettePort) {
218+
this.marionettePort = marionettePort;
219+
return this;
220+
}
221+
222+
/**
223+
* Configures the WebSocket port for BiDi. A value of 0 will automatically allocate a free port.
224+
*
225+
* @param websocketPort The port to use for WebSocket communication, or 0 for automatic
226+
* allocation.
227+
* @return A self reference.
228+
*/
229+
public GeckoDriverService.Builder withWebSocketPort(@Nullable Integer websocketPort) {
230+
this.websocketPort = websocketPort;
231+
return this;
232+
}
233+
207234
@Override
208235
protected void loadSystemProperties() {
209236
parseLogOutput(GECKO_DRIVER_LOG_PROPERTY);
@@ -229,13 +256,27 @@ protected List<String> createArgs() {
229256
List<String> args = new ArrayList<>();
230257
args.add(String.format(Locale.ROOT, "--port=%d", getPort()));
231258

232-
int wsPort = PortProber.findFreePort();
233-
args.add(String.format("--websocket-port=%d", wsPort));
234-
235-
args.add("--allow-origins");
236-
args.add(String.format("http://127.0.0.1:%d", wsPort));
237-
args.add(String.format("http://localhost:%d", wsPort));
238-
args.add(String.format("http://[::1]:%d", wsPort));
259+
// Check if marionette port is specified via connectToExisting method
260+
if (marionettePort != null) {
261+
args.add("--connect-existing");
262+
args.add("--marionette-port");
263+
args.add(String.valueOf(marionettePort));
264+
} else {
265+
// Configure websocket port for BiDi communication
266+
if (websocketPort != null) {
267+
args.add("--websocket-port");
268+
args.add(String.valueOf(websocketPort));
269+
270+
args.add("--allow-origins");
271+
args.add(String.format("http://127.0.0.1:%d", websocketPort));
272+
args.add(String.format("http://localhost:%d", websocketPort));
273+
args.add(String.format("http://[::1]:%d", websocketPort));
274+
} else {
275+
// Use 0 to auto-allocate a free port
276+
args.add("--websocket-port");
277+
args.add("0");
278+
}
279+
}
239280

240281
if (logLevel != null) {
241282
args.add("--log");

java/test/org/openqa/selenium/firefox/FirefoxDriverConcurrentTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.openqa.selenium.ParallelTestRunner.Worker;
2929
import org.openqa.selenium.WebDriver;
3030
import org.openqa.selenium.WebElement;
31+
import org.openqa.selenium.bidi.BiDi;
3132
import org.openqa.selenium.testing.JupiterTestBase;
3233
import org.openqa.selenium.testing.drivers.WebDriverBuilder;
3334

@@ -164,4 +165,69 @@ void shouldBeAbleToUseTheSameProfileMoreThanOnce() {
164165
if (two != null) two.quit();
165166
}
166167
}
168+
169+
@Test
170+
void multipleFirefoxInstancesWithBiDiEnabledCanRunSimultaneously() {
171+
// Create two Firefox instances with BiDi enabled, should use different ports
172+
FirefoxOptions options1 = new FirefoxOptions().enableBiDi();
173+
FirefoxOptions options2 = new FirefoxOptions().enableBiDi();
174+
175+
WebDriver driver1 = null;
176+
WebDriver driver2 = null;
177+
178+
try {
179+
driver1 = new WebDriverBuilder().get(options1);
180+
BiDi biDi1 = ((FirefoxDriver) driver1).getBiDi();
181+
assertThat(biDi1).isNotNull();
182+
183+
// Extract the BiDi websocket URL and port for the first instance
184+
String webSocketUrl1 =
185+
(String) ((FirefoxDriver) driver1).getCapabilities().getCapability("webSocketUrl");
186+
String port1 = webSocketUrl1.replaceAll("^ws://[^:]+:(\\d+)/.*$", "$1");
187+
188+
driver2 = new WebDriverBuilder().get(options2);
189+
BiDi biDi2 = ((FirefoxDriver) driver2).getBiDi();
190+
assertThat(biDi2).isNotNull();
191+
192+
// Extract the BiDi websocket URL and port for the second instance
193+
String webSocketUrl2 =
194+
(String) ((FirefoxDriver) driver2).getCapabilities().getCapability("webSocketUrl");
195+
String port2 = webSocketUrl2.replaceAll("^ws://[^:]+:(\\d+)/.*$", "$1");
196+
197+
// Verify that the ports are different
198+
assertThat(port1).isNotEqualTo(port2);
199+
} finally {
200+
// Clean up
201+
if (driver1 != null) {
202+
driver1.quit();
203+
}
204+
if (driver2 != null) {
205+
driver2.quit();
206+
}
207+
}
208+
}
209+
210+
@Test
211+
void geckoDriverServiceConnectToExistingFirefox() {
212+
GeckoDriverService.Builder builder = new GeckoDriverService.Builder();
213+
214+
// Test connectToExisting method
215+
builder.connectToExisting(2829);
216+
GeckoDriverService service = builder.build();
217+
218+
assertThat(service).isNotNull();
219+
service.stop();
220+
}
221+
222+
@Test
223+
void geckoDriverServiceCustomWebSocketPort() {
224+
GeckoDriverService.Builder builder = new GeckoDriverService.Builder();
225+
226+
// Test withWebSocketPort method
227+
builder.withWebSocketPort(9225);
228+
GeckoDriverService service = builder.build();
229+
230+
assertThat(service).isNotNull();
231+
service.stop();
232+
}
167233
}

0 commit comments

Comments
 (0)