How to select/switch to an Iframe (as the currently targeted document) in Firefox through selenium webdriver. What are the different ways to select an iframe with/ without webdriver.
driver.switchTo.frame("FrameID");
Try this sample example:
WebElement iframeElement = driver.findElement(By.id("IF1"));
//now use the switch command
driver.switchTo().frame(0);
//You can use iFrame name
//driver.switchTo().frame(iframeElement);
//Switch to parent window
driver.switchTo().defaultContent();
driver.quit();
Follow this link to understand more:
http://toolsqa.com/selenium-webdriver/handling-iframes-using-selenium-webdriver/
You can actually select an iFrame using the below methods: -
frame(index)
frame(Name of Frame [or] Id of the frame)
frame(WebElement frameElement)
defaultContent()
So you can switch by passing the any above information about the frame. Yes you need to switch everytime according to require action
Example in c#:-
driver.SwitchTo().Frame("top");
.... Perform your action on frame
driver.SwitchTo().defaultContent();
driver.SwitchTo().Frame("navigation");
.... Perform your action on frame
driver.SwitchTo().defaultContent();
....
Now you have to find the hierarchy of your nested frame and switch all one by one.
use chrome dev tools and select the element you can see the hierarchy .. just switch from parent to child till your element not reach. perform your operation and switch back to default
Related
Background Information:
Our situation
At work we have created multiple apps and a few of them make use of an interactive grid inside of a modal dialog page. Last week we upgraded from Oracle APEX 19.1 to Oracle APEX 21.1 .
The problem described below didn't exist in version 19.1.
(If important: We have to support Google Chrome on Windows)
How to navigate to the IG
In all our cases the interactive grid can be reached by:
nagivating to page x
open modal dialog y
from modal dialog y open modal dialog z (via a branch after page processing)
=> the interactive grid can be found in modal dialog z
Aim and preparations
We only want to give the users access to a few interactive grid functionalities.
For this reason we gave each IG a static id.
What still works
The modal dialog opens and the interactive grid is displayed normally.
Our Problem
Up until the upgrade the following snippet removed some functionality of the respective IG:
$(window).on("load", function() {
var actions = apex.region("example_ig_id").widget().interactiveGrid("getActions");
actions.remove("selection-copy-down");
actions.remove("selection-fill");
actions.remove("selection-clear");
actions.remove("single-row-view");
actions.remove("selection-copy");
});
But since upgrading to version 21.1 apex.region("example_ig_id") returns null. The dom element also can't be found via $("#example_ig_id").
What we found out and tried
In the google chrome developer tools the div with id example_ig_id is visible under elements.
After loading the page, then clicking into the class attribute of the div (via developer tools) to edit it (no need to realy edit anything) and canceling it, apex.region("example_ig_id") isn't returning null anymore. That also works if I edit its direct or indirect parent elements (also tested with the iframe of the modal dialog containing the IG).
Since finding that out i tried to work around the problem with forcing a refresh or a reflow.
I tested multiple of the answers given here: Force DOM redraw/refresh on Chrome/Mac
The tests I tried (in the inline console) all didn't solve my problem:
$("iframe").each(function(){$(this).addClass("testClass"); $(this).removeClass("testClass");});
and:
$("iframe").each(function(){$(this).hide(); $(this).show(0);});
and:
$("iframe").each(function () {
$(this).css("opacity", .99);
setTimeout(function () {
$(this).css("opacity", 1);
}, 20);
});
I used the iframe of the modal dialog itself since it is selectable from the start.
I am not sure if I made a mistake but help would be much appreciated.
At this point I got help and the problem is solved.
Instead of defining this'
$(window).on("load", function() {
var actions = apex.region("example_ig_id").widget().interactiveGrid("getActions");
actions.remove("selection-copy-down");
actions.remove("selection-fill");
actions.remove("selection-clear");
actions.remove("single-row-view");
actions.remove("selection-copy");
});
inside the page under
Function and Global Variable Declaration
pasting just the function content
var actions = apex.region("P7_SAVED_JOBS_IG").widget().interactiveGrid("getActions");
actions.remove("selection-copy-down");
actions.remove("selection-fill");
actions.remove("selection-clear");
actions.remove("single-row-view");
actions.remove("selection-copy");
into the page under
Execute when Page Loads
did the trick.
I don't know if the execution time of the event handler was too early or if it had something to do with the iframe and its context.
I have an application that produces many pages of content. In order to expedite review of the process, I have a linkbutton that opens a child window starting at the page I'm on so reviewers can enter comments. I open the child window in javascript
objCmtWindow = window.open(MyURL, "comments", "width=800,height=600,menubar=no,toolbar=no,status=no,location=no,resizable=yes,scrollbars=yes,directories=no");
objCmtWindow.focus();
The child window has some javascript (an excerpt from a larger script) to listen to an API in the parent window so that it can know what to load
function updtSlide(){
if(window.opener.MyAPI)
{
window.opener.MyAPI.addEventListener("MyEnterBtn", function(e)
{
updtContent();
});
}
}
It works on load to grab the data with the function updtContent as part of the page load. When I click for the next page (MyEnterBtn) in the parent window, the child window is not updating for the next page data it needs to display. Is there a piece I'm missing to poll the parent window? Since the parent can operate independantly of the child, I really can't put the command in the next page button. I know the API is working correctly and emitting next page events.
Thank You
In the js function, the first 'opener' is spelled wrong.
I have a mainscreen with 2 iframes. In iframe named (and also id) "leftmenu" I load frmLeftMenu.php and in the second iframe named (and also id) "appscreen" I load frmAppScreen.php.
In the frmLeftMenu.php I have a tree menu (dhtmlX) and on the onclick event I want to load a page in the iframe named "appscreen". The handling of the onclick is made in the frmLeftMenu.php.
What is the best way to do this?
I found the solutions. on the onclick I execute a function named DoOnclick. There I'm testing the id from the menu items and then execute a window.open("formname.php","appscreen"); This is working well for my application.
code example:
myTree.setOnClickHandler(DoOnclick);
function DoOnclick(id){
switch(myTree.getSelectedItemId()){
case 'adm_users' : window.open("frmUserMaintenance.php", "appscreen");
break;
}
};
I was successful to track all "uiStreamSource" that holds the link associated with each facebook post (status, image, etc) to add one extra button next to the date to do some other tasks using google chrome extensions. This button does a predefined job which not important to mention in this context.
I wrote this content script:
contentscript.js
var nodeslist=document.getElementsByClassName("uiStreamSource");
alert(nodeslist.length);
Each time a facebook page is loaded, the alert shows me 10 detected classes (i.e., 10 posts). But when I scroll down, new posts show up and this code fails to detect them. Since I need to update all uiStreamSource nodes in all posts, how can I solve this?
UPDATE
I tried this code in contentscript.js:
load();
document.addEventListener("DOMNodeInsertedIntoDocument", load, false);
function load(){
var nodeslist=document.getElementsByClassName("uiStreamSource");
alert(nodeslist.length);
}
The first time it runs, I get the correct number of the current nodes (current facebook posts) but once I scroll down and more posts are fetched, the alert shows up indicating that load function is called but the number of nodes printed is 0. Why is that?
Thanks on advance.
You can add a DOMNodeInserted event and check if the element that is going to be inserted is a post by checking its classes.
Or an easy solution is to use the jcade plugin. It can call a callback function when an element with specified selector is inserted.
Listen to the scroll event and add any new posts to nodeslist. You could use setInterval as well to catch any posts that are added when the user is not scrolling.
Can anyone help with this please?
I have a webpage with an asp.net frame on it- the frame shows the contents of an html document.
When someone clicks on a link in the html document, I need to show some content in another frame on the same page.
So, the question is, what should 'myTag' be in the following...
e.g.
//this is the contents of my html file`
<p>to be or not to be, <myTag>that</myTag> is the question</p>
Whatever 'myTag' is (maybe a piece of javascript? don't know), it should be able to fire an event on the server so I can send some more text to the other frame on the page
Any ideas?
thanks..
The first thing I would do is give the other frame an ID or some way to easily get to it with javascript. Then inside your iframe, you could do something like:
var other_frame_document = window.parent.document.getElementById('other_frame').contentWindow.document;
// example 1: set the HTML of the other frame from a string.
// this is usually a bad idea because of XSS.
other_frame_document.body.innerHTML = '<b>aloha</b>';
// example 2: better way is to manipulate the DOM in the other iframe
var elm = other_frame_document.createElement('b');
elm.appendChild(other_frame_document.createTextNode('aloha'));
other_frame_document.body.appendChild(elm);
that is one way to fire an action.
Or you can bind the action using jQuery (or some other library) when the DOM loads, like this:
jQuery("#myTagId").bind("click", function() { ... });
This will cause the event to fire when the element is clicked.
You can then use ajax to call the server to update the other frame.