So i've ran into what is probably a common issue when designing a page object model based framework. For this specific example I am using Cypress (So JavaScript) but the problem exists for all PoM based setups.
Currently the way I have designed the framework is by breaking large pieces of the page into "Page Components". These are children of the PageObject class (but just smaller). Typically they make up obvious chunks of the page (IE: A Login form would be it's own component, a Header would be a "Common" component", etc...)
Typically these components ONLY model the UI. So their methods are aimed at returning elements OR filling in inputs. IE: fillInEmail getLoginButton etc...
The actual PageObject for that specific page pulls in all the "Components" for that page and created public methods that the test scripts will use. For example Login() will use the LoginFormComponent fillInEmail/fillInPassword/getSubmitButton.click()/etc... methods. This abstracts the test scripts into readable/obvious functions. It also helps break up larger more complex pages.
The issue I have ran into is with large forms with multiple inputs. I see a few options of how I can handle it:
Create a method that takes an object (or fixture) in the Page Component for that Form (IE: the form itself is a component). The Page Component handles inputting everything and doing all the dirty work (IE: filling in/selecting/clicking based on the fixture/object passed). (This is what I am currently doing)
The Page Component simply returns all the inputs as different methods (Keep in mind sometimes it can be 6-7+ inputs) and the Page Object handles all the dirty work within a public method (IE: filling in inputs/selecting/clicking based off the methods the Component passes to the page object). This would require sending an object/fixture in the test script itself for that method.
Break the Form inputs into individual discrete methods (IE: one input is one page component). I think this is probably going to far and doesn't really do anything to abstract the page personally.
All of these feel not great. And despite me currently going with option #1...I don't like that either (As I am going against my own setup by handling larger behavior in the "PageComponents" which are really meant to just model the page.
It's also hard to figure out how to pass the data for the large amounts of inputs. I've been using an object but passing an object into the test script feels ugly. Any advice on handling this?
I think in the end passing down a fixture potentially and breaking it up as you've done above is ideal though (IE: fixture.input1data, fixture.input2data). I think probably breaking out the inputs individually in the component class is probably a good idea though regardless.
– Mercfh Feb 12 '20 at 18:37