Cucumber, Capybara, and Selenium check if browser alert is showing - ruby

I am looking for checking browser alert when I do a test case. In my scenario, if there is an error occurence, it will alert an pop up dialog. I was looking the solution to handle this. So far I have done a function like this :
def alert_present?
begin
page.driver.browser.switch_to.alert
true
rescue
Selenium::WebDriver::Error::NoAlertOpenError
false
end
end
is there any way other than this?

ok so if you want just to accept the alert and you are not sure that even there will be one
then i think overriding the confirm method in javascript will do it, just make sure add this line before the line that triggers the dialogue to pop up
page.evaluate_script('window.confirm = function() { return true; }')
your line of code that triggers the alert
if there will be alert it will be accepted once it popup if not there won't be problems.

Related

How to handle windows pop up in IE using Ruby

Please help me how to handle this pop ups.
Based on your last question, I assume you are using Watir-Classic (even though you have also listed Watir-Webdriver).
As #orde mentioned in the comments, Watir has an Alert class for handling these types of dialogs. Unfortunately, in terms of clicking buttons, Watir-Classic only has an #ok method defined:
# Press the "OK" button on the JavaScript dialog.
def ok
dialog.button(:value => "OK").click
wait_until_not_exists
end
This will not work for this dialog as there is a "Yes" and "No" button rather than an "OK" button. You will need to duplicate this functionality with the right value.
Note that the dialog is a RAutomation window and no longer Watir specific code. As a result, the button values are not always intuitive - it is not always just the text you see. To get the right values, you should ask the dialog what values it sees:
browser.alert.send(:dialog).buttons.map(&:value)
#=> ["&Yes", "&No"]
We can then make the same calls as the #ok method, but with the correct value:
alert = browser.alert
alert.send(:dialog).button(:value => '&Yes').click
alert.wait_while_present
This code is working fine to handle this type of pop ups:
save_dialog = WIN32OLE.new("AutoItX3.Control") save_dialog.ControlClick("Windows Internet Explorer", "Yes", "[CLASS:Button;INSTANCE:1]")

how to reload page until a button appears using capybara and ruby

I want to click a button after an action and button does not appear until and unless I reload the page. And some times it takes some time to appear the button and I have to reload page for more than once. I don't want to put static delays. So is there a way to achieve following using capybara and ruby:
do
page.evaluate_script("window.location.reload()")
until a button appears
While Mesut's code should work fine, I would re-write it as:
Timeout.timeout(Capybara.default_max_wait_time) do
loop do
page.evaluate_script("window.location.reload()")
break if page.has_selector?(...)
end
end
This will make sure to fail if it will have to wait more than timeout defined in Capybara settings. It can be useful when for example specs are running on the CI server.
Be aware that it can still lead to unexpected behaviors in some drivers, because it can interrupt while some scripts are evaluating.
reoload until page.has_selector? returns true, check this:
while true
page.evaluate_script 'window.location.reload()'
if page.has_selector?("css_selector")
break
end
end

click_no_wait doesn`t act click

I have some code like this:
content.button(:id,/Submit/).click_no_wait
puts 2
autoit = WIN32OLE.new("AutoItX3.Control")
puts 3
autoit.WinWait "XXXX"
puts 4
autoit.ControlClick "","OK","Button1"
After click the Submit button,a alert box will pop out,and the code after will click OK of that.The function "click" will hang program there so I need to use "click_no_wait".
But as a result,I can get the puts of 3,and the submit button doesn`t been licked.
Why?And what is the best solution?
If you are dealing with javascript popups, see this page: http://watirwebdriver.com/javascript-dialogs/
If the #click_no_wait does not open the dialog, but regular #click will, then it does not work for some reason. I have written a blog post about debugging #click_no_wait problems at http://itreallymatters.net/post/1366392123/debugging-and-improving-watirs-click-no-wait-method#.UMCuJoOgnvA
In short, set $DEBUG to true before #click_no_wait to get more troubleshooting information:
$DEBUG=true
content.button(:id,/Submit/).click_no_wait
$DEBUG=false

How to handle Modals in cucumber + Capybara + Selenium

So I am trying to click a forgot password link (which causes a modal pop up) and confirm the pop up link so I can perform a test on the sent out email.
My code looks like this:
page.find(:css, '#launch-modal-link').click # code fails on this line, after clicking the link
page.driver.browser.switch_to.alert.accept # does not get to this line of code.
What am I doing wrong exactly when trying to click the "Ok" button in the modal pop up?
Do I need to add a try catch block (or whatever it is called in Ruby) around the link
Solved it - Found the answer somewhere else. Its a hack though, and not something done via cucumber directly.
page.evaluate_script('window.confirm = function() { return true; }')
This works because it over writes the confirm() to always return true and the confirm function seems to be a common javascript function to return the button clicked in a dialog box. Could be wrong about that. (read the javascript function being performed onclick. Might not always work)

Selenium Webdriver - How do I skip the wait for page load after a click and continue

I have an rspec test using webdriver that clicks on a button... after clicking the button, the page never fully loads (which is expected and correct behaviour). After clicking the button, I want to wait 2 seconds and then navigate to a different URL... despite the fact that the page has not loaded. I don't want to throw an error because the page hasn't loaded, I want to just ignore that, and continue on as if everything is good. The page should never load, that is the expected and correct behaviour.
How can I avoid waiting until the timeout, and secondly, how can I have that not throw an error which casuses the test to fail.
Thank you!
WebDriver has a blocking API and it will always wait for page to be loaded. What you can do instead, is to press the button via JavaScript, i.e. trigger its onclick event. I am not familiar with Ruby, but in Java it would be:
WebDriver driver = ....; // Init WebDriver
WebElement button = ....; // Find your element for clicking
String script = "if (document.createEventObject){"+
"return arguments[0].fireEvent('onclick');"+
"}else{"+
"var evt = arguments[0].ownerDocument.createEvent('MouseEvents');"+
"evt.initMouseEvent('click',true,true,"+
"element.ownerDocument.defaultView,1,0,0,0,0,false,"+
"false,false,false,1,null);"+
"return !element.dispatchEvent(evt);}" ;
((JavascriptExecutor)driver).executeScript(script, button);
After this you can wait for 2 seconds and continue
I had this similar problem, I tried this solution which #Sergii mentioned but was getting below error:
org.openqa.selenium.JavascriptException: javascript error: element is not defined (Session info: chrome=84.0.4147.89)
As a workaround had to initialize element within java script code.
String script = "var element = document.querySelector('button[type=submit]');" +
"if (document.createEventObject){"+
"return element.fireEvent('onclick');"+
"}else{"+
"var evt = element.ownerDocument.createEvent('MouseEvents');"+
"evt.initMouseEvent('click',true,true,"+
"element.ownerDocument.defaultView,1,0,0,0,0,false,"+
"false,false,false,1,null);"+
"return !element.dispatchEvent(evt);}" ;
Thank you #Sergii for your answer, I was not able to add this as a comment due to limited characters, so added it as a separate answer.
why don't you try a simple trick of using "waiting()" after waitForPageToLoad() which makes it to neglect the previous command in Selenium and never fails that step
What if you used RSpec's expect method:
expect {
Thread.new() {
sleep(2)
raise RuntimeError
}
theButton.click()
}.to raise_error
Send the 'Enter' key to the link or button in question instead of a click, webdriver won't wait for the page to load and will return instantly (this is in C#, just translate to Ruby):
element.SendKeys(Key,Return);

Resources