How to get screenshot from RemoteWebDriver server instead of local FirefoxDriver? - java

I am running Selenium WebDriver test on a remote PC from my laptop(java client), by using RemoteWebDriver. But RemoteWebDriver haven't provided screenshot API to directly get a screenshot of remote PC. Googled a lot but found seems need use to Json API to get it from remoteWebDriver server directly. Anyone can give me some instruction about how to do that? Thanks.

The RemoteWebDriver must be augmented before you can use the screenshot capability. As you have no doubt already found, attempting to cast without augmenting results in an exception.
WebDriver driver = new RemoteWebDriver( ... );
driver = new Augmenter().augment( driver );
( (TakesScreenshot)driver ).getScreenshotAs( ... );

I was able to get this working...here is what you need to do:
1) Create a new class file in a Util directory or somewhere
package com.util;
import java.net.URL;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.DriverCommand;
import org.openqa.selenium.remote.RemoteWebDriver;
public class ScreenShotRemoteWebDriver extends RemoteWebDriver implements TakesScreenshot {
public ScreenShotRemoteWebDriver(URL url, DesiredCapabilities dc) {
super(url, dc);
}
#Override
public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException {
if ((Boolean) getCapabilities().getCapability(CapabilityType.TAKES_SCREENSHOT)) {
return target.convertFromBase64Png(execute(DriverCommand.SCREENSHOT).getValue().toString());
}
return null;
}
}
2) Then...where ever you start the RemoteWeDriver, replace with this code:
driver = new ScreenShotRemoteWebDriver(new URL(-PUT YOUR HUB URL HERE-),cap);
Your screenshots will be stored locally.
Hope this helps.

I think this is the best way:
public<T> Object getScreenshotAs(OutputType<T> outputType) {
Augmenter augmenter = new Augmenter();
TakesScreenshot ts = (TakesScreenshot) augmenter.augment(driver);
return ts.getScreenshotAs(outputType);
}

Here's another solution:
https://groups.google.com/d/topic/selenium-users/NLHXlhPrADs/discussion

The RemoteWebDriver does not implement the TakesScreenShot and the methods described here to cast the instance of RemoteWebDriver to TakesScreenShot will cause a ClassCastException. I'll see if I can find a solution as I'm interested in doing the same.
The Augmenter will "enhance the interfaces implemented by this instance of WebDriver iff that instance is a RemoteWebDriver". Depending on how the RemoteWebDriver is configured and how the selenium server is running on the remote host, it may be possible to get a screen shot in using the org.openqa.selenium.remote.Augmenter.
I've configured the RemoteWebDriver to use DesiredCapabilities.htmlUnit() capabilities and this gives an ClassCastError. If the RemoteWebDriver is configured with the capabilities of a driver that implements the TakesScreenshot interface, then a ClassCastException may not occur, though I have yet to test this.
From the TakesScreenshot interface, the known implementing drivers are: AndroidDriver, AndroidWebDriver, ChromeDriver, EventFiringWebDriver, FirefoxDriver, InternetExplorerDriver, IPhoneDriver, IPhoneSimulatorDriver, and SafariDriver

Related

Robot framework: how can I get current instance of selenium webdriver to write my own keywords?

I have a maven-powered Robot-framework project in java that uses selenium 3.4.0 dependency, robotframework 3.0.2 dependency, markusbernhardt's selenium2library version 1.4.0.8, and robotframework-maven-plugin version 1.4.7.
My robot tests live in the src/main/test/robotframework/acceptance folder, while in src/main/java/mypackage I created a Customized.java file to set a system property for the browser driver path (I then import this library in my tests:
*** Settings ***
Library Selenium2Library
Library mypackage.Customized
This works perfectly. But now I'd like to implement my own keywords to extend Selenium2Library. But I'm not sure how to obtain the current WebDriver instance that is running.
I mean, if I weren't using Robot and just plain Selenium, I'd do something like this:
WebDriver driver=new ChromeDriver();
driver.doSomething();
However, in this case I don't want to instantiate a new WebDriver but instead get the one that is currently running (which Robot automatically instantiated). How can I do that?
I've so far created a Selenium2Library object and set it with the value returned by Selenium2Library.getLibraryInstance(); but that's not giving me access to selenium's methods (e.g.: getCurrentUrl() is not listed).
in python it can be done with following code
from robot.libraries.BuiltIn import BuiltIn
def _browser(self):
return BuiltIn().get_library_instance('Selenium2Library')._current_browser()
Actually, I found a solution, but I'm not sure it's the right approach:
public class Customized {
private static Selenium2Library s;
private BrowserManagement b;
private WebDriver driver;
public Customized() throws ScriptException {
try {
Customized.s = (Selenium2Library) Selenium2Library.getLibraryInstance();
} catch (javax.script.ScriptException e) {
e.printStackTrace();
}
b = s.getBrowserManagement();
driver=b.getCurrentWebDriver();
}
}
Now the selenium methods are available from the driver object. However, there might be a better way to do it, as there's this message in the javax.script.ScriptException exception: "Access restriction: The type 'ScriptException' is not API (restriction on required library 'C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar')"
For newer Selenium version (4.0) the following snippet can be used:
class SelCustomLib():
def get_browser_driver(self):
return BuiltIn().get_library_instance('SeleniumLibrary').driver

Exception in thread "main" java.lang.IllegalStateException: The driver executable does not exist: /Users/Golcha/Desktop/Automation/geckodriver.exe

Getting the following error
Exception in thread "main" java.lang.IllegalStateException: The driver
executable does not exist:
/Users/Golcha/Desktop/Automation/geckodriver.exe
Code:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class selenium{
private static WebDriver driver;
public static void main(String[]args){
System.setProperty("webdriver.gecko.driver","Users/Golcha/Desktop/Automation/geckodriver.exe");
setDriver(new FirefoxDriver());
}
public static WebDriver getDriver() {
return driver;
}
public static void setDriver(WebDriver driver) {
selenium.driver = driver;
}
}
Try below code but check the path of geckodriver properly before executing the below code or I ll suggest you to paste geckodriver in C drive or any other drives to make your path simple as below one :
System.setProperty("webdriver.firefox.marionette", "C:\\geckodriver.exe");
It should work without any problem . All the best !
I thing you have not mentioned the complete(full) path for the Geckodriver in your System.setProperty() method. you have missed the drive letter "C"
"C:/Users/Golcha/Desktop/Automation/geckodriver.exe"
Let me know if this solved your problem.
I had a similar problem but weirdly I was not able to execute the selenium script on both my drivers (chrome and firefox), I tried checking my setProperty method, my gecko driver path and chrome driver path. Lastly, I tried updating both my browser and it seems to be working now. (my current version of Chrome is 66 and my current version of my Firefox is 56.0).

java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property

package com.merchantPlatform;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
public class MerchantPlatformTest {
public static void main(String[] args) {
System.getProperty("webdriver.gecko.driver", "C:\\Selenium WebDriver\\geckodriver\\geckodriver-v0.17.0-win64\\geckodriver.exe");
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability("marionette", true);
// Initialize WebDriver
WebDriver driver = new FirefoxDriver(capabilities);
/* This works fine for versions lesser than Selenium 3. For Selenium 3 and higher, it will throw java.lang.IllegalStateException */
// Maximize Window
driver.manage().window().maximize();
// Wait For Page To Load
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
// Navigate to MerchantPlatform URL
driver.get("http://localhost:52939/");
}
}
Error
I am getting the below exception with System.getProperty
Exception in thread "main" java.lang.IllegalStateException: The path
to the driver executable must be set by the webdriver.gecko.driver
system property; for more information, see
https://github.com/mozilla/geckodriver. The latest version can be
downloaded from https://github.com/mozilla/geckodriver/releases
at com.google.common.base.Preconditions.checkState(Preconditions.java:738)
at org.openqa.selenium.remote.service.DriverService.findExecutable(DriverService.java:124)
at org.openqa.selenium.firefox.GeckoDriverService.access$100(GeckoDriverService.java:41)
at org.openqa.selenium.firefox.GeckoDriverService$Builder.findDefaultExecutable(GeckoDriverService.java:115)
at org.openqa.selenium.remote.service.DriverService$Builder.build(DriverService.java:330)
at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:207)
at org.openqa.selenium.firefox.FirefoxDriver.(FirefoxDriver.java:108)
at org.openqa.selenium.firefox.FirefoxDriver.(FirefoxDriver.java:137)
at com.merchantPlatform.MerchantPlatformTest.main(MerchantPlatformTest.java:20)
You have to use System.setProperty not the System.getProperty as follows.
System.setProperty("webdriver.gecko.driver",
"C:\\Selenium WebDriver\\geckodriver\\geckodriver-v0.17.0-win64\\geckodriver.exe");
I have noticed that you are using wrong syntax, to opening the browser.
Instead of using System.getProperty, You have to use System.setProperty as mentioned below.
System.setProperty("webdriver.gecko.driver", "C:\\Selenium WebDriver\\geckodriver\\geckodriver-v0.17.0-win64\\geckodriver.exe");
For more details on this issue, refer this page.

Drag and drop not working in Selenium 3.0

I am trying the below code to test drag and drop in Selenium 3.0 and find that code is not working, meaning that it's not showing any error and also not providing expected result.
I have tried the same code in selenium 2.53 and it's working . Kindly someone review my code for the same and let me know if I missed something.
Selenium 3.0
Browser : Mozilla 2.52
package dynamicXpath;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
public class refermeprobI {
public static void main(String[] args) throws InterruptedException{
System.setProperty("webdriver.gecko.driver", "D:\\Drivers\\geckodriver.exe");
FirefoxProfile profile = new FirefoxProfile();
profile.setEnableNativeEvents(true);
WebDriver driver = new FirefoxDriver(profile);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("https://the-internet.herokuapp.com/drag_and_drop");
Actions act = new Actions(driver);
WebElement src = driver.findElement(By.xpath("//*[#id='column-a']"));
WebElement dst = driver.findElement(By.xpath("//*[#id='column-b']"));
act.dragAndDrop(src, dst).build().perform();
System.out.println(driver.findElement(By.xpath("//*[#id='column-b']/header")).getText());
}
}
I've checked your code. Everything is fine except if you use Selenium 3.0.0 then need to set Desired Capabilities. I've also checked your code with Selenium latest 3.4. If you use Selenium 3.4 then you don't need to set Desired Capabilities. I used Firefox 52.
I hope that this info will help you to understand the problem you have encountered.
Thanks
You can also try following:
act.clickAndHold(src).moveToElement(dst).release(src).build().perform();
This works in certain scenarios where dragAndDrop() doesn't.

Cannot instantiate the type AppiumDriver

I have added following jars in my projects build path:
java-client-2.0.0 from http://appium.io/downloads.html >> Appium Client libraries >> Java
selenium-java-2.43.1
selenium-java-2.43.1-srcs
selenium-server-standalone-2.43.1
and here's my code:
public class SampleApp{
WebDriver dr;
#Test
public void testApp() throws MalformedURLException, InterruptedException {
String apkpath = "D:\\apkdump\\sampleapp.apk";
File app = new File (apkpath);
DesiredCapabilities capabilities= new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME,"");
capabilities.setCapability("deviceName","TestADB18");
capabilities.setCapability("platformName","Android");
capabilities.setCapability("app",app.getAbsolutePath());
capabilities.setCapability("appPackage", "com.test");
capabilities.setCapability("appActivity", "com.sampleapp.Main");
dr = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
dr.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
}
I am getting red line below new AppiumDriver which says that Cannot instantiate the type AppiumDriver. Now if remove all selenium jars the error disappears but then I can't resolve errors with webdriver.What is the conflict between jars?
I saw similar question here but that could run the code and was getting Null pointer exception but in my case I cant even run it, it is giving run on saving the code. Secondly the answer has been posted without using AppiumDriver
You don't need to downgrade or anything. There is a design change in the Java Client version 2.0.0 as they mention on their site:
AppiumDriver is now an abstract class, use IOSDriver and AndroidDriver which both extend it.
So, just change your driver line to be:
dr = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
Hope that helps...
This error can be fixed by downgrading the Appium Client(see step 1 in my question) from latest to java-client-1.5.0. You can keep rest of the jars to latest.
Downgraded version of Appium Client can be downloaded from here http://mvnrepository.com/artifact/io.appium/java-client/1.5.0
WebDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),getDesiredCapabilities("192.21.168.56:5555"));
use this. and import:
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
dr=new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
proper URL to be established
for appium version 1.7 use capability
cap.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
while for v1.8.1
its not needed

Categories

Resources