I am running a test and am running into unexpected issue managing a modal dialog box.
The user uploads a file in a modal dialog box and if the file already exist on the system another seperate modal dialog opens asking the user if they want to overwrite the existing file.
I am having difficulties in manipulating the buttons on this second dialog.
When I manage the first dialog I do the following, which works:
void switch_to_dialog_window(WebDriver driver){
driver.switchTo().frame(driver.findElement(By.cssSelector("div.d2l-dialog>div>iframe")));
}
The html when both dialogs are open looks like this:
<div class="d2l-dialog" style="top: 70px; width: 700px; height: 520px; left: 630px; z-index: 1002;">
<div class="d2l-dialog-inner" style="height: 518px;">
<iframe class="d2l-dialog-frame" src="/d2l/common/dialogs/file/main.d2l?ou=11346&af=MyComputer%2cOuFiles%2cSharedFiles%2cgooglefiledownloader%2coffice365filedownloader&am=1&fsc=1&asc=0&mfs=0&afid=0&uih=&area=MyComputer&f=&path=%2fcontent%2fenforced%2f11346-Gherkin_Cucumber%2f&d2l_body_type=2" name="d2l_c_10_968" allowfullscreen="" scrolling="no" style="width: 698px; height: 518px; overflow: hidden;" frameborder="0"/>
</div>
</div>
<div class="d2l-dialog" style="top: 90px; width: 475px; height: 415px; left: 800px; z-index: 1004; display: block;">
<div class="d2l-dialog-inner" style="height: 413px;">
<iframe class="d2l-dialog-frame" src="/d2l/lp/fileinput/11346/Duplicates?files=photo.jpg" name="d2l_c_1_182" allowfullscreen="" scrolling="no" style="width: 473px; height: 413px; overflow: hidden;" frameborder="0"/>
</div>
</div>
I'm trying to control the dialog which mentions duplicates.
I tried to modify the method for switch_to_dialog_window to be more specific (as a test to identify the first dialog box to control that):
driver.switchTo().frame(driver.findElement(By.cssSelector("div.d2l-dialog>div>iframe[src^='/d2l/common/dialogs/file/main.d2l']")));
This doesn't work though so i cant implement that way to manage the 2 dialogs.
I tried to switch to the default content and then switch back to the Dialog using the method 'switch_to_dialog_window' but that doesn't work either. I tried just trying to access the button on the dialog box directly but that doesnt work:
public void confirm_duplicate() {
//driver.findElement(By.xpath("//iframe[starts-with(#src, '/d2l/lp/fileinput/11346/Duplicates')]"));
//driver.switchTo().frame(driver.findElement(By.cssSelector("div>div>iframe[src^='/d2l/lp/fileinput/11346/Duplicates']")));
try{
//driver.switchTo().frame(driver.findElement(By.cssSelector("div>div>iframe[name^='d2l_c_1_']")));
driver.findElement(By.linkText("Update")).click();
}catch(Exception e)
{
System.out.println("could not click on the Update button on the top most dialog box");
e.printStackTrace();
}
}
I seem to be running around in circles with this one and is exhausting. Can someone explain how to get control of this top most dialog box?
And also could you possibly teach me as to why the following expression isnt working:
driver.switchTo().frame(driver.findElement(By.cssSelector("div.d2l-dialog>div>iframe[src^='/d2l/common/dialogs/file/main.d2l']")));
Robot API can be used to get handle topmost modal box if there is an issue with switching to frame.
To use Robot API, give the following line of codes
Robot key = new Robot();
key.keyPress(KeyEvent.VK_ENTER);
key.keyRelease(KeyEvent.VK_ENTER);
Make sure that the control is already on the intended button. If the focus is on another button on the modal, then give 'tab' or other keyevent to get the control on the update button.
I have taken a break of a couple of months from automation. I happened to be doing some maintenance on my scripts and found the root cause of this problem.
The issue was not with my code, the code was fine just i forgot one crucial step. During the business process a second window was opened which required user input. I used the code to switch to this popup window.:
public void get_window_ids(){
//Get the handles for the main window and the popup window for the upload button
try {
Set<String> AllWindowHandles = driver.getWindowHandles();
System.out.println(AllWindowHandles.size()+ " distinct windows: " + AllWindowHandles);
window1 = (String) AllWindowHandles.toArray()[0];
System.out.println("\nwindow 1 is " + window1+"\n");
window2 = (String) AllWindowHandles.toArray()[1];
System.out.println("\nwindow 2 is " + window2+"\n");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getWindow1() {
return window1;
}
public String getWindow2() {
return window2;
}
When I switched to the window2 I forgot to switch back to the first window. I just missed the fact that there was a popup window I forgot about. So if you are using these modal popups remember to return control back to the main window.
Related
I want to show a WebPage on another WebPage using InlineFrame.
I initialized it like this:
Wicket/ Java:
InlineFrame choosenTestcaseInlineFrame =
new InlineFrame("inlineFrame", AuthenticationPage.class);
public WhatToDoPage() {
Form whatToDoForm = configureWhatToDoForm();
add(whatToDoForm);
add(choosenTestcaseInlineFrame.setOutputMarkupId(true));
add(choosenTestcaseInlineFrame);
}
'
HTML:
<iframe wicket:id="inlineFrame" style="margin-left: 200px; height: 500px; width: 1000px">
The Problem is That the InlineFrame seems to refuse to show the Content.
here is a Screenshot:
I don't know if Chrome has a specific option to allow iframe to be displayed, but you might find some clues to solve the problem here:
iframe refuses to display
I am using Java and chromedriver. So far I used the following code to simply click on a button, then a small window popped up and I clicked another button. Interestingly I had not to change to any frame. All worked fine. Here is the code:
// click on button
driver.findElement(By.xpath(hyperlink_take_order)).click();
// a second small window popped up and I clicked another button
driver.findElement(By.xpath("//a[contains(text(),'accept')]")).click();
So far I used xpath to identify the buttons I need to click.
From time to time there is an additional checkbox (sometimes multiple checkboxes) on the second small window which I all need to click on. I tried to find them via xpath but found out that xpath did not work here. All I get in HTML is something like this:
The number in the brackets [] in this case 17232 vary each time, therefore I cannot find a name I can use for the checkbox. I read many articles on stackoverflow and found this peace of code which also did not work.
// click on button
driver.findElement(By.xpath(hyperlink_take_order)).click();
// a second small window popped up
try
{
driver.switchTo().frame(driver.findElement(By.tagName("iframe")));
System.out.println("change to iframe worked");
List<WebElement> CHECKBOXlist = driver.findElements(By.xpath("//input[#type='checkbox']"));
for(WebElement checkbox : CHECKBOXlist)
{
System.out.println("there was a checkbox");
System.out.println(checkbox.getAttribute("name"));
checkbox.click();
}
driver.switchTo().defaultContent();
}
catch (Exception e)
{
System.out.println("there was no checkbox");
}
driver.findElement(By.xpath("//a[contains(text(),'accept')]")).click();
<div class="md-checkbox product-service md-theme-whitebackground">
<div tabindex="0" class=md-checkbox-container">
<input name="service[17232]" tabindex="-1" id="service_17232" type="checkbox" value ="1" />
</div>
<label class="md-check-label" for="service_17232">This one is blue</label>
</div>
Do you have any idea how I can simply click on all (sometimes multiple) checkboxes on the second small window? Thanks
Is there a way to pull a browser window to the foreground/focus from a Java applet alert window? I have an applet in a html page that brings up an alert with a button in it. When the button is pressed, I want the original browser window to pop up from wherever it is (minimized, covered, etc.) I believe there is a way to connect Java to Javascript to do this, but I don't know Javascript.
Here is the Java applet code:
/** An applet that posts an alert and waits for the alert button to be pressed.
* Version 1 uses http://java.sun.com/products/plugin/1.3/docs/jsobject.html
*/
import netscape.javascript.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Bounce extends JApplet implements ActionListener {
JDialog dialog;
JSObject window;
String message;
public void paint(Graphics g) {
g.clearRect(0,0, 400,40);
g.drawString(message,40,20);
}
public void init() {
JFrame frame= null;
dialog= new JDialog(frame, "Bounce App");
JButton setupButton= new JButton("Bounce it back!");
setupButton.addActionListener(this);
JPanel contentPane= new JPanel();
contentPane.add(setupButton);
contentPane.setOpaque(true);
dialog.setContentPane(contentPane);
dialog.setSize(new Dimension(400, 110));
dialog.setVisible(true);
message= "This applet posts an alert panel.";
window= JSObject.getWindow(this);
// String[] params= { "An alert message" };
// window.call("alert", params);
// window.eval("alert('Important Alert!')");
}
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
dialog.dispose();
System.err.println("button has been pushed; focus set");
message= "Somebody pushed my bounce-back button.";
JSObject document= (JSObject)window.getMember("document");
document.setMember("bgColor", "orange");
window.eval("focus()");
repaint();
}
}
And here is the HTML code:
<HTML>
<HEAD><TITLE>The Reappearing Page</TITLE></HEAD>
<body bgcolor="#f0ffc0">
<H2>Make this page reappear</H2>
This page will start an applet (white box below) that sets up an alert.
Before you respond to the alert, hide the window you are reading right now,
using one of these methods:<ul>
<li> cover it with another window, </li>
<li> Hide it using a menu item, </li>
<li> Minimize it, or </li>
<li> move it to another workspace or desktop. </li>
</ul>
Then click on the button in the alert.
<P>
<EMBED type="application/x-java-applet;version=1.3" width="400" height="40"
align="baseline" code="Bounce.class" MAYSCRIPT=true
pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
<NOEMBED>
No JDK 1.3 support for APPLET!!
</NOEMBED>
</EMBED>
<P>What is supposed to happen is that the main window
will emerge from wherever you hid it and reappear.
Since I don't know how to do this, it is your challenge to actually make it happen.
We need to be able to achieve this magic from any of the situations listed above.</P>
</body>
(Changed from comment to answer so I can post a decent code snippet for you) There is no reliable way to "foreground" a window using JavaScript, unless it's a window you created yourself from a parent page, for obvious reasons ("Congratulations!! You are our 1000th customer, you win a prize!!!!!"). If you've loaded your applet window as a popup using window.open from another window, you could try using window.focus:
var w = window.open(appletPageUrl);
w.focus()
I imagine popup blockers don't appreciate this sort of thing, so YMMV. On a personal note, I would suggest that you have a think about whether a user wants to know about your alert if they've chosen to hide/minimise your app.
I've the current situation:
Have a Link in some HTML page.
When the user click that Link, an NORMAL (vs Ajax) HTTP request is being sent to a Web Server (typically a Java Servlet)
After that, of course the browser will bring the contents from the server and start rendering it. (actually it's the same page with modified contents - don't ask me to do it in ajax, cause it is the requirements)
Before step 3 is being done (while the page is being loaded) I need to display some frame to the user saying something like loading ....
Well, just populate a div somewhere on the page with "Loading..." when the link is clicked. Here's some rough code
$('#yourlink').click(function(){
$('#loading').html('Loading....');
});
<div id="loading">
</div>
And when the page loads, the current loading div will be replaced with an empty one, this will signify that the loading is complete.
Another approach:
The css
#loading
{
display: none;
}
The html
<div id="loading">
Loading....
</div>
The js
$('#yourlink').click(function(){
$('#loading').show();
});
Well, there's several non Ajax ways to do this. The simplest I guess would be to have a giv animated image with your loading bar, which you keep in a hidden div in your initial page:
<div style="display:hidden;"><img src="/img/loading.gif"></div>
Then add some javascript to the link/button that submits the page, such as when it is clicked it unhides the div with image.
There are many ways to do this. I handle it something like this:
// Any anchor with showOverlay class will invoke the overlay function
$("a.showOverlay").click(function() {
overlay();
});
// Normal form submits are intercepted. Overlay call also be skipped by
// making the form of class "noOverlay"
$("form").submit(function() {
var skipOverlay = $(this).hasClass("noOverlay");
if(!skipOverlay){
overlay();
}
return valid;
});
// This overlay function uses the blockUI plugin, other methods can also be used
function overlay(){
$.blockUI({
fadeIn: 500,
css: {
height: '150px',
top: '35%'
},
message: '<div style="margin-top: 40px;"><table align="center" ><tr ><td style="padding-right: 25px;"><img src="/images/wait.gif" /></td><td style="line-height: 25px;"><h1> Just a moment...</h1></td></tr></table></div>'
});
}
There are a few ways out there in the internet to centre something on the screen via css (-ve margins, table-cell hack etc). I was quite happy with that until now when I wanted to use native gwt2.0 layout panels/widgets. Imagine you want to do a "loading screen" to show a spinning circle until the app tries to figure out where to send user next (in background the app is checking if user is logged in or not).
I have this code in gwt uiBinder xml:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='res' type='ru.atamur.resources.CommonBundle'/>
<g:HTMLPanel>
<g:Image resource='{res.loader}'/>
</g:HTMLPanel>
</ui:UiBinder>
I basically want the image to be displayed in the center of the screen both vertically and horizontally.
Any bright ideas how to achieve that w/o scripting getWidth/setHeight etc?
Thanks.
In the end I was able to use general css with the help of HTMLPanel:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='res' type='ru.atamur.resources.CommonBundle'/>
<g:HTMLPanel>
<div class="{res.centerStyle.container}">
<p class="{res.centerStyle.centered}">
<g:Image resource='{res.loader}'/>
</p>
</div>
</g:HTMLPanel>
</ui:UiBinder>
where corresponding css (linked via a bundle) is:
.container {
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
display: table
}
.centered {
display: table-cell;
vertical-align: middle;
text-align: center;
}
the only hint here was to call ensureInjected in the corresponding widget constructor (see http://code.google.com/p/google-web-toolkit/issues/detail?id=4408 for details):
#UiField CommonBundle res;
public LoadingScreen() {
initWidget(uiBinder.createAndBindUi(this));
res.centerStyle().ensureInjected();
}
I'm not sure why you're against scripting to achieve this, especially since you're going to need at least some amount of scripting in order to show and hide the loader at the right times. You may find your solution isn't going to work well across browsers.
GWT has the PopupPanel, which makes what you're trying to do quite simple.
// A popup that doesn't auto-hide, and doesn't let the
// user click on anything else.
PopupPanel popup = new PopupPanel(false,true);
popup.setGlassEnabled(); // Dims the rest of the page
popup.setWidget(new Image(res.loader()));
popup.center(); // Show popup centered
Then you just call popup.hide() when you're done.
Centering items can also be done using UIBinder without CSS:
<g:HorizontalPanel width="100%" height="100%">
<g:cell horizontalAlignment="ALIGN_CENTER" verticalAlignment="ALIGN_MIDDLE">
<g:Label>Hello Center</g:Label>
</g:cell>
</g:HorizontalPanel>