jQuery Error
I've done some extensive searching, and have found samples of code to handle an alert box when you expect it; but I haven't been able to find anything on handling a random alert box that might, or might not appear.
The website I'm dealing with is very stubborn to begin with. Several elements without any kind of ID's, timeouts, network failures, etc.
98% of the time when I run the tests, they run without getting the alert box error and everything is good. When the alert box does popup the other 2% of the time which says "Error:jQuery not found," all my other tests fail with unexpected alert errors.
My first question is, could it be something in my code that's causing the error to happen? (see code below) My gut tells me it's probably the website. So if that's the case, could someone please show me an example that would handle a "possible" alert box and accept it, without failing my test? The swithTab() test is running first, and then the setDates() test is running next. The alert box error pops up after the switch tab, as the page is loading. I've tried using a deferred promise to handle the alert, and catch the error, but it fails before it can even catch the error. It fails as soon as it hits browser.switchTo().alert() because the alert usually doesn't exist. I really appreciate any help I could get.
this.switchTab = function(){
browser.getAllWindowHandles().then(function(handles){
browser.switchTo().window(handles[1]);
browser.sleep(2000);
var lockBoxTitle = element(by.css('td.title'));
browser.driver.wait(EC.visibilityOf(lockBoxTitle),5000);
});
}
this.setDates = function(yesterdayDate){
browser.sleep(3000);
//handleAlert();
startDateTextBox.clear();
startDateTextBox.sendKeys(yesterdayDate);
endDateTextBox.clear();
endDateTextBox.sendKeys(yesterdayDate);
retrieveBtn.click();
browser.sleep(5000);
expect(validateStart.getText()).toEqual(yesterdayDate);
expect(validateEnd.getText()).toEqual(yesterdayDate);
}
You can check if popup is displayed and if is displayed click the button for closing it:
var popUpElm = element(by.model(""));
var closeBtn= element(by.model(""));
popUpElm.isDisplayed().then(function(isDisplayed) {
if (isDisplayed) {
closeBtn.click();
console.log("Popup is closed");
} else {
console.log("Popup is not displayed");
}
});
Related
In a page, when I click on a certain button, I get a javascript popup with 'Ok' and 'Cancel' buttons. I want to click 'Ok' button in that popup using Ruby Watir script. So I use the following code. I get the FAIL message since javascript popup comes and goes out within fraction of a second in Firefox browser. So to check whether the script catches the alert, I did print p browser.alert.present? and I get that as false. How to handle such a issue?
if (certain_button_click)
p browser.alert.present? #I get this as 'false'
browser.wait_until(30) {
browser.alert.present?
} rescue nil
p browser.alert.present? #I get this as 'false'
if browser.alert.present?
browser.alert.ok
message = 'Click Ok - PASS'
else
message = 'Click Ok - FAIL'
end
end
Please help. Thanks in advance.
Thanks,
Ashwin
Honestly I can't tell what you are trying to accomplish here, but I see what your code is doing.
Selenium raises an UnhandledAlertError whenever an alert is present, but a non-alert related action is taken with the driver. What your code is doing is rescuing that exception (well, all exceptions, which you should avoid doing when you know which exception you want to avoid). Firefox has different behavior than Chrome in this respect in that it also closes the alert when it raises the exception. So your code is doing exactly what you are telling it to do.
if you use Watir 6.0 you don't have to specify the waits any longer. If you only want to dismiss an alert when it shows up, this code will automatically wait for the alert to show up and click ok when it does. If the alert never shows up it will give a timeout error.
element_causing_alert.click
browser.alert.ok
If you are trying to test that the alert shows up, then you can use this code:
begin
browser.alert.ok
true
rescue Watir::Wait::TimeoutError
false
end
Or if you want to specify the time to wait before timing out:
begin
browser.alert.wait_until(timeout: 5, &:present?).ok
true
rescue Watir::Wait::TimeoutError
false
end
Here's an alternate idea. You can use execute_script in the browser which 'stubs out' the alert call to set a global variable. Then another execute_script which checks that the variable was set.
Example:
def stub_alert
script = <<-JS
window.alert = function(){ window.alerted = true }
JS
browser.execute_script stub_alert
end
def check_for_alert
script = <<-JS
return window.alerted == true
JS
browser.execute_script stub_alert
end
Watir uses selenium under the hood, and there's some tricky things about working with alerts. I've experienced the situation where Selenium's reference to the alert disappeared if I ran any javascript before handling the alert.
So, I am writing a protractor test to log into an app. When a user logs in successfully a popup notification appears stating "you have successfully logged in."
Right now I am doing a browser.sleep() to wait for the popup to pop up after the login button is clicked. I don't like doing this, on slower networks Protractor is not waiting long enough and the test is failing when I try to catch the popup or alert because alert.accept() is running too soon.
Is there a way to wait the promise from the login to return to continue on with the test?
UPDATE:
I think that I have figured it out. So I'm doing this:
LoginView.loginButton.click().then(function () {
browser.wait(exc.alertIsPresent()).then(function () {
App.catchAlert();
})
});
This seems to be working, but I haven't tested it on a slower network. What do you think?
You need to wait specifically for the alert to be present. There is a specific built-in Expected Condition called alertIsPresent:
var EC = protractor.ExpectedConditions;
browser.wait(EC.alertIsPresent(), 10000);
I am trying to delete a database for unit testing:
var DeleteDb = indexedDB.deleteDatabase(dbName);
this piece of code gets directly called in the first beforeEach in jasmine.
with chrome devTools i can see that DeleteDb.error has the following value:
error: [Exception: DOMException: Failed to read the 'error' property from 'IDBRequest': The request has not finished.]
DeleteDb.onsuccess or DeleteDb.onerror are never fired. Also i am never trying to read an 'error' property in the code.
Does somebody know what this error means, where it is coming from or how i can solve it?
UPDATE:
This code still sometimes fails for me. it gives me the same error as above.
<html>
<head>
<script>
var deleteDb = window.indexedDB.deleteDatabase('fakeNonExistentDatabase');
deleteDb.onsuccess = function() {
console.log('complete');
};
</script>
</head>
</html>
I am still not sure why this is happening. sometimes opening a new tab or closing another one works.
Also it never gives an error when removing the onsuccess callback
UPDATE 2
Well it seems that the code is actualy working, but the onsuccess event is never getting fired because no events are getting fired anymore when pressing F8 in chrome devtools. The error i;m getting now is:
Uncaught InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing.
I thought the above error message was a result of the first error message in this post but actualy it was the other way around. There are a few pages i can find about this topic on the internet but there isn't really provided a answer.
Any thoughts?
Also check onblocked. There might be another db connection that keeps your delete request from neither succeeding nor failing.
It is possible to avoid this behaviour by listening to onversionchange on your opened connections and make sure to close the connection when that event is triggered.
Okay as it turns out all of my code was good but deleting a database a second time takes somwhere between 10 seconds and several minutes.
you can test this for yourself: the code in this post shows it
what was happening is that jasmine times out after 5 seconds by default (i changed this to a higher number but who would think i takes THAT long)
browser: Chrome 39.0.2171.71 m
Make sure when deleting
the RESULT from DB creation is not empty
close the RESULT before deleting
delete through the same connection you created
var init=function(){
var request = this.connection.open(name,version);
request.onupgradeneeded=function(e){
var version=e.target.result;
};
request.onsuccess=function(e){
db.result=e.target.result;
};
request.onerror=function(e){
};
};
var remove=function(){
if (typeof db.result !== 'undefined') {
db.result.close();
return this.connection.deleteDatabase(version);
}
}
This is 5 years late, but just in case there are more guys like me...
close the connection to the database before deleting it...
I work with some very large and confusing JavaScript files that I did not write. Sometimes an alert will come up but I don't know where it's coming from.
You could search all files for the text contained in the alert but if that text is dynamic it won't work.
Is there a way to set a breakpoint in order to intercept an alert?
At the very top of your HTML:
window.alert = function() {
debugger;
}
debugger is a statement that invokes any debugging functionality available. With developer tools open, you'll automatically hit a breakpoint whenever alert is called. You can then inspect the call stack to see exactly what called the custom alert function.
It may or may not be helpful to you, but you can overwrite the alert function to do whatever you want with it. For example, instead of alert boxes, you could have it log the message to the console.
window.alert = function(msg) {
console.log(msg);
}
alert('test');
I agree with Brian Glaz, but in order to get more details (line number) you might try to throw an error when alerting something and outputting the error on the console. this way, the console will point you to the right line number where the alert function was called.
Put this snippet at the top of your document and give it a try :
var originalAlert = window.alert;
window.alert = function(){
try{
throw new Error('alert was called');
} catch(e){
console.warn(e);
}
return originalAlert.apply(window, arguments);
}
Open Chrome push F12 key and go to Sources.
Then choose a script file Ctrl+F and search for alert.
You can put breakpoint on any line you wish
I have the following issue and I'm a bit new to Phonegap! On my index page I have three functions that will create a Javascript Prompt asking the user for their name, email and title (position) and store each to the localStorage. Three items like this:
function promptName(){
var salesPName = prompt("Bitte geben Sie Ihren Namen","");
if(salesPName == null || salesPName == ""){
promptName()
}else{
localStorage.setItem("salesP", salesPName);
}
}
Then using $(document).ready I call these three functions:
$(document).ready(function(){
if(!localStorage.getItem("salesP")){
promptName();
promptEmail();
promptPosition();
}
});
This is all working well, however when deploying to my Android device I get the prompts but before I can complete all three I get an error dialog stating:
The connection to the server was unsuccessful (file:///android_asset/www/appname/index.html)
Removing the prompts removes the error but I need this functionality. I have tried different ways of calling the functions, for example on the body tag's onload event or using .load(). I still get this error. I thought about setting a Javascript interval to call this after a few seconds (once the page is loaded) as I'm sure the problem is due to Javascript's blocking nature. Has anyone come across this before?
Please note that I added the following to the com.mypackage.xxx.java file (as advised from phonegap, connection to server unsuccessful)
super.setIntegerProperty("loadUrlTimeoutValue", 10000);
And I still get the problem!
with nothing working I put a setTimeout() around my condition like so...
$(document).ready(function(){
setTimeout(function (){if(!localStorage.getItem("salesP")){
// item doesn't exist... so let's raise some dialogs to capture the name, email address and title
promptName();
promptEmail();
promptPosition();
}
}, 5000)
});
now it works fine... a bit of a fudge but so what, if anyone has any ideas on a better solution or any objections to this please let me know