Selenium: cookie functionality not working - selenium

I am new to selenium. I am trying to test an application. Application has two pages login.jsp, restricted.jsp. You can access restricted.jsp, only after login (trying to access restricted.jsp without login will redirect to login.jsp page). My selenium application is like below.
a. Login to the app first
b. After successful login, store all the cookies to "session.properties" file.
c. Next time onwards, I am loading all the cookies from "session.properties" to driver and try to access "restricted.jsp" page. But I am redirecting to login.jsp, instead of restricted.jsp.
Following is my Java code.
public class App {
private static void loginApp(WebDriver driver) {
driver.get("http://localhost:8080/selenium_app/login");
WebElement userName = driver.findElement(By.name("userName"));
WebElement password = driver.findElement(By.name("password"));
userName.sendKeys("admin");
password.sendKeys("admin");
userName.submit();
}
private static void storeSessionProps(WebDriver driver) throws IOException {
File f = new File("session.properties");
f.delete();
f.createNewFile();
FileWriter fos = new FileWriter(f);
BufferedWriter bos = new BufferedWriter(fos);
/* Get all the cookies and store them to session.properties file */
Set<Cookie> cookies = driver.manage().getCookies();
for (Cookie cookie : cookies) {
bos.write(cookie.getName() + "=" + cookie.getValue());
bos.newLine();
}
bos.flush();
bos.close();
fos.close();
}
private static void loadPropertiesToDriver(WebDriver driver)
throws IOException {
Properties properties = new Properties();
FileInputStream fin = new FileInputStream("session.properties");
properties.load(fin);
Set<Object> props = properties.keySet();
for (Object prop : props) {
Cookie ck = new Cookie((String) prop,
properties.getProperty((String) prop));
driver.manage().addCookie(ck);
System.out.println(ck);
}
}
public static void main(String[] args) throws InterruptedException,
IOException {
WebDriver driver = new FirefoxDriver();
// loginApp(driver);
// storeSessionProps(driver);
loadPropertiesToDriver(driver);
driver.get("http://localhost:8080/selenium_app/restricted");
Thread.sleep(5000);
driver.quit();
}
}
When I uncomment the lines loginApp(driver);, storeSessionProps(driver); everything is fine, I am able to access restricted.jsp page, but when I ran application by commenting those and loading the cookies, I am redirecting to login.jsp page. Any help on this??

You need to store all the data from your cookies, not just the names/values. Moreover, before creating a cookie, your need to load a page with a domain that will match the domain of the cookie.
This is an example to quickly store and restore the cookies:
Path cookiesFile = Paths.get("C:\\Temp\\cookies.txt");
WebDriver driver = new FirefoxDriver();
JavascriptExecutor js = (JavascriptExecutor)driver;
// load the domain
driver.get("https://www.google.com");
if(cookiesFile.toFile().exists()) {
// load the cookies into the browser for the current domain
String cookies = new String(Files.readAllBytes(cookiesFile), Charsets.UTF_8);
js.executeScript(cookies);
// reload the page with the injected cookies
driver.get("https://www.google.com");
}
// save the cookies to a file for the current domain
try(PrintWriter file = new PrintWriter(cookiesFile.toFile(), "UTF-8")){
for(Cookie c : driver.manage().getCookies()) {
file.println("document.cookie='" + c.toString() + "';");
}
}

Related

driver.getCurrentUrl() returns data:, instead of actual URL

I'm writing a test with Serenity BDD-Cucumber.
I want to check if the URL is correct when it's navigated. But the result always shows data, and my test fails with driver.getCurrentUrl().
Please see my code below:
Feature steps:
public void homePageOpens() {
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.titleContains("STORE"));
String homepageUrl = navigationUser.getUrl();
System.out.println(homepageUrl);
Assert.assertTrue(homepageUrl.contains("https://www.example.com/index.html"));
driver.close();
}
Navigation steps:
#Step("Get the URL")
public String getUrl() { return basePage.getUrl();
}
BasePage:
public String getUrl() {
System.out.println("just testing");
WebDriver driver = new ChromeDriver();
return driver.getCurrentUrl();
}
This also opens a page with URL: "data:," which doesn't close after the test
Use driver.get in order to navigate somewhere.
String someUrl = "https://www.example.com/index.html";
driver.get(someUrl);
This code:
public String getUrl() {
System.out.println("just testing");
WebDriver driver = new ChromeDriver();
return driver.getCurrentUrl();
}
just launch the browser, and the initial url is data:,.
Also it's unclear why BasePage getUrl() method launches the new webdriver and uses it as a local variable. But in homePageOpens() method in feature steps looks like some another driver used..

while using cookies in Xunit Selenium C# Got System.NullReferenceException : Object reference not set to an instance of an object Error

[Theory]
[InlineData(BrowserType.Chrome)]
[InlineData(BrowserType.Firefox)]
public void GetCookies(BrowserType browserType)
{
using (var driver = WebDriverInfra.Create_Browser(browserType))
{
driver.Manage().Cookies.DeleteAllCookies();
TestOutputHelper.WriteLine("Login is started.");
Wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl(LoginUrl);
driver.FindElement(By.Id("username")).SendKeys(Username);
driver.FindElement(By.Id("password")).SendKeys(Password);
driver.FindElement(By.ClassName("submit")).Click();
string welcomeSign = Wait.Until<string>(driver => driver.FindElement(By.XPath("/html/body/div[1]/div[2]/div[2]/div/div[1]/div/div/div/div[1]/h2")).Text);
welcomeSign.Should().NotBeNull();
welcomeSign.Should().Contain("Welcome");
var userFirstNameCookie = Driver.Manage().Cookies.GetCookieNamed("userFirstName")
userFirstNameCookie.Value.Should().Be(FirstName);
TestOutputHelper.WriteLine("login is completed.");
webDriverInfra.CS
public static IWebDriver Create_Browser(BrowserType browserType)
{
switch (browserType)
{
case BrowserType.Chrome:
return new ChromeDriver();
case BrowserType.Firefox:
return new FirefoxDriver();
default:
throw new ArgumentOutOfRangeException(nameof(browserType), browserType, null);
}
}
Browsertype.CS
public enum BrowserType
{
NotSet,
Chrome,
Firefox,
}
Can anyone help me on this to get rid of the null reference exception. This is my whole code. My test is passing till login when it hits the cookie line the null exception appears.

Selenium Firefox Browser has no internet connection

Selenium Firefox Browser has no internet connection :- when i try to run my selenium script using firefox , I get no internet connection error where as i do have good internet connection. Can anyone help?Thanks in advance
Here is the code, Its a dataprovider code to be able to create the data driven tests. But everytime i run this whether on firefox or be it chrome its not working
public class Test2 {
//webdriver object
WebDriver driver;
//test annotation
#Test(dataProvider="wordpressdata")
public void loginTest(String Username, String Password) throws InterruptedException{
//Setting the system property to use chrome exe
System.setProperty("webdriver.chrome.driver","C:\\Downloads\\Softwares\\chromedriver_win32\\chromedriver.exe" );
driver=new ChromeDriver();
driver.navigate().to("http://demosite.center/wordpress/wp-login.php");
Thread.sleep(5000);
driver.findElement(By.id("user_login")).sendKeys(Username);
driver.findElement(By.id("user_pass")).sendKeys(Password);
driver.findElement(By.xpath(".//*[#id='wp-submit']")).click();
}
//this is after method for driver quit
#AfterMethod
public void teardown(){
driver.quit();
}
//this is data provider
#DataProvider(name="wordpressdata")
public Object[][] passdata(){
Object[][] data = new Object[3][2];
data[0][0] = "Admin";
data[0][1] = "demo123";
data[1][0] = "Admin";
data[1][1] = "demo23";
data[2][0] = "Admin";
data[2][1] = "demo14";
return data;
}
}
This code is not letting me open it in either Firefox browser or Chrome.

Wait for page loading using PageFactory C#

I'm using PageFactory in my selenium tests. And I've faced a problem in waiting for loading page. I'm not talking about an element on a page I'm talking about timeout of page loading.
So, I have a method like the following:
public MyProjectsPage ClickSaveAndCloseButton()
{
//Do something and click a button
SaveAndCloseButton.Click();
return new MyProjectsPage(Driver); //return new page
}
And when I'm waiting for returning new PageObject (in my case it is "MyProjectsPage") I got a timeout exception. So, where can I set a page loading timeout?
Actual mistake looks like this:
AutomatedTests.FrontEnd.SouvenirProduct.SouvenirTestExecution.OrderSouvenirWithAuthorization(ByCash,Pickup,True,Cup):
OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:7585/session/b68c04d1ead1fc78fe083e06cbece38f/element/0.46564483968541026-14/click timed out after 60 seconds.
----> System.Net.WebException : The operation has timed out
I have:
The latest version of WebDriver
And the latest version of ChromeDriver and the latest version of Chrome Browser
The mistake that is above apears int the next line:
return new MyProjectsPage(Driver); //return new page
I create my ChromeDriver the next way:
public DriverCover(IWebDriver driver)
{
_driver = driver;
_driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
}
private readonly IWebDriver _driver;
1 note considering wait mechanisms on the page:
Take a couple of webElements and apply for them fluentWait() . That'll be explicit wait webdriver approach.
Another approach is to try out implicit wait like:
int timeToWait=10;
driver.manage().timeouts().implicitlyWait(timeToWait, TimeUnit.SECONDS);
Considering you pageObject code:
I would recommed you the following:
MyPage myPageInstance= PageFactory.initElements(driver, MyPage.class);
then you write the following method :
public MyPage clickSaveAndOtherActions(MyPage testPageToClick)
{
testPageToClick.clickFirstButton();
testPageToClick.clickSecondButton();
testPageToClick.closePoPup();
return testPageToClick; //return page in a new state
}
and if you wanna continue working (I mean update your page state) you do the following:
myPageInstance = clickSaveAndOtherActions(myPageInstance );
Hope this helps you. Thanks.
UPD : as I see from the log something looks wrong with remoteWebdriver server:
OpenQA.Selenium.WebDriverException : The HTTP request to the remote
WebDriver server for URL
http://localhost:7585/session/b68c04d1ead1fc78fe083e06cbece38f/element/0.46564483968541026-14/click
timed out after 60 seconds. ----> System.Net.WebException : The
operation has timed out
Also, I'd recommend you to double check you driver method init. I'm using the following piece of java code for driver init (UI , chrome instance, selenium grid+ hub nodes test architecture):
public static WebDriver driverSetUp(WebDriver driver) throws MalformedURLException {
DesiredCapabilities capability = DesiredCapabilities.chrome();
log.info("Google chrome is selected");
//System.setProperty("webdriver.chrome.driver", System.getProperty("user.home")+"/Documents/Tanjarine/chromedriver");
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
capability.setBrowserName("chrome");
capability.setPlatform(org.openqa.selenium.Platform.WINDOWS);
String webDriverURL = "http://" + environmentData.getHubIP() + ":" + environmentData.getHubPort() + "/wd/hub";
driver = new RemoteWebDriver(new URL(webDriverURL), capability);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1920, 1080));
return driver;
}
What you should really be doing when using the PageFactory pattern is when initialising your Page you should be using a constructor to initialise the elements.
public MyProjectsPage ClickSaveAndCloseButton()
{
//Do something and click a button
//I am guessing this is taking you to the MyProjectsPage
SaveAndCloseButton.Click();
return new MyProjectsPage(Driver); //return new page
}
public class MyProjectsPage
{
[FindsBy(How = How.Id, Using = "yourId")]
public IWebElement AWebElement { get; set; }
private IWebDriver WebDriver;
public MyProjectsPage (IWebDriver webDriver)
{
WebDriver = webDriver;
PageFactory.InitElements(WebDriver, this);
}
}
When you return the page, all elements using the FindsBy attribute will be initialised.
Update:
set this property on the driver when you initialise it:
WebDriver.Manage().Timeouts().SetPageLoadTimeout(timespan)
// Wait Until Object is Clickable
public static void WaitUntilClickable(IWebElement elementLocator, int timeout)
{
try
{
WebDriverWait waitForElement = new WebDriverWait(DriverUtil.driver, TimeSpan.FromSeconds(10));
waitForElement.Until(ExpectedConditions.ElementToBeClickable(elementLocator));
}
catch (NoSuchElementException)
{
Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");
throw;
}
}
// Wait For Page To Load
public static void WaitForPage()
{
new WebDriverWait(DriverUtil.driver, MyDefaultTimeout).Until(
d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
}

How to pass through window asking for basic auth credentials that appears when click link redirecting from HTTP to HTTPS?

I have a website where most of pages are normally used via HTTP but some other pages are available only via HTTPS. Site is protected by basic auth (credentials are the same for HTTP and HTTPS pages).
When I open any HTTP page in browser (either FF or Chrome) and click link that leads to HTTPS page, browser shows alert that asks for basic auth credentials.
I have same issue with Webdriver (either FF or Chrome):
When I visit http://username:password#some_domain.com and click link that leads to HTTPS page, browser alert window that asks for basic auth credentials appears. Selenium doesn't "remember" credentials that were entered for HTTP page.
How can I follow this sequence of actions with Webdriver? If it's not possible what can you advice?
FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("network.http.phishy-userpass-length", 255);
profile.SetPreference("network.automatic-ntlm-auth.trusted-uris", hostname);
Driver = new FirefoxDriver(profile);
hostname is your URL (example.com) then try to
Driver.Navigate().GoToUrl(http://user:password#example.com);
The best solution I've been able to come up with so far is create a new Thread that handles a timeout. As WebDriver doesn't return control on FF and other certain browsers, I can call the thread handler that then uses Robot to enter in the credentials and press enter (could also use AutoIt here). Then the control is returned back to WebDriver to continue with script.
//put this where it belongs, say calling a new url, or clicking a link
//assuming necessary imports
int pageLoadTimeout = 10;
String basicAuthUser = "user";
String basicAuthPass = "pass";
String url = "https://yourdomain.com";
WebDriver driver = new FirefoxDriver();
TimeoutThread timeoutThread = new TimeoutThread(pageLoadTimeout);
timeoutThread.start();
driver.get(url);
//if we return from driver.get() call and timeout actually occured, wait for hanlder to complete
if (timeoutThread.timeoutOccurred){
while (!timeoutThread.completed)
Thread.sleep(200);
}
else {
//else cancel the timeout thread
timeoutThread.interrupt();
}
public class TimeoutThread extends Thread {
int timeout;
boolean timeoutOccurred;
boolean completed;
public TimeoutThread(int seconds) {
this.timeout = seconds;
this.completed = false;
this.timeoutOccurred = false;
}
public void run() {
try {
Thread.sleep(timeout * 1000);
this.timeoutOccurred = true;
this.handleTimeout();
this.completed = true;
}
catch (InterruptedException e) {
return;
}
catch (Exception e){
System.out.println("Exception on TimeoutThread.run(): "+e.getMessage());
}
}
public void handleTimeout(){
System.out.println("Typing in user/pass for basic auth prompt");
try {
Robot robot = new Robot();
//type is defined elsewhere - not illustrating for this example
type(basicAuthUser);
Thread.sleep(500);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
Thread.sleep(500);
type(basicAuthPass);
Thread.sleep(500);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
}
catch (AWTException e) {
System.out.println("Failed to type keys: "+e.getMessage());
}
}
}