Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛 Bug]: Using WebDriverListener with Augmenter throws ArgumentException #10233

Closed
arsen-papoyan opened this issue Jan 7, 2022 · 20 comments · Fixed by #10271
Closed

[🐛 Bug]: Using WebDriverListener with Augmenter throws ArgumentException #10233

arsen-papoyan opened this issue Jan 7, 2022 · 20 comments · Fixed by #10271

Comments

@arsen-papoyan
Copy link

arsen-papoyan commented Jan 7, 2022

What happened?

Getting error in case of RemoteWebDriver using WebDriverListener.

How can we reproduce the issue?

Project: Maven
Runner: TestNG

src/main/java folder:

public class Driver {
    public static void initDriver() {
        assertionMode = AssertionMode.SOFT;
        baseUrl = "https://www.google.com/";
        pageLoadStrategy = "eager";
        browser = "Chrome";
        pollingInterval = 500;
        holdBrowserOpen = false;
        savePageSource = false;
        fastSetValue = true;
        screenshots = false;
        remote = "remoteMachineUrl";
        driverManagerEnabled = true;
        headless = false;
        timeout = 10000;
        WebDriverRunner.addListener(new WebDriverEvent());
        open();
    }


public final class Util {
    public static WebDriver driver = new Augmenter().augment(getWebDriver());
    public static DevTools devTools = ((HasDevTools) driver).getDevTools();
}


public class WebDriverEvent implements WebDriverListener {
    @Override
    public void beforeClick(WebElement element) {
        WebDriverListener.super.beforeClick(element);
        System.out.println("Before Click");
    }
}

src/test/java folder:

public class DevToolsTest {
    @Test
    public void devToolTest(){
        Driver.initDriver();
        open(baseUrl);
        Util.devTools.createSession();
        Util.devTools.send(Network.clearBrowserCache());
    }
}


pom XML:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Draft</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.codeborne</groupId>
            <artifactId>selenide</artifactId>
            <version>6.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.selenide</groupId>
            <artifactId>selenide-testng</artifactId>
            <version>1.0.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.12.6</version>
        </dependency>
    </dependencies>
</project>


The problem is connected with the WebDriverListener interface, when I remove this everything is okay.
But the problem is only arising in the case of running the test on the remote machine, when I run the test with the WebDriverListener interface in the local machine, everything is okay.

Relevant log output

java.lang.ExceptionInInitializerError
	at DevToolsTest.devToolTest(DevToolsTest.java:13)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
	at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
	at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
	at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
	at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
	at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.testng.TestRunner.privateRun(TestRunner.java:794)
	at org.testng.TestRunner.run(TestRunner.java:596)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
	at org.testng.SuiteRunner.run(SuiteRunner.java:276)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
	at org.testng.TestNG.runSuites(TestNG.java:1063)
	at org.testng.TestNG.run(TestNG.java:1031)
	at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
	at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: java.lang.IllegalArgumentException: Cannot subclass primitive, array or final types: class jdk.proxy2.$Proxy10
	at net.bytebuddy.ByteBuddy.subclass(ByteBuddy.java:490)
	at net.bytebuddy.ByteBuddy.subclass(ByteBuddy.java:463)
	at net.bytebuddy.ByteBuddy.subclass(ByteBuddy.java:360)
	at org.openqa.selenium.remote.Augmenter.augment(Augmenter.java:179)
	at Util.<clinit>(Util.java:10)

Operating System

Local: macOS Monterey / Remote: Windows 10

Selenium version

JavaSE 14: version 16.0.1

What are the browser(s) and version(s) where you see this issue?

Chrome 96

What are the browser driver(s) and version(s) where you see this issue?

ChromeDriver 96.0.4664.45

Are you using Selenium Grid?

Selenium Grid (selenium server 4.1.0)

@github-actions
Copy link

github-actions bot commented Jan 7, 2022

@arsen-papoyan, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

@titusfortner titusfortner changed the title [🐛 Bug]: [🐛 Bug]: Using WebDriverListener with Augmenter throws ArgumentException Jan 7, 2022
@pujagani
Copy link
Contributor

Thank you for sharing the details. The example shared is not complete in terms of how the web driver is created. I am sharing a simple example that just uses Selenium below. I hope that gives you a fair idea about how to proceed.

By the error message shared, I see the problem arises when trying to augment the proxied instance return by the EventFiringDecorator (Proxy is a final class and ByteBuddy does not support subclassing a final class).
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/events/EventFiringDecorator.html EventFiringDecorator is a wrapper around the web driver.
Augmenter enhances a web driver instance. https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/remote/Augmenter.html
Both provide a different set of functionalities and internally both use different mechanisms.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.events.EventFiringDecorator;
import org.openqa.selenium.support.events.WebDriverListener;

import java.net.MalformedURLException;
import java.net.URL;

public class EventFiringDecoratorSel4Augment {

  public static void main(String[] args) throws MalformedURLException {
    WebDriver original = new RemoteWebDriver(new URL("http://localhost:4444"), setChromeOptions());

    // This is similar to WebDriverEvent implemented in the code shared in the issue
    WebDriverListener customListener = new WebDriverListeners();
    WebDriver decorated = new EventFiringDecorator(customListener).decorate(original);

    WebDriver augmented = new Augmenter().augment(original);
    DevTools devTools = ((HasDevTools) augmented).getDevTools();
    devTools.createSession();

    decorated.get("https://www.google.it/?safe=active&ssui=on");
    original.quit();
  }

  private static ChromeOptions setChromeOptions() {
    ChromeOptions chromeOptions = new ChromeOptions();
    return chromeOptions;
  }
}

I understand, using Augmenter with WebDriverListener instance should be straightforward and not related to the internals. I am investigating how that can be done since internally it relies on Java reflection dynamic proxies.
Meanwhile, please refer to the example shared. I hope that helps.

@arsen-papoyan
Copy link
Author

@pujagani Thank you for your reply.
As I use Selenide, so when calling open() the web driver is created under it, and whit the "remote" config it is launched on a remote machine.
Your example also works for me, but as there is a constructor with RemoteDriver, the implementation in my framework launches two browsers with each test run.

@pujagani
Copy link
Contributor

Thank you for providing the feedback. I have made the fix to allow using the WebDriveDecorator with the Augmenter without the exception and double declaration. The example was just to demo how it can be done meanwhile. The way web driver instance is created depends on the user. The changes will be available as part of the next release.

@arsen-papoyan
Copy link
Author

@pujagani Got you. Thanks!

@tkumar18
Copy link

Hello @pujagani I have tried the one which you have mentioned above but it is still throwing error message, can you please help?
Error:
java.lang.ClassCastException: class org.openqa.selenium.remote.RemoteWebDriver$ByteBuddy$mdQkPi43 cannot be cast to class org.openqa.selenium.devtools.HasDevTools (org.openqa.selenium.remote.RemoteWebDriver$ByteBuddy$mdQkPi43 is in unnamed module of loader net.bytebuddy.dynamic.loading.ByteArrayClassLoader @3ce443f9; org.openqa.selenium.devtools.HasDevTools is in unnamed module of loader 'app')

My Code
driver = new RemoteWebDriver(new URL("browserstack URL"), setChromeOptions());
WebDriver augmented = new Augmenter().augment(driver);
WebDriver decorated = new EventFiringDecorator(new CustomWebDriverEventListener(testReporter)).decorate(driver);
DevTools devTools = ((HasDevTools) augmented).getDevTools();
devTools.createSession();
decorated.manage().window().maximize();
decorated.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));
decorated.navigate().to("url");

Operating System
Remote: Windows 10 (Browserstack)

Selenium version
selenium 4.0.0

What are the browser(s) and version(s) where you see this issue?
Chrome 97

Java Version
Java 16

@pujagani
Copy link
Contributor

@tkumar18 Thank you for providing the details. I have run the example below and it works on my local machine as expected.

    WebDriver driver = new RemoteWebDriver(new URL(URL), capabilities);
    WebDriver augmented = new Augmenter().augment(driver);
    WebDriverListener customListener = new WebDriverListeners();
    WebDriver decorated = new EventFiringDecorator(customListener).decorate(driver);
    DevTools devTools = ((HasDevTools) augmented).getDevTools();
    devTools.createSession();
    decorated.manage().window().maximize();
    decorated.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));
    decorated.navigate().to("http://www.google.com");
    driver.quit();

How are you running the Java code? Are you building your own jar and running that jar to run the code snippet shared?

@tkumar18
Copy link

@pujagani It works Locally, I am facing this problem with Remote , it is Browerstack in my case. I am getting the same error while running in Docker with selenium/hub 4

Raw Selenium Logs from BS Console
11:05:07.273 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
11:05:07.282 DEBUG [UrlChecker.waitUntilAvailable] - Waiting for [http://localhost:7888/status]
11:05:07.288 DEBUG [UrlChecker.lambda$waitUntilAvailable$1] - Polling http://localhost:7888/status
11:05:07.820 DEBUG [UrlChecker.lambda$waitUntilAvailable$1] - Polling http://localhost:7888/status
11:05:07.822 DEBUG [HttpURLConnection.writeRequests] - sun.net.www.MessageHeader@176d79b5 pairs: {GET /status HTTP/1.1: null}{User-Agent: Java/1.8.0_181}{Host: localhost:7888}{Accept: text/html, image/gif, image/jpeg, *; q=.2, /; q=.2}{Connection: keep-alive}
11:05:07.824 DEBUG [HttpURLConnection.getInputStream0] - sun.net.www.MessageHeader@1b120c54 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 247}{Content-Type: application/json; charset=utf-8}{cache-control: no-cache}
11:05:09.663 INFO [ProtocolHandshake.createSession] - Detected dialect: W3C
11:05:09.665 DEBUG [RemoteWebDriver.log] - Executing: newSession [null, newSession {desiredCapabilities=Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 97.0.4692.71, chrome: {chromedriverVersion: 97.0.4692.36 (747e0a0f19c13..., userDataDir: C:\Windows\proxy\scoped_dir...}, goog:chromeOptions: {debuggerAddress: localhost:1237}, networkConnectionEnabled: false, pageLoadStrategy: eager, platformName: windows, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}}]
11:05:09.666 DEBUG [RemoteWebDriver.log] - Executed: [null, newSession {desiredCapabilities=Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 97.0.4692.71, chrome: {chromedriverVersion: 97.0.4692.36 (747e0a0f19c13..., userDataDir: C:\Windows\proxy\scoped_dir...}, goog:chromeOptions: {debuggerAddress: localhost:1237}, networkConnectionEnabled: false, pageLoadStrategy: eager, platformName: windows, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}}]

@tkumar18
Copy link

@pujagani Are you able to replicate this issue from your end with Browserstack or Remote ?

@pujagani
Copy link
Contributor

@tkumar18 I am unable to replicate this issue using the Grid or with Browserstack. Would appreciate it if you can help me understand how you are running the Java code. Is it from IDE or using a Java jar? A reproducible test project will make it easier to debug this since I am unable to reproduce it locally. To have a conversation to triage this, please reach out to us through our IRC/Slack/Matrix channels.

@arsen-papoyan
Copy link
Author

@tkumar18 If I am not mistaken your problem is not related to the WebDriverListener with Augmenter but DevTools with the RemoteDriver.
Thus, if I am right, you can find a conversation connected on the topic here:
#9803

@arsen-papoyan
Copy link
Author

Hello.
I am still getting the error.

@arsen-papoyan
Copy link
Author

@pujagani Could you please support?

@diemol
Copy link
Member

diemol commented Feb 5, 2022

This fix is included in 4.1.2, are you using that version?

@arsen-papoyan
Copy link
Author

It finally worked, thanks for your support.

@pujagani
Copy link
Contributor

pujagani commented Feb 8, 2022

Thank you for checking with the latest version and confirming that!

@arsen-papoyan
Copy link
Author

Hello @pujagani.
I found another problem related to the DevTools protocol, should I create a new bug or can we discuss it before then?

@pujagani
Copy link
Contributor

Hey! It will be easy to track if could you file a new bug with the details. Appreciate it. That way we can keep track of related changes or examples. Thank you!

@arsen-papoyan
Copy link
Author

Created

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants