Selenium Webdriver sessionId or check if all browser windows are closed - selenium

Is there a way to see if all the browser windows are closed? I see that if you call driver.quit() or driver.close() on the WebDriver, the sessionId becomes null. Is there a way to check that?
I don't want to make a call to a closed or quit driver as it throws a WebDriverException. So I want to check to see the state of the browser before continuing on.

Just set
driver=null;
everytime you quit the browser and than check
if (browser!=null){
//Attention: this comand is not supported
//as far as i know ;)
driver.doSomething();
}
or
try{
}catch (NullPointerException e)
e.printStackTrace();
System.err.print"DAMN";
}
or receive a NullPointerException ;)

public bool InstanceExist
{
get
{
if (Instance != null)
{
try
{
return (Instance.WindowHandles != null); // allways returns true if browser instance exist or thrown error
}
catch (Exception e)
{
return false;
// means that browser was closed by user
}
}
return false; // means that it wasn't created yet or was closed by developer programmally
}
}
You need to check 3 situations:
driver wasnt created
driver was closed by developer
browser was closed by user, but driwer instance still exists
All of those situations is checked with this code.

I think the cleanest way to detect if all windows are closed is smth like:
boolean allWindowsClosed = webDriver.getWindowHandles().isEmpty();
getWindowHandles returns a set of window handles for all open windows - see http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebDriver.html#getWindowHandles()

Actually calling getWindowHandles while the browser windows is gone will raise an "UnreachableBrowserException".
You have to put the call into a try-catch block and handle that error. Actually that is the only known WORKING workournd for catching unexpected browser windows closes. I have a static method in a config class doing my driver handling: I restart my browser like this:
protected static void loadPages() {
if (driver == null || driver.toString().contains("null")) { //null refers to an missing session id
driver = new FirefoxDriver();
//load all my page objects like
loginpage = new LoginPage(driver);
//....
//....
}
try {
if (driver.getWindowHandles() == null || driver.getWindowHandles().isEmpty()){ //will cause an UnreachableBrowserException if the browser really is not avalable.
try { //you actually dont need this try catch block
driver.quit();
} catch (Exception e) {
System.err.println("Quitting levtover driver did not work.");
}
driver = null; //you have to set the driver to null
loadPages();
}
} catch (UnreachableBrowserException ube) {
driver = null; //like above set to null to make sure no driver left
}
}
Now, ofc your current test will fail but you will be able to go on with the rest of them.

in C#
public void BrowserCheck()
{
try
{
var h = webDriver.WindowHandles;
return; // no problem
}
catch // browser window is closed so re-init it
{
webDriver.Quit();
WebDriverInit(); // your init code
}
}

Related

Stopwatch timer not updated while AndroidDriver is waiting

I have a specific case in which I have to pause my driver using a method found somewhere here on s/o for a minute in order to achieve a valid booking time(>60s) which looks like this:
return waitf.until(new Function<WebDriver, Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement timer = null;
try {
timer = driver.findElement(By.xpath(Utils.STOPWATCH_TIMER));
String timerTextString = timer.getText(); // so question
LocalTime localTime = LocalTime.parse(timerTextString, DateTimeFormatter.ofPattern("H:mm:ss"));
if (localTime.isAfter(LocalTime.of(0, 1, 5))) {
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
});
Now, the thing is that the variable timerTextString doesn't update, because when I debugged the value(0:00:00) it didn't change the whole time. My understanding of it was that the driver should poll and check every xx miliseconds and update the value. On the web version of my application it worked but on the mobile app I have this presented situation. I also tried using implicit wait but it didn't help me.

I am not able to switch to IFrame using Internet Explorer

I have developed a s keyword driven framework. It has a action keyword to switch the frame.
It works fine with Mozilla. But when it comes to IE it is not switching. It logs error.
IE driver -IEDriverServer_x64_2.44.0
IE version -9
Selenium version -selenium-java-2.44.0
Thanks in advance.
public static void switchFrame(String object,String data)throws Exception{
try{
driver.switchTo().frame("Ifrm");
Log.info("Switched the frame");
}
catch(Exception e){
Log.error("Not able to switch the frame--- " + e.getMessage());
DriverScript.bResult = false;
}
}
Here exception occurs.
I assume, the value you specified in frame is id/name/etc. You have to access the frame by calling the driver with specified value. Code would be
driver.switchTo().frame(driver.findElement(By.id("Ifrm")));
Selenium won't let me switch to the iframe by ID on Internet Explorer, but it does allow me to switch by index. If you have some sort of property that you can check that it is only available on the iframe you can do the following
new WebDriverWait(driver, 5).until(
new Predicate<WebDriver>() {
#Override
public boolean apply(WebDriver input) {
try {
int i = 1;
while (true) {
driver.switchTo().defaultContent();
driver.switchTo().frame(i);
String aClass =
driver.findElement(By.xpath("/html/body"))
.getAttribute("class");
if (aClass.contains("modal")) {
return true;
}
++i;
}
} catch (NoSuchFrameException e) {
return false;
}
}
}
);
In my case I was looking for a body class of modal

play, java8 - re-use test fake application in tests?

is there anyway to stop the actor system from shutting down and starting up between tests?
I keep getting akka exceptions complaining about the actor system being down.
I can mock/stub to get rid of the reliance on the fake app but it needs a bit of work - hoping to be able to just start one static test application up and run different things in the app.
Eg I have a (crappy) test like this - can I somehow re-use the running app between tests? it still seems to shut down somewhere along the line.
running(Fixtures.testSvr, HTMLUNIT, browser -> new JavaTestKit(system) {{
F.Promise<TestResponseObject> resultPromise = client.makeRequest("request", "parameterObject", system.dispatcher());
boolean gotUnmarshallingException = false;
try {
Await.result(resultPromise.wrapped(), TotesTestFixtures.timeout.duration());
} catch (Exception e) {
if ((e instanceof exceptions.UnmarshallingException)) {
gotUnmarshallingException = true;
}
}
if(gotUnmarshallingException == false) fail();
}});
You can try to get rid of the running method (it stops the testserver at the end) and initialize a testserver by yourself, but I don't know if Akka will be available to you:
#BeforeClass
public static void start() {
testServer = testServer(PORT, fakeApplication(inMemoryDatabase()));
testServer.start();
// Maybe you dont ned this...
try {
testbrowser = new TestBrowser(HTMLUNIT, "http://localhost:" + PORT);
} catch (Exception e) {
}
}
#Test
public void testOne() {
new JavaTestKit() {
// (...)
}
}
#AfterClass
public static void stop() {
testServer.stop();
}

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

NullPointerException in PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()

//obtain the active page
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
returns Exception in thread "Thread-3" java.lang.NullPointerExceptionµ.
What shall i do?
If the thread does not run in the active window, PlatformUI.getWorkbench().getActiveWorkbenchWindow() will return "null".
You must wrap your code in a Display, e.g.:
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
IWorkbenchWindow iw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
}
});
Add some null checks, it is possible for the workbench to not have an active window, not it is also possible for PlatformUI.getWorkbench to throw an IllegalStateException if the workbench is not yet started (e.g createAndRunWorkbench() has not yet been called).
IWorkbenchWindow window = PlatformUI.getWorkbench().getInstance()
.getActiveWorkbenchWindow();
if(workbenchWindow != null) {
IWorkbenchPage page = window .getActivePage();
}
I have a work-around for this. even though its an old post.
IWorkbench wb = PlatformUI.getWorkbench();
if (wb.getWorkbenchWindowCount() == 1) {
try{
wb.getWorkbenchWindows()[0].getActivePage().getPerspective();
}
catch(NullPointerException e)
{
Logger.log(e);
}
}