SitePrism - Dynamically Define Element Based on Current Edit ID - site-prism

Please note I'm new to SitePrism. I'm putting together a Capybara feature test case for editing data. The form's ID is "edit_bears_1", where you can imagine the #1 changes based on the current object's ID.
<form class="form-horizontal validate-form" id="edit_bears_1" action="admin/bears/1" accept-charset="UTF-8" method="post" novalidate="novalidate">
Here is the SitePrism file I created to define the form:
module Pages
module Admin
module Bears
class Edit < SitePrism::Page
set_url '/admin/bears/edit/:id'
set_url_matcher %r{/admin/bears/\d+/edit}
binding.pry
section :form, Form, "form#edit_bears_1"
end
end
end
end
As you can see I currently have the form's ID hard-coded to #1, but this is likely to change. How can I replace #1 with the some sort of variable that gets evaluated to and is linked to the bear I'm editing? All help is appreciated!

You could script in something that would re-create it. Or if you feel as if this is something we should be supporting out of the box you could create an issue and request a new feature for it.
GH Link: https://github.com/natritmeyer/site_prism/issues
Script example 5.times { |i| section "form#{i}", Form, "form#edit_bears_#{i}" }
Make sure to give each of the references an index-linked name otherwise they'll self-overwrite.

Related

Rails Active Admin unpermitted parameter

I have some problem/issues with active admin on rails, specifically unpermitted params error:
existing active admin parameter
here is the existing active admin parameter
model associated with the main model im working with
As per active admin documentation I should be doin right, as the other attributes for dispatch_information model is being accepted by rails and I was able to read and write with out any issues. Just with this recently added attribute "custom_attorney". Associations already set. and with out declaring an attr_accessor on model file it says this error
No method error
as it seems it cannot read or detect the column that I added for dispatch_information model, while in my console its already there.
When I add it with attr_accessor "while it should not, just to proceed on the form page" then I fill in the attributes need, im getting weird stuff in my console
Console view
as you can see it seems it being added inside efile_order hash instead of dispatch_information_attribute hash, and at the bottom part of the image you can see it says unpermitted parameters, even I added it inside the correct attribute block, we can also notice that the other attributes pf dispatch_information works really fine, just this recently added custom_attorney attribute. I already did everything like migration and other stuff.
Form Input
here is my form where we can see that input is on the same block where dispatch_defendant and dispatch_plaintiff is included and those two attribute works fine as well.
I really dont know what I missed here. TIA
The problem is that custom_attorney should be nested under dispatch_information_attributes you have it in the wrong place so it's unpermitted.
The correct way to do that is to add a block for those attributes and nest them.
- f.simple_fields_for :dispatch_information do |d|
- d.input :custom_attorney, :input_html => { id: 'new-attorney' }
It may be a good idea to provide an object for dispatch_information if you care for existing data. Assuming your ivar is named #e_filling_order then you should have the following.
- f.simple_fields_for :dispatch_information, #e_filling_order.dispatch_information || #e_filling_order.build_dispatch_information do |d|

ActiveAdmin auto create single nested item

I have User, and every user must have one Contact item (but not all contacts need to have a user). A user can create contacts via nested forms, but I'm not happy with that.
How do I set it so that when I go to new User, it automatically creates the first one and won't allow me to add more contact items?
After doing some searching I found the answer, and it comes in two steps.
First, to ensure that the first nested item is created first, you need to first override the new method of the controller and initialise all the sub items you want first, this will cause the page to render with the nested items created.
Using my question as the example, you would do it like this:
controller do
def new
#user = User.new
#user.contact = Contact.new
new!
end
end
The second is to add the following to your active_admin css file:
#new_user .has_many_remove {
display: none;
}
with #new_user being the name of my form, substitute this with the name of your form.
I found the answer here on a github issue for ActiveAdmin.

Following Test Automation best practise of "Methods return other PageObjects" in Ruby

I am a big advocate of the Page Object Pattern (POP) as defined by the experts at Selenium:
https://code.google.com/p/selenium/wiki/PageObjects
A key view of theirs that I have always followed when using Appium with Java is:
"Methods return other PageObjects"
e.g. LoginPage loginPage = homePage.gotoLoginPage();
I am now trying to following POP using Calabash with Ruby and so have been writing code like this:
e.g. #login_page = #home_page.goto_login_page
However, since Ruby doesn't know what type of object #login_page is or #home_page is, you dont get any of the benefits of intellisense showing what methods are available for a given page.
Anyone know a good way around this?
As much as I appreciate and apply PO design pattern, as much I disagree with returning page object by page object. Page object should be independent and don't need to know about other page objects. Look at two examples:
You test form validation. Click on submit button returns page object which is subsequent in the workflow, but in this case you remain on page with validation errors. Your page object won't know about it and will return the other page.
Page which you get to after clicking a button may differ depending on the context (e.g. from what other page you got to current page). It can lead to having multiple versions of actually same method, which will return different page objects depending on context. This is not good and overcomplicates simple thing.
If you want to return current page object, you can benefit from it e.g. in Java, when you return this at the end of the method. Then you can chain all methods you execute as long as you are on the same page. But when it comes to the question 'how to implement returning different page objects' - answer is simple - 'just don't'. Please note wiki entry you quoted has not been updated for a good while and best practices has evolved since it was originally published.
It seems like you already have your solution. However for others and perhaps also for you the x-platform approach to calabash uses page objects so you could check out that implementation https://github.com/calabash/x-platform-example
An alternative method would be as follows. Not as neat as I would like (given the need to manually create new instances of subsequent pages), but available as an alternative option:
When(/^I buy a movie from the movie page$/) do
movie_page = MoviePage.new
movie_page.buyMovie("Test Movie")
purchase_page = PurchasePage.new
purchase_page.confirmPurchase
end
Found a way of getting this to work after much research and applying well known Java/C#/Obj-c principles to Ruby:
Given(/^I am on the launch page$/) do
#launch_page ||= LaunchPage.new
end
When(/^I open the set alarm time page$/) do
#set_alarm_page = #launch_page.goto_set_alarm_page
end
When(/^I open our apps from the home page$/) do
#launch_page.navigation_toolbar.open_our_apps
end
Then(/^I should see the homepage alarm time is (\d+)$/) do |alarm_time|
alarm_time_actual = #launch_page.get_alarm_time
assert_equal(alarm_time, alarm_time_actual)
end
As long as somewhere on the step definition class you explicitly create a new page object (in the above example: LaunchPage.new), then all subsequent pages will provide intellisense method/property values, since the resulting page types returned will be known by RubyMine.

How do I implement Post-redirect-get on Google App Engine with Python?

I am developing an online bidding system on Google App Engine with Python. Regarding the post-redirect-get mechanism, I've been googling a while and still have no clear idea of how to implement it. Suppose:
HTML:
<form action="/test" method="post">
...
<input type="submit" value="Submit" />
</form>
Python:
# Collect data from the posted form
...
# Save data into datastore
...
# Prepare template values
tempalteValues = { ... }
path = os.path.join(os.path.dirname(__file__), 'templates/', 'responseMessage.html')
handler.response.out.write(template.render(path, templateValues))
# Then what?
I have two questions:
1) After rendering the response message file, what should I do next? That is, how to implement the 'GET'?
2) Another strategy I can think of is: If the post is supposed to happen only once (e.g., product purchasing with a unique order number), can I set a flag in the entity indicating that the form has been submitted and the following posts will be ignored if the flag is set? Is this feasible or even correct?
(Note: because the order number is generated by the system, the entity has to be saved before the form submission in order to get that number)
Thanks in advance.
What you are looking for is building a Restful service something like this:
class BiddingHandler(webapp2.RequestHandler):
def get(self):
#Get code goes here for this handler
def post(self):
#code that gets your posted data and processes it
def delete(self):
#code to delete something
app = webapp2.WSGIApplication([('/bidding', BiddingHandler)])
Looking at the above if you wanted to do a redirect after making a post in the last line of your post instead of rendering a template you would simply redirect the user to the get part of the handler with the following line:
self.response.redirect('/bidding')
What I have shown you above is the correct way to implement it. Writing to the datastore and reading from it for every request would mean more overhead and costs.

How do I fill in a specific field in Webrat when several share the same name and id?

I'm just getting started with Cucumber and Webrat, and am adding feature specifications to an existing Rails application. One page in the app has multiple forms on it, representing different ways to build a new Character object. Here's a simplified example:
<form id="adopt_character_form">
....
<input type="text" name="character[name]" id="character_name">
...
</form>
<form id="spawn_character_form">
....
<input type="text" name="character[name]" id="character_name">
...
</form>
As you can see, there are (at least) two fields that have the same name and id on the page, though they are in different forms, and I can't find a way in the Webrat rdoc or source code to specify a particular one.
I know that I could change the name or id on one of them, but I would have to deviate from the Rails naming conventions to do so, which I'd really rather not. I could also put the forms on different pages, but it would take more modification to the work flow than I want to do. I could also try to merge them in to a single form that was more modular and dynamic, but having to make structural changes to the UI just to support a given testing framework seems a little questionable and might not always be feasible, plus I would have to require javascript.
Is there any way to specify one of these fields in Webrat, or should I just give up and try Cucumber on a different project?
You can use webrats within method
For example in a cucumber steps file
#my_steps
Then /^I update character name with "([^\"]*)"$/ do |updated_character|
within '#adopt_character_form'
fill_in "character[name]", :with => updated_character
end
end
Hope that helps
Considering having multiple elements with the same ID is an explicit violation of HTML validity, I think you've already deviated from the path of Rails conventions. Recent versions of Rails generally make an effort to keep things standards-conformant. IIRC it's pretty straightforward to call the form helpers in such a way that the IDs are differentiated. If nothing else you can just supply an explicit ID with each call. For the purpose of Rails conventions the name field is the only one that matters, since that's the one Rails will have to map back to a field name on a model.

Resources