Writing SpecFlow scenario that includes a prompt for a user decision - bdd

I'm new to SpecFlow and BDD and I've hit a roadblock in writing a scenario that requires a user to make a choice. Essentially here is the scenario:
Scenario: Deleting a record
Given I am on the edit record page
And I click the delete button
Then I should see a prompt asking for confirmation
I'm not sure how to proceed beyond this point. There are two paths to test here, one for when the user says "OK" to the confirmation, and one for when the user says "Cancel".
I want to say "And If I click OK" followed by "Then the record should be deleted", etc. But it seems like it should be broken up a better way.
How would you reword this scenario?

I would recommend writing your scenarios on a higher level. Avoid buttons, clicks and textboxes in your scenarios and try to talk about what the user want to accomplish - the behaviour of your system. The actual interaction with the page is then hidden in the step definitions.
So in your case that will be something like;
Given I am on the record page
When I delete a record
Then I should see a confirmation message
In the step definition for [When("I delete a record")] you then implement the clicking on the delete button and the Ok-button for "are you sure" or whatever is needed to delete the record.
I hope this was clear. Wrote it on my phone ;)

There might actually be three scenarios here. The first one focusses as Marcus suggests:
Given I am on the record page
When I delete a record
Then I should see a confirmation message
But are there also scenarios for the behaviour of the confirmation dialog?
Given I am presented with a confirmation message
When I confirm the action
Then the action proceeds
And
Given I am presented with a confirmation message
When I cancel the action
Then the action does not proceed

Related

Intermediate save and readonly after termination

We have the requirement that users, after terminating the input of a form, can only see the data; only authorized users can modify the data.
For this purpose we use the following permissions and it works smoothly:
Now raised a second requirement.
The users wish the possibility to finish the input of the form in a second moment, so that they don't have to fill in the form entirely after pressing the new button, before they can push the save button.
Because some forms are large and maybe they are in a hurry to catch the bus, or maybe for some answer they have to ask someone else not contactable at the moment.
The idea was to add the save-draft button.
The first save-draft is OK; the message is "Draft saved successfully!".
But the second save complains:
It seems that the permissions don't differentiate between save and draft-save, so that also after a draft-save the form data is read-only.
Which possibilities I have to achive this two goals?
Many thanks.
The save-draft process is very much like the regular save (save-final process), except that it lets users save data even if the value of some fields is invalid. So, indeed, from the perspective of the permissions, save-final and save-draft are the same.
What you would really need is the ability for:
A process to save the stage of the form along with the data. In your case, the stage could be "work in progress" or "submitted".
The permissions to be able to depend on that stage, so you can say "users can edit their own data if the stage is work in progress, but can only view it if the stage is submitted".
You can do #1 right now using a hidden field and an xf:setvalue() action. But you can't do #2. For that, you would need the workflow feature to be implemented (see RFE #2256), which we hope to be able to complete in 2018. So, you guessed it, the good news is that this is coming, but the bad news is, at least as I write these lines, that it isn't implemented yet.

Is making a user confirm a UIActionSheet action bad design?

I'm using a UIActionSheet to let the user choose one of multiple actions. One of these actions is "Delete". However, the user might hit delete by mistake.
Should I reconsider having the action "Delete" mixed with other actions in this list, or is there some way I could make the user confirm that the choice was correct? For example a new UIActionSheet with the question "Are you sure you want to delete? Yes/No", or would this be considered as bad design?
I'd consider having the delete action as a separate button, and then having the Action sheet as the confirmation.
If you take the Photos app as an example, the delete action is not in the action menu, but it's own button which then asks for confirmation using an action sheet. This is the same with other apps, like iMovie and Pages.
The user probably won't like having to press through 2 action sheets, but will be even more annoyed if they accidentally press it. You can help with preventing accidents by making the delete option red in the action sheet, if you haven't already.
It also depends on what is being deleted, if you are wiping the phone in the settings menu, then you will be asked twice. But deleting something like text is not going to have confirmation at all.
Depends on what he deletes is critical or not.
If it's critical, you should definitively have the user re-confirm.
Tell me one OS where formatting the Hard Disk for example doesn't ask you to reconfirm... :-)

A "strange" (maybe "extreme" or "crazy") approach to test by using Cucumber

I am using Ruby on Rails 3.2.2, cucumber-rails-1.3.0, rspec-rails-2.8.1, capybara-1.1.2 and factory_girl-2.6.3. I have a Scenario that tests the user sign up like the following:
Scenario: I register an user
When I fill in "Name" with "Foo"
And I fill in "Email" with "foo_bar#email.com"
And I fill in "Password" with "test_password"
And I click button "Register"
Then I should be redirected to the homepage
and I am trying to state a new Feature (within a separated file) where to implement a Scenario that, by using a token, should test the signed up user confirmation process to be properly completed (note: in reality, this process involves an email message delivering but I do not want to test if that email was sent; just ignore it for this question). Since I would like to test exclusively the confirmation process, I thought to implement a new Feature/Scenario where to state something like Given I am a registered user for which to run the Scenario: I register an user.
Scenario: I confirm an user
Given I am a registered user # Here I would like to run the 'Scenario: I register an user'
When I go to the confirmation page
And I enter the confirmation token
Then ...
In few words, I thought to call an entire Scenario within another Scenario.
Even if I can use the FactoryGirl gem to "create"-"register" an user, I prefer to proceed with the above approach because I'd tests ("practically" speaking, those "represent" "invisible people" that, managed by the Selenium gem, open my browser and perform actions) to behave as much as possible like "real people" behave, and so those test steps to implicitly follow all "real" steps that should be made in reality in order to sign up a new user. By following this approach I can test whether or not the application "interiors" are properly working.
Is it a correct approach? If no, how could/should I proceed?
One of the principles of well designed tests is that you exercise a particular feature in all of its various forms, but beyond that presume it to be working within the context of other tests that are exercising other features. That is, once you've tested that users can register, you should not be re-testing the same thing unless you're testing it in a different way.
The phrasing "Given I am a registered user" is something that implies the user has already successfully registered. You shouldn't go testing registration at this point since that's outside the scope of the test you're trying to perform.
Each test should have a mandate and it should stick to it. If you don't limit yourself your tests will spiral into a uselessly inter-dependent mess where changing one thing requires changing every other thing hooked in to it.
The syntax to run a scenario within a step is:
Given /^I authenticate successfully$/ do
Given 'I am on the login page'
And 'I fill in "Email" with "eddie#hotmail.com"'
And 'I fill in "Password" with "secret"'
When 'I press "Login"'
Then 'I should see "Welcome"'
end
Final thoughts: In general, have your Feature file not have any "fill in" --- just have it describe the actions, and have your steps do the dirty work.

Disallow 'Back' in Rails

I am creating a web application that asks user for randomized security question. However, when the user answer the initially given question incorrectly, the user can go back and try a different answer. Is there a way to make sure that the page will do a re-submission when the user clicks the 'Back' button?
Dont fall back to javascript as a last resort, add an attempted boolean field to the question in the database and use that in your controller to ensure users are not just guessing at security questions.
If the user submits the form too many times for one question mark that as attempted and redirect them to another question.
Maybe you should do it with javascript because it's all in the browser...
this could help:
http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

How to create integration level test for two user interaction?

How would you test multi user interaction with Cucumber/webrat?
Meaning that there must be more than one user logged in. Good example would be simple chat application, where I want to send message from one user to another and check if the other user received the message.
I'd like to test at integration level, without any stubbing or mocking.
I'd use Selenium RC with two separate instances controlling separate browsers. I imagine there may be other tools out there for web-based integration tests that are as useful as Selenium or even more, but, personally, I have never met one yet.
I know how this should be done, I just cannot find the right place to do it:
You need to create a second Webrat::Session instance the original webrat_session that you get for free can be one party, while the new one can be the other. I might make two new named sessions just so I could name them.
alice = Webrat::Session.new #I think I have to hook this into merb and I don't know how
bob = Webrat::Session.new
alice.visit url(:chat)
bob.visit url(:chat)
alice.fill_in('chat', 'Hi, bob')
bob.visit url(:chat) #simulate poling
bob.responce.body should_contain "alice: Hi, bob"
HTTP is a pull protocol, this means that users can't be notified when another performs an action. Because of this it is sufficient to simply switch users half way through your scenario. To take your chat example, here's the cucumber scenario that you would use
Scenario: Send a message
When I login in as "user_a"
And I go to the chat page
And I fill in "message" with "blah blah"
And I press "Send"
And I switch_user_to "user_b"
And I go to the chat page
Then I should see "blah blah"
Even if your page is sending polling requests via ajax to get the latest messages it is still sending a request. In that case you could test the ajax call by simply doing a step where user_b calls the url that the ajax request is calling.

Resources