diff --git a/java/src/org/openqa/selenium/bidi/browsingcontext/DownloadInfo.java b/java/src/org/openqa/selenium/bidi/browsingcontext/DownloadInfo.java new file mode 100644 index 0000000000000..b5c6425026548 --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/browsingcontext/DownloadInfo.java @@ -0,0 +1,80 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.bidi.browsingcontext; + +import org.openqa.selenium.json.JsonInput; + +public class DownloadInfo extends NavigationInfo { + + private final String suggestedFilename; + + private DownloadInfo( + String browsingContextId, + String navigationId, + long timestamp, + String url, + String suggestedFilename) { + super(browsingContextId, navigationId, timestamp, url); + this.suggestedFilename = suggestedFilename; + } + + public static DownloadInfo fromJson(JsonInput input) { + String browsingContextId = null; + String navigationId = null; + long timestamp = 0; + String url = null; + String suggestedFilename = null; + + input.beginObject(); + while (input.hasNext()) { + switch (input.nextName()) { + case "context": + browsingContextId = input.read(String.class); + break; + + case "navigation": + navigationId = input.read(String.class); + break; + + case "timestamp": + timestamp = input.read(Long.class); + break; + + case "url": + url = input.read(String.class); + break; + + case "suggestedFilename": + suggestedFilename = input.read(String.class); + break; + + default: + input.skipValue(); + break; + } + } + + input.endObject(); + + return new DownloadInfo(browsingContextId, navigationId, timestamp, url, suggestedFilename); + } + + public String getSuggestedFilename() { + return suggestedFilename; + } +} diff --git a/java/src/org/openqa/selenium/bidi/browsingcontext/NavigationInfo.java b/java/src/org/openqa/selenium/bidi/browsingcontext/NavigationInfo.java index 73f24c56229bc..76ec8bb99aa79 100644 --- a/java/src/org/openqa/selenium/bidi/browsingcontext/NavigationInfo.java +++ b/java/src/org/openqa/selenium/bidi/browsingcontext/NavigationInfo.java @@ -33,7 +33,7 @@ public class NavigationInfo { private final String url; - private NavigationInfo( + protected NavigationInfo( String browsingContextId, String navigationId, long timestamp, String url) { this.browsingContextId = browsingContextId; this.navigationId = navigationId; diff --git a/java/src/org/openqa/selenium/bidi/module/BrowsingContextInspector.java b/java/src/org/openqa/selenium/bidi/module/BrowsingContextInspector.java index 4b08dc9c11906..4b7637e2af22f 100644 --- a/java/src/org/openqa/selenium/bidi/module/BrowsingContextInspector.java +++ b/java/src/org/openqa/selenium/bidi/module/BrowsingContextInspector.java @@ -29,6 +29,7 @@ import org.openqa.selenium.bidi.Event; import org.openqa.selenium.bidi.HasBiDi; import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo; +import org.openqa.selenium.bidi.browsingcontext.DownloadInfo; import org.openqa.selenium.bidi.browsingcontext.HistoryUpdated; import org.openqa.selenium.bidi.browsingcontext.NavigationInfo; import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed; @@ -61,6 +62,14 @@ public class BrowsingContextInspector implements AutoCloseable { } }; + private final Function, DownloadInfo> downloadWillBeginMapper = + params -> { + try (StringReader reader = new StringReader(JSON.toJson(params)); + JsonInput input = JSON.newInput(reader)) { + return input.read(DownloadInfo.class); + } + }; + private final Event browsingContextCreated = new Event<>("browsingContext.contextCreated", browsingContextInfoMapper); @@ -79,6 +88,9 @@ public class BrowsingContextInspector implements AutoCloseable { private final Set> navigationEventSet = new HashSet<>(); + private final Event downloadWillBeginEvent = + new Event<>("browsingContext.downloadWillBegin", downloadWillBeginMapper); + private final Event userPromptOpened = new Event<>( "browsingContext.userPromptOpened", @@ -151,8 +163,12 @@ public void onBrowsingContextLoaded(Consumer consumer) { addNavigationEventListener("browsingContext.load", consumer); } - public void onDownloadWillBegin(Consumer consumer) { - addNavigationEventListener("browsingContext.downloadWillBegin", consumer); + public void onDownloadWillBegin(Consumer consumer) { + if (browsingContextIds.isEmpty()) { + this.bidi.addListener(downloadWillBeginEvent, consumer); + } else { + this.bidi.addListener(browsingContextIds, downloadWillBeginEvent, consumer); + } } public void onNavigationAborted(Consumer consumer) { @@ -210,6 +226,7 @@ public void close() { this.bidi.clearListener(userPromptOpened); this.bidi.clearListener(userPromptClosed); this.bidi.clearListener(historyUpdated); + this.bidi.clearListener(downloadWillBeginEvent); navigationEventSet.forEach(this.bidi::clearListener); } diff --git a/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java b/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java index b9b98905cc6f8..f869cf78961df 100644 --- a/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java +++ b/java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextInspectorTest.java @@ -31,6 +31,7 @@ import org.openqa.selenium.bidi.module.BrowsingContextInspector; import org.openqa.selenium.testing.JupiterTestBase; import org.openqa.selenium.testing.NeedsFreshDriver; +import org.openqa.selenium.testing.NotYetImplemented; class BrowsingContextInspectorTest extends JupiterTestBase { @@ -231,4 +232,26 @@ void canListenToNavigationCommittedEvent() assertThat(navigationInfo.getUrl()).contains("/bidi/logEntryAdded.html"); } } + + @Test + @NeedsFreshDriver + @NotYetImplemented(FIREFOX) + void canListenToDownloadWillBeginEvent() + throws ExecutionException, InterruptedException, TimeoutException { + try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) { + CompletableFuture future = new CompletableFuture<>(); + + inspector.onDownloadWillBegin(future::complete); + + BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle()); + context.navigate(appServer.whereIs("/downloads/download.html"), ReadinessState.COMPLETE); + + driver.findElement(By.id("file-1")).click(); + + DownloadInfo downloadInfo = future.get(5, TimeUnit.SECONDS); + assertThat(downloadInfo.getBrowsingContextId()).isEqualTo(context.getId()); + assertThat(downloadInfo.getUrl()).contains("/downloads/file_1.txt"); + assertThat(downloadInfo.getSuggestedFilename()).isEqualTo("file_1.txt"); + } + } }