What are the key fundamental differences between Screen Play and Page Object patterns?
At the UK Selenium Conference, there was a presentation on the Screen Play pattern, see The Screenplay Pattern - a SOLID alternative to Page Objects | Antony Marcano
We have a huge technology ecosystem (60+ apps) and base everything on the Page Object model. We tried the Screen Play pattern and learned many things about it and where it is more and less effective.
IMHO, this is just one more tool to apply where needed. The Page Object Model works because it is quite flexible and if used on a large SUT it works best. Using the Screen Play pattern sparingly applied to a stable or smaller system where well-defined Requirements and Use Case exist it works best.
The question is not which pattern is better? Page Object Model or Screen Play Model are both tools. The questions are as follows: Which is better for testing your product? Do you have a development environment that supports Screen Play pattern needs as inputs? (i.e. Clear requirements, use cases, etc.) Are you implementing automation from scratch? Or are you playing catch up and/or migrating? None of these questions will itself eliminates one pattern or the other; we are not looking at an OR statement here, it is an AND statement with weights and balances. You want to make an informed decision and have a 6-month goal/plan in mind.
In our projects, we applied the Screen Play to a complex and then a simple project. Start simple; there is a lot to learn, follow SOLID principles, practice your discipline to keep the structure pure and refactor often.
The references provided above are a good starting place too.
The key difference is that the screenplay pattern organizes the Page Objects
The Screen Play pattern tries to address the issues, challenges and solutions that you will eventually encounter and address when developing most UI acceptance test automation, including when you would introduce the Page Object pattern and then face challenges using it due to the simple need to organize and arrange code and data that tend to lead to requiring programming languages and frameworks. I have seen it called "what would result from the merciless refactoring of Page Objects using SOLID design principles"
The Screenplay Pattern is also known as the Journey Design Pattern and is the application of SOLID design principles to automated acceptance testing. It uses an actor-centric model with tests that focus on how a user interacts with the application to achieve a goal as opposed to how a 'page' is used in the Page Object model.
In the Screenplay pattern, each Actor has Abilities and Questions such as querying a restful web service. Actors can also perform Tasks such as adding an item to a list on a Web Page. To achieve these Tasks, they perform Actions such as clicking or typing. Actors can also ask Questions about the state of the application, such as the contents of a certain field on a page or by querying a web service.
I have personally seen the Page Object pattern be introduced, initially for less than 30 page locators. Over time the (single file) grow to nearly 500 lines of identifiers and actions. As they were 'all in one place' this meant that over time bad things happened. Specifically:
- We had about 6 duplicates within the file
- We had about 12 unused page objects for removed tests that left orphaned page objects
- We didn't immediately know if changing a Page Object would break other tests
- We didn't know if it was shared and used in tests other than the one you are working on
Disclaimer up front: I do not agree with some of what is quoted below. I believe that a decent POM-framework can lead to VERY readable and maintainable tests.
Reading this page, the intent becomes clear. Per the source:
Even though Page Objects reduce code duplication and encourage reuse across tests within a single project and a single test suite, the design falls short if we need to enable code reuse across multiple projects and teams. This of course affects the scalability.
SPP defines general Tasks, Abilities and Actions; because they are not linked to specific pages they can more readily be reused across projects. This can easily be done with POM also, if you provide the general actions (such as logging in) as a separate package that all projects can reuse.
Also, the fact that each page object is tightly coupled to Protractor APIs: element and by - global functions that are browser instance-specific - makes it impossible to use this design "as is" for multi-browser testing (chat systems, workflow systems, multi-player games, etc.).
By buffering the use of a WebDriver as an Ability (see the code), their framework is not strictly coupled to WebDriver technology only. Additional abilities may allow for wider testing variation (games, chat systems, ...).
Not to mention that even after extracting a Page Object from the original test script, there's still plenty of low-level Protractor/WebDriver API calls left in the Cucumber steps. They are important as they deal with managing the browser window and synchronising WebDriver Control Flow, with Cucumber callbacks, but which also cloud the business logic of the implementation.
Again, SPP pattern supposedly provides a better decoupling of business logic and technical implementation. However, in my framework I have close to zero technical calls in my test methods. The framework hides all complexity.
Page Objects also introduce a more subtle problem. As the name implies, Page Objects reason at the level of the user interface, in terms of fields, buttons and links that the user manipulates. This affects the way you think about the application too. Instead of placing the primary focus on what the user needs to do with the application, Page Objects lead you to focus on how the user interacts with individual pages. As a result, the tests become tightly coupled to the structure of the user interface, making them more brittle and more likely to be affected by UI changes.
The author here suggests that using SPP will you think differently about tests than with POM, and that the previously mentioned generalized Tasks and Questions are more robust with a changing UI because they're not as strictly coupled with UI actions.
Since a Page Object works with two distinct concepts, there are two reasons why it might need to be changed. The page structure may have changed, or a test might need to describe a new user interaction with that page. In both cases, deliberate or unintended changes to the page object carry a risk of having a negative impact on existing tests that use it. The more interactions and page elements a given page object describes, the higher the likelihood of the problem occurring.
Again, the author suggests that, due to the different compositing in SPP, changes will have a reduced impact. However, changes in UI need to a changes Task/Question and this will also possibly impact every test it's being used by?!
I have been working as a QA Engineer for 7 years and I have found that using the PageObject framework on its own creates a lot of duplicate code.
For example, if your application has a login page and a case creation page then every test case in your entire suite will include code that does the following things.
- Logins to the application
- Clicks the Create Case button
- Enters data
- Clicks the save button
That's at least 4 lines of duplicate code that exist in every test case in your application. Now you could solve this issue by creating a helper method called LoginAndCreateCase() but if you are following the traditional page object model it is unclear as to where you should put this new method.
What the screenplay does is separate the code associated with performing specific tasks from the code to interact directly with the application UI. This list of high-level actions the user can perform on your application are Tasks.
If you have been working on Selenium test case for long enough it's likely you have already done this without knowing it. Every time you create a method in a page object which interacts with more than one element that code can be converted into a Task in the screenplay pattern.