RemoteWebDriver is null error (sauce labs implementation) -selenium,cucumber,java - java

I am implementing my code to work on remote machines on Sauce Labs. The code worked fine until I have changed my driver initialisation (to work with remote server). I keep getting this.driver is null exception. I don't know what's wrong with it, I was following official documentation and tried many things. I hope someone can see the issue here. Thank you in advance. My code:
DRIVER:(my username and key are copied from my sauce labs account, renamed for this purpose)
public class Hooks {
public RemoteWebDriver driver;
public WebDriverWait wait;
#Before
public void setup(Scenario scenario) throws MalformedURLException {
String username = System.getenv("my username");
String accessKey = System.getenv("key");
ChromeOptions chromeOpts = new ChromeOptions();
MutableCapabilities sauceOpts = new MutableCapabilities();
sauceOpts.setCapability("name", scenario.getName());
sauceOpts.setCapability("username", username);
sauceOpts.setCapability("accessKey",accessKey);
MutableCapabilities browserOptions = new MutableCapabilities();
browserOptions.setCapability(ChromeOptions.CAPABILITY, chromeOpts);
browserOptions.setCapability("sauce:options", sauceOpts);
browserOptions.setCapability("browserName", "chrome");
browserOptions.setCapability("browserVersion", "latest");
browserOptions.setCapability("platformName", "Windows 10");
String sauceUrl = "https://ondemand.us-west-1.saucelabs.com:443/wd/hub";
URL url = new URL(sauceUrl);
driver = new RemoteWebDriver(url, browserOptions);
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
#After
public void tearDown(Scenario scenario) {driver.quit();}
}
PAGE OBJECT WHERE MY CODE IS: (shortened for privacy purposes)
public class LandingPO extends Hooks {
static RemoteWebDriver driver;
static WebDriverWait wait;
String url = "https://google.com"
public void openUrl() {
driver.get(url);}
And then I just call this method (landingPO.openUrl();) in my stepDefinition class.
The error is thrown where first driver usage is found:
Step failed
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.remote.RemoteWebDriver.get(String)" because "pageObjects.LandingPO.driver" is null
it breaks right at "driver.get(url)" in my LandingPO

If anyone will have the same problem, the answer was:
I was using wrong Before/After import. The correct import should be:
import io.cucumber.java.After;
import io.cucumber.java.Before;

Related

Having trouble with SkipException, testNG, what am I doing wrong?

I am very new to selenium UI automation and I am trying my hands on with a simple application. I am using java with testNG. I need to integrate this test with CI and the test environment url will be different with every deployment. I am passing this as a parameter, difference between test and prod environment is that in the test, there won't be any login screen hence there is no need for authentication but my test verifies login and a login method. I need to be able to skip this test based on the URL supplied. Here is my code and the problem is testNG always suggests that the test was skipped but I can see it executing the login method. Please help me correct or understand what mistake I am committing.
public class Login {
WebDriver driver;
//Parameter - test environment URL
String url = System.getProperty("environment");
#Test (priority = 1)
public void verifyLogin() {
//Skip verifyLogin test in non prod environments
System.setProperty("webdriver.chrome.driver", "C://chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
if (url=="www.google.com")
//If url matches production url then execute the test, if url doesn't match production URL then skip login test as there won't be any authentication/login in non prod
{
LoginPage login = new LoginPage(driver);
login.signIn();
Assert.assertEquals(driver.getTitle(), "Application Name", "Login failed,");
String title = driver.getTitle();
System.out.println("Page title is " + title);
driver.close();
}
else if (url!="www.google.com"){
throw new SkipException("Skipping this test");
}
}
#Test(priority = 2)
public void userKey() {
System.setProperty("webdriver.chrome.driver", "C://chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
//If URL equals prod then call the login method to be able to login to the app else just execute the userKey method without having the need to login
if (url=="www.google.com");
{
LoginPage login = new LoginPage(driver);
login.signIn();
}
AccountManagementPage userKey = new AccountManagementPage(driver);
userKey.key();
driver.close();
}
}
The very exact use case is well explained here without throwing SkipException.
The idea is to create a custom annotation for the methods to be skipped & read the methods using IMethodInterceptor - decide to execute or not behind the scenes.
Updated for the question in the comment section:
You do not have to worry about 'TestEnvironment' or 'TestParameters' class.Just directly use the production check logic here.
Predicate<IMethodInstance> isTestExecutingOnProduction = (tip) -> {
return system.getProperty("env").
.equals("<production check here>");
};

How do I pass the current capabilities to individual tests

This may be as simple as getting a variable from another class. I am still learning Java and Selenium.
I would like the test run report (ExtentReports) to be able to report the browser at a #Test level (capabilities). Currently Grid runs the same tests on different browsers, and the report does not distinguish them.
Using Selenium Grid, I define my #Test's Capabilities (including browser) with #BeforeMethod. I do this in my BaseTest class.
public class BaseTest {
#BeforeMethod(alwaysRun = true)
#Parameters({ "platform", "browser", "version" })
public void setup(String platform, String browser, String version)
throws MalformedURLException, InterruptedException {
RemoteWebDriver driver = null;
//important: Thread local!
threadedDriver = new ThreadLocal<RemoteWebDriver>();
DesiredCapabilities caps = new DesiredCapabilities();
// Platforms
if (platform.equalsIgnoreCase("windows"))
caps.setPlatform(Platform.WINDOWS);
if (platform.equalsIgnoreCase("XP"))
caps.setPlatform(Platform.XP);
if (platform.equalsIgnoreCase("WIN8"))
caps.setPlatform(Platform.WIN8);
if (platform.equalsIgnoreCase("WIN8_1"))
caps.setPlatform(Platform.WIN8_1);
if (platform.equalsIgnoreCase("ANY"))
caps.setPlatform(Platform.ANY);
if (platform.equalsIgnoreCase("MAC"))
caps.setPlatform(Platform.MAC);
if (platform.equalsIgnoreCase("Android"))
caps.setPlatform(Platform.ANDROID);
// Browsers
if (browser.equalsIgnoreCase("Internet Explorer"))
caps.setBrowserName("internet explorer");
if (browser.equalsIgnoreCase("Firefox"))
caps.setBrowserName("firefox");
if (browser.equalsIgnoreCase("chrome"))
caps.setBrowserName("chrome");
if (browser.equalsIgnoreCase("MicrosoftEdge"))
caps.setBrowserName("MicrosoftEdge");
if (browser.equalsIgnoreCase("iPad"))
caps.setBrowserName("ipad");
if (browser.equalsIgnoreCase("iPhone"))
caps.setBrowserName("iphone");
if (browser.equalsIgnoreCase("Android"))
caps.setBrowserName("android");
// Version
caps.setVersion(version);
System.out.println(caps);
System.out.println(browser);
//Initialize driver with capabilities
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), caps);
//this uses below methods to set above RemoteWebDriver to the getDriver()
//method in a threaded instance.
setWebDriver(driver);
initialize();
}
}
So now I have a browser variable local to each threaded Grid test run. I need to get that variable into each #Test method. Here is my #Test in a separate class. At the beginning of the try statement I would like to print the browser variable for the current threaded Grid test capabilities
public class Workflow1 extends BaseTest {
#Test
public void Workflow1TestInvalidPolicyNumbers() throws InterruptedException {
HomePage homePage = new HomePage(getDriver());
ExtentTest testReporter = ComplexReportFactory.getTest();
try {
System.out.println("This is the browser:" + ??(help here)??);
loginMethod("TestUser","TestPassword");
homePage.setFindAPersonOrPolicySearchField("1234");
homePage.clickSearchButton();
testReporter.log(LogStatus.INFO, "Searched \"1234\"");
Thread.sleep(2000);
if (getDriver().getPageSource().contains("Policy numbers should be 7 or 10 digits long"))
testReporter.log(LogStatus.PASS, "Policy numbers should be 7 or 10 digits long");
else
testReporter.log(LogStatus.FAIL, "Results incorrect" + testReporter.addScreenCapture(ComplexReportFactory.CaptureScreen(getDriver())));
} catch (Exception e) {
testReporter.log(LogStatus.ERROR, "Exception found: " + e.getMessage()
+ testReporter.addScreenCapture(ComplexReportFactory.CaptureScreen(getDriver())));
System.out.println(e);
}
}
It looks like the browser information is passed into the BaseTest.java class in the setup() method.
You could store this data in a variable which would then be available to all dependant classes:
public class BaseTest {
protected String browser; // add a property to hold this value
#BeforeMethod(alwaysRun = true)
#Parameters({ "platform", "browser", "version" })
public void setup(String platform, String browser, String version)
throws MalformedURLException, InterruptedException {
this.browser = browser; // store the given browser string
RemoteWebDriver driver = null;
//important: Thread local!
threadedDriver = new ThreadLocal<RemoteWebDriver>();
DesiredCapabilities caps = new DesiredCapabilities();
// Platforms
if (platform.equalsIgnoreCase("windows"))
caps.setPlatform(Platform.WINDOWS);
And then the BaseTest subclasses could reference it directly:
public class Workflow1 extends BaseTest {
#Test
public void Workflow1TestInvalidPolicyNumbers() throws InterruptedException {
HomePage homePage = new HomePage(getDriver());
ExtentTest testReporter = ComplexReportFactory.getTest();
try {
System.out.println("This is the browser:" + browser); // then retrieve it
You can also get the browser flavor name and a whole bunch of information by querying the RemoteWebDriver object itself to reveal the actual capabilities by invoking
getDriver().getCapabilities().getBrowserName()
This does away with the need to even have the browser flavor as a separate data member in the test class.
See here for javadocs.

webdriver on safari works well in debug mode, but could not work well when I run it

I test safari browser on Windows with Selenium Webdriver, when in debug mode, my script works well, but when I run it, it could not work well. Does anyone encounter this situation?
public class JustForTestSafari {
public WebDriver driver;
#Test
public void f() {
driver = new SafariDriver();
String baseURL = "http://universitytest.emersonprocess.com/";
String expectedTitle = "ProcessWorld - Your Connection to Global Information";
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.get(baseURL);
driver.manage().window().maximize();
String actulTitle = driver.getTitle();
Assert.assertEquals(expectedTitle, actulTitle);
driver.findElement(By.id("_ctl0_mastercontent_username")).clear();
driver.findElement(By.id("_ctl0_mastercontent_username")).sendKeys("***.guo");
driver.findElement(By.id("_ctl0_mastercontent_password")).clear();
driver.findElement(By.id("_ctl0_mastercontent_password")).sendKeys("*******");
driver.findElement(By.id("_ctl0_mastercontent_btn_standardsignin")).click();
}

Running Selenium Webdriver script in Chrome

I am trying to run Selenium Webdriver script in Chrome, have added following lines in my existing script
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Garimaari\\IdeaProjects\\Webdriver testing\\Chromedriver\chromedriver.exe");
private WebDriver driver = new ChromeDriver();
I am building my script in Intellij using Java. Not sure why i am getting "can not resolve symbol setProperty". I tried changing JRE and JDK files but nothing has worked. Any help would be appreciated.
Adding code
public class StartCaseJava extends TestCase {
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
// Getting Date and Timestamp for Last Name
Date d = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddyyHHmmss");
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Garimaari\\IdeaProjects\\Webdriver testing\\Chromedriver\\chromedriver.exe");
// private WebDriver driver = new ChromeDriver();
// driver = new FirefoxDriver();
// driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
private WebDriver driver = new ChromeDriver();
public void testStartCaseJava() throws Exception {
// System.setProperty("webdriver.chrome.driver", "C:\\Users\\Garimaari\\IdeaProjects\\Webdriver testing\\Chromedriver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
It's a long shot but should this
C:\Users\Garimaari\IdeaProjects\Webdriver testing\Chromedriver\chromedriver.exe")
maybe be renamed to C:\Users\Garimaari\IdeaProjects\Webdriver testing\Chromedriver\chromedriver.exe")
or are the double back slashes actually a necessary feature?
This might be because of one missing '\' before chromedriver.exe in your setProperty string.
Try using :
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Garimaari\\IdeaProjects\\Webdriver testing\\Chromedriver\\chromedriver.exe");
I am able to run my script using Chrome now. Here is the small sample declaration I used:
class StartCaseJAva {
static WebDriver driver;
public void testcasejava()) {
System.setProperty(path);
driver = new ChromeDriver();
}
}

How to find Frame element using PhantomJS?

I am working on frame based website. I am using selenium 2.47.1 & PhantomJS 1.9.2. I have written Automation Script & run it using firefox driver, it works perfectly. I am trying to execute the code with help PhanthomJS driver. But whenever I am trying to execute the it gives NoSuchFrameFoundException. My script is given below...
public class iFrame {
public String baseUrl = "https://test5.icoreemr.com/interface/login/login.php";
public WebDriver cd;
String scenarioName = "Sheet1";
ExcelLibrary ex = new ExcelLibrary();
#BeforeTest
public void SetBaseUrl() {
Capabilities caps = new DesiredCapabilities();
((DesiredCapabilities) caps).setJavascriptEnabled(true);
((DesiredCapabilities) caps).setCapability(
PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
"C:\\Users\\Probe7\\Downloads\\phantomjs-1.9.2-windows\\phantomjs.exe"
);
this.cd = new PhantomJSDriver(caps);
cd.get(baseUrl);
cd.manage().window().maximize();
}
#Test(priority = 0)
/* Login into the Application */
public void Login() {
cd.manage().timeouts().implicitlyWait(25, TimeUnit.SECONDS);
cd.switchTo().frame("Login");
System.out.println("Control Moved to Login Frame");
String UserName = ex.getExcelValue(scenarioName, 2, 4);
cd.findElement(By.xpath("//body/center/form/table/tbody/tr/td/div/div[2]/table/tbody/tr[1]/td[2]/input")).sendKeys(UserName);
}
Above code gives following exception..
org.openqa.selenium.NoSuchFrameException: No frame element found by name or id Login
Eventhough same script works perfectly in firefox driver, but not in PhantomJS.
Please advice me what went wrong?? I am looking into this nearly a day, but didn't find any solution.. Please help me on this?
Thanks in Advance...

Categories