Data inserted in Cucumber tests not populating Dropdown - ruby-on-rails

DISCLAIMER: I am still a Rails/Cucumber newbie but I am trying to learn. I am still using the "web_steps" for Cucumber while I work through the RailsInAction book and I have experimented with writing my own steps. I understand why they were taken out and I will get there.
Problem:
In one of my Cucumber Scenarios I am populating some data and trying to use that data to populate a dropdown. The data is definitely being inserted, I know this because I wrote a step to test to see if the data is in fact there and it is.
When then DropDown is suppose to populated and I try "select" from that DropDown I get the error "*cannot select option, no option with text 'Steven' in select box 'result_winner' (Capybara::ElementNotFound)*"
I am sure I am missing something basic but I have lost about an hour to this now and I just need some help.
My Code:
The tests:
When I follow "Record new Result"
And the users "Steven, Joshua" exist
And I select "Steven" from "result_winner"
The test steps:
When /^the users "([^"]*)" exist$/ do |playerNames|
#names = playerNames.scan(/[\w']+/)
for name in #names
#newPlayer = Player.new
#newPlayer.name = name
#newPlayer.save
end
end
Then the view code in the _form.html.erb:
<p>
<%= f.label :winner %>
<%= select("result", "winner", #players.map {|p| [p.name, p.id]}) %>
</p>
The Controller:
def new
#result = Result.new
#players = Player.find(:all)
end
If I manually populate the development database with names and load it up in the browser, the dropdowns have data populated in them and work perfectly. I am pretty sure I am misunderstanding when/where test data is visible, or how to test for and select data from a dropdown.
Any help would be greatly appreciated.

It looks to me like a simple problem with the step sequence. You're visiting the page, and then populating the database, but the page doesn't get reloaded to take account of the new database values. If you swap the order of the first 2 steps around, I expect that would fix it.
To be clear, cucumber will literally step through your scenario one line at a time:
Load up the webpage (which doesn't contain your test data)
Insert your data into the DB
Look for that data in the dropdown (which won't be there as the page was loaded before the data was in the DB)

Your "the users "Steven, Joshua" exist" should be in a Given step.
It describes a state before an action is done.
Given the users "Steven, Joshua" exist
When I follow "Record new Result"
And I select "Steven" from "result_winner"

Related

Creating Rails todo list app with goals and tasks on one page - missing params

I'm a Rails beginner, and have been reading tutorials and typing out applications for a few months now. I'm really enjoying it after a few years spent in the front end world, and beginning to get up to speed with it all. The time has come though for me to start building my own stuff without any handholding. So far, so good.
I'm creating a basic to-do list app, where goals and tasks are displayed on the same page - goals#index. My issue is that I'm not sure how to get all tasks for a particular goal (that belongs to a user). I understand that I need to pass an ID param to the Goal model in order to find out its tasks, like so:
Goal.find(1).tasks
The above works fine, as I've already set up foreign keys on the tasks table and have a has_many :tasks relationship for the Goal model and a belongs_to relationship for the Task model.
Here's my Goals controller:
def index
#user = current_user
#goals = #user.goals # list all goals for the current user and assign it to the #goals variable.
# Need to find all tasks for each goal ID and assign it to the #tasks variable. Goal ID needs to be supplied here, but it isn't as we're not in show action.
#tasks = Goal.find(1).tasks
As I said, I can find all tasks for a Goal when I manually enter the ID (1 in this example). This works fine in my app, no errors. But obviously I want to supply these IDs dynamically, and I'm just not sure how I get the params in there.
I have tried the below:
#tasks = Goal.find(params[:id]).tasks
and
#tasks = Goal.find(params[:goal_id]).tasks
And I get the "Couldn't find Goal without an ID" error when I try to iterate over #tasks in my view. Which makes sense, as I don't think the goal params are being passed to it as we're not in the Show action.
Surely there must be an easy Rails way?! I'm stumped and don't really know where to look. Thanks for your help and Happy New Year.
You are getting current user's goals, so when you will do this you have one array object. so when you will pass array object to find, it will have multiple IDS. so when need to find All the tasks from all goals you just need to pass Array of IDS instead of single value.
#tasks = Task.where(:goal_id => #goals)
This will run this SQL query.
SELECT "tasks".* FROM "tasks" WHERE "tasks"."goal_id" IN (SELECT
"goals"."id" FROM "goals")
So when you are dealing with array just pass ids. for e.g. [1,2,3]
Once you do #goals = #user.goals (assuming that's working, which it sounds like it is), you have your goals and there is no reason to go back to the DB to "find" them.
To get ALL your tasks from ALL of user's goals, you can do the following:
#tasks = []
#goals.each do |goal|
#tasks << goal.tasks
end
Ah of course, #goals is an array of the user's goals so I can just work with that. So simple when someone just tells you. Thanks for all your help!
Here's my final code that works (I left the controller unchanged). This gets the first goal in the array and then gets the tasks associated with each goal. I have a set number of goals so I can just use goals[0], goals[1] or goals[2] for each goal.
<% #goals[0].tasks.each do |task| %>
<li><div class="task-item"><%= task.task_name %></div></li>
<% end %>

Capybara won't select item from select

I'm using Capybara to test a little Web app I'm writing. It refuses to select the right item from a select. Here's the code:
before do
fill_in 'Assignment', with: "blah blah blah"
select student.name, from: "assignment[student_id]"
end
I've tried every supported format in the "from" field. I've used the id, the name, and the label text to try and select the correct element. I've even booted the rails server in test, and manually ran through the steps in my test in the console. No matter what I do, capybara kicks back:
cannot select option, no option with text 'John Doe' in select box 'assignment[student_id]'
As stated before, I have kicked up the rails server in the test environment, and then manually added users to the database the same way I have done in my tests. I am 100% confident of the fact that there is indeed an option with text 'John Doe' in select box 'assignment[student].' This leads me to believe that I must be using the select method incorrectly. Can someone enlighten me?
Does the select from: need the select fields name or the ID?
Try it with the ID instead (assuming standard form style):
select student.name, from: "assignment_student_id"
If you inspect source on the select element you can confirm the fields ID.
Does it use the value of the option element rather than the text? Again, inspect and see what the value of "John Doe" is and see if it works by using student.id.
select student.id, from: "assignment[student_id]"
Lastly, have you tried the syntax in the documentation that includes the page?
page.select student.name, :from => 'assignment[student_id]'
The problem wasn't with the select code. I forgot how FactoryGirl's let works. I called build through a relationship on a User created by Factory Girl, and then tried assigning that result to student via let. Unfortunately, since let is lazy, it wasn't being created when it needed to be, so basically the page was getting called up before the student object was even created. I moved the code in my let statement into a before, and then assigned student using let and User.students.first.

Creating Table Filters

I have a simple table with 3 columns like so
table
thead
th Element
th Owner
th Progress
tbody
== render :partial => "element_row" :collection => #elements :as => table_element
Each element is unique, and one owner may have several elements. There are a few different types of "progress" e.g. "started", "not started", and "completed".
I want to create a few links that filter the table. For example, I want to create an started link where when the user clicks on the link, the table is filtered down to only show rows where "started" is displayed. Another example of a filter is by owner.
Does anyone have any suggestions for how to do this?
If you're looking for a gem to help you, Ransack is a great, popular, and active project for searching (and by extension, filtering) ActiveRecord data.
If you check out Ernie's demo site you can see how the search parameters modify the URL through GET queries. You could easily create links like your desired started link to mock these GET form requests.
If you want to do this on the server side, add a filter method to the controller that uses link parameters to filter the #elements.
If you selecting #elements from the database using ActiveRecord, you could do:
#elements = Element.where(progress: params[:progress])
If you just want to filter the #elements in memory, you could do:
#elements = #elements.select{ |element| element.progress == params[:progress] }

Pass values of checkboxes into an array?

Im trying to update someone else's Rails app. Right now, an HTML table displays values from a database. What i want is to be able to display a checkbox for each row and on submit, the values of the checkboxes are sent into an array (and the values shouldnt be "checked" or "unchecked", they should be the id's of the database row).
Heres what i have so far.
Checkbox : (message.id being a dynamic id)
<%= check_box_tag "message_ids[]", message.id %>
And on the controller:
#dispatches = Dispatch.find_by_message_ids(CODE TO RETRIEVE CHECKBOX ARRAY GOES HERE)
Any suggestions?
Have you tried inspecting the value of params?
Chances are this will work:
#dispatches = Dispatch.find_by_message_ids(params[:message_ids])
But if it doesn't, just look at what is being sent to your page. Try one of these:
logger.info(params)
or
raise (params.inspect)
or
render :inline => params.to_yaml
Check what you receive in your params because they're probably there if this is defined correctly. The current parameters are always logged in log/development.log which is something you should have open any time you're debugging something.

Record id with cucumber and pickle [Rails]

I am using Cucumber, Webrat, and Pickle in conjunction.
When I write a scenario, I can do something like this:
Given a product exists with title: "Bread"
When I go to the edit page for that product
And I fill in "Title" with "Milk"
And I press "Save changes"
Then I should see "Successfully edited product."
And I should be on that car's page
Notice the for that product. This is something pickle provides which is very convenient for referencing the record for a product I'm checking the existence of. That last line, though, is not working.
Basically I am trying to make sure I am the show page for that record, but since I do not have an ID for it, I don't know how to reference it.
Any help?
Thanks!
To have a reference to the created product or anything else you can use naming that's provided by pickle:
Given product: "bread" exists with title: "Bread"
...
Then I should be on the showing page for the product "bread"
To handle this url you will need to add couple lines into /features/support/paths.rb:
when %r{^the showing page for the (.+)$}
polymorphic_path(model($1))
Also it could be useful to handle edit path for the model like this:
Then I should be on the edit page for the product "bread"
paths.rb:
when %r{^the edit page for the (.+)$}
polymorphic_path(model($1), :action => 'edit')

Resources