I'm trying to validate if selenium-chromedriver can share cookies between multiple webdriver instances. The idea is that, I'll create one webdriver instance and login into the application. I'll keep this webdriver instance running and will create another webdriver instance and try to access a secure page on the same site. Since I already logged into the application from first instance, I should be automatically logged into the second instance. But this didn't work. After a lot of research, I found that I need to set a specify the directory where Chrome creates the session cookies while creating the chromedriver instance. Following is the code I have.
public class TestClass {
private static WebDriver webDriver = null;
public static void main(String[] args) throws InterruptedException {
TestClass tc = new TestClass();
if(webDriver == null) {
webDriver = tc.getWebDriverInstance();
webDriver.get("https://example.com/loginpage");
//enter userid/password, click login button
//login is successful and redirected to next page - https://example.com/securepage
}
WebDriver newWebDriverOne = this.getWebDriverInstance();
newWebDriverOne.get("https://example.com/securepage"); // this doesn't work
WebDriver newWebDriverTwo = this.getWebDriverInstance();
newWebDriverTwo.get("https://example.com/securepage");// this doesn't work
}
WebDriver getWebDriverInstance(){
DesiredCapabilities dCaps = DesiredCapabilities.chrome();
ChromeOptions options = new ChromeOptions();
options.addArguments("user-data-dir=C:/user/me/selenium/chrome");
dCaps.setCapability(ChromeOptions.CAPABILITY, options);
return new ChromeDriver(dCaps);
}
}
Problem with this is, when I call get() on the newWebDriver instance which is created after the first one, nothing happens. Selenium opens the second window as since I created a new webdriver instance, but get() doesn't do anything. I tried manually entering the securepage url in the opened window and it worked. I was able to see the secure page without getting redirected to login page.
It seems like it is impossible to have multiple webdriver instances if we specify user-data-dir. Is there any other option to share cookie data between sessions?
----- Update ------
The reason I'm trying to do this is a very peculiar usecase.
--> I need to run multiple automation runs simultaneously - only way I know to achieve this is creating multiple webdriver instances.
--> Automation script needs to login using only one account. And the IDP allows only one active session at a time. That means, if the automation script logs in second webdriver instance, then the first webdriver instance logs out.
So while researching a way to share session between webdriver instances, I came across user-data-dir option.
Couldn't you just use one Chrome Profile and have the cookies saved on the one profile and it would automatically login with those details as it remembers you? I don't see why you would need two instances.
If you wanted to use multiple instances I assume you'd have to load up the exact same profile in a separate instance as a new profile would not work.
Related
Writing acceptance test for Magento 1.9 site using Codeception and Selenium-webdriver I got some issue.
Every time, when driver go to another page, for example clicks link and goes to product page or any other, new session starts. Magento "frontend" cookie get new value every time, so it's create a lot of problems. Troubles with adding item to cart, refusing payment. When I use site manualy, it's OK. Session still the same all the time. So problem is in webdriver. How can I fix it?
use "this" key work for using same instance for webdriver
ex.
#BeforeMethod
public void sample(WebDriver driver)
{`enter code here`
driver1-this.driver;
]
My testing scenario includes launching a url, entering the cutomer id in that page, which gets stored in the web server and is valid till browser session ends. I have to launch a 2nd url and continue for the same session, but in webdriver launching a 2nd url starts a new session. Can this be handled in Webdriver.
You can use get method as many time you want :)
driver.get("1st_URL");
// perform your business logic and then again use get method
driver.get("2nd_URL"); //again
OR you can also use navigate option
driver.navigate().to("2nd_URL");
If you want to open new link with the same session then you should be using remoteWebDriver. Here' how you can do it -
driver = new FirefoxDriver(); //Start you webDriver
driver.get("1st url"); //get url
//Perform operations that you want
//If you are using Firefox use it this way
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
driver = new RemoteWebDriver(new URL("http://localhost:7055/hub"),capabilities); //Now run a RemoteWebdriver
driver.get("2nd url");
More info on remoteWebDriver. Hope this helps.
I was trying to access a https login url to login to a page and do my actions, but unable to do the same.
These are my observations.
When I hit the actual url, internally its leading to another url having JSESSION ID appended to it and then loading the requested page [now actual url formed].
Steps :
The actual url is like : https:/abcd.xyz.com:7443/abcd/Web/Admin
when I hit the above url driver.get("https:/abcd.xyz.com:7443/abcd/Web/Admin"); and when the test is running it appended Jsession id to another url, it looks like below,
https:/abcd.xyz.com:7443/abcd/loginAsGuest.jsp;jsessionid=z712Ty0Rn0BHLTH6Q2Q02cBj233L0JHwNhy7vxW9ntNZDbLJLxQT!-840704556
Then actual url is formed [https://abcd.xyz.com:7443/abcd/Web/Admin] with the page loaded.
Here my problem is, my script is not proceeding from there and getting NoSuchElementFound exception due to which am not able to login to the page.
Any help in resolving the above issue will be very much useful.
My Webdriver code looks like :
FirefoxProfile profile = new FirefoxProfile();
profile.setAssumeUntrustedCertificateIssuer(false);
WebDriver driver = new FirefoxDriver();
driver.get("https://abcd.xyz.com:7443/abcd/Web/Admin");
WebElement uname = driver.findElement(By.name("username"));
WebElement pwd = driver.findElement(By.name("password"));
log shows something like this :
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"name","selector":"username"}
Any help in resolving the above issue will be very much useful.
Thanks,
-Anil 09566212889
I think it will be useful for you...
FirefoxDriver Driver=new FirefoxDriver();
Driver.get("http://www.gmail.com");
Thread.sleep(1000);
Driver.findElement(By.id("Email")).sendKeys("xx");
Driver.findElement(By.id("Passwd")).sendKeys("xx");
Driver.findElement(By.id("signIn")).click();
Thread.sleep(10000);
I'm not sure if this will help, but I've used this method a few times. You need to form your get request with the login information you want to use like username:password#url.com. I can't remember where I saw to do this, but I'll try to dig it up.
In Python it would look like the following:
browser = webdriver.Firefox()
browser.get("https://username:password#192.168.1.1")
Previously I have been using chrome Auto Refresh plug in. However, now my code has multiple ChromeDriver instances opening and closing and I cannot use Auto Refresh. Also, it is quite a hassle to install Auto Refresh on new computers.
Is there any way to refresh driver (simulate F5 say every 15 seconds if driver does not change remains motionless) with Selenium similar to Google Auto Refresh?
refresh is a built in command.
driver = webdriver.Chrome()
driver.get("http://www.google.com")
driver.refresh()
If you don't have the chrome driver it can be found here:
https://code.google.com/p/chromedriver/downloads/list
Put the binary in the same folder as the python script you're writing. (Or add it to the path or whatever, more information here: https://code.google.com/p/selenium/wiki/ChromeDriver)
edit:
If you want to refresh ever 10 seconds or something, just wrap the refresh line with a loop and a delay. For example:
import time
while(True):
driver.refresh()
time.sleep(refresh_time_in_seconds)
If you only want to refresh if the page hasn't changed in the meantime, keep track of the page that you're on. driver.current_url is the url of the current page. So putting it all together it would be:
import time
refresh_time_in_seconds = 15
driver = webdriver.Chrome()
driver.get("http://www.google.com")
url = driver.current_url
while(True):
if url == driver.current_url:
driver.refresh()
url = driver.current_url
time.sleep(refresh_time_in_seconds)
Well there are two ways of doing this.
1. We can use refresh method
driver.get("some website url");
driver.navigate().refresh();
We can use actions class and mimic F5 press
Actions act = new Actions(driver);
act.SendKeys(Keys.F5).perform();
If you write unit tests that must be run like if you had to open/refresh a new browser session each time, you can use a method with before annotations:
#Before
public void refreshPage() {
driver.navigate().refresh();
}
If all tests are individually successful (green) but fail all together, the reason might also been that you need to wait for some resources to be available on the page, so you also need to handle it, setting the timeout like this:
public WebElement getSaveButton() {
return findDynamicElementByXPath(By.xpath("//*[#id=\"form:btnSave\"]"), 320);
}
320 is a long time, but you must make sure that you give enough time to get all that it takes to test.
I just started using Selenium Web Driver to test an online banking transaction application.
I love it, but there is something that annoy me. Let say i access the login screen with this code:
driver.get("https://webdev.myurl:18113/");
WebElement element = driver.findElement(By.name("username"));
element.sendKeys("xxxx");
element.submit();
the browser start and the page load and display. But it look like the page try loading element from an external site and the findElement (2nd line) wait for these request to complete!
Is there a way to bypass this beahvior?
I tried this too :
WebElement element = (new WebDriverWait(driver, 10)).until(new ExpectedCondition<WebElement>() {
#Override
public WebElement apply(WebDriver d) {
return d.findElement(By.name("username"));
}
});
But it does not help since this line seems to execute only when the page is totally loaded.
EDIT: I spoke with one of the guy here.. and he told me ipinvite.iperceptions.com is not called by our app.!!! and in fact when i load the site in FF, i don't see this call?!
Does Selenium web driver call this site : ipinvite.iperceptions.com?
Anyone have the same issue?
You can try setting implicitly wait time and page load time to 0. Google "selenium implicitly wait time" and "selenium page load time."
Time outs on get function have not been implemented yet.
When creating a new FirefoxDriver, there are overloads in the constructor that allow you to specify a command timeout which is the maximum time to wait for each command.
You could refer to the answer on this post
ok, i found the problem. I commented out the setPreference to my FirefoxProfile that was setting the proxy parameters. I noticed i did not need them anyway. And now there is no more call to this wierd ipinvite.iperception.com!
Thanks for the time you took to reply
Regards