diff --git a/java/src/org/openqa/selenium/bidi/module/BUILD.bazel b/java/src/org/openqa/selenium/bidi/module/BUILD.bazel index 13bd4b6452418..bb8e51cb62a9d 100644 --- a/java/src/org/openqa/selenium/bidi/module/BUILD.bazel +++ b/java/src/org/openqa/selenium/bidi/module/BUILD.bazel @@ -25,6 +25,7 @@ java_library( "//java/src/org/openqa/selenium/bidi/permissions", "//java/src/org/openqa/selenium/bidi/script", "//java/src/org/openqa/selenium/bidi/storage", + "//java/src/org/openqa/selenium/bidi/webextension", "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote/http", artifact("com.google.auto.service:auto-service-annotations"), diff --git a/java/src/org/openqa/selenium/bidi/webextension/BUILD.bazel b/java/src/org/openqa/selenium/bidi/webextension/BUILD.bazel new file mode 100644 index 0000000000000..cf1199d8fa9fc --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/BUILD.bazel @@ -0,0 +1,25 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") +load("//java:defs.bzl", "java_library") + +java_library( + name = "webextension", + srcs = glob( + [ + "*.java", + ], + ), + visibility = [ + "//java/src/org/openqa/selenium/bidi:__subpackages__", + "//java/src/org/openqa/selenium/firefox:__subpackages__", + "//java/src/org/openqa/selenium/remote:__pkg__", + "//java/test/org/openqa/selenium/bidi:__subpackages__", + "//java/test/org/openqa/selenium/grid:__subpackages__", + ], + deps = [ + "//java/src/org/openqa/selenium:core", + "//java/src/org/openqa/selenium/bidi", + "//java/src/org/openqa/selenium/json", + "//java/src/org/openqa/selenium/remote/http", + artifact("com.google.auto.service:auto-service-annotations"), + ], +) diff --git a/java/src/org/openqa/selenium/bidi/webextension/ExtensionArchivePath.java b/java/src/org/openqa/selenium/bidi/webextension/ExtensionArchivePath.java new file mode 100644 index 0000000000000..465aa08f740b1 --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/ExtensionArchivePath.java @@ -0,0 +1,34 @@ +// 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.webextension; + +import java.util.Map; + +public class ExtensionArchivePath extends ExtensionData { + private final String path; + + public ExtensionArchivePath(String path) { + this.path = path; + } + + @Override + public Map toMap() { + String type = "archivePath"; + return Map.of("extensionData", Map.of("type", type, "path", path)); + } +} diff --git a/java/src/org/openqa/selenium/bidi/webextension/ExtensionBase64Encoded.java b/java/src/org/openqa/selenium/bidi/webextension/ExtensionBase64Encoded.java new file mode 100644 index 0000000000000..06a7e49dc0d0d --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/ExtensionBase64Encoded.java @@ -0,0 +1,34 @@ +// 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.webextension; + +import java.util.Map; + +public class ExtensionBase64Encoded extends ExtensionData { + private final String value; + + public ExtensionBase64Encoded(String value) { + this.value = value; + } + + @Override + public Map toMap() { + String type = "base64"; + return Map.of("extensionData", Map.of("type", type, "value", value)); + } +} diff --git a/java/src/org/openqa/selenium/bidi/webextension/ExtensionData.java b/java/src/org/openqa/selenium/bidi/webextension/ExtensionData.java new file mode 100644 index 0000000000000..61347c5fa5eff --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/ExtensionData.java @@ -0,0 +1,24 @@ +// 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.webextension; + +import java.util.Map; + +public abstract class ExtensionData { + public abstract Map toMap(); +} diff --git a/java/src/org/openqa/selenium/bidi/webextension/ExtensionPath.java b/java/src/org/openqa/selenium/bidi/webextension/ExtensionPath.java new file mode 100644 index 0000000000000..1839ab5c3e0d1 --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/ExtensionPath.java @@ -0,0 +1,34 @@ +// 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.webextension; + +import java.util.Map; + +public class ExtensionPath extends ExtensionData { + private final String path; + + public ExtensionPath(String path) { + this.path = path; + } + + @Override + public Map toMap() { + String type = "path"; + return Map.of("extensionData", Map.of("type", type, "path", path)); + } +} diff --git a/java/src/org/openqa/selenium/bidi/webextension/InstallExtensionParameters.java b/java/src/org/openqa/selenium/bidi/webextension/InstallExtensionParameters.java new file mode 100644 index 0000000000000..7c5df23509e86 --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/InstallExtensionParameters.java @@ -0,0 +1,31 @@ +// 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.webextension; + +public class InstallExtensionParameters { + + private final ExtensionData extensionData; + + public InstallExtensionParameters(ExtensionData extensionData) { + this.extensionData = extensionData; + } + + public ExtensionData getExtensionData() { + return extensionData; + } +} diff --git a/java/src/org/openqa/selenium/bidi/webextension/UninstallExtensionParameters.java b/java/src/org/openqa/selenium/bidi/webextension/UninstallExtensionParameters.java new file mode 100644 index 0000000000000..763997c06bb73 --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/UninstallExtensionParameters.java @@ -0,0 +1,29 @@ +// 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.webextension; + +import java.util.Map; + +public class UninstallExtensionParameters { + + public final Map extension; + + public UninstallExtensionParameters(Map extension) { + this.extension = extension; + } +} diff --git a/java/src/org/openqa/selenium/bidi/webextension/WebExtension.java b/java/src/org/openqa/selenium/bidi/webextension/WebExtension.java new file mode 100644 index 0000000000000..99e8142e55054 --- /dev/null +++ b/java/src/org/openqa/selenium/bidi/webextension/WebExtension.java @@ -0,0 +1,50 @@ +// 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.webextension; + +import java.util.Map; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.bidi.BiDi; +import org.openqa.selenium.bidi.Command; +import org.openqa.selenium.bidi.HasBiDi; +import org.openqa.selenium.internal.Require; + +public class WebExtension { + private final BiDi bidi; + + public WebExtension(WebDriver driver) { + Require.nonNull("WebDriver", driver); + + if (!(driver instanceof HasBiDi)) { + throw new IllegalArgumentException("WebDriver instance must support BiDi protocol"); + } + + this.bidi = ((HasBiDi) driver).getBiDi(); + } + + public Map install(InstallExtensionParameters parameters) { + Require.nonNull("Install parameters", parameters); + return bidi.send( + new Command<>("webExtension.install", parameters.getExtensionData().toMap(), Map.class)); + } + + public Map uninstall(UninstallExtensionParameters parameters) { + Require.nonNull("Uninstall parameters", parameters); + return bidi.send(new Command<>("webExtension.uninstall", parameters.extension, Map.class)); + } +} diff --git a/java/src/org/openqa/selenium/remote/BUILD.bazel b/java/src/org/openqa/selenium/remote/BUILD.bazel index 0834343da717f..d5eabf080dcea 100644 --- a/java/src/org/openqa/selenium/remote/BUILD.bazel +++ b/java/src/org/openqa/selenium/remote/BUILD.bazel @@ -34,6 +34,7 @@ java_export( "//java/src/org/openqa/selenium/bidi/permissions", "//java/src/org/openqa/selenium/bidi/script", "//java/src/org/openqa/selenium/bidi/storage", + "//java/src/org/openqa/selenium/bidi/webextension", "//java/src/org/openqa/selenium/devtools", "//java/src/org/openqa/selenium/devtools:augmenter", "//java/src/org/openqa/selenium/os", diff --git a/java/test/org/openqa/selenium/bidi/input/BUILD.bazel b/java/test/org/openqa/selenium/bidi/input/BUILD.bazel index 690d36b9a0de4..b0a129cd85bd6 100644 --- a/java/test/org/openqa/selenium/bidi/input/BUILD.bazel +++ b/java/test/org/openqa/selenium/bidi/input/BUILD.bazel @@ -24,6 +24,7 @@ java_selenium_test_suite( "//java/src/org/openqa/selenium/bidi/network", "//java/src/org/openqa/selenium/bidi/permissions", "//java/src/org/openqa/selenium/bidi/script", + "//java/src/org/openqa/selenium/bidi/webextension", "//java/src/org/openqa/selenium/chrome", "//java/src/org/openqa/selenium/firefox", "//java/src/org/openqa/selenium/json", diff --git a/java/test/org/openqa/selenium/bidi/webextension/BUILD.bazel b/java/test/org/openqa/selenium/bidi/webextension/BUILD.bazel new file mode 100644 index 0000000000000..ae482e778df94 --- /dev/null +++ b/java/test/org/openqa/selenium/bidi/webextension/BUILD.bazel @@ -0,0 +1,37 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") +load("//java:defs.bzl", "JUNIT5_DEPS", "java_selenium_test_suite") + +java_selenium_test_suite( + name = "large-tests", + size = "large", + srcs = glob(["*Test.java"]), + browsers = [ + "firefox", + ], + tags = [ + "selenium-remote", + ], + deps = [ + "//java/src/org/openqa/selenium/bidi", + "//java/src/org/openqa/selenium/bidi/browsingcontext", + "//java/src/org/openqa/selenium/bidi/log", + "//java/src/org/openqa/selenium/bidi/module", + "//java/src/org/openqa/selenium/bidi/network", + "//java/src/org/openqa/selenium/bidi/script", + "//java/src/org/openqa/selenium/bidi/webextension", + "//java/src/org/openqa/selenium/firefox", + "//java/src/org/openqa/selenium/grid/security", + "//java/src/org/openqa/selenium/json", + "//java/src/org/openqa/selenium/manager", + "//java/src/org/openqa/selenium/remote", + "//java/src/org/openqa/selenium/support", + "//java/test/org/openqa/selenium/build", + "//java/test/org/openqa/selenium/environment", + "//java/test/org/openqa/selenium/testing:annotations", + "//java/test/org/openqa/selenium/testing:test-base", + "//java/test/org/openqa/selenium/testing/drivers", + artifact("com.google.guava:guava"), + artifact("org.junit.jupiter:junit-jupiter-api"), + artifact("org.assertj:assertj-core"), + ] + JUNIT5_DEPS, +) diff --git a/java/test/org/openqa/selenium/bidi/webextension/WebExtensionTest.java b/java/test/org/openqa/selenium/bidi/webextension/WebExtensionTest.java new file mode 100644 index 0000000000000..a7ed5c37ed458 --- /dev/null +++ b/java/test/org/openqa/selenium/bidi/webextension/WebExtensionTest.java @@ -0,0 +1,76 @@ +// 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.webextension; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Base64; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.build.InProject; +import org.openqa.selenium.testing.JupiterTestBase; + +public class WebExtensionTest extends JupiterTestBase { + + private final Map extensionData = + Map.of( + "id", "webextensions-selenium-example-v3@example.com", + "path", "common/extensions/webextensions-selenium-example-signed", + "archivePath", "common/extensions/webextensions-selenium-example.xpi"); + + @Test + void installExtensionPath() { + Path path = InProject.locate(extensionData.get("path")); + + WebExtension extension = new WebExtension(driver); + var exIn = + extension.install(new InstallExtensionParameters(new ExtensionPath(path.toString()))); + assert exIn.get("extension").equals(extensionData.get("id")); + + extension.uninstall(new UninstallExtensionParameters(exIn)); + } + + @Test + void installArchiveExtensionPath() { + Path path = InProject.locate(extensionData.get("archivePath")); + + WebExtension Extension = new WebExtension(driver); + var ex = + Extension.install( + new InstallExtensionParameters(new ExtensionArchivePath(path.toString()))); + assert ex.get("extension").equals(extensionData.get("id")); + + Extension.uninstall(new UninstallExtensionParameters(ex)); + } + + @Test + void installBase64ExtensionPath() throws IOException { + Path path = InProject.locate(extensionData.get("archivePath")); + + WebExtension Extension = new WebExtension(driver); + var ex = + Extension.install( + new InstallExtensionParameters( + new ExtensionBase64Encoded( + Base64.getEncoder().encodeToString(Files.readAllBytes(path))))); + assert ex.get("extension").equals(extensionData.get("id")); + + Extension.uninstall(new UninstallExtensionParameters(ex)); + } +}