I'm using SitePrism to test my web application. I have a number of classes that extend SitePrism::Page
and a number of often-used HTML snippets are represented by matching classes extending SitePrism::Section
class Login < SitePrism::Section
element :username, "#username"
element :password, "#password"
element :sign_in, "button"
end
class Home < SitePrism::Page
section :login, Login, "div.login"
end
The problem is, the application I'm working on is based on a CMS, in which a page can be assembled by selecting a Template based on pre-defined content and then drag-and-dropping any number of available components onto the page.
The initial developers created a Page Object to mirror every available Template. This was fine as long as the number of tests was low and there weren't too many variants of pages that we had to test in our feature files.
With the addition of multiple test cases, the page objects started growing at an alarming rate.
While we can easily mitigate code duplication by defining Sections for every component available in the CMS and reusing them across Page Objects, there's just a lot of properties that rarely get used.
class BlogPost < SitePrism::Page
section :logo, MySite::Components::Logo, '.logo'
section :navigation, MySite::Components::Navigation, '.primary-navigation'
section :header, MySite::Components::BlogHeader, '.header'
section :introduction, MySite::Components::Text, '.text .intro'
# and so on, a lot of dynamic staff that could potentially be dropped onto the page
# but does not neccessarily be there, going in dozens of lines
end
Is there a way in SitePrism to dynamically add a section to an instance of a Page Object as opposed to a whole class?
Then(/^Some step$/) do
@blog = PageObjects::BlogPost.new()
@blog.load("some url")
@blog.somehow_add_a_section_here_dynamically
expect (@blog.some_added_section).to be_visible
end
It also worries me that doing something like this would potentially cause CSS selectors to leak into the step definitions, which is generally a bad practice.
Another way to work around this would be to build Page Objects for specific examples of pages as opposed to the versatile templates. The Template Page Objects could just contain whatever's baked into the templates and be extended by other Page Objects that mirror specific pages, taking care of the differences. It sounds like a much cleaner approach so I'm probably going to write my tests this way
Anyway, the technical part of the question stands. Regardless of how good or bad an idea it is, how could I dynamically extend a page object with an additional section? I'm just curious.