Selenium C# IJavaScriptExecutor throws error but JS is fine - javascript

I'm using Selenium C# to test a pretty complex web UI in Internet Explorer 11. As you might know, Selenium's Click() tends to not work in which case inserting a JS click method is necessary.
I'm running the dynamically generated script below using
(IJavaScriptExecutor) driver).ExecuteScript(script).
Here is the script :
let iFrame = document.getElementById("dkwframe").contentWindow.document;
let element = iFrame.querySelector("[id*='_ImgLnkNewPage_LinkButtonControl']");
element.click();
The script works fine when I execute it directly in the IE console, but when executing with it Selenium I get this :
System.InvalidOperationException : Error executing JavaScript (UnexpectedJavaScriptError)
The IE console is empty so I don't think it's even trying. Also, switching browser isn't an option.
Thanks for the help

Maybe the script is being executed before the page is fully loaded ,try to put it in a page ready event ha dler like that
window.onload = function() {
et iFrame = document.getElementById("dkwframe").contentWindow.document;
let element = iFrame.querySelector("[id*='_ImgLnkNewPage_LinkButtonControl']");
element.click();
}
Or you can check if the fully loaded with :
if (document.readyState === 'complete') {
}

Related

Error cannot read property 'style' of null

That's what my JavaScript look like
JS:
const secondHand = document.querySelector(".sechand");
secondHand.style.width = "10px";
This is when run on Chrome mobile browser.
Can anyone help me?
If the error is that your selector turned up null, then you haven't correctly selected the element.
Either you don't have an element that has the class "sechand"... or, more likely, you're running the JS before the DOM is ready. Try running your JS on an 'onload' event, or place it at the bottom of your page.

How to remove HTML script tag with open type [duplicate]

How can I remove script elements before they are being executed?
I thought about using the DOMNodeInserted event, but apparently it doesn't catch script elements. I've also tried using the jQuery livequery plugin like that:
$("script").livequery(function () {
$(this).remove();
});
It did remove the script element, but after it was executed.
I'm looking for a cross-browser solution, but I'm not even sure if that's possible. I read about Mutation Observers which seems close enough but I'm not sure if it can solve my problem.
It would be even better if there was a way to modify the script content before it is being executed without removing and recreating it.
Removing a script element does not do anything. If you can somehow access a script element, it was executed a long time ago and removing it will have no effect.
So we need to work around it. If your script element is at the top of the page like this:
<head>
<script src="yourscript.js"></script>
You could make a synchronous ajax request to the same page, so you can parse its content into a new document, modify all script tags and then replace
the current document with the modified document.
var xhr = new XMLHttpRequest,
content,
doc,
scripts;
xhr.open( "GET", document.URL, false );
xhr.send(null);
content = xhr.responseText;
doc = document.implementation.createHTMLDocument(""+(document.title || ""));
doc.open();
doc.write(content);
doc.close();
scripts = doc.getElementsByTagName("script");
//Modify scripts as you please
[].forEach.call( scripts, function( script ) {
script.removeAttribute("src");
script.innerHTML = 'alert("hello world");';
});
//Doing this will activate all the modified scripts and the "old page" will be gone as the document is replaced
document.replaceChild( document.importNode(doc.documentElement, true), document.documentElement);
Unfortunately this cannot be set up in jsfiddle or jsbin. But you should be able to copy paste this code exactly as it is into this
page's console in google chrome. You should see the alerts and when you inspect the live dom, each script was modified.
The difference is that we are running this after scripts have been executed on the page, so the old scripts should still have a working effect on the page.
That's why, for this to work, you need to be the very first script on the page to do it.
Tested to work in google chrome. Firefox is completely ignoring the doc.write call for some reason.
i donot know what you are trying to do. But it is better to load them on request rather than delete on some conditions.
$.getScript('helloworld.js', function() {
$("#content").html('
Javascript is loaded successful!
');
});
If you wants to remove scripts before there execution, its not possible.
But what you can do is, remove script programatically on a condition & if have an issue with memory-leaks, then you can call below code before remove script.
var var1 = 'hello';
var cleanAll = function () {
delete window.var1;
delete window.cleanAll;
};
// unload all resources
cleanAll();

jquery doesn't work in WebBrowser control with specific webpage

I'm trying to programmatically open the hidden div containing the bitrate information in this web page: http://www.myfreemp3.cc/mp3/jamie+jones+cookie+monster
I'm using an hidden WebBrowser, in which i'm injecting and executing this code:
$("[class^='bitrate butt bit']")[0].click();
but it doesn't work.
If you put the code line above in the Firefox debugger's console it works...
This is my code:
webBrowser.Navigate("http://www.myfreemp3.cc/mp3/jamie+jones+cookie+monster");
waitTillLoad(webBrowser); //wait till the document finish to load
string script = "function click_checkButtons () { $(\"[class^='controll_button playlist_button']\").click(); }";
HtmlElement head = webBrowser.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = script;
head.AppendChild(scriptEl);
webBrowser.Document.InvokeScript("click_checkButtons");
This is due to that WebBrowser is basic component of older IE, you can enter settings in registry to run your webbrowser to use latest internet explorer which you have in your computer, Take a look at this link
Will the IE9 WebBrowser Control Support all of IE9's features, including SVG?
Have you tried appending to document.body instead of document.head?
...Tom

jQuery 2.0.3 bug - fadeIn(), show() broken in firefox - SecurityError: The operation is insecure

I have a very basic html element that I would like to fadeIn(). I am however using require.js so I believe this could be part of the problem. I am using jQuery 2.0.3 When using fadeIn I get this error:
SecurityError: The operation is insecure.
chrome://firebug/content/console/commandLineExposed.js
Line 5
I have never seen this before, I have reset firefox and my PC.
Html
<message-box>
<message-info></message-info>
<close-box>x</close-box>
</message-box>
JS
$('message-Box').fadeIn();
I only get this error with firefox v27. No other browsers are having this problem, but I haven't tested it in any older versions of FF
I am not seeking help for anything other than the error...
See the error in action? and run this command: SD.message.showMessage('Somehow this breaks everything', 'bad');
-----Edit-------
So sadly you'll need to test this Here I assure you this is SFW, its just the sign in page.
I am confident there must be something in my other JS files that is conflicting, but I, as yet, have not found the problem.
I removed a fiddle that was here as it in no way helped the question, since adding the bounty I want it to be as helpful as possible.
Second Edit
Oddly, when running any show(), hide(), fadeIn() etc an iframe is created at the base of the page, just before the body. I'll need to have a think in my code why this would be happening.
Third Edit
I have no reason or explanation for this, but updating to jQuery 2.1.0 has fixed my issues. If anybody can explain the problem then I'd love to give them the points :)
Stepping through the jQuery code, you eventually hit this internal function below. The security error is thrown when jQuery attempts to write to the iframe document. jQuery 2.1.0 has a different way of determining the default node display value so you can just treat this as a jQuery/browser combo bug. You can minimally recreate the security error by pasting the following into the console:
var iframe = jQuery("<iframe frameborder='0' width='0' height='0'/>").css( "cssText", "display:block !important" ).appendTo(document.documentElement);
iframe[0].contentWindow.document.write("<!doctype html><html><body>");
Internal jQuery function:
function css_defaultDisplay( nodeName ) {
var doc = document,
display = elemdisplay[ nodeName ];
if ( !display ) {
display = actualDisplay( nodeName, doc );
// If the simple way fails, read from inside an iframe
if ( display === "none" || !display ) {
// Use the already-created iframe if possible
iframe = ( iframe ||
jQuery("<iframe frameborder='0' width='0' height='0'/>")
.css( "cssText", "display:block !important" )
).appendTo( doc.documentElement );
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
doc.write("<!doctype html><html><body>");
doc.close();
display = actualDisplay( nodeName, doc );
iframe.detach();
}
// Store the correct default display
elemdisplay[ nodeName ] = display;
}
return display;
}
As per specification custom elements shall have '-' in their tags, so your markup should look like this:
<message-box>
<x-message><div></div></x-message>
<x-close>x</x-close>
</message-box>
After the change and corresponding style updates it works as far as I can tell: http://jsfiddle.net/9Frn8/11/
Looks like this may be due to the absolute paths in your CSS file. I also see (in console) you are trying to do a call to localhost (which fails, of course). There seems to be some issues in your code that is causing Firefox to stop specific processes. Specifically, something that firefox considers cross-domain.
This is most likely a Same-Origin-Policy issue.

Javascript not finding Button with ID

In my HTML, I have a simple button defined, like so:
<button id="toggleButton">Stop</button>
I am trying to grab it with the following code:
buttonElement = document.getElementById("toggleButton");
with the goal of assigning an event to it, like so:
buttonElement.onclick = stopTextColor();
The problem is that the getElementById is returning null, even though I can see it in the DOM. What am I doing wrong here?
For clarity, I posted the full code at http://cdpn.io/sqEuH
The problem, probably, is that you're including the JS in the head. What's happening there is the JS is running before the page gets loaded, so the button doesn't show up. Move it to right before the </body> tag, and this problem will be solved, or wrap it with a window.onload() event.
The code you post will work unless the javascript cannot access the given DOM element.
The main possibilities:
The javascript runs before the DOM is parsed (IE if you run it in the head of the document without any code to instruct it to wait till the DOM is ready)
You can usually get around this by placing your script at the bottom of the body rather than in the head or midway through the body. The essential thing to understand here though is that JS can't access an element till the browser has parsed the DOM. The browser parses HTML top-down, and JS scripts run top down, so if you run the JS before the element is parsed, it won't be available to the javascript function yet.
The javascript runs in a context where it can't access the element (inside an iFrame for instance). In this case it would be a question of whether the element is really under the "document" object that you're referring to. If the element is inside an iFrame it will be underneath the iFrame's document object.
Try putting your script just before closing your <body> tag. The DOM is probably not fully loaded when your script is run.
Also, I think you have an error in your Javascript. It should be
buttonElement.onclick = stopTextColor;
instead of
buttonElement.onclick = stopTextColor();
Altough it shouldn't throw any error, it's good practice.
If you want to keep your Javascript before <body>, you can use a listener to wait for the DOM to be loaded and then execute your script, like this :
window.addEventListener("DOMContentLoaded", function() {
buttonElement = document.getElementById("toggleButton");
buttonElement.onclick = stopTextColor;
}, false);
[edit]
The snippet above doesn't work in IE < 9. If you need to support it, use document.load instead, it should give the same result, like so :
document.onload = function() {
buttonElement = document.getElementById("toggleButton");
buttonElement.onclick = stopTextColor;
}
The differece between both, besides browser compatibility, is that window.addEventListener("DOMContentLoaded", function() {...} will fire when the DOM is loaded, but window.load will fire when the DOM AND all other resources (images, stylesheets, etc.) are loaded (slower, and not necessary in your case).

Categories

Resources