I'm trying to use JavaScript's setTimeout in an extension I've made for Selenium IDE.
In short I have made the extension to take a username and password to login to a page, rather than having to use a few commands on every test I make, it'd save a lot of time using my custom command.
So obviously In need to wait for the page to load, so I have added a setTimeout which calls a function that will keep checking if the page is ready yet.
setTimeout only seems to run the once however.
Thinking I may have something wrong with my script I just copied some off w3schools and that fails to work either, so tried this simple one below, which surely should work, but I only get a log output of '1'.
var i=0;
function loopThrough(){
i=i+1;
LOG.info(i);
setTimeout("loopThrough()", 2500);
}
loopThrough();
Related
First of all: I know that there are some questions similar to this, but I could not found any alternative to it, but to ask.
Hello!
Is there any event like "DOMLastNodeRemoved" (or FirstNode, since u can't know for sure when it will be the last node removed) to prevent multiple executions of code?
Here's the deal, I'm using Genexus. The only way to make an event work in this weird SPA concept is using DOMNodeRemoved event.
But whenever you click a button, it will insert a lot of nodes, making the function execute like 25 times instead of just one.
Let's go to an example:
I'm currently with this code:
$(document).on("DOMNodeRemoved", function() {
$(".Button").click(function() {
setTimeout(
function() {
toastrgx();
$('.gx-warning-message').css('display', 'none');
}, 800);
});
function toastrgx() {
var meuLoader = new Loader($);
meuLoader.Insert();
setTimeout(function() {
meuLoader.Remove();
var text = $('.gx-warning-message').text();
toastr.error(text, '');
}, 500);
};
});
I need to use timeout because the DOM is still loading up the message.
Anyways, with this code I'll get this result presented in the image:
If i use something like preventPropagation (at least the way I used) it will run my code only once, but returns a lot of errors in the console (one for each execution) and also breaks my loader.
BTW, I have power only over one custom script, everything else is generated by Genexus.
So, if I use any other normal event like document.ready, it will fire the first time I load a page within my MasterPage, but, if I click in any other page, it will not fire the event again.
So, my question is:
There is any way to execute a code only once in my case?
Is it something that I'm not seeing clearly like another event or another way to make the code work?
If the question sounds silly, sorry, i'm a newbie in JS.
The way to go in this case is creating a User Control and using its show function, that is executed by the generated application every time the control should update (for example, when the page is loaded or when a property of the control is modified).
Why a User Control?
User Controls offer a standard interface to interoperate with GeneXus generated applications. This interface is well documented and abstracts you from the inner workings of the generated applications.
If you try to extend GeneXus by including scripts, you will be exposed to unexpected behavior and changes without previous notice.
How to create a User Control
To create a User Control I recommend using the GeneXus User Control Generator, for Atom. Using this Atom package you can easily create a GeneXus User Control.
Follow the steps to create a User Control and choose Web when prompted for the supported platforms by the package.
How to have code execute only once, when the page is loaded
After creating the User Control, open the src/<YourUserControlName>Render.js file and edit the show function this way:
this.show = function() {
if (!this.IsPostBack) {
// This code will be executed only, when the page is loaded.
}
}
Inside the if you can code whatever you need to execute only once per page.
How to deploy a User Control
To build and deploy the User Control to your GeneXus installation directory, follow the build process steps described in the package documentation.
Once you have deployed your User Control, you should include it in the master page object, to start using it, instead of the script you are using now.
Suppose I want to build someone similar to an alarm, except every hour it performs a list of tasks. For the sake of this example, suppose it is to send notifications. I want the inner function to look something like this:
$scope.performTasks = function(){
emailUserWeb();
emailUserPhone();
postToFacebook();
postToTwitter();
postToWherever();
}
So, assume everyday, this sends a notification at exactly ##:37pm. If I want something like this to run even when I am not on the site, how can I build something like that? Is it even possible?
Your Javascript is client-sided. That means it can only be executed as long as it is executed by the client's browser.
If you want to execute scheduled tasks, you need a server that runs the code (e.g., NodeJS).
You can build it as Chrome App/Extension which will have a backgroud process, If you keep Chrome running, even if not on the app webpage, it will work.
Check: https://developer.chrome.com/extensions/background_pages
I'm wondering if it is possible to, in Java, detect whether or not an HTML file would open an alert dialog if opened in the browser. Preferably headlessly. For example, a file with the below contents were parsed, it would return true.
<html><script>alert("hey")</script></html>
and the below would return true also
<html><iframe src="javascript:alert(1)" onload="alert(2)"></iframe></html>
but the below would return false because it would not open an alert dialog if it were opened in the browser (because none of the code is syntactically correct, and the part that is isn't in a tag).
<html><script>alert;,(123w)</script>alert(1)</html>
I have thought of a way to approach this problem, but it is flawed. Basically, you see if the stringalert(1) is in the file, etc.
The problem with this is that it wouldn't work in cases where that code isn't inside of script tags or tags that make it execute. An example of where it wouldn't work is: The following would return true, even though it wouldn't actually open a popup <html>alert(1)</html>.
This isn't Android by the way. Appreciate your help!
You will need to not only verify if the Alert function is there but check if the JavaScript function would even run. An example of this is if there is a script with an Alert function inside a function that never runs. The Alert function would be there but it would never run. This would give a false positive. So the in the best case you should run the JavaScript in some way to validate the code and to see if the function would ever run.
As Louis pointed out in the comments Option 2 is better in this case as you will need to account for both the DOM and JavaScript's behaviour as both can change if the Alert function runs and how it runs.
Option 1 : Run the JavaScript with Script Engine
You would need some way of separating the HTML from the JavaScript but once you have that you can do this method.
You can run the JavaScript in Java using ScriptEngine. https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/api.html
If you read the API there is a way to create variables and communicate between your Java Program and the JavaScript you are Running.
To capture the context of the Alert you can create a custom JavaScript function that overwrites the Alert function. Inside this custom function you can send the arguments of the function back to your Java Program.
Option 2 : Headless Browser
You can also try to use a headless browser like JBrowserDriver and as you can see you have an Alert interface with getText as a function. For async issue the headless browser has a default amount of time for waiting for the script to complete. If this default amount is not enough you can use the setScriptTimeout to handle it.
http://machinepublishers.github.io/jBrowserDriver/
I'm starting with Sencha test and trying run some simple tests.
I start with simple webpage and it works. Now when I create simple form i ext, and try to test it using localhost, I have communicate
Failed: Timeout waiting for target (input[name="name"]) to be available
I'm doing it exactly same way just change the elements names, so it should work.
I know that it can be cos page loading is too long so I try add function for wait (both with time and until it find element), nothing helps.
Any ideas?
I'd like to write a test case (using Selenium, but not the point of this question) to validate that my web application has no script errors\warnings or unhanded exceptions at certain points in time (like after initializing a major library).
This information can easily be seen in the debug consoles of most browsers. Is it possible to execute a javascript statement to get this information programatically?
It's okay if it's different for each browser, I can deal with that.
not so far read about your issue (as far as I understood your problem) here
The idea be the following:
I found, however, that I was often getting JavaScript errors when the page first loaded (because I was working on the JS and was introducing errors), so I was looking for a quick way to add an assert to my test to check whether any JS errors occurred. After some Googling I came to the conclusion that there is nothing built into Selenium to support this, but there are a number of hacks that can be used to accomplish it. I'm going to describe one of them here. Let me state again, for the record, that this is pretty hacky. I'd love to hear from others who may have better solutions.
I simply add a script to my page that will catch any JS errors by intercepting the window.onerror event:
<script type="text/javascript">
window.onerror=function(msg){
$("body").attr("JSError",msg);
}
</script>
This will cause an attribute called JSError with a value corresponding to the JavaScript error message to be added to the body tag of my document if a JavaScript error occurs. Note that I'm using jQuery to do this, so this specific example won't work if jQuery fails to load. Then, in my Selenium test, I just use the command assertElementNotPresent with a target of //body[#JSError]. Now, if any JavaScript errors occur on the page my test will fail and I'll know I have to address them first. If, for some strange reason, I want to check for a particular JavaScript error, I could use the assertElementPresent command with a target of //body[#JSError='the error message'].
Hope this fresh idea helps you :)
try {
//code
} catch(exception) {
//send ajax request: exception.message, exception.stack, etc.
}
More info - MDN Documentation