Skip to content

Commit 3a0b3ae

Browse files
authored
[java][BiDi] implement browser.setDownloadBehavior (#16646)
1 parent 8a0b916 commit 3a0b3ae

File tree

3 files changed

+240
-1
lines changed

3 files changed

+240
-1
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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.bidi.browser;
19+
20+
import java.nio.file.Path;
21+
import java.nio.file.Paths;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
26+
public class SetDownloadBehaviorParameters {
27+
private final Map<String, Object> map = new HashMap<>();
28+
29+
public SetDownloadBehaviorParameters(Boolean allowed, String destinationFolder) {
30+
this(allowed, destinationFolder != null ? Paths.get(destinationFolder) : null);
31+
}
32+
33+
public SetDownloadBehaviorParameters(Boolean allowed, Path destinationFolder) {
34+
if (allowed == null) {
35+
map.put("downloadBehavior", null);
36+
} else if (allowed) {
37+
if (destinationFolder == null) {
38+
throw new IllegalArgumentException("destinationFolder is required when allowed is true");
39+
}
40+
Map<String, String> behavior = new HashMap<>();
41+
behavior.put("type", "allowed");
42+
behavior.put("destinationFolder", destinationFolder.toAbsolutePath().toString());
43+
map.put("downloadBehavior", behavior);
44+
} else {
45+
if (destinationFolder != null) {
46+
throw new IllegalArgumentException(
47+
"destinationFolder should not be provided when allowed is false");
48+
}
49+
Map<String, String> behavior = new HashMap<>();
50+
behavior.put("type", "denied");
51+
map.put("downloadBehavior", behavior);
52+
}
53+
}
54+
55+
public SetDownloadBehaviorParameters userContexts(List<String> userContexts) {
56+
map.put("userContexts", userContexts);
57+
return this;
58+
}
59+
60+
public Map<String, Object> toMap() {
61+
return map;
62+
}
63+
}

java/src/org/openqa/selenium/bidi/module/Browser.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.openqa.selenium.bidi.Command;
2727
import org.openqa.selenium.bidi.HasBiDi;
2828
import org.openqa.selenium.bidi.browser.ClientWindowInfo;
29+
import org.openqa.selenium.bidi.browser.SetDownloadBehaviorParameters;
2930
import org.openqa.selenium.json.JsonInput;
3031

3132
public class Browser {
@@ -90,4 +91,8 @@ public void removeUserContext(String userContext) {
9091
public List<ClientWindowInfo> getClientWindows() {
9192
return bidi.send(new Command<>("browser.getClientWindows", Map.of(), clientWindowsInfoMapper));
9293
}
94+
95+
public void setDownloadBehavior(SetDownloadBehaviorParameters parameters) {
96+
bidi.send(new Command<>("browser.setDownloadBehavior", parameters.toMap()));
97+
}
9398
}

java/test/org/openqa/selenium/bidi/browser/BrowserCommandsTest.java

Lines changed: 172 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,28 @@
1717

1818
package org.openqa.selenium.bidi.browser;
1919

20-
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
import static org.openqa.selenium.testing.drivers.Browser.FIREFOX;
2122

23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
import java.time.Duration;
2226
import java.util.List;
27+
import java.util.stream.Collectors;
2328
import org.junit.jupiter.api.BeforeEach;
2429
import org.junit.jupiter.api.Test;
30+
import org.openqa.selenium.By;
31+
import org.openqa.selenium.TimeoutException;
32+
import org.openqa.selenium.WindowType;
33+
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
34+
import org.openqa.selenium.bidi.browsingcontext.CreateContextParameters;
35+
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
2536
import org.openqa.selenium.bidi.module.Browser;
37+
import org.openqa.selenium.io.TemporaryFilesystem;
38+
import org.openqa.selenium.support.ui.WebDriverWait;
2639
import org.openqa.selenium.testing.JupiterTestBase;
2740
import org.openqa.selenium.testing.NeedsFreshDriver;
41+
import org.openqa.selenium.testing.NotYetImplemented;
2842

2943
class BrowserCommandsTest extends JupiterTestBase {
3044

@@ -91,4 +105,161 @@ void canGetClientWindows() {
91105
assertThat(windowInfo.getHeight()).isGreaterThan(0);
92106
assertThat(windowInfo.isActive()).isIn(true, false);
93107
}
108+
109+
@Test
110+
@NeedsFreshDriver
111+
@NotYetImplemented(FIREFOX)
112+
void canSetDownloadBehaviorAllowed() throws Exception {
113+
Path tmpDir = TemporaryFilesystem.getDefaultTmpFS().createTempDir("downloads", "test").toPath();
114+
115+
try {
116+
browser.setDownloadBehavior(new SetDownloadBehaviorParameters(true, tmpDir));
117+
118+
BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
119+
String url = appServer.whereIs("downloads/download.html");
120+
context.navigate(url, ReadinessState.COMPLETE);
121+
122+
driver.findElement(By.id("file-1")).click();
123+
124+
new WebDriverWait(driver, Duration.ofSeconds(5))
125+
.until(
126+
d -> {
127+
try {
128+
return Files.list(tmpDir)
129+
.anyMatch(path -> path.getFileName().toString().equals("file_1.txt"));
130+
} catch (Exception e) {
131+
return false;
132+
}
133+
});
134+
135+
List<String> fileNames =
136+
Files.list(tmpDir)
137+
.map(path -> path.getFileName().toString())
138+
.collect(Collectors.toList());
139+
assertThat(fileNames).contains("file_1.txt");
140+
} finally {
141+
browser.setDownloadBehavior(new SetDownloadBehaviorParameters(null, (Path) null));
142+
TemporaryFilesystem.getDefaultTmpFS().deleteTempDir(tmpDir.toFile());
143+
}
144+
}
145+
146+
@Test
147+
@NeedsFreshDriver
148+
@NotYetImplemented(FIREFOX)
149+
void canSetDownloadBehaviorDenied() throws Exception {
150+
Path tmpDir = TemporaryFilesystem.getDefaultTmpFS().createTempDir("downloads", "test").toPath();
151+
152+
try {
153+
browser.setDownloadBehavior(new SetDownloadBehaviorParameters(false, (Path) null));
154+
155+
BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
156+
String url = appServer.whereIs("downloads/download.html");
157+
context.navigate(url, ReadinessState.COMPLETE);
158+
159+
driver.findElement(By.id("file-1")).click();
160+
161+
// Try to wait for file to be downloaded - should timeout
162+
try {
163+
new WebDriverWait(driver, Duration.ofSeconds(3), Duration.ofMillis(200))
164+
.until(
165+
d -> {
166+
try {
167+
return Files.list(tmpDir).findAny().isPresent();
168+
} catch (Exception e) {
169+
return false;
170+
}
171+
});
172+
173+
List<String> files =
174+
Files.list(tmpDir)
175+
.map(path -> path.getFileName().toString())
176+
.collect(Collectors.toList());
177+
throw new AssertionError("A file was downloaded unexpectedly: " + files);
178+
} catch (TimeoutException ignored) {
179+
}
180+
} finally {
181+
browser.setDownloadBehavior(new SetDownloadBehaviorParameters(null, (Path) null));
182+
TemporaryFilesystem.getDefaultTmpFS().deleteTempDir(tmpDir.toFile());
183+
}
184+
}
185+
186+
@Test
187+
@NeedsFreshDriver
188+
@NotYetImplemented(FIREFOX)
189+
void canSetDownloadBehaviorWithUserContext() throws Exception {
190+
Path tmpDir = TemporaryFilesystem.getDefaultTmpFS().createTempDir("downloads", "test").toPath();
191+
String userContext = browser.createUserContext();
192+
193+
try {
194+
BrowsingContext bc =
195+
new BrowsingContext(
196+
driver, new CreateContextParameters(WindowType.WINDOW).userContext(userContext));
197+
String contextId = bc.getId();
198+
199+
try {
200+
driver.switchTo().window(contextId);
201+
202+
browser.setDownloadBehavior(
203+
new SetDownloadBehaviorParameters(true, tmpDir).userContexts(List.of(userContext)));
204+
205+
String url = appServer.whereIs("downloads/download.html");
206+
bc.navigate(url, ReadinessState.COMPLETE);
207+
208+
driver.findElement(By.id("file-1")).click();
209+
210+
new WebDriverWait(driver, Duration.ofSeconds(5))
211+
.until(
212+
d -> {
213+
try {
214+
return Files.list(tmpDir)
215+
.anyMatch(path -> path.getFileName().toString().equals("file_1.txt"));
216+
} catch (Exception e) {
217+
return false;
218+
}
219+
});
220+
221+
List<String> files =
222+
Files.list(tmpDir)
223+
.map(path -> path.getFileName().toString())
224+
.collect(Collectors.toList());
225+
assertThat(files).contains("file_1.txt");
226+
227+
int initialFileCount = files.size();
228+
229+
browser.setDownloadBehavior(
230+
new SetDownloadBehaviorParameters(false, (Path) null)
231+
.userContexts(List.of(userContext)));
232+
233+
driver.findElement(By.id("file-2")).click();
234+
235+
try {
236+
new WebDriverWait(driver, Duration.ofSeconds(3), Duration.ofMillis(200))
237+
.until(
238+
d -> {
239+
try {
240+
long fileCount = Files.list(tmpDir).count();
241+
return fileCount > initialFileCount;
242+
} catch (Exception e) {
243+
return false;
244+
}
245+
});
246+
247+
List<String> filesAfter =
248+
Files.list(tmpDir)
249+
.map(path -> path.getFileName().toString())
250+
.collect(Collectors.toList());
251+
throw new AssertionError("A file was downloaded unexpectedly: " + filesAfter);
252+
} catch (TimeoutException ignored) {
253+
}
254+
} finally {
255+
browser.setDownloadBehavior(
256+
new SetDownloadBehaviorParameters(null, (Path) null)
257+
.userContexts(List.of(userContext)));
258+
bc.close();
259+
}
260+
} finally {
261+
browser.removeUserContext(userContext);
262+
TemporaryFilesystem.getDefaultTmpFS().deleteTempDir(tmpDir.toFile());
263+
}
264+
}
94265
}

0 commit comments

Comments
 (0)