0

I was using a cucumber/ruby/capybara/siteprism framework and implementing the test pages at present. I've reached a point where there are a lot of radio buttons (over 20) per page in several pages, and I was thinking if there's really any benefit in trying to map all those as static elements in my page object model?

Ie, thinking about it, it seems much more convenient to just use the text of the radio button in the step definition and call the capybara 'choose' method directly, something like the following, so that I don't need to do anything else for those 20+ radio buttons, it should all just work by changing the parameter we're passing in the feature:

cucumber feature:
  When I select that "I am over 18"

capybara step:
  When /^I select that "(.*)"$/ |option|
      choose(option)

Whereas with a page object model like siteprism, I guess the implementation would need to define and maintain all those elements independently in a format similar to:

element :over_18_button, :radio_button, "I am over 18"
element :over_12_button, :radio_button, "I am over 12"
etc x50times

And for using it, one should create the page, call the element, which doesn't seem as straight forward to me?

siteprism step:
  When /^I select that "(.*)"$/ |option|
     case option
        when 'I am over 18'
           over_18_button.click
        when 'I am over 12'
           over_12_button.click

I guess one could create 'elements' or a 'section' with an array to all the buttons, but then, we'll have to put extra logic to parse them and click on the relevant one anyway somewhere in the code, whilst it would be all done neatly and without the need for any extra code or maintenance with the 'choose' method from capybara.

Am I right to assume that in this example using Capybara is a better option? or if it'd be better to define 'ALL' web elements in the page object model, what would the benefit of that be? and could the page object code be done in a different way to take advantage of any possible benefit?

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
mickael
  • 2,033
  • 7
  • 25
  • 38

2 Answers2

0

That complicated case statement is unnecessary.

  When /^I select that I am over "(\d\d)"$/ |age|
   @page_object.select_age(age)

I'm not familiar with site_prism. My watir_drops gem would let you define everything with the same pattern like this:

element(:age_button) { |age| browser.radio_button(text: "I am over #{age}")

with this method in the page object:

def select_age(age)
  age_button(age).set
end

We could also get into a whole long discussion on using declarative instead of imperative steps. Also, best practice Page Object usage avoids directly calling defined elements. Call methods that accomplish the business logic and those methods do all the implementation including element definitions and actions on them.

titusfortner
  • 4,099
  • 2
  • 15
  • 29
  • I see what you mean, have a function which gets the parameter and pass it when defining the page object element... but in that case, what is the advantage of using '@page_object.select_age(age)' with the new implementation (plus the need to create the new function and define the element) rather than just using the capybara or watir way directly - like 'choose(age)' and avoid all the other bits? I can't see why it'd be a good idea, but I might be missing an important point in the page object model? – mickael Dec 03 '16 at 01:36
  • The Page Object pattern addresses several problems. 1) Abstract the implementation logic from the business logic (what vs how) 2) keep the code DRY (everything can be updated in one place) and 3) Intelligent organization for easier maintenance (when a page changes, you update the one associated page object). I can't speak to Capybara best practices, but Watir is more of a library (to Capybara's framework), which lends itself well to this kind of abstraction. – titusfortner Dec 03 '16 at 02:14
0

Old question but adding important missing info

The way in which site_prism works allows you to define your selector using anything that can be queried in Capybara. So if you want to define your radio using the text, you can do that. Or any other locating strategy you want to use.

Obviously traditionally I would advise using css locators ( element :my_radio, text: 'foo'), because they're easiest to debug and re-use. Furthermore the OP advised he had 50+ of these. If they were identical, they could be abstracted out into a Helper Module or he could even meta-program them in using a loop and index (If they followed a simple index_naming_pattern)

Luke Hill
  • 460
  • 2
  • 10