Skip to content

Commit

Permalink
[java][bidi] Add BrowsingContext module commands
Browse files Browse the repository at this point in the history
  • Loading branch information
pujagani authored Dec 5, 2022
1 parent a6313cf commit 3832787
Show file tree
Hide file tree
Showing 7 changed files with 657 additions and 0 deletions.
1 change: 1 addition & 0 deletions java/src/org/openqa/selenium/bidi/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ java_library(
srcs = glob([
"*.java",
"log/*.java",
"browsingcontext/*.java"
]),
visibility = [
"//java/src/org/openqa/selenium/bidi:__subpackages__",
Expand Down
241 changes: 241 additions & 0 deletions java/src/org/openqa/selenium/bidi/browsingcontext/BrowsingContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
// 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 com.google.common.collect.ImmutableMap;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDi;
import org.openqa.selenium.bidi.Command;
import org.openqa.selenium.bidi.HasBiDi;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.json.JsonInput;
import org.openqa.selenium.json.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public class BrowsingContext {

private final String id;
private final BiDi bidi;
private static final String CONTEXT = "context";
private static final String RELOAD = "browsingContext.reload";
private static final String HANDLE_USER_PROMPT = "browsingContext.handleUserPrompt";

protected static final Type LIST_OF_BROWSING_CONTEXT_INFO =
new TypeToken<List<BrowsingContextInfo>>() {}.getType();

private final Function<JsonInput, String> browsingContextIdMapper = jsonInput -> {
Map<String, Object> result = jsonInput.read(Map.class);
return result.getOrDefault(CONTEXT, "").toString();
};

private final Function<JsonInput, NavigationResult> navigationInfoMapper =
jsonInput -> (NavigationResult) jsonInput.read(NavigationResult.class);

private final Function<JsonInput, List<BrowsingContextInfo>> browsingContextInfoListMapper =
jsonInput -> {
Map<String, Object> result = jsonInput.read(Map.class);
List<Object> contexts = (List<Object>) result.getOrDefault("contexts", new ArrayList<>());

if (contexts.isEmpty()) {
return new ArrayList<>();
}

Json json = new Json();
String dtr = json.toJson(contexts);

return json.toType(dtr, LIST_OF_BROWSING_CONTEXT_INFO);
};

public BrowsingContext(WebDriver driver, String id) {
Require.nonNull("WebDriver", driver);
Require.nonNull("Browsing Context id", id);

if (!(driver instanceof HasBiDi)) {
throw new IllegalArgumentException("WebDriver instance must support BiDi protocol");
}

this.bidi = ((HasBiDi) driver).getBiDi();
this.id = id;
}

public BrowsingContext(WebDriver driver, WindowType type) {
Require.nonNull("WebDriver", driver);

if (!(driver instanceof HasBiDi)) {
throw new IllegalArgumentException("WebDriver instance must support BiDi protocol");
}

this.bidi = ((HasBiDi) driver).getBiDi();
this.id = this.create(type);
}

public BrowsingContext(WebDriver driver, WindowType type, String referenceContextId) {
Require.nonNull("WebDriver", driver);
Require.nonNull("Reference browsing context id", referenceContextId);
if (!(driver instanceof HasBiDi)) {
throw new IllegalArgumentException("WebDriver instance must support BiDi protocol");
}

this.bidi = ((HasBiDi) driver).getBiDi();
this.id = this.create(type, referenceContextId);
}

public String getId() {
return this.id;
}

private String create(WindowType type) {
return this.bidi.send(
new Command<>("browsingContext.create",
ImmutableMap.of("type", type.toString()),
browsingContextIdMapper));
}

private String create(WindowType type, String referenceContext) {
return this.bidi.send(
new Command<>("browsingContext.create",
ImmutableMap.of("type", type.toString(),
"referenceContext", referenceContext),
browsingContextIdMapper));
}

public NavigationResult navigate(String url) {
return this.bidi.send(
new Command<>("browsingContext.navigate",
ImmutableMap.of(CONTEXT, id,
"url", url),
navigationInfoMapper));
}

public NavigationResult navigate(String url, ReadinessState readinessState) {
return this.bidi.send(
new Command<>("browsingContext.navigate",
ImmutableMap.of(CONTEXT, id,
"url", url,
"wait", readinessState.toString()),
navigationInfoMapper));
}

public List<BrowsingContextInfo> getTree() {
return this.bidi.send(
new Command<>("browsingContext.getTree",
ImmutableMap.of("root", id),
browsingContextInfoListMapper));
}

public List<BrowsingContextInfo> getTree(int maxDepth) {
return this.bidi.send(
new Command<>("browsingContext.getTree",
ImmutableMap.of("root", id,
"maxDepth", maxDepth),
browsingContextInfoListMapper));
}

public List<BrowsingContextInfo> getTopLevelContexts() {
return this.bidi.send(
new Command<>("browsingContext.getTree",
new HashMap<>(),
browsingContextInfoListMapper));
}

// Yet to be implemented by browser vendors
private void reload() {
this.bidi.send(new Command<>(RELOAD, ImmutableMap.of(CONTEXT, id)));
}

// Yet to be implemented by browser vendors
private void reload(boolean ignoreCache) {
this.bidi.send(new Command<>(
RELOAD,
ImmutableMap.of(CONTEXT, id,
"ignoreCache", ignoreCache)));
}

// Yet to be implemented by browser vendors
private void reload(ReadinessState readinessState) {
this.bidi.send(new Command<>(
RELOAD,
ImmutableMap.of(CONTEXT, id,
"wait", readinessState.toString())));
}

// Yet to be implemented by browser vendors
private void reload(boolean ignoreCache, ReadinessState readinessState) {
this.bidi.send(new Command<>(
RELOAD,
ImmutableMap.of(CONTEXT, id,
"ignoreCache", ignoreCache,
"wait", readinessState.toString())));
}

// Yet to be implemented by browser vendors
private void handleUserPrompt() {
this.bidi.send(new Command<>(
HANDLE_USER_PROMPT,
ImmutableMap.of(CONTEXT, id)));
}

// Yet to be implemented by browser vendors
private void handleUserPrompt(String userText) {
this.bidi.send(new Command<>(
HANDLE_USER_PROMPT,
ImmutableMap.of(CONTEXT, id,
"userText", userText)));

}

// Yet to be implemented by browser vendors
private void handleUserPrompt(boolean accept, String userText) {
this.bidi.send(new Command<>(
HANDLE_USER_PROMPT,
ImmutableMap.of(CONTEXT, id,
"accept", accept,
"userText", userText)));

}

// Yet to be implemented by browser vendors
private String captureScreenshot() {
return this.bidi.send(new Command<>(
HANDLE_USER_PROMPT,
ImmutableMap.of(CONTEXT, id),
jsonInput -> {
Map<String, Object> result = jsonInput.read(Map.class);
return (String) result.get("data");
}
));
}

public void close() {
// This might need more clean up actions once the behavior is defined.
// Specially when last tab or window is closed.
// Refer: https://github.com/w3c/webdriver-bidi/issues/187
this.bidi.send(new Command<>(
"browsingContext.close",
ImmutableMap.of(CONTEXT, id)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// 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 static org.openqa.selenium.bidi.browsingcontext.BrowsingContext.LIST_OF_BROWSING_CONTEXT_INFO;

import org.openqa.selenium.json.JsonInput;

import java.util.List;

public class BrowsingContextInfo {

private final String id;

private final String url;

private final List<BrowsingContextInfo> children;

private final String parentBrowsingContext;

public String getId() {
return id;
}

public String getUrl() {
return url;
}

public List<BrowsingContextInfo> getChildren() {
return children;
}

public String getParentBrowsingContext() {
return parentBrowsingContext;
}

public BrowsingContextInfo(
String id, String url, List<BrowsingContextInfo> children, String parentBrowsingContext) {
this.id = id;
this.url = url;
this.children = children;
this.parentBrowsingContext = parentBrowsingContext;
}

public static BrowsingContextInfo fromJson(JsonInput input) {
String id = null;
String url = null;
List<BrowsingContextInfo> children = null;
String parentBrowsingContext = null;

input.beginObject();
while (input.hasNext()) {
switch (input.nextName()) {
case "context":
id = input.read(String.class);
break;

case "url":
url = input.read(String.class);
break;

case "children":
children = input.read(LIST_OF_BROWSING_CONTEXT_INFO);
break;

case "parent":
parentBrowsingContext = input.read(String.class);
break;

default:
input.skipValue();
break;
}
}

input.endObject();

return new BrowsingContextInfo(id, url, children, parentBrowsingContext);
}
}
Loading

0 comments on commit 3832787

Please sign in to comment.