Reputation: 1375
Each of our page objects has around 80-100 PageObject elements defined. This is a byproduct of a very data centric application and I don't see that changing any time soon. We have many text fields, select lists, buttons, and menus. I want to clean up these somehow and put them somewhere, but the things I've thought about don't seem very clean.
Ideas:
The first solution has the problem that each module can be included in other classes if somebody doesn't pay attention. It's not restricted to the single class
The second solution seems slow and not very "rubular", along with being confusing to update elements for those new to the project
The third solution seems like the best, but like the first solution, you could potentially include Sections into a class that they don't belong in.
What other way can I move the definition of these elements out of the class so that our class is cleaner, shorter, easier to read, and defined to Ruby Specifications (i.e. the Ruby Style Guide). They really just seem like config data rather than ruby code, so I feel like they don't belong in the class. Especially when we have 80+ elements in each class.
Upvotes: 1
Views: 108
Reputation: 1490
I don't see why you wouldn't keep the elements in the page object class. That's kind of the point of the class, right? If they're shared across multiple pages, then I understand putting them in a module and mixing in. But why abstract the unique elements on that page away from the page class?
But if you're absolutely going to do this, I'd think this is the best option:
Move elements for each PageObject into a corresponding module and include that module into a single PageObject only
There are ways you could ensure these modules are included only in the classes you expect. I have Module#included in mind. Something like:
module MyPageElements
def self.included cls
raise "Expected to be included on MyPage, got: #{cls}" unless cls == MyPage
end
# ... elements ...
end
create a YAML config file, with the mapping of element_type => element_name => element_id and then call the corresponding element methods using metaprogramming
Seems like this would be a headache to bring new, unfamiliar people up to speed on the code. Ultimately, I agree that it's just too un-Ruby like.
Utilize the upcoming PageObject sections feature to create different "panels" within each page and then include those Panels into the page.
Since I've just barely looked at this (thanks for linking me to the PR), I don't feel like I can speak to its efficacy.
Upvotes: 1