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

Issue when casting decorated WebDrivers to RemoteWebDriver or JavascriptExecutor #9416

Closed
adngzz opened this issue Apr 23, 2021 · 6 comments · Fixed by #9466
Closed

Issue when casting decorated WebDrivers to RemoteWebDriver or JavascriptExecutor #9416

adngzz opened this issue Apr 23, 2021 · 6 comments · Fixed by #9466
Labels

Comments

@adngzz
Copy link

adngzz commented Apr 23, 2021

🐛 Bug Report

In Selenium Java Since EventFiringWebDriver got deprecated in Beta 2 I changed my implementation to envelop my remoteWebDriver into to a decorated Webdriver using EventFiringDecorator. But i am having trouble whenever i have to cast it as a JavascriptExecutor or back to a remotewebdriver to access some values.

I get the following error:

java.lang.ClassCastException: class jdk.proxy2.$Proxy18 cannot be cast to class org.openqa.selenium.remote.RemoteWebDriver (jdk.proxy2.$Proxy18 is in module jdk.proxy2 of loader 'app'; org.openqa.selenium.remote.RemoteWebDriver is in unnamed module of loader 'app')
	at com.peektraffic.spinnaker.TestNgTestBase.initDriver(TestNgTestBase.java:570)
	at com.peektraffic.spinnaker.TestNgTestBase.init(TestNgTestBase.java:169)
	at com.peektraffic.spinnaker.Roles.Test_SystemPermissions.systemPermissions_AES_VERBA_INFO_Display(Test_SystemPermissions.java:1180)
	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.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:77)
	at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:15)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:831)

To Reproduce

  1. Create a new remote webdriver
  2. implement a listener
  3. decorate the remotewebdriver with EventFiringDecorator
  4. cast the decorated driver into a JavascriptExecutor or RemoteWebDriver

Expected behavior

object type is changed

Test script or set of commands reproducing this issue

private void initDriver(DesiredCapabilities capabilities) throws Exception
	{
		HashMap<String, String> data = Testdata.get();
		// BasicConfigurator.configure();
		EventListener eventListener = new EventListener();

		RemoteWebDriver rem;
		Long start = System.currentTimeMillis();
		while (true)
		{
			if (System.currentTimeMillis() - start >= MAX_TRY_MS.get())
			{
				fail(threadId.get() + "Couldn't Start driver within " + MAX_TRY_MS.get() + " ms.");
			}
			try
			{
				log(Status.INFO, "Initializing EventFiringWebDriver..");

				rem = new RemoteWebDriver(new URL(data.get("REMOTE_HUB_LOCATION")), capabilities);

				break;
			}
			catch (Exception e)
			{
				Thread.sleep(5000);
				// log(Status.INFO, "Exception "+ e);
			}

		}
		System.out.println(((RemoteWebDriver)new EventFiringDecorator(eventListener).decorate(rem)).getSessionId());
	}

Environment

OS: windows 10
Browser: firefox
Browser version: 86.0
Browser Driver version: GeckoDriver 0.29
Language Bindings version: java 4 beta 3
Selenium Grid version (if applicable): java 4 beta 3

@pujagani
Copy link
Contributor

Thank you for sharing the details. I was able to reproduce the issue.
Was it working as expected when using EventFiringWebDriver? If so, can you share a snippet of the usage, please?
It will help to figure out a fix for the same.
Thank you so much!

@pujagani
Copy link
Contributor

Till the fix is in place, you can leverage the RemoteDriver object directly to get the session id.

@pujagani
Copy link
Contributor

I have tried casting to JavascriptExecutor and it works as expected. No class cast exception is seen. If you faced any other error, please provide details for the same.

@adngzz
Copy link
Author

adngzz commented May 10, 2021

The issue with the JavascriptExecutor seems to only happen when using a WebElement as a parameter. I am not sure how related the issues are other than they are caused by the decorator. Should i open another case?


		EventListener eventListener = new EventListener();

		RemoteWebDriver rem;
		Long start = System.currentTimeMillis();
		while (true)
		{
			if (System.currentTimeMillis() - start >= MAX_TRY_MS.get())
			{
				fail(threadId.get() + "Couldn't Start driver within " + MAX_TRY_MS.get() + " ms.");
			}
			try
			{
				log(Status.INFO, "Initializing EventFiringWebDriver..");

				rem = new RemoteWebDriver(new URL(data.get("REMOTE_HUB_LOCATION")), capabilities);

				break;
			}
			catch (Exception e)
			{
				Thread.sleep(5000);
				// log(Status.INFO, "Exception "+ e);
			}

		}

		// envelop remotedriver into eventfiring webdriver

		WebDriver DecoratedDriver=new EventFiringDecorator(eventListener).decorate(rem);
		
		DecoratedDriver.get("https://www.google.com");
		List<WebElement> googleicon = DecoratedDriver.findElements(By.cssSelector("span svg"));
		JavascriptExecutor executor = (JavascriptExecutor) DecoratedDriver;
		//executor.executeScript("arguments[0].click();", googleicon);
		System.out.println(executor.executeScript("arguments[0].getAttribute('style')", googleicon.get(0)).toString()); 
java.lang.IllegalArgumentException: Argument is of an illegal type: jdk.proxy2.$Proxy19
	at org.openqa.selenium.remote.internal.WebElementToJsonConverter.apply(WebElementToJsonConverter.java:85)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:550)
	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.openqa.selenium.support.decorators.WebDriverDecorator.call(WebDriverDecorator.java:228)
	at org.openqa.selenium.support.decorators.DefaultDecorated.call(DefaultDecorated.java:48)
	at org.openqa.selenium.support.decorators.WebDriverDecorator.lambda$createProxy$0(WebDriverDecorator.java:287)
	at jdk.proxy2/jdk.proxy2.$Proxy18.executeScript(Unknown Source)
	at com.peektraffic.spinnaker.TestNgTestBase.initDriver(TestNgTestBase.java:580)
	at com.peektraffic.spinnaker.TestNgTestBase.init(TestNgTestBase.java:169)
	at com.peektraffic.spinnaker.Help.Test_Help.help_DeviceFlyoutIcon(Test_Help.java:22)
	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.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:77)
	at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:15)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:831)

@adngzz
Copy link
Author

adngzz commented May 10, 2021

This is how I have implemented RemoteFiringWebdriver, it is working fine up to Beta 1

		WebDriverEventListener eventListener = new EventListener();

		RemoteWebDriver rem;
		Long start = System.currentTimeMillis();
		while (true)
		{
			if (System.currentTimeMillis() - start >= MAX_TRY_MS.get())
			{
				fail(threadId.get() + "Couldn't Start driver within " + MAX_TRY_MS.get() + " ms.");
			}
			try
			{
				log(Status.INFO, "Initializing EventFiringWebDriver..");

				rem = new RemoteWebDriver(new URL(data.get("REMOTE_HUB_LOCATION")), capabilities);

				break;
			}
			catch (Exception e)
			{
				Thread.sleep(5000);
				// log(Status.INFO, "Exception "+ e);
			}

		}

		// envelop remotedriver into eventfiring webdriver
		log(Status.INFO, "Remotewebdriver session ID : " + rem.getSessionId());
		log(Status.INFO, "Driver: " + rem.toString());
		eventDriver.set(new EventFiringWebDriver(rem).register(eventListener));

@pujagani
Copy link
Contributor

Thank you for providing the samples, especially the JavascriptExecutor code sample. Appreciate it.
Ideally, it could have not have been a separate issue. However, the fix was similar in both the issues mentioned so I have added a fix for both a single PR.
Additionally added tests to ensure this exact problem is not longer there.

pujagani added a commit that referenced this issue May 12, 2021
…ation (#9466)

Fixes #9416. It is related to the motivation of #8346 (which will help create a Proxy due to the interface).
@github-actions github-actions bot locked and limited conversation to collaborators Sep 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants