Invalid session id when running parallel tests using chromedrivermanager - selenium

When running tests in parallel sometimes I get this message:
org.openqa.selenium.NoSuchSessionException: invalid session id
I'm using WebDriverManager:
private WebDriver driver;
static { WebDriverManager.chromedriver().setup(); }
public Browser() {
Map<String, Object> prefs = new HashMap<>();
ChromeOptions chromeOptions = new ChromeOptions();
if (GVDLUtils.isOnServerEnv()) {
System.out.println("working on server");
chromeOptions.addArguments("--window-size=1400,900");
chromeOptions.addArguments("--headless");
chromeOptions.addArguments("--no-proxy-server");
chromeOptions.addArguments("--proxy-server='direct://'");
chromeOptions.addArguments("--proxy-bypass-list=*");
}
String FilesPath = System.getProperty("user.dir") + File.separator + SeleniumUtilities.getDownloadsPath();
prefs.put("download.default_directory", FilesPath);
chromeOptions.setExperimentalOption("prefs", prefs);
this.driver = new ChromeDriver(chromeOptions);
if (!GVDLUtils.isOnServerEnv()) {
this.driver.manage().window().maximize();
}
}
And I initiate new browser before each test:
public static String redux = "";
protected Browser browser;
#BeforeMethod
public void initTest() {
this.browser = new Browser();
JavascriptExecutor jse = (JavascriptExecutor) this.browser.getDriver();
jse.executeScript("localStorage.setItem('redux', '"+redux+"')");
}
Any ideas why it happens?

Related

Selenium Actions - jsonKeyboard and jsonMouse = null

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

Parallel Testing Thread Getting Orphaned Selenium

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);
}
}

Passing data to local storage

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;
}

How can I run the same test on browserstack and local browsers?

I've set up NUnit tests that runs on BrowserStack (set up from this example https://github.com/browserstack/nunit-browserstack )
Base class:
namespace Bloc.TestProject
{
public class BrowserStackNUnitTest
{
protected IWebDriver driver;
protected string profile;
protected string environment;
private Local browserStackLocal;
public BrowserStackNUnitTest(string profile, string environment)
{
this.profile = profile;
this.environment = environment;
}
[SetUp]
public void Init()
{
...
Browserstack tests:
namespace Bloc.TestProject
{
[TestFixture("parallel", "chrome")]
[TestFixture("parallel", "ie11")]
[TestFixture("parallel", "iphoneX")]
[TestFixture("parallel", "ipad")]
[TestFixture("parallel", "samsungGalaxyS8")]
[Parallelizable(ParallelScope.Fixtures)]
public class OnTimeOnlineBooking : BrowserStackNUnitTest
{
WebDriverWait wait;
public OnTimeOnlineBooking(string profile, string environment) : base(profile, environment)
{
}
... my tests ...
Local tests:
namespace Bloc.TestProject
{
[TestFixture(typeof(PhantomJSDriver))]
public class LocalBrowserTest<TWebDriver> where TWebDriver : IWebDriver, new()
{
private IWebDriver driver;
[SetUp]
public void CreateDriver()
{
this.driver = new TWebDriver();
}
[TearDown]
public void Cleanup()
{
driver.Quit();
}
... my tests ...
Is there any way I can structure my tests so that I can run a test and it'll run both locally and on browserstack without having to duplicate the test code?
I can Suggest a workaround for this case in Java, needs to change in C#.
write the code of browser-stack setup
public static browserstack_setup() {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("browserName", "chrome");
caps.setCapability("version", "");
caps.setCapability("platform", "windows");
caps.setCapability("os_version", "8.1");
WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
driver.get("http://www.google.com");
}
then write code for launch browser
public void openbrowser(String browsername, String URL){
if(browsername.equalsIgnoreCase("broserstack")){
browserstack_setup();
}else if(browsername.equalsIgnoreCase("CH")){
System.setProperty("webdriver.chrome.driver",chromedriverpath);
driver=new ChromeDriver();
driver.get(URL);
}
}
You may fetch the name from test context and based on that information, launch the local driver or remote driver. For the repo and you example, I assume the below code should work. You may also want to look at other APIs available under TestContext.CurrentContext.Test for your comparison operation
[SetUp]
public void Init()
{
if(TestContext.CurrentContext.Test.Name == "MyTestName"){
this.driver = new TWebDriver();
}
else{
NameValueCollection caps = ConfigurationManager.GetSection("capabilities/" + profile) as NameValueCollection;
NameValueCollection settings = ConfigurationManager.GetSection("environments/" + environment) as NameValueCollection;
DesiredCapabilities capability = new DesiredCapabilities();
foreach (string key in caps.AllKeys)
{
capability.SetCapability(key, caps[key]);
}
foreach (string key in settings.AllKeys)
{
capability.SetCapability(key, settings[key]);
}
String username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
if(username == null)
{
username = ConfigurationManager.AppSettings.Get("user");
}
String accesskey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
if (accesskey == null)
{
accesskey = ConfigurationManager.AppSettings.Get("key");
}
capability.SetCapability("browserstack.user", username);
capability.SetCapability("browserstack.key", accesskey);
if (capability.GetCapability("browserstack.local") != null && capability.GetCapability("browserstack.local").ToString() == "true")
{
browserStackLocal = new Local();
List<KeyValuePair<string, string>> bsLocalArgs = new List<KeyValuePair<string, string>>();
bsLocalArgs.Add(new KeyValuePair<string, string>("key", accesskey));
browserStackLocal.start(bsLocalArgs);
}
driver = new RemoteWebDriver(new Uri("http://"+ ConfigurationManager.AppSettings.Get("server") +"/wd/hub/"), capability);
}
}
You need to ensure you have specified test fixtures for running on Local and Grid. For example, if test A on Safari on Grid and test A on local browser

Why is Gecko Driver (v0.17.0 - x64bit) not opening Browser?

Why is Gecko Driver (v0.17.0 - x64bit) not opening Browser?
Base Page / Method:
public BasePage loadUrl(String url) throws Exception {
driver.get(url);
return new BasePage(driver);
}
Cucumber Step:
#Given("^User navigates to the \"([^\"]*)\" website$")
public void user_navigates_to_the_website(String url) throws Throwable {
BasePage basePage = new BasePage(driver);
basePage.loadUrl(url);
}
Driver Factory:
public WebDriver getDriver() {
try {
if(driver == null){
System.setProperty("webdriver.gecko.driver", Constant.GECKO_DRIVER_DIRECTORY);
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
basePage = PageFactory.initElements(driver, BasePage.class);
loginPage = PageFactory.initElements(driver, LoginPage.class);
}
} catch (Exception e) {
}
return driver;
}
NEW CODE - Driver Factory: uses if statements to point to exe files for each browser type:
public WebDriver getDriver() {
try {
ReadConfigFile file = new ReadConfigFile();
if (driver == null) {
if("chrome".equalsIgnoreCase(file.getBrowser())){
System.setProperty("webdriver.chrome.driver", Constant.CHROME_DRIVER_DIRECTORY);
driver = new ChromeDriver();
}
if("firefox".equalsIgnoreCase(file.getBrowser())){
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
System.setProperty("webdriver.gecko.driver", Constant.GECKO_DRIVER_DIRECTORY);
capabilities.setCapability("marionette", true);
driver = new FirefoxDriver(capabilities);
}
if("ie".equalsIgnoreCase(file.getBrowser())){
System.setProperty("webdriver.ie.driver", Constant.IE_DRIVER_DIRECTORY);
driver = new InternetExplorerDriver();
}
}
}
fixed upgrading to Selenium version: 3.4.0