Exception: null when setting up Selenium using ThreadLocal and ChromeDriver (Version 75)? - java

Current setup stored inside my DriverFactory:
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
return webDriver.get();
Currently the following method seems to be failing:
public void loadUrl(String url) {
try {
getDriver().get(url);
System.out.println("Successfully navigated to URL: " + url);
} catch (Exception e) {
System.out.println(e.getStackTrace());
Assert.fail("Unable to navigate to URL: " + url + ", Exception: " + e.getMessage());
}
}
Set driver method:
public final void setDriver(String browser) throws Exception {
String remoteHubUrl = "http://xxx.xxxx.xxx.xxx:4444/wd/hub/";
try {
switch (setBrowserType(browser)) {
case "grid":
DesiredCapabilities capabilities =new DesiredCapabilities();
capabilities.setBrowserName("chrome");
ChromeOptions op = new ChromeOptions();
op.merge(capabilities);
webDriver.set(new RemoteWebDriver(new URL(remoteHubUrl), op));
break;
}
}
Exception Message:
Exception: null
There seems to be no issues when using older versions of chromedriver, any ideas?
Base Step which is used to initialise the driver prior to executing the tests:
#Before
public void setupHook() {
setDriver("grid");
}

The main Issue I see with the above code is that you are trying to instantiate a RemoteWebDriver instance using a ChromeOptions object instead of a DesiredCapabilities object.
RemoteWebDriver requires a DesiredCapabilities (See Selenium code here) which ChromeOptions does not extend or implement. They do both extend AbstractCapabilities so you may just have been getting lucky in the past, but now they have diverged to an extent that they are no longer compatible.
*EDIT*
I would suggest you update your code to do this:
switch (setBrowserType(browser)) {
case "grid":
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
webDriver.set(new RemoteWebDriver(new URL(remoteHubUrl),capabilities));
break;
}

Related

java.lang.NullPointerException when using webdriver manager selenium java

While using selenium with java, WebdriverManager is not running and the below code is giving null pointer exception. I have returned the driver at end of class.
I have one ask whether should I keep the Webdriver driver as static or not.
import io.github.bonigarcia.wdm.WebDriverManager;
public class Browserselector {
public WebDriver driver;
public static Properties prop;
public WebDriver initializeDriver() throws IOException {
{
String browserName = "firefox";
System.out.println(browserName);
if (browserName.contains("Chrome")) {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
} else if (browserName.contains("IE")) {
WebDriverManager.iedriver().setup();
driver = new InternetExplorerDriver();
} else if (browserName.contains("FireFox")) {
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
} else if (browserName.contains("EDGE")) {
WebDriverManager.edgedriver().setup();
driver = new EdgeDriver();
}
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("google.com");
return driver;
}
}
Thanks for your help in advance.
you are trying to start "firefox" - but the if condition checks for "Firefox", if you want to use it like that change the following condition
browserName.contains("FireFox")
into
browserName.equalsIgnoreCase("FireFox")
I recommend you to change the nested if with a "switch" it's more readable and easy to follow/understand
Also, don't use a URL without specifying the protocol
driver.get("https://www.google.com");

Dynamically choose driver type in Appium in order to write 'hybrid' tests

I use Appium with Java to automate tests for mobile applications. It is clear that when I want to write tests for Android I use AndroidDriver<MobileElement> driver = [..] and for iOS I need to use IOSDriver<MobileElement> driver = [..] though with this approach I'd need to write same tests twice for iOS and Android. Is there a way that I could choose type of Appium Driver dynamically based on i.e. some kind of variable to choose between AndroidDriver and iOSDriver? I tried:
if(platform == "Android"){
//returns AndroidDriver
AppiumDriver<MobileElement> driver = COMMON.startAndroid(name, id, platform, version);
} else {
//returns IOSDriver
AppiumDriver<MobileElement> driver = COMMON.startIOS(name, id, platform, version);
}
but below in Test Eclipse points out that with this approach driver is not defined
Both of those drivers extend WebDriver interface (via inheritance). You can define driver from this type. It is also OOP encapsulation concept
WebDriver driver;
if(platform.equals("Android")){
driver = COMMON.startAndroid(name, id, platform, version);
} else {
driver = COMMON.startIOS(name, id, platform, version);
}
public class AppiumController {
public static OS executionOS = OS.ANDROID;
public AppiumDriver<MobileElement> driver;
DesiredCapabilities capabilities = new DesiredCapabilities();
public enum OS {
ANDROID,
IOS,
MOBILEBROWER_IOS,
MOBILEBROWER_ANDROID
}
public void start() {
if (driver != null) {
return;
}
switch(executionOS){
case ANDROID:
// set android caps
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
case IOS:
// set ios caps
driver = new IOSDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
case MOBILEBROWER_IOS:
// set ios browser caps
driver = new IOSDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
case MOBILEBROWER_ANDROID:
// set android browser caps
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
}
public void stop() {
if (driver != null) {
driver.quit();
driver = null;
}
}
}

Selenium chromedriver opens a blank page instead of url on linux

I am trying to open a url in chromedriver(using RemoteWebDriver) on linux.
I took a screenshot after driver.get(url) is called. It displays a blank page.
east-northamptonshire_screenshot.jpg
I tried this(open a url using ChromeDriver) on my local machine(Windows). It is working fine.
This is the url I am trying to open. "https://publicaccess.east-northamptonshire.gov.uk/online-applications/search.do?action=weeklyList"
Main method:
public static void main(String[] args) throws Exception {
String OS = System.getProperty("os.name").toLowerCase();
WebDriver driver = null;
ChromeDriverService service = null;
boolean isWindows = OS.indexOf("win") >= 0;
logger.info("operating System : " + OS);
if (!isWindows) {
service = new ServerChromeDriver().loadService();
}
driver = new ServerChromeDriver().getPIDriver(service, isWindows);
String url = "https://publicaccess.east-northamptonshire.gov.uk/online-applications/search.do?action=weeklyList";
driver.get(url);
Thread.sleep(3000);
ScreenShot.takeScreenShot(driver);
driver.close();
driver.quit();
service.stop();
}
ServerChromeDriver Class:
public ChromeDriverService loadService() throws Exception {
Configuration configuration = new Configuration();
configuration.loadProperties();
Properties props = new Properties();
try {
props.load(new FileInputStream("config//log4j.properties"));
} catch (IOException e) {
logger.error(e);
}
PropertyConfigurator.configure(props);
service = new ChromeDriverService.Builder().usingDriverExecutable(new File(configuration.getChromeDriverPath()))
.usingAnyFreePort().withEnvironment(ImmutableMap.of("DISPLAY", configuration.getDisplay())).build();
service.start();
return service;
}
public WebDriver getPIDriver(ChromeDriverService service, boolean isWindows) {
WebDriver driver;
if (isWindows) {
driver = new LocalChromeDriver().getDriver();
} else {
driver = new ServerChromeDriver().getDriver(service.getUrl());
}
String hostName = new ServerChromeDriver().getHostName(driver);
logger.info("Running the application on host: " + hostName);
return driver;
}
public WebDriver getDriver(URL serviceUrl) {
Configuration configuration = new Configuration();
configuration.loadProperties();
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--headless");
chromeOptions.addArguments("--disable-gpu");
// chromeOptions.addArguments("--start-maximized");
chromeOptions.addArguments("--window-size=1800,1800");
// chromeOptions.addExtensions(new File(configuration.getAdBlockPath()));
System.setProperty("webdriver.chrome.driver", configuration.getChromeDriverPath());
System.setProperty("webdriver.chrome.logfile", configuration.getChromeDriverLogFilePath());
System.setProperty("webdriver.chrome.verboseLogging", configuration.getChromeVerboseLogging());
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
capabilities.setJavascriptEnabled(true);
try {
driver = new RemoteWebDriver(serviceUrl, capabilities);
} catch (Exception e) {
logger.error("Error creating a new chrome instance");
throw new RuntimeException(e.getMessage());
}
driver.manage().timeouts().implicitlyWait(180, TimeUnit.SECONDS);
return driver;
}
Application is working fone for this url: https://eplanning.birmingham.gov.uk/Northgate/PlanningExplorer/GeneralSearch.aspx
birmingham_screenshot.jpg
I am using
Headless Chrome : 67.0.3396.62
chromedriver : 2.40.565383
This is what I found from the chromedriver.log file
[0617/144457.403693:ERROR:nss_ocsp.cc(601)] No URLRequestContext for NSS HTTP handler. host: crt.comodoca.com
[0617/144457.403801:ERROR:cert_verify_proc_nss.cc(980)] CERT_PKIXVerifyCert for publicaccess.east-northamptonshire.gov.uk failed err=-8179
I think because Chrome version in your Linux machine is not supported.
For people using newer versions of Selenium who are dealing with this issue, I was able to do the following (similar to Abhilash's answer which is using an older version of Selenium) to resolve the blank-page issue for uncertified domains with Chrome:
ChromeOptions options = new ChromeOptions();
...
options.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, true);
options.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
...
driver = new ChromeDriver(options);
(In my case, webdriver worked fine on my local machine but not on the Linux box hosting CI tools)
After researching about certificate errors, I have added additional capabilities to chrome driver to ignore certificate related errors. Below is my solution.
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
capabilities.setJavascriptEnabled(true);
capabilities.setCapability(CapabilityType.PROXY, proxy);
capabilities.setCapability("acceptSslCerts", true); // Added this additionally
capabilities.setCapability("acceptInsecureCerts", true); // Added this additionally
capabilities.setCapability("ignore-certificate-errors", true); // Added this additionally

org.openqa.selenium.SessionNotCreatedException: desired capabilities error

After the attempt to run my tests I always get:
org.openqa.selenium.SessionNotCreatedException: Unable to create new remote session. desired capabilities = Capabilities [{platformVersion=6.0, platformName=Android, deviceName=Xiomi}], required capabilities = Capabilities [{}]
java-client 5.0.0 beta 9
Appium 1.6.5
selenium standalone 3.4.0
Using Android Studio
public class MyTest1 {
AppiumDriver driver;
#Before
public void setUp() throws Exception {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Xiomi");
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "6.0");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
driver = new AppiumDriver(url, desiredCapabilities);
}
#After
public void tearDown() throws Exception {
driver.quit();
}
#Test
public void Test(){
}
}
Please help! I can't understand what am I doing wrong
I've added next desired capabilities and exception stopped occurring:
desiredCapabilities.setCapability("appPackage", "com.package.app");
desiredCapabilities.setCapability("appActivity", ".activities.App");
// Add real app package and activity instead of mine.

Appium startActivity() Function

I am new to Appium, In my code I have given required desired capabilities and wrote one test case that is working fine. Now I want to launch another App for second test in same code , how can I do that ?
I heard about startActivity(app-package,app Activity) but its not working, it says startActivity() not defined for Web Driver .
public class Calculator {
WebDriver driver;
#BeforeClass
public void setUp() throws MalformedURLException{
//Set up desired capabilities and pass the Android app-activity and app-package to Appium
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "Android");
capabilities.setCapability(CapabilityType.VERSION, "4.4");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", "14085521650378");
capabilities.setCapability("appPackage", "com.android.calculator2"); // This is package name of your app (you can get it from apk info app)
capabilities.setCapability("appActivity","com.android.calculator2.Calculator");
configurations specified in Desired Capabilities
driver = new RemoteWebDriver(new URL("http://127.0.0.1:9515/wd/hub"), capabilities);
}
#Test
public void testCal(){
driver.findElement(By.name("2")).click();
driver.findElement(By.name("+")).click();
driver.findElement(By.name("4")).click();
driver.findElement(By.name("=")).click();
}
#Test
public void Test2() { driver.startActivity("appPackage", "com.tttk.apc","appActivity","com.tttk.apc.DWDemoActivity");
for(int i=0; i<20;i++)
driver.findElement(By.className("android.widget.ImageButton")).click();
}
#AfterClass
public void teardown(){
//close the app
driver.quit();
}}
Seems like you are trying to use the method with a WebDriver instance.
The startActivity method is provided by an interface StartsActivity implemented by AndroidDriver only. So ideally this shall work :
((AndroidDriver) driver).startActivity(<appPackage>, <appActivity>);
public static void start() {
try {
((AndroidDriver) driver).startActivity("com.example.test", "com.example.LaunchApp");
} catch (Exception e) {
e.printStackTrace();
}
}
You have to enter your app package name and activity name to maximize the app.

Categories

Resources