Apologies if this is an improper question, as it's actually a multi-part question (But it seems like unnecessary clogging of the site to make multiple posts).
Im writing my first PoM framework, it's using Ruby and Capybara (With Selenium for the webdriver). Currently I have it setup as such (Folder wise, - represents depth):
spec
-support
--Modules
--PageObjects
(actual test .rb files)
However im running into a few "Design/Architecture" questions that I can't seem to find a solid opinion on:
The first one is best way to set up "Selectors". Currently each Page Object is a class (All inheriting from one Base Page Object class). Right now my selectors all essentially ruby methods (Private methods to be specific). I wonder if this is overkill...and it makes more sense to just make variables at the top similar to how (http://elementalselenium.com/tips/7-use-a-page-object) does it? Do I gain anything making them private methods at all?
Speaking of the base page object, currently it only contains methods (Selectors) and other public methods for dealing with common objects (Header/Footer) or items that appear on every page. But ALSO common "helper" functions (Such as selectors/special functions for dealing with quirky react selects and so forth). Does it make sense to keep those here? I feel like maybe helper functions should maybe go in a "Helper" module or something (Currently Modules is empty, since im not sure what to put there)
This maybe be specific to Capybara, as im not working with Selenium directly. But im handling sessions within each page object creation. I notice in most PoM examples with Selenium an instance of "driver" is created with initialization (Can be seen here: https://github.com/SeleniumHQ/selenium/wiki/PageObjects) specifically as:
public LoginPage(WebDriver driver) { this.driver = driver;
From my understanding, this allows us to chain together methods correct? Capybara seems to work slightly different and we don't create drivers the same way but can do the same thing with sessions.
Currently I am initializing a @session
variable and calling all the methods with that variable (and then returning self
or a new page object depending on navigation). This works, however my question is I actually have this initialize method in my BASE page object, and then call super
in the child page objects....does this work as I expect? Or should I be calling a specific initialize method for each child object?
My base page object looks like this with regards to session/driver
(Child objects just call super
so basically the same thing:
attr_reader :session
def initialize(session)
@session = session
end
From which I call session.find/fill_in/etc...
in the rest of the class. And then I actually create the session via (in the test scripts themselves):
let(:login_page) {LoginPage.new(Capybara.current_session)}
Which I then use for all the it
test cases. I create a new current_session
/page object everytime I do a new describe
test context.
- Sort of an extra side question....but how discrete should my methods be? For instance let's pretend In my Login Page object I have a Login method (Fills in the username and the password). Does it make any sense/benefit to also have methods for the username/password fill in's that the main login method calls? Or is that just overkill?
Apologies for wall of text!
@session
variable