How to get iframe src value dynamically in nightwatch test case? - javascript

My html dom includes a tag and the value of the src is dynamically generated. Please see below screenshot as an example:
I want to test the dom under the selected iframe tag:
<iframe class="ide-page-frame" ng-src="http://localhost:8080/che/wksp-rn6c?uid=514006" src="http://localhost:8080/che/wksp-rn6c?uid=514006"></iframe>
I use below method to load the frame and put the assert code in the callback function. But it doesn't find any dom. The code is shown as below.
browser
.url('http://localhost:8080/dashboard/#/ide/che/wksp-rn6c')
.frame(".ide-page-frame",()=>{
// it can't find any dom here
})
})
If I load the dynamical url http://localhost:8080/che/wksp-rn6c?uid=514006 directly, it is able to find the dom elements. So I want to know how I can get the url from the iframe src in the test case. Does nightwatch support something like $(.ide-page-frame).getAttribute('src')?

I think that your problem is in browser.iframe(".ide-page-frame")
nightwatch will look for an iFrame having the id="ide-page-frame" which does not exist in your page.
If the frame id is missing or null, the server should switch to the
page's default content.
My proposition: Please change your iFrame creation by changing class="ide-page-frame" by id="ide-page-frame" (or you can just add the id and keep the class)
<iframe id="ide-page-frame" class="ide-page-frame" ng-src="http://localhost:8080/che/wksp-rn6c?uid=514006" src="http://localhost:8080/che/wksp-rn6c?uid=514006"></iframe>
Does this solve your problem?

Related

Get contents from second iframe

At the moment I can retrieve the contents of the first iframe on a web page that is not mine with $('iframe').contents()
From this I can get the body tag by doing $('iframe').contents().find('body'). The results are what is expected
However, I an trying to get the body tag of the second iframe. By doing `$('iframe').eq(1) I can get the second iframe, but $('iframe').eq(1).contents() gets nothing.
How can I get the contents of the second iframe?
A lot of the Fiddles and such may not be a good test place. There are complications with CORS. Here is an example that works:
https://jsfiddle.net/Twisty/037yueqj/9/
HTML
<iframe id="frame-1"></iframe>
<iframe id="frame-2"></iframe>
JavaScript
$(function() {
var f1 = $("#frame-1"),
f2 = $("#frame-2"),
frames = $("iframe");
f1.contents().find("body").html("<strong>Frame 1</strong>");
f2.contents().find("body").html("<strong>Frame 2</strong>");
console.log(frames.eq(0).contents().find("body").text());
console.log(frames.eq(1).contents().find("body").text());
});
If you give them unique IDs or classes, you can just call on the proper selector. You can call on a wider selector and use .eq() or iterate with .each().
Had to use --disable-web-security in chromium to access contents in an iframe from another url

Frame handling in Webdriver IO

I am testing a webpage that has multiple forms in it.
When I use
client.frame({id:client.element('#frameId')});
I don't get any error, but when I try to interact with an element within that frame I get a RuntimeError telling me the element could not be located.
I have been looking out for literature about how the frame() method works but I don't have any luck.
I was also using webdriver.io and it looks like documentation is a bit wrong.
You can access frames:
1) via it's number on the page. For example the first frame met in HTML DOM is
client.frame(0), second client.frame(1) etc
2) via name attribute:
<frame name="test"></frame>
client.frame('test')
3) find the element with client.element('css_selector'), then in a callback pass the returned value to the .frame()
The way to go to a new frame is:
client.frame(<id of frame here>)
What you have should work too though. Try doing a client.waitForExist on an element that only exists on the frame, instead of just switching to frame and immediately trying to interact with element in that frame, as you may be firing your interaction event before selenium has had a chance to fully switch to the frame:
client.frame(<id of frame here>
client.waitForExist(<id of some css element that only exists in the frame>)
client.frame(<name_of_frame>) worked.
I tried using a selector like #idOfSelector but it didn't seem to work.
This works for me
const frameValue = browser.element('frame_selector').value;
browser.frame(frameValue);
Hopefully, it works for you.

Javascript TypeError with IFrame

I'm attempting to change an IFrame twice with the click of one link. I continuously get this error: Uncaught TypeError: Cannot set property 'src' of null whenever that link is clicked.
What this needs to do, is change the source of the IFrame on the index page, and then change the source of an IFrame on the page that was loaded into the outer IFrame on the index page.
<div class="subjects list-group" target="../../body.html ">
<script>
function doneLoading() {
document.getElementById('index.html#large-column').src = 'body.html';
}
</script>
<span class="badge">26</span>English
</div>
A cleaner approach would be to use iframe targeting.
<iframe id='content' src='body-default.html'>
<a href='body-en.html' target='content'>English</a>
The body-default.html or body-en.html files could contain javascript to update themselves if needed.
Another way you can look at the problem - is to take the opposite approach - and create a series of pages - and load them in the standard way. You could use iframes to remove duplicated content e.g. headers and footers if needed.
It is hard to assist further without understanding your use case in more detail.

javascript multiple forms on the same rendered screen

I'm working with classic ASP.
I have an 2 includes that have 2 different forms on them. They are both unique in name. However, when I try to read the value of the one the elements in the 2nd form I get an error saying it is null. However, when I view the source in Firebug I can see that in face there is a value in that element.
My javascript code:
console.log(document.getElementById('focusValue').value);
Output from firebug:
<input id="focusValue" type="hidden" value="1006" name="focusValue">
Is there something I need to do because there are 2 forms on this "rendered" screen? The only other thing I think I should mention is that these pages are in an iFrame. Not sure if that really matters...
An iFrame creates a separate document within the containing document, you need to get a reference to that document before you can access its content. There is a reasonable tutorial at http://www.dyn-web.com/tutorials/iframes/.
If you only have one iFrame in the page, then you can reference it by:
var frame = window.frames[0];
Or you could use an id with getElementById. To get a reference to the document:
var doc;
if (frame) {
doc = frame.contentDocument || frame.contentWindow.document;
}
Now you can get to the input element:
var input = doc && doc.getElementById('focusValue');
Of course this all depends on you complying with the same origin policy, otherwise you can't access the frame content.
Can't see your page, so it's hard to debug. Assuming the script runs AFTER the forms. The only thing i can think is that there is more than one element on the page with the id "focusValue".
What happens when you console.log(document.getElementById('focusValue'))

Running the javascript code present on another html page through jquery

It might be a noob questions but I have just started using jquery.
My basic requirement to extract the link which is there in the javascript code present in another html (code is embedded in the html page and not in a seperate file).
The link is also present as a href attribute of <a> tag inside a tag, just to add if it is easier to extract it from there (I am using chrome so I think it considers there are no child nodes of <noscript> tag)
After this I tried doing an ajax request to the html page (using $.ajax) thinking it will run the scripts on the page but got the html code of the page in return :S . I have also heard of something called evalscripts:true but not sure if that will work here or how to use it?
I have also tried to search for the link in html code returned by my html page by using the "contains" operation of jquery.
I am doing all this to create a greasemonkey script. Please suggest
Example Code:
This is a function present inside the html of that page:
function fun() {
obj = new pollingObj('argument', "a link I want to extract comes here");
}
I want to extract the link: "a link I want to extract comes here" and then open it.on my page where I am running my jquery script
This link is also present like this on the html page:
<noscript>
blabla
</noscript>
Also is it possible to run the javascripts present on that page if the link extraction is not possible?
If you're able to get the html code of the page successfully via .ajax, and the data you want is in the HTML code, it's not worth the effort to bother with trying to run the scripts. Just access the URL through the DOM:
// ajax success function
success: function(html) {
var anchorCode = $(html)
// this assumes that noscript is a top-level element
// otherwise, use .find('noscript')
.filter('noscript')
.text(); // get the code for the anchor tag, as a string
var myLink = $(anchorCode).attr('href');
// do something with myLink
}
Edit: It turns out that jQuery is a little funny in the way it deals with noscript tags - inner tags don't appear to be considered part of the DOM, so you need to grab the text content of the tag and then use jQuery to DOM-ify it. See updated code above.

Categories

Resources