I am using Ruby on Rails with Cucumber and Capybara.
How would I go about testing a simple confirm command ("Are you sure?")?
Also, where could I find further documentation on this issue?
The selenium driver now supports this
From Capybara you would access it like this:
page.driver.browser.switch_to.alert.accept
or
page.driver.browser.switch_to.alert.dismiss
or
page.driver.browser.switch_to.alert.text
Seems like there's no way to do it in Capybara, unfortunately. But if you're running your tests with the Selenium driver (and probably other drivers that support JavaScript), you can hack it. Just before performing the action that would bring up the confirm dialog, override the confirm method to always return true. That way the dialog will never be displayed, and your tests can continue as if the user had pressed the OK button. If you want to simulate the reverse, simply change it to return false.
page.evaluate_script('window.confirm = function() { return true; }')
page.click('Remove')
I've implemented these two web steps in /features/step_definitions/web_steps.rb:
When /^I confirm popup$/ do
page.driver.browser.switch_to.alert.accept
end
When /^I dismiss popup$/ do
page.driver.browser.switch_to.alert.dismiss
end
If you want to specifically test the message being displayed, here's a particularly hacky way to do so. I don't endorse it as beautiful code, but it gets the job done. You'll need to load http://plugins.jquery.com/node/1386/release, or change it to do cookies natively if you don't want jQuery.
Use this sort of story:
Given I am on the menu page for the current booking
And a confirmation box saying "The menu is £3.50 over budget. Click Ok to confirm anyway, or Cancel if you want to make changes." should pop up
And I want to click "Ok"
When I press "Confirm menu"
Then the confirmation box should have been displayed
And these steps
Given /^a confirmation box saying "([^"]*)" should pop up$/ do |message|
#expected_message = message
end
Given /^I want to click "([^"]*)"$/ do |option|
retval = (option == "Ok") ? "true" : "false"
page.evaluate_script("window.confirm = function (msg) {
$.cookie('confirm_message', msg)
return #{retval}
}")
end
Then /^the confirmation box should have been displayed$/ do
page.evaluate_script("$.cookie('confirm_message')").should_not be_nil
page.evaluate_script("$.cookie('confirm_message')").should eq(#expected_message)
page.evaluate_script("$.cookie('confirm_message', null)")
end
Updating this for current releases of Capybara. Most Capybara drivers today support the modal API. To accept a confirm modal you would do
accept_confirm do # dismiss_confirm if not accepting
click_link 'delete' # whatever action triggers the modal to appear
end
This can be used in Cucumber with something like
When /^(?:|I )press "([^"]*)" and confirm "([^"]*)"$/ do |button, msg|
accept_confirm msg do
click_button(button)
end
end
which will click the named button and then accept a confirm box with text matching msg
The capybara-webkit driver supports this as well.
Scenario: Illustrate an example has dialog confirm with text
#
When I confirm the browser dialog with tile "Are you sure?"
#
=====================================================================
my step definition here:
And(/^I confirm the browser dialog with title "([^"]*)"$/) do |title|
if page.driver.class == Capybara::Selenium::Driver
page.driver.browser.switch_to.alert.text.should eq(title)
page.driver.browser.switch_to.alert.accept
elsif page.driver.class == Capybara::Webkit::Driver
sleep 1 # prevent test from failing by waiting for popup
page.driver.browser.confirm_messages.should eq(title)
page.driver.browser.accept_js_confirms
else
raise "Unsupported driver"
end
end
Prickle adds some handy convenience methods for working with popups in selenium and webkit
This gist has steps to test a JS confirm dialog in Rails 2 and 3 with any Capybara driver.
It's an adaptation of a previous answer, but doesn't need the jQuery Cookie plugin.
Tried the above answers with no luck. In the end this worked for me:
#browser.alert.ok
Related
For some reason, when I use the following code in package I'm trying to contribute to, an integral sign (∫) appears in the active document when a button is selected on the dialog.
checkAutoSave: ()->
if atom.workspace.getActiveTextEditor().isModified()
if atom.config.get('build.saveOnBuild') is true
atom.workspace.getActiveTextEditor().save()
return 1
else if atom.config.get('build.promptToSaveOnBuild') is true
diaDirection = atom.confirm
message: 'Do you want to save the current file before building?'
detailedMessage: 'This message can be turned off in the Build settings.'
buttons: ['Yes', 'No', 'Cancel Build']
switch diaDirection
when 0
atom.workspace.getActiveTextEditor().save()
return 1
when 1
return 0
when 2
return -1
else #Current File wasn't changed.
return 0
I have tried narrowing it down and I am 100% it has something to do with the dialog. The problem does not exists without the dialog call. The Integral sign appears in the document regardless of the button pressed.
I've had a similar problem a while ago - see here for more details.
The action I wanted to trigger in the editor was bound to Ctrl+Alt+B, which by default inserts the integral sign on Mac OS X. The integral sign was inserted into the currently open document when I opened a standard alert box from my package's code.
I didn't found out why, but it looks similar to your problem. In the end, I resolved it by removing the alert and using an Atom view instead for showing the message. As soon as I did this, the integral sign was no longer inserted into the document.
It looks like there's an issue with the key binding and preventing event propagation when using some dialogs. In some cases, the key event is handed to the OS and it inserts the character associated with the pressed key.
Maybe you can try using an Atom view instead of the confirm dialog, and it will resolve your issue as well.
I have a requirement that is :--
On click of ‘Logout’ link, popup message “This will terminate the session and close the browser. Do you want to continue?” with Yes and No buttons. On click of ‘Yes’, session should be terminated in IIS server and current tab of browser closed.
To implement this I have writen below piece of code but I dont know how to terminate the session on IIS
<script language="vbscript">
Function OnClickLogout()
dim Answer, msg
Msg = "This will terminate the session and close the browser. Do you want to continue?"
Answer = MsgBox(Msg, vbYesNo + vbCritical, "Error")
if Answer = vbYes then
window.close
else
'Retrun to the previous page
end if
End Function
</script>
Could anyone please suggest me how to do this in vbscript. My website is in ASP but its a legacy application so I have to do the code!!!
Couldn't you simply use JavaScript? We us it all the time at work in our ASP Classic projects. Something like that to start off:
function DeleteProductGroup(){
var r=confirm("Are you sure you want to delete this product group?");
if (r==true){//here goes the code if user presses YES
}
else{//here goes the code if user presses NO
}
}
Take a standard web page with lots of text fields, drop downs etc.
What is the most efficient way in webdriver to fill out the values and then verify if the values have been entered correctly.
You only have to test that the values are entered correctly if you have some javascript validation or other magic happening at your input fields. You don't want to test that webdriver/selenium works correctly.
There are various ways, depending if you want to use webdriver or selenium. Here is a potpourri of the stuff I'm using.
Assert.assertEquals("input field must be empty", "", selenium.getValue("name=model.query"));
driver.findElement(By.name("model.query")).sendKeys("Testinput");
//here you have to wait for javascript to finish. E.g wait for a css Class or id to appear
Assert.assertEquals("Testinput", selenium.getValue("name=model.query"));
With webdriver only:
WebElement inputElement = driver.findElement(By.id("input_field_1"));
inputElement.clear();
inputElement.sendKeys("12");
//here you have to wait for javascript to finish. E.g wait for a css Class or id to appear
Assert.assertEquals("12", inputElement.getAttribute("value"));
Hopefully, the results of filling out your form are visible to the user in some manner. So you could think along these BDD-esque lines:
When I create a new movie
Then I should see my movie page
That is, your "new movie" steps would do the field entry & submit. And your "Then" would assert that the movie shows up with your entered data.
element = driver.find_element(:id, "movie_title")
element.send_keys 'The Good, the Bad, the Ugly'
# etc.
driver.find_element(:id, "submit").click
I'm just dabbling in this now, but this is what I came up with so far. It certainly seems more verbose than something like Capybara:
fill_in 'movie_title', :with => 'The Good, the Bad, the Ugly'
Hope this helps.
I have a simple page that returns an ajax success/error message on submission. The form is submitted using a standard ASP.Net linkbutton.
My Selenium test correctly clicks the linkbutton, however the click event times out and fails. The rest of the testcase conditions pass (as selenium is successfully clicking the link and the ajax success message is displayed).
All I can think is that for some reason click() is calling waitForPageToLoad which is why it is timing out. Is there any way to suppress this, or am I barking up the wrong tree?
Is there an alternative way to handle the click that doesn't care what happens after the event fires?
More Info: Selenium IDE 1.0.2 hosted in Firefox 3.5.2 on Vista (don't ask)
Workaround
I've managed to get my test to pass by creating my own click() function in user-extensions.js that does not call Selenium.decorateFunctionWithTimeout(). While my test does pass now, this is not really an ideal solution.
If you'd like to try this yourself, add the following to user-extensions.js (make sure you are referencing this file in your Se:IDE configuration via Tools | Selenium IDE | Options | Options | General | Selenium Core extensions)
Selenium.prototype.doBeatnicClick = function(locator) {
/**
* Clicks on a link, button, checkbox or radio button.
* Hacky workaround for timeout problem with linkbutton.
* Suspect there is an issue with Selenium.decorateFunctionWithTimeout()
*/
var element = this.browserbot.findElement(locator);
var elementWithHref = getAncestorOrSelfWithJavascriptHref(element);
if (browserVersion.isChrome && elementWithHref != null) {
var win = elementWithHref.ownerDocument.defaultView;
var originalLocation = win.location.href;
var originalHref = elementWithHref.href;
elementWithHref.href = 'javascript:try { '
+ originalHref.replace(/^\s*javascript:/i, "")
+ ' } finally { window._executingJavascriptHref = undefined; }';
win._executingJavascriptHref = true;
this.browserbot.clickElement(element);
}
this.browserbot.clickElement(element);
};
Reload Se:IDE and you'll have access to a new command, beatnicClick() which should work where you're experiencing a click() timeout.
Hopefully this will be patched, or fixed in the next release of Se:IDE.
I believe this is raised in the OpenQA Jira: http://jira.openqa.org/browse/SIDE-316. It has also been discussed here: http://clearspace.openqa.org/message/64455
Until the issue has been resolved you can revert to the 1.0b2 version of Selenium IDE http://release.seleniumhq.org/selenium-ide/1.0-beta-2/ but this wont install on Firefox 3.5.x unless you disable extensions.checkCompatability in about:config. See http://kb.mozillazine.org/Extensions.checkCompatibility
I was hitting what I assume is this bug when testing a GWT site with Selenium IDE 1.0.2. I just updated to 1.0.4 and don't have it any more.
I'm still fairly new to ASP.Net, so forgive me if this is a stupid question.
On page load I'm displaying a progress meter after which I do a post back in order to handle the actual loading of the page. During the post back, based on certain criteria I'm disabling certain links on the page. However, the links won't disable. I noticed that if I force the links to disable the first time in (through debug) that the links disable just fine. However, I don't have the data I need at that time in order to make the decision to disable.
Code Behind
If (Not IsCallback) Then
pnlLoading.Visible = True
pnlQuote1.Visible = False
Else
pnlLoading.Visible = False
pnlQuote1.Visible = True
<Load data from DB and web service>
<Build page>
If (<Some Criteria>) Then
somelink.Disable = True
End If
End If
JavaScript
if (document.getElementById('pnlQuote1') === null) {
ob_post.post(null, 'PerformRating', ratingResult);
}
ob_post.post is an obout js function that does a normal postback and then follows up with a call to the server method named by the second param. then followed by the call to a JavaScript method named by the third param. The first parameter is the page to post back to. A value of null posts back to the current page.
The post back is working fine. All methods are called in the correct order. The code that gives me trouble is under the code behind in bold. (somelink.disabled = True does not actually disable the link) Again, if I debug and force the disabling of the link to happen the first time in, it disables. Does anyone know what I might do to get around this?
Thanks,
GRB
Your code example is using the IsCallBack check, while the question text talks about the IsPostback Check. I'd verify that you're using Page.IsPostBack in your code to turn off the links.