I'm using Cucumber with Java and I'm trying to pass a value to local storage. I'm using also WebDriverManager and when I try to execute some script with JavaScripExecutor, another instance of a browser is opened.
I tried to implement the JavaScriptExecutor in the WebDriverManager but I got the same result as before.
public class WebDriverManager {
private WebDriver driver;
private static DriverType driverType;
private static EnvironmentType environmentType;
private static final String CHROME_DRIVER_PROPERTY = "webdriver.chrome.driver";
private JavascriptExecutor js;
public WebDriverManager() {
driverType = FileReaderManager.getInstance().getConfigReader().getBrowser();
environmentType = FileReaderManager.getInstance().getConfigReader().getEnvironment();
}
public WebDriver getDriver() throws MalformedURLException {
if(driver == null) driver = createDriver();
return driver;
}
public JavascriptExecutor getJavaScriptExecutor() {
js = (JavascriptExecutor) driver;
return js;
}
private WebDriver createDriver() throws MalformedURLException {
switch (environmentType) {
case LOCAL : driver = createLocalDriver();
break;
case REMOTE : driver = createRemoteDriver();
break;
}
return driver;
}
I want to be able to use this executor in the already existing browser instance.
I got some help from a team member and we figured it out already.
public WebDriverManager() throws MalformedURLException {
driverType = FileReaderManager.getInstance().getConfigReader().getBrowser();
environmentType = FileReaderManager.getInstance().getConfigReader().getEnvironment();
driver = createDriver();
}
By passing driver variable to constructor and by creating appropriate constructors in classes I managed to make JavaScriptExecutor use already existing instance of a WebDriver. Example:
JavascriptExecutor js;
public AcceptanceHelper(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, 15);
this.js = (JavascriptExecutor) driver;
}
Related
1.Creating a page in which declaring driver as RemoteDriver.
2.Calling a function where again I’m declaring a driver as RemoteDriver.
3.Running a test where I’m declaring driver as RemoteDriver.
4.Trying to access the AppiumDriver method in my test method.
I had the similar problem and solved it using the below code.
Public class DriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
private static AppiumDriver driver;
private static DesiredCapabilities caps = new DesiredCapabilities();
public void initDriver(String browser){
if (browser.equalsIgnoreCase("chrome")){
caps.setCapability("");
....
....
webDriver.set(driver = new AppiumDriver(new URL("<<.../hub>>"), caps));
}
}
public AppiumDriver getDriver() throws Exception {
return driver;
}
}
Can you please tell me why the values jsonKeyboard and jsonMouse of null and because of this my actions do not work?
When I try to get my driver like that: driver = DriverFactory.getDriver();
private static WebDriver driver;
public static WebDriver getDriver() {
if (null == driver) {
LOG.info("The driver is null. Attempt to create new instance for webdriver.");
driver = new ChromeDriver();
}
return driver
But if I try to use some wrapper for my driver and get driver like that: driver = new AddLogsForWebDriver(DriverFactory.getDriver());
public class AddLogsForWebDriver implements WebDriver {
private static final CustomLogger LOG = LoggerFactory.getLogger();
private final WebDriver driver;
public AddLogsForWebDriver(WebDriver driver) {
this.driver = driver;
}
#Override
public void get(String url) {
driver.get(url);
LOG.info("The " + url + " was opened.");
}
#Override
public String getCurrentUrl() {
LOG.info("The current url was got.");
return driver.getCurrentUrl();
}
...
}
After that my Actions don't work
Any help would be helpful. Thank you
My test is executed on my VM. Chrome loads first and then IE. IE Completes the test but Chrome gets orphaned. I think this has something to do with the threads connecting with the proper browser.
I have tried many hours trying different ways of setting up Parallel testing with Selenium/TestNG and the result is the same as I described above.
My goal is for both browsers to complete the test. Can you please help me.
Please find my code below.
public class BaseTestDirectory {
// -------Reference Variables-------------
// ----- Regression Test Cases -----
LoginLogoutPage objBELogin;
HomeNavigationPage obj_navigation;
DirectoryPage obj_directory;
// -------------------------------
protected static WebDriver driver;
protected ExtentTest test;// --parent test
ExtentReports report;
ExtentTest childTest;
#BeforeClass
#Parameters(value={"browser"})
public void setUp(String browser) throws InterruptedException, MalformedURLException {
// --------Extent Report--------
if(browser.equals("Chrome")){
report = ExtentManager.getInstance();
System.setProperty("webdriver.chrome.driver", "C:\\GRID\\chromedriver.exe");
System.out.println(System.getenv("BUILD_NUMBER"));
String env = System.getProperty("BUILD_NUMBER");
if (env == null) {
driver = new RemoteWebDriver(new URL(COMPLETE_NODE_URL), OptionsManager.getChromeOptions());
driver.get(HOME_PAGE);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
} else {
driver = new ChromeDriver();
driver.get(HOME_PAGE);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
else if (browser.equals("IE")) {
report = ExtentManager.getInstance_IE();
System.setProperty("webdriver.ie.driver", "C:\\GRID\\IEDriverServer.exe");
System.out.println(System.getenv("BUILD_NUMBER"));
String env = System.getProperty("BUILD_NUMBER");
driver = new RemoteWebDriver(new URL(COMPLETE_NODE_URL), OptionsManager.getInternetExplorerOptions());
driver.get(HOME_PAGE);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
public class OptionsManager {
//Get Chrome Options
// --https://stackoverflow.com/questions/43143014/chrome-is-being-controlled-by-automated-test-software
// --https://stackoverflow.com/questions/56311000/how-can-i-disable-save-password-popup-in-selenium
public static ChromeOptions getChromeOptions() {
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("useAutomationExtension", false);
options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
options.addArguments("--disable-features=VizDisplayCompositor");
options.addArguments("--start-maximized");
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("credentials_enable_service", false);
prefs.put("profile.password_manager_enabled", false);
options.setExperimentalOption("prefs", prefs);
DesiredCapabilities capability = DesiredCapabilities.chrome();
capability.setCapability(CapabilityType.BROWSER_NAME, "Chrome");
capability.setPlatform(Platform.XP);
capability.setBrowserName("Chrome");
capability.setCapability(ChromeOptions.CAPABILITY, options);
options.merge(capability);
return options;
}
public static InternetExplorerOptions getInternetExplorerOptions () {
InternetExplorerOptions capabilities = new InternetExplorerOptions();
capabilities.ignoreZoomSettings();
capabilities.setCapability("browser.download.folderList", 2);
capabilities.setCapability("browser.download.manager.showWhenStarting", false);
capabilities.setCapability("browser.helperApps.neverAsk.saveToDisk","application/octet-stream;application/csv;text/csv;application/vnd.ms-excel;");
capabilities.setCapability("browser.helperApps.alwaysAsk.force", false);
capabilities.setCapability("browser.download.manager.alertOnEXEOpen", false);
capabilities.setCapability("browser.download.manager.focusWhenStarting", false);
capabilities.setCapability("browser.download.manager.useWindow", false);
capabilities.setCapability("browser.download.manager.showAlertOnComplete", false);
capabilities.setCapability("browser.download.manager.closeWhenDone", false);
//capabilities.setCapability(InternetExplorerDriver.IE_SWITCHES, "-private");
//capabilities.setCapability("requireWindowFocus", true);
return capabilities;
}
}
Initializing the WebDriver object as a Thread Local for Parallel Test Execution: When you have decided to run your selenium's tests in parallel, your Webdriver object should be thread-safe i.e. a single object can be used with multiple threads at the same time without causing problems.
public class BaseTest {
//Declare ThreadLocal Driver (ThreadLocalMap) for ThreadSafe Tests
protected static ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
public CapabilityFactory capabilityFactory = new CapabilityFactory();
#BeforeMethod
#Parameters(value={"browser"})
public void setup (String browser) throws MalformedURLException {
//Set Browser to ThreadLocalMap
driver.set(new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilityFactory.getCapabilities(browser)));
}
public WebDriver getDriver() {
//Get driver from ThreadLocalMap
return driver.get();
}
#AfterMethod
public void tearDown() {
getDriver().quit();
}
#AfterClass void terminate () {
//Remove the ThreadLocalMap element
driver.remove();
}
}
Try to design your base class in the below given example
public class WebDriverFactory {
static WebDriver create(String type) throws IllegalAccessException{
WebDriver driver;
switch(type) {
case "Firefox":
driver = new FirefoxDriver();
break;
case "Chrome":
driver = new ChromeDriver();
break;
default:
throw new IllegalAccessException();
}
return driver;
}
}
public class BaseClass extends WebDriverFactory {
public static ThreadLocal<WebDriver> dr = new ThreadLocal<WebDriver>();
#Parameters("browser")
#BeforeMethod
public void beforemethod() throws IllegalAccessException{
WebDriver driver = new WebDriverFactory().create(browser);
setWebDriver(driver);
getWebDriver().manage().window().maximize();
getWebDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
public void setWebDriver(WebDriver driver){
dr.set(driver);
}
public WebDriver getWebDriver(){
return dr.get();
}
#AfterMethod
public void aftermethod(){
getWebDriver().quit();
dr.set(null);
}
}
It runs the first test OK, but then I'm getting a null pointer exception when running the "Edit Profile" test, and I'm not sure why. I globally declared public driver.
public class TestLogin
{
public WebDriver driver;// = new FirefoxDriver();
public String baseURL = "mytestsite.com";
#BeforeTest
public void setBaseURL()
{
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait( 20L, TimeUnit.SECONDS );
driver.get( baseURL );
}
// Login test
#Test
public void testLogin() throws InterruptedException{
driver.manage().timeouts().implicitlyWait(20L, TimeUnit.SECONDS);
analyticsLoginPage mylogin = PageFactory.initElements(driver, ` ` analyticsLoginPage.class);
analyticsLandingPage landingpage = mylogin.login("username", "password");
Thread.sleep(3000);
}
// Edit Profile test
#Test // (dependsOnMethods = { "testLogin" })
public void verifyProfile()
throws InterruptedException
{
// driver = new FirefoxDriver();
Thread.sleep( 3000 );
analyticsLandingPage landingpage = new analyticsLandingPage( driver );
Thread.sleep( 3000 );
landingpage.gotoProfile();
// Thread.sleep(5000);
analyticsEditProfilePage editprofile = PageFactory.initElements( driver, analyticsEditProfilePage.class );
editprofile.verifyEditFirstName();
editprofile.verifyEditLastName();
editprofile.verifyCompanyName();
editprofile.verifyReportingProfile();
editprofile.verifyUsageStatistics();
}
Landing page class
package com.tapanalytics.pom.domain;
import java.util.concurrent.TimeUnit;
import javax.security.auth.login.Configuration;
import org.junit.Test;
public class analyticsLandingPage
{
WebDriver driver;
public analyticsLandingPage( WebDriver driver )
{
this.driver = driver;
}
#FindBy( xpath = Configuration.manage_dashboard )
public WebElement manage_dashboard;
#FindBy( xpath = Configuration.manage_services )
public WebElement manage_services;
#FindBy( xpath = Configuration.profile )
public WebElement profile;
#FindBy( xpath = Configuration.support )
public WebElement support;
#FindBy( xpath = Configuration.logout )
public WebElement logout;
public void gotoMangeDashboards()
{
manage_dashboard.click();
}
public void gotoServices()
{
manage_services.click();
}
public void gotoProfile()
{
profile.click();
}
public void gotoSupport()
{
support.click();
}
public void Logout()
{
logout.click();
}
}
There are multiple ways you could fix this. I think you could use a #BeforeMethod method that initializes the driver before each test method and then a #AfterMethod that calls driver.quit() and sets the driver to null after each test method. The non-static driver can remain the same as a class member.
Personally, with Selenium tests I never re-use the same driver for multiple test methods. Your asking for trouble when you do that and you usually need to enforce test method order.
More advanced: create your WebDriver instance in a data provider and then pass it into each test method. Then, have a #AfterMethod that closes the driver after each test. Then, your test class doesn't need to contain its own shared driver instance and TestNG handles your test multi-threading.
Try with
public static WebDriver driver;
in two classes.
Thank You,
Murali
I'm trying to test one specific Selenium's Actions class method, which is as below.
public Actions sendKeys(java.lang.CharSequence... keysToSend)
Sends keys to the active element. This differs from calling WebElement.sendKeys(CharSequence...) on the active element.
public class Demo_1 {
private WebDriver driver;
private Actions action;
private String baseUrl;
#Before
public void setUp() throws Exception {
File file = new File("C:\\Users\\ProgramFiles\\firefox.exe");
FirefoxProfile profile = new FirefoxProfile();
FirefoxBinary binary = new FirefoxBinary(file);
driver = new FirefoxDriver(binary, profile);
action = new Actions(driver);
baseUrl = "http://www.mortgagecalculator.org";
}
#Test
public void testUntitled() throws Exception {
driver.get(baseUrl + "/");
driver.findElement(By.name("param[homevalue]")).click();
driver.findElement(By.name("param[homevalue]")).clear();
action.sendKeys("300000");
}
#After
public void tearDown() throws Exception {
//driver.quit();
}
}
I can do this alternatively, but in some cases when there is no WebElement, action.sendKeys can help to send CharSequence without any WebElement as parameter.
Can some come up with similar kind of issue, as the above code is not working :(
Cause its Actions class object so you need to tell the driver the actions you are performing.
action.sendKeys("300000").perform();
Will do the needful.