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
Related
I cannot get Capybara to click on the SCA/3DS ‘Complete authentication’ button when running RSpec tests. Similar tests which do not trigger SCA pass just fine, and if I run VNC to view what Firefox is doing, the button is visible and I can click it myself in the browser.
My problem seems very similar to what’s discussed in the comments here, but the solutions do not work: I have tried changing the browser used, and flattening the iframe traversal.
Test code:
scenario "SCA required" do
create_payment_method(account, payment_method: "stripe", last_four: "1234")
visit "/billing"
click_on "Enter Card Payment"
within "#main-content" do
within_frame(find("iframe")) do # Stripe payment form is in an iframe.
find("input#Field-numberInput").set("4000002760003184") # SCA-required test card.
find("input#Field-expiryInput").set("1234")
find("input#Field-cvcInput").set("123")
find("input#Field-postalCodeInput").set("12345")
end
end
find("button#submit").click
# Stripe nests the popup in several layers of iframes.
stripe_frame = find("body > div > iframe") # Popup is prepended to the body element.
switch_to_frame(stripe_frame)
challenge_frame = find("iframe#challengeFrame")
switch_to_frame(challenge_frame)
fullscreen_frame = find("iframe.FullscreenFrame")
switch_to_frame(fullscreen_frame)
click_on "Complete authentication"
switch_to_frame(:top)
expect(page).to have_content "ends in 3184"
end
Is there some way to debug what Selenium is doing under the hood here? I don’t see any movement on the page when running click_on "Complete authentication", but if I click on the button myself in the Firefox instance being controlled by Selenium it does work.
Running click_on "Complete authentication" returns the element clicked, which appears to be the expected element when I drop into Pry and call native.dom_attribute("id").
I can see an error of some kind in the browser container’s logs:
1654078084345 Marionette WARN TimedPromise timed out after 500 ms: stacktrace:
TimedPromise/<#chrome://remote/content/marionette/sync.js:239:19
TimedPromise#chrome://remote/content/marionette/sync.js:224:10
interaction.flushEventLoop#chrome://remote/content/marionette/interaction.js:431:10
webdriverClickElement#chrome://remote/content/marionette/interaction.js:179:31
It’s a bit odd because it mentions #chrome but this is a headless Firefox instance.
Assuming no error is returned by the click_on call then I'm guessing the button is being clicked before it's ready to be clicked. You can test that by sleeping for a few seconds before calling 'click_on'/navigating through the frames. If that fixes it then you'd need to look at what changes on the button to indicate that the page has finished whatever work it's doing and the button is ready to be clicked.
I have solved this by clicking on the button directly with JavaScript:
execute_script(%Q{ document.querySelector("button#test-source-authorize-3ds").click() })
However, this does not in any way explain why click_on is not working, and if anything makes it more strange that it is not. If anyone has a better solution or a way to dig into why Capybara/Selenium are failing then that would be welcome.
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]")
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
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)
I'm automating IE with watir, and I want to know what html element(s) are clicked (selected). Can this be done using watir? win32ole? In a last chance, without ruby?
Something like:
Click a button -> button with id=213 and class=btn_class was clicked.
Click a text field -> text field with id=123 and value=my_text was clicked.
Try one of the recorders, Selenium IDE for example.
I'm not sure if I completely understand either, but would a custom function like this work?
def click(item, how, what)
#browser.item(how, what).click
puts "#{item} with #{how}->#{what} was clicked"
end
click("button", ":id", "awesome")
Edit: If you're attempting to identify page elements so that you can then use them in a Watir script, the Developer Toolbar is perfect for this application, much like Firebug for Firefox.
http://www.microsoft.com/download/en/details.aspx?id=18359
Your comment to me & your response to Zeljko appear to contradict each other. If you want to use WATIR for this task, the code above will execute a mouse click and post the information to console. The only other way to get information is to locate the object in WATIR and fish for more details:
object = #browser.button(:name, /myButton/)
object.id
object.title
object.status
object.height, etc.
or
#browser.divs.each do |div|
puts div.id, div.title
end
I'd recommend a strong look at the capabilities of the various developer tools, such as are provided with Chrome, Firefox, and IE. those are generally the best means to get this kind of information.
Watir is really about driving the browser, and getting info out of the DOM. it's not really setup to report on manual interactions with the browser.