Javascript on page preventing Selenium from detecting certain frames & elements - javascript
I'm using Selenium with Python to fill in a form on a site where the frames are visible in the html but I still haven't been able to get Selenium to detect any frames or form elements.
I think it is because there is Javascript in the since I see the same scripts referenced throughout the html of the form fields.
I'm very new to this so I'm not quite sure where to get started. From what I've read I might need to use Python's "execute_script" and/or Selenium's javascriptexecutor.
Here is a snippet of the HTML from top to the frame with the fields I'm after (the frame name "main" is the one with the form in it):
<html><head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>eBridge Inc.</title>
<script type="text/javascript">
function startup() {
parent.header.location.href = 'header.aspx?guid=' + window.name;
parent.nav.location.href = 'nav.aspx?guid=' + window.name;
parent.main.location.href = 'welcome.aspx?guid=' + window.name;
parent.footer.location.href = 'footer.aspx?guid=' + window.name;
}
</script>
</head>
<frameset rows="75px,25px,*,30px" frameborder="0" border="0" framespacing="0" onload="startup();">
<frame name="header" scrolling="no" noresize="noresize" frameborder="0" marginheight="0">
<frame name="nav" scrolling="no" noresize="noresize" frameborder="0" marginheight="0">
<frame name="main" noresize="noresize" frameborder="0">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html><head>
<html>
<head>
<title>Retrieve</title>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<link id="mainStylesheet" href="../StyleSheet.css?62" rel="stylesheet" type="text/css">
<link id="dhtmlxStylesheet" href="../Scripts/combobox/style/dhtmlxcombo_touch.css?62" rel="stylesheet" type="text/css">
<link id="datepickerStylesheet" href="../Scripts/datepicker/jquery.ui.datepicker.css?62" rel="stylesheet">
<link id="jqueryuiStylesheet" href="../Scripts/jquery-ui-1.10.3.custom.css?62" rel="stylesheet">
<script src="../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui-1.8.15.custom.min.js" type="text/javascript"></script>
<script src="../Scripts/datepicker/jquery.ui.datepicker.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery.maskedinput-1.3.min.js" type="text/javascript"></script>
<script src="../Scripts/json.js" type="text/javascript"></script>
<script src="../Scripts/combobox/scripts/dhtmlxcommon.js?version=3" type="text/javascript"></script>
<script src="../Scripts/combobox/scripts/dhtmlxcombo_touch.js?version=3" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
try
{
parent.nav.document.location = '../nav.aspx?menu=&guid=' + parent.window.name;
}
catch(ex){}
//focus on first tb/ddl
$('#tblIndex').find('input[type=text]').filter(':visible:first').focus();
$("#start_date").datepicker({
changeMonth: true,
changeYear: true
});
$("#end_date").datepicker({
changeMonth: true,
changeYear: true
});
$("#start_date").mask("99/99/9999");
$("#end_date").mask("99/99/9999");
$("#start_calendar_icon").click(function (event) {
$("#start_date").focus();
});
$("#end_calendar_icon").click(function (event) {
$("#end_date").focus();
});
// for enter keystroke
$(document).keyup(function (e) {
CheckKeyCode(e);
e.preventDefault();
});
$('.dhx_combo_input').keyup(function (e) {
CheckKeyCode(e);
e.preventDefault();
});
When I use the following python in Selenium, it throws the "no such frame" exception:
driver.switch_to.frame("header")
It does this for the rest of the frames as well.
So I tried listing all elements on the page using this:
for ii in ids:
print(ii.get_attribute('id'))
And it only returns a few of the page elements (none of which are form fields), namely these:
stylesheet
hf
imgLogo
welcome
h_log_out
retrieve
aView
help
aSupport
cabnm
My goal is to input text into the form fields within the frame "main". I normally don't have any issue with using Python to interact with pages, but I'm not sure how to deal with the scripts on this page that seem to be preventing me from detecting and switching frames.
Any advice on whether the scripts are the culprit and if so, how to make them display the rest of the frames and elements is appreciated. I prefer solutions in Python but am open to anything.
'#TodorMinakov: Thanks Todor, I was able to fill out and submit the form ONLY after adding the following lines before anything else:
driver.switch_to_default_content()
driver.switch_to.frame("main")
I'd love to know why this is necessary, but at least it works now.
Thanks again Todor for your answer in the comments.
Related
W3C validator error with Chatango embedded code
So I embedded a chatango tab on my website, but I get this error when validating it for HTML. The text content of element script was not in the required format: Expected space, tab, newline, or slash but found { instead. Any workarounds for this? Thank you! <script id="cid0020000101807397328" data-cfasync="false" async src="//st.chatango.com/js/gz/emb.js" style="width: 603px;height: 471px;"> {"handle":"********","arch":"js","styles":{"a":"000000","b":100,"c":"a0a0a0","d":"FFFFFF","e":"202020","g":"bbbbbb","h":"202020","j":"c0c0c0","k":"0084ef","l":"606060","m":"0084ef","n":"FFFFFF","p":"10","q":"000000","r":100,"pos":"br","cv":1,"cvfntsz":"14px","cvbg":"3366ff","cvw":600,"cvh":30,"surl":0,"allowpm":0,"cnrs":"0.35","ticker":1,"fwtickm":1}}</script>
As Ben said - you cannot use code inside tag with src. But here is some valid and working solution: <!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>chatango</title> </head> <body> <script type="text/javascript"> var chatango = document.createElement('script'); chatango.setAttribute('type','text/javascript'); chatango.setAttribute('id','cid0020000101807397328'); chatango.setAttribute('data-cfasync','false'); chatango.setAttribute('async',true); chatango.setAttribute('src','//st.chatango.com/js/gz/emb.js'); chatango.setAttribute('style','width: 603px;height: 471px;'); chatango.innerHTML = '{"handle":"1shotgg","arch":"js","styles":{"a":"000000","b":100,"c":"a0a0a0","d":"FFFFFF","e":"202020","g":"bbbbbb","h":"202020","j":"c0c0c0","k":"0084ef","l":"606060","m":"0084ef","n":"FFFFFF","p":"10","q":"000000","r":100,"pos":"br","cv":1,"cvfntsz":"14px","cvbg":"3366ff","cvw":600,"cvh":30,"surl":0,"allowpm":0,"cnrs":"0.35","ticker":1,"fwtickm":1}}'; document.body.appendChild(chatango); </script> </body> </html>
Use javascript on embedded site? (iframe, object)
This is what I have tried, couple of other things too, no luck. This too, document.getElementsByName('btnK')[0].submit(); <!doctype html> <html> <head> <meta charset="utf-8"> <title>Untitled Document</title> <script type="text/javascript"> function click() { $('#myiframe').document.getElementsByName('btnK')[0].submit(); } </script> </head> <body> <iframe id="myiframe" src="http://google.com"></iframe> <button type="button" onClick="click()">Logg inn</button> <object type="text/html" data="http://google.no" width="100%" height="1000px"></object> </body> </html>
It is impossible because of the Same Origin Policy. Do you want someone to load your bank account in an iframe on some random page and start clicking buttons? No, that is why this security measure is in place.
How do you reference an html document to another html document in a div using jQuery?
this is my html: <!DOCTYPE html> <html> <head> <title>Free Jokes!</title> <meta charset="utf-8"> <link href="final%20project.css" rel="stylesheet"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> </head> <body> <div id="left"></div> <script type="text/javascript"> $(document).ready(function() { $('#left').load("left.html"); }); </script> <div id="right"></div> <script type="text/javascript"> $(document).ready(function() { $('#right').load("right.html"); }); </script> </body> </html> The html is opening fine, but my left and right html documents aren't showing up. This may be from not correctly typing in the code. Was there anything I did wrong? Is there any way I can reference my left and right html documents to this without using iframes?
The load function attempts to make an ajax call to the location specified (remember, here in JavaScript we're on the client), so unless you specify absolute URLs, it won't retrieve from the correct location. Furthermore, assuming that left.html and right.html are complete documents including doctype and <head> etc, that would produce invalid HTML. Try the following: <html> <head> <title>Free Jokes!</title> <meta charset="utf-8"> <link href="final%20project.css" rel="stylesheet"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> </head> <body> <iframe id="left" frameborder="0" style="border: 0;" src="left.html"></iframe> <iframe id="right" frameborder="0" style="border: 0;" src="right.html"></iframe> </body> </html> While it's not perfect, it should at least display the pages correctly.
Why does my code only show a White Screen in the Nokia Here HTML5 version?
I have followed the following example from Nokia Here HTML5. It's not working as expected. This is my current code: <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <!-- You should also add the following meta tags to support Blackberry 7.0+ devices --> <meta name="HandheldFriendly" content="True"> <meta name="touch-event-mode" value="native"> <meta name="cursor-event-mode" value="native"> <!-- To disable address sniffing and prevent native maps from starting, use the following meta tags --> <meta name="format-detection" content="telephone=no"/> <meta name="format-detection" content="address=no"/> <!-- <link rel="stylesheet" href="http://api.maps.nokia.com/mobile/1.0.2/lib/mh5.js">--> <link rel="stylesheet" href="http://api.maps.nokia.com/mobile/latest/lib/colors.css"> <!-- <script src="http://api.maps.nokia.com/mobile/1.0.2/lib/mh5.js"></script>--> <script src="http://api.maps.nokia.com/mobile/latest/lib/mh5.js"></script> </head> <body class="mh5_hwacc_body"> <div id="app_location" style="width:320px; height:480px; position:relative;"></div> <script> nokia.mh5.assetsPath = "http://api.maps.nokia.com/mobile/1.0.2/lib/"; nokia.mh5.app.embed({ domNode: "#app_location", appId: "_peU-uCkp-j8ovkzFGNU", appCode: "gBoUkAMoxoqIWfxWA5DuMQ" }); </script> </body> </html> I don't know why only shows a white screen. Do you have any idea? Optionally, I have another question. Does anyone know if this mobile version allows adding markers and clustering?
You need to make sure that the <script> initializing the mh5 container is called after the <body class="mh5_hwacc_body"> has been initialized. It would also help to include the doctype element as well. If you run your example in Chrome and check the error statements you can see that is attempting to append items into the body of the DOM when it is still null. The quick start example (appended below) works fine. You'll need to substitute in your own app id and token <!doctype html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="stylesheet" href="http://api.maps.nokia.com/mobile/1.0.2/lib/mh5.css"> <link rel="stylesheet" href="http://api.maps.nokia.com/mobile/1.0.2/lib/colors.css"> </head> <body class="mh5_hwacc_body"> <script src="http://api.maps.nokia.com/mobile/1.0.2/lib/mh5.js"> </script> <div id="app_location" style="width: 320px; height: 480px; position: relative;"> </div> <script> nokia.mh5.assetsPath = "http://api.maps.nokia.com/mobile/1.0.2/lib/"; nokia.mh5.app.embed ({ domNode: "#app_location", appId: "YOUR APP ID", appCode: "YOUR TOKEN" }); </script> </body> </html> Use the addPOI() method described here to add markers to the map. Clustering is not a standard feature of MH5 - it is a framework, not an API - works best within its own use case - i.e. rapid cross-platform mobile development for "search for X, route for X, add markers for X" and drill down to give an infobubble or new page. Where X is supplied by your data.
Loading linked .js with phonegap project
I've scoured the net and stackoverflow looking for help, but can't seem to find any and I consider myself officially stumped. All of my code worked without a problem when it was all within standard script tags, then as soon as I moved them to their own .js file it crapped out. Help! This is what I now have in index.html (I've cut out all the irrelevant code since I'm just testing): <html> <head> <title>PhoneGap Test</title> <meta name="viewport" content="width=device-width, user-scalable=no;" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript" charset="utf-8" src="phonegap-1.3.0.js"></script> <script type="text/javascript" charset="utf-8" src="jquery/src/lib/jquery-1.7.js"></script> <script type="text/javascript" charset="utf-8" src="jquery/src/jqtouch-jquery.js"></script> <script type="text/javascript" charset="utf-8" src="jquery/src/jqtouch.js"></script> <script type="text/javascript" src="databasecalls.js"></script> </head> <body onload="init();"> <p>Some stuff here</p> </body> </html> Then, this is what I have in databasecalls.js: alert("file loaded"); function init(){ document.addEventListener("deviceready", phoneReady, false); } function phoneReady(){ // **** first, open the database **** alert("Start making DB object"); dbShell = window.openDatabase("TimeBlogger", "1.0", "TimeBlogger", 20000000); alert("Created DB object"); //and run another function if the setup is successful (displayEntries) dbShell.transaction(setupDBTable, errorHandler, getDBProjectEntries) } So, unless I am mistaken, I should at the very least get alert(); to run as soon as it is read into index.html, right? I'm not even getting that! Is there something with the phonegap API that I missed... like everything needs to be in index.html or something? Thanks in advance! Justin