Handling an AngularJS popup with Selenium WD - java

The following picture shows a pop-up that appears when clicked on the "Random User" text; WD is not able to shift its focus to the pop-up you see.
Below is the code I employed with various trial codes commented as in
public static void teardownAppRetrieveOnce() throws InterruptedException {
synchronized(obj){
obj.wait(2000);
driver.findElement(By.xpath(".//*[#id='sidebar']/nav/ul[2]/li[3]/button[1]/span/span")).click();
System.out.println("Clicked sidebar..");
obj.wait(2000);
String winHandleBefore = driver.getWindowHandle();
**driver.switchTo().window(winHandleBefore);
driver.switchTo().findElement(By.id(".//*[#id='logoutButton']")).click();**
***driver.switchTo().activeElement().findElement(By.id(".//*[#id='logoutButton']")).click();***
System.out.println("Clicked on logout");
obj.wait(2000);
driver.switchTo().alert().accept();
obj.wait(2000);
System.out.println("Logged out...");
}
}
Please help me clarify if such pop-up means a separate new window or frame that is to be handled?
NOTE:
** means the first solution I tried that failed
*** means the second solution i tried that too failed

I have had a lot of trouble with WebDriver/AngularJS. Sometimes native Selenium methods of WebElements work - sometimes not. The best solution is to execute raw Javascript on the web page.
I your case, it would be something like this:
driver.executeScript("$x(\".//*[#id='logoutButton']\")[0].click()");

Related

How can I tell Selenium to press cancel on a print popup?

I am checking whether or not a page appears using Selenium. When I click the page, however, a printer print prompt appears (like the window that says select printer and such). How can I have Selenium close this window by hitting cancel?
I tried looking to alerts, but it seems like those will not work since the print window is a system prompt. It does not recognize any alerts appearing.
The most recent I tried using is by just sending keys like tab and enter in order to have the cancel button selected, however, it doesn't recognize any keys as being pressed.
How can I handle this case?
public static boolean printButton() throws Exception {
WebDriver driver = new FirefoxDriver();
driver.get("website");
try {
Thread.sleep(3000);
WebElement temp = driver.findElement(By.xpath("//*[#id='block-print-ui-print-links']/div/span/a"));
temp.click();
Actions action = new Actions(driver);
action.sendKeys(Keys.TAB).sendKeys(Keys.ENTER);
Thread.sleep(6000);
}
catch (Exception e) {
System.out.println("No button.");
driver.close();
return false;
}
I would simply disable the print dialog by overriding the print method :
((JavascriptExecutor)driver).executeScript("window.print=function(){};");
But if you goal is to test that the printing is called then :
// get the print button
WebElement print_button = driver.findElement(By.cssSelector("..."));
// click on the print button and wait for print to be called
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);
((JavascriptExecutor)driver).executeAsyncScript(
"var callback = arguments[1];" +
"window.print = function(){callback();};" +
"arguments[0].click();"
, print_button);
If you are going for testing only Chrome browser here is mine solution. Because of 'Robot' class or disabling print didn't work for my case.
// Choosing the second window which is the print dialog.
// Switching to opened window of print dialog.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
// Runs javascript code for cancelling print operation.
// This code only executes for Chrome browsers.
JavascriptExecutor executor = (JavascriptExecutor) driver.getWebDriver();
executor.executeScript("document.getElementsByClassName('cancel')[0].click();");
// Switches to main window after print dialog operation.
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
Edit: In Chrome 71 this doesn't seem to work anymore since the script can't find the Cancel button. I could make it work by changing the line to:
executor.executeScript("document.querySelector(\"print-preview-app\").shadowRoot.querySelector(\"print-preview-header\").shadowRoot.querySelector(\"paper-button.cancel-button\").click();");
Actually you can't handle windows (OS) dialogs inside Selenium WebDriver.
This what the selenium team answers here
The current team position is that the print dialog is out of scope for
the project. WebDriver/Selenium is focused on emulating a user's
interaction with the rendered content of a web page. Other aspects of
the browser including, but not limited to print dialogs, save dialogs,
and browser chrome, are all out of scope.
You can try different approach like AutoIt
we can also use key for handling the print or press the cancel button operation. and it works for me.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
WebElement webElement = driver.findElement(By.tagName("body"));
webElement.sendKeys(Keys.TAB);
webElement.sendKeys(Keys.ENTER);
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
Native window based dialog can be handled by AutoItX as described in the following code
File file = new File("lib", jacobDllVersionToUse);
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
WebDriver driver = new FirefoxDriver();
driver.get("http://www.joecolantonio.com/SeleniumTestPage.html");
WebElement printButton = driver.findElement(By.id("printButton"));
printButton.click();
AutoItX x = new AutoItX();
x.winActivate("Print");
x.winWaitActive("Print");
x.controlClick("Print", "", "1058");
x.ControlSetText("Print", "", "1153", "50");
Thread.sleep(3000); //This was added just so you could see that the values did change.
x.controlClick("Print", "", "2");
Reference : http://www.joecolantonio.com/2014/07/21/selenium-how-to-handle-windows-based-dialogs-and-pop-ups/
Sometimes 2 different statements as above (webElement.sendKeys(Keys.TAB)
webElement.sendKeys(Keys.ENTER)) will not work, you can use with combination of Tab and Enter keys as below, This will close the Print preview window.
Using C# :
Driver.SwitchTo().Window(Driver.WindowHandles[1]);
IWebElement element = Driver.FindElement(By.TagName("body"));
element.SendKeys(Keys.Tab + Keys.Enter);
Driver.SwitchTo().Window(Driver.WindowHandles[0]);
Erçin Akçay answer updated.
// Choosing the second window which is the print dialog.
// Switching to opened window of print dialog.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
// Runs javascript code for cancelling print operation.
// This code only executes for Chrome browsers.
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.querySelector(\"body > print-preview-app\").shadowRoot.querySelector(\"#sidebar\").shadowRoot.querySelector(\"print-preview-button-strip\").shadowRoot.querySelector(\"div > cr-button.cancel-button\").click();");
// Switches to main window after print dialog operation.
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());

Pop up message to display for few seconds in selenium

I am running a selenium script using Java. The functionality of the code is to open a Google web page and exit the browser.
After exiting the browser i need a pop up message to be displayed saying "Code executed" and fade away in couple of seconds.
I believe there is an way to display a message either by using JQuery or Javascript but i do not know how to inject that JQuery/Javascript method into my script.
Here's my code:
public class test1 {
public static void main(String[] args) {
WebDriver driver=new FirefoxDriver();
driver.get("http://google.com");
driver.quit();
//I need a method here to display a pop up msg and fade away
}
}
Add this line where ever you want to display the popup box.
JOptionPane.showMessageDialog(frame,"Welcome please look in to the process");
plese go through https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html
Regards,
BK

The screen is not navigating even the click() method is executed successfully in mobile web app using selenium web driver

I was trying to click a button on my mobile web app, using selenium web driver. The button is located, the text over the button can be derived and even the click event is performing well. But the navigation doesn't occur.
I tried with Click() method, sendKeys() method and also with script executor. But couldn't process further on.
CODE:
public class TestWeb
{
WebDriver driver;
private Selenium selenium;
#Before
public void setUp() throws Exception {
driver = new IPhoneDriver();
driver.get("http://10.5.95.25/mobilebanking");
}
#Test
public void TC() throws Exception {
System.out.println("page 1");
Thread.sleep(5000);
WebElement editbtn1 = driver.findElement(By.id("ext-comp-1018"));
String s1 = editbtn1.getText();
System.out.println(s1);
editbtn1.click();
editbtn1.sendKeys(Keys.ENTER);
((JavascriptExecutor)driver).executeScript("arguments[0].click;", editbtn1);
System.out.println("ok");
}
#After
public void tearDown() throws Exception {
System.out.println("*******Execution Over***********");
}
}
I tried click, sendKeys and ScriptExecutor separately and also combined. It is executing without any error but the navigation doesn't occur.
Does anybody can help me with some other ways to perform click function on the button?
Ram
This may not be your issue but I noticed "ext-comp-" and guess you are using extjs.
I'm using GXT and while finding by id worked for many things, on some submit buttons it didn't.
I had to use firebug in firefox to locate the element and copy the xpath.
Then I could click the element by
driver.findElement(By.xpath("//div[#id='LOGIN_SUBMIT']/div/table/tbody/tr[2]/td[2]/div/div/table/tbody/tr/td/div")).click(); // worked
It was failing silently for me too. My submit button has the id of LOGIN_SUBMIT so I don't know why the following failed but ....
driver.findElement(By.id("LOGIN_SUBMIT")).click();//failed
Edit:
Here is an exact example (case 1 of 2):
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#id='gwt-debug-LOGIN_SUBMIT']")));
//wait.until(ExpectedConditions.elementToBeClickable((By.id("gwt-debug-LOGIN_SUBMIT")))); <!-- id works as well
OK so the element is found. It will timeout and throw an exception if it is not.
Still, the following fails (under firefox, works with chrome) with no error and the page does not navigate.
driver.findElement(By.xpath("//div[#id='gwt-debug-LOGIN_SUBMIT']")).click();
//driver.findElement(By.id("gwt-debug-LOGIN_SUBMIT")).click(); <-- fails too
What I have to do is:
driver.findElement(By.xpath("//div[#id='gwt-debug-LOGIN_SUBMIT']/div/table/tbody/tr[2]/td[2]/div/div/table/tbody/tr/td/div")).click();
So my experience was that even if I found the element with xpath, clicking failed unless I used a complete xpath.
Here is another exact example (case 2 of 2):
I can find an element like so:
WebElement we = driver.findElement(By.xpath("//*[#id=\"text" + i + "\"]"));
I know I have found it because I can see the text via:
we.getText();
Still selecting by the path I found it fails.
//get outta town man the following fails
driver.findElement(By.xpath("//*[#id=\"text" + i + "\"]")).click();
In this case there is not more explicit xpath to try as in case 1
What I had to do was use css:
//bingo baby works fine
driver.findElement(By.cssSelector("div#text" + i + ".myChoices")).click();
Actually, I obtained the css path via firebug than shortened it.
//this is what I recieved
html.ext-strict body.ext-gecko div#x-auto-0.x-component div#x-auto-1.x-component div#x-auto-3..myBlank div#choicePanel1.myBlank div.x-box-inner div#text3.myChoices //text3 is the id of the element I wanted to select
Whether or not you can figure out your needed xpaths and css selectors, I don't know, but I believe I experienced exactly what you did.

Webdriver showModalDialog

We are using webdriver for our functional tests. But our application uses the showModalDialog JS function a lot to open a popup. When we try to test this functionality with webdriver it hangs from the moment the popup is opened.
We tried several things to test this:
Using the workaround explained here. But this seems to be a fix for selenium and not for webdriver. We tried it but it didn't work.
Searching for a good alternative, HtmlUnit opened the modal dialog and could interact with it, but it has it's drawbacks like no visual help to fix certain tests and it stopped execution when it detected a JS error in a JS library we have to use but have no control over.
How can we test this or work around this problem?
From my experiences with various automation tools interaction with "webpage dialog" windows opened from IE using window.showModalDialog() or window.showModelessDialog() is not available.
Since the window is not a "true" window (look at the taskbar, it doesn't even show up) most tools can't "inspect" it and/or interact with it.
However if you do find a tool that will, please advise - there are many people looking for such a beast.
That all said, if you can possibly avoid using either of these 2 proprietary methods you'll have much more luck.
(and yes, for the picky ones, Firefox and Chrome have adopted these kind of dialogs but they don't work quite the same)
None of the answers answer the question. If the driver hangs, then you can't call any methods on it. The question is NOT about finding the pop up, it is about how to stop the driver hanging. The only way I have found is to not use showModalDialog. This can be done by adding the folowing to your test code :
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
which calls window.open each time your JavaScript calls window.showModalDialog.
I am using webdriver.SwitchTo().Window() method but my concern is my popup window does not have "Name"
When I use webdriver.WindowHandles it return only one handle, I am using this statement after popup window open.
As I don't have name / handle I cannot switch from parent window to child window.
Any other solution to do the same functionality
First we have to switch to the active element:
driver.switchTo().activeElement();
To check whether we have actually switched to the correct active element:
driver.switchTo().activeElement().getText();
Even if the window doesn't have name u can use
driver.switchTo.defaultcontent();
and perform the operation you want to execute
or else you can get the window handle name using the below command
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle); }
hope this should work for you.
Issue 284 is for WebDriver. It seems that it will be implemented only after Issue 27 will be implemented, so the fix should be in Beta 1 or 2 of WebDriver.
Set<String> beforePopup = driver.getWindowHandles();
Set<String> afterPopup = driver.getWindowHandles();
afterPopup.removeAll(beforePopup);
if(afterPopup.size()==1){
System.out.println(afterPopup.toArray()[0]);
}
driver.switchTo().window((String) afterPopup.toArray()[0]);
What I have been using and it works great for us on with IE and Firefox is to go through popups
and look for a a unique text on the popup you are trying to interact with. Here is the method, let me know if it works for you. Please note the line driver = driver.switchTo().window(windowHandle);
public void switchWindow(String containingText, WebDriver driver) throws Exception {
if ( StringUtils.isEmpty(containingText))
return;
int counter = 1;
int numOfpopups = driver.getWindowHandles().size();
System.out.println("Waiting for popup to load..... # handles:" + numOfpopups);
while ( numOfpopups < 2 && ((counter%10) != 0) ) {
counter++;
try{Thread.sleep(1000);}catch (Exception e) {}
}
System.out.println("Done waiting for..... " + counter + " seconds");
if (driver.getWindowHandles().size() < 2)
throw new BrowserException("Timeout after " + counter + " secs. No popup present. ");
System.out.println("Going through window handles...");
for (String windowHandle : driver.getWindowHandles()) {
driver = driver.switchTo().window(windowHandle);
if ( driver.getPageSource().contains(containingText)
return;
else
continue;
}
throw new Exception("Window containing text '" + containingText + "' not found");
}
To my knowledge, webdriver has no built-in functionality to handle modal windows as of now. Webdriver will hang once you click button which opens modal window. This happens due to JS on parent window halts until child window is closed.
To handle modal windows such as this one, see below for possible workaround written in Java. The main idea is to perform action that opens modal window (click on the button) in new thread.
/**
* Click button to open modal window and switch to it
* #param we webElement handle of a button
*/
public void clickToOpenModal(final WebElement we) {
//Get handles of all opened windows before opening modal window
Set<String> initWindowHandles = getDriverInstance().getWindowHandles();
//Create new thread and click button to open window
Thread thread1 = new Thread() {
#Override
public void run() {
//Click button
click(we);
}
};
thread1.start();
//Wait for window to appear
waitForWindow(initWindowHandles, pauseL);
thread1.interrupt();
thread1 = null;
//Get handles of all opened windows after opening modal window
Iterator<String> it = getDriverInstance().getWindowHandles().iterator();
//Select handle of modal window
String windowHandle = "";
while(it.hasNext()){
windowHandle = it.next();
}
//Switch focus and work on the modal window
getDriverInstance().switchTo().window(windowHandle);
}
The solution by Hugh Foster works, i tried this and succeeded
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
You can find the url of modal dialog then open it on another tab, it will work as normal.
In case you want to deal with open modal dialog, you can try to send "tab" key for move around objects and "send keys... enter" for setText or click.
Note: Below is some information why you cannot use selenium webdriver for work with that modal.
Modal pop-up - This is very specific to IE, Microsoft defined it as
When Windows Internet Explorer opens a window from a modal or modeless HTML dialog box by using the showModalDialog method or by using the showModelessDialog method, Internet Explorer uses Component Object Model (COM) to create a new instance of the window. Typically, the window is opened by using the first instance of an existing Internet Explorer process. When Internet Explorer opens the window in a new process, all the memory cookies are no longer available, including the session ID. This process is different from the process that Internet Explorer uses to open a new window by using the open method.
http://msdn.microsoft.com/en-us/library/ms536759(VS.85).aspx
MSDN blog on Modal dialog
When user select Model popup, parent window is blocked waiting for the return value from the popup window. You will be not able to see the view source of the page, need to close the popup then only the parent window is activated.

How do you get selenium to recognize that a page loaded?

In certain unknown situations selenium does not detect that a page has loaded when using the open method. I am using the Java API. For example (This code will not produce this error. I don't know of an externally visible page that will.):
Selenium browser = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com");
browser.start();
browser.open("http://www.google.com/webhp?hl=en");
browser.type("q", "hello world");
When the error occurs, the call to 'open' times out, even though you can clearly see that the page has loaded successfully before the timeout occurs. Increasing the timeout does not help. The call to 'type' never occurs, no progress is made.
How do you get selenium to recognize that the page has loaded when this error occurs?
I faced this problem quite recently.
All JS-based solutions didn't quite fit ICEFaces 2.x + Selenium 2.x/Webdriver combination I have.
What I did and what worked for me is the following:
In the corner of the screen, there's connection activity indicator.
<ice:outputConnectionStatus id="connectStat"
showPopupOnDisconnect="true"/>
In my Java unit test, I wait until its 'idle' image comes back again:
private void waitForAjax() throws InterruptedException {
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try {
if ("visibility: visible;".equals(
selenium.getAttribute("top_right_form:connectStat:connection-idle#style"))) {
break;
}
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
You can disable rendering of this indicator in production build, if showing it at the page is unnecessary, or use empty 1x1 gifs as its images.
Works 100% (with popups, pushed messages etc.) and relieves you from the hell of specifying waitForElement(...) for each element separately.
Hope this helps someone.
Maybe this will help you....
Consider the following method is in page called Functions.java
public static void waitForPageLoaded(WebDriver driver) {
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver,30);
try {
wait.until(expectation);
} catch(Throwable error) {
Assert.assertFalse(true, "Timeout waiting for Page Load Request to complete.");
}
}
And you can call this method into your function. Since it is a static method, you can directly call with the class name.
public class Test(){
WebDriver driver;
#Test
public void testing(){
driver = new FirefoxDriver();
driver.get("http://www.gmail.com");
Functions.waitForPageLoaded(driver);
}
}
When I do Selenium testing, I wait to see if a certain element is visible (waitForVisible), then I do my action. I usually try to use an element after the one I'm typing in.
Using 'openAndWait' in place of 'open' will do the trick.
From the website:
Many Actions can be called with the "AndWait" suffix, e.g. "clickAndWait". This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load.
Enabling the 'multiWindow' feature solved the issue, though I am not clear why.
SeleniumServer(int port, boolean slowResources, boolean multiWindow)
SeleniumServer server = new SeleniumServer(4444, false, true);
Any clarification would be helpful.
I've run into similar issues when using Selenium to test an application with iFrames. Basically, it seemed that once the primary page (the page containing the iframes) was loaded, Selenium was unable to determine when the iframe content had finished loading.
From looking at the source for the link you're trying to load, it looks like there's some Javascript that's creating additional page elements once the page has loaded. I can't be sure, but it's possible that this is what's causing the problem since it seems similar to the situation that I've encountered above.
Do you get the same sort of errors loading a static page? (ie, something with straight html)
If you're unable to get a better answer, try the selenium forums, they're usually quite active and the Selenium devs do respond to good questions.
http://clearspace.openqa.org/community/selenium_remote_control
Also, if you haven't already tried it, add a call to browser.WaitForPageToLoad("15000") after the call to open. I've found that doing this after every page transition makes my tests a little more solid, even though it shouldn't technically be required. (When Selenium detects that the page actually has loaded, it continues, so the actual timeout variable isn't really a concern..
Not a perfect solution, but I am using this method
$t1 = time(); // current timestamp
$this->selenium->waitForPageToLoad(30);
$t2 = time();
if ($t2 - $t1 >= 28) {
// page was not loaded
}
So, it is kind of checking if the page was not loaded during the specified time, so it is not loaded.
another idea is to modify AJAX API (to add some text after AJAX actions).
After ajax action was finished, before return, set invisible field to TRUE, selenium will find it and read as green-light
in html:
<input type='hidden' id="greenlight">
in selenium
if(driver.findElement(By.id("greenlight")).getAttr("value").equals("TRUE")){
// do something after page loading
}
If you page has no AJAX, try to seek footer of page (I also use Junit fail(""), you may use System.err.println() instead):
element.click();
int timeout =120;
// one loop = 0.5 sec, co it will be one minute
WebElement myFooter = null;
for(int i=0; i<timeout; i++){
myFooter = driver.findElement(By.id("footer"));
if(myFooter!= null){
break;
}
else{
timeout--;
}
}
if(timeout==0 && myFooter == null){
fail("ERROR! PAGE TIMEOUT");
}

Categories

Resources