{"id":22616094,"url":"https://github.com/ferdyciputra/serenity-screenplay-practice","last_synced_at":"2026-05-07T13:35:53.326Z","repository":{"id":216493029,"uuid":"609210748","full_name":"ferdyciputra/serenity-screenplay-practice","owner":"ferdyciputra","description":"This Project Web Automation Testing Using Selenium, Cucumber, JUnit and Serenity BDD for Reporting with Screenplay pattern ","archived":false,"fork":false,"pushed_at":"2023-03-07T08:17:13.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-30T04:00:37.805Z","etag":null,"topics":["automated-testing","cucumber","java","screenplay-pattern","selenium","serenity","serenity-bdd"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ferdyciputra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-03-03T15:56:07.000Z","updated_at":"2024-01-29T13:55:29.000Z","dependencies_parsed_at":"2024-01-10T15:33:48.809Z","dependency_job_id":null,"html_url":"https://github.com/ferdyciputra/serenity-screenplay-practice","commit_stats":null,"previous_names":["ferdyciputra/serenity-screenplay-practice"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ferdyciputra/serenity-screenplay-practice","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferdyciputra%2Fserenity-screenplay-practice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferdyciputra%2Fserenity-screenplay-practice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferdyciputra%2Fserenity-screenplay-practice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferdyciputra%2Fserenity-screenplay-practice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ferdyciputra","download_url":"https://codeload.github.com/ferdyciputra/serenity-screenplay-practice/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferdyciputra%2Fserenity-screenplay-practice/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32740378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-07T02:14:30.463Z","status":"ssl_error","status_checked_at":"2026-05-07T02:14:29.405Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automated-testing","cucumber","java","screenplay-pattern","selenium","serenity","serenity-bdd"],"created_at":"2024-12-08T19:10:40.807Z","updated_at":"2026-05-07T13:35:53.310Z","avatar_url":"https://github.com/ferdyciputra.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Getting started with Serenity and Cucumber\n\nSerenity BDD is a library that makes it easier to write high quality automated acceptance tests, with powerful reporting and living documentation features. It has strong support for both web testing with Selenium, and API testing using RestAssured.\n\nSerenity strongly encourages good test automation design, and supports several design patterns, including classic Page Objects, the newer Lean Page Objects/ Action Classes approach, and the more sophisticated and flexible Screenplay pattern.\n\nThe latest version of Serenity supports Cucumber 6.x.\n\n## The swaglabs project\nThe best place to start with Serenity and Cucumber is to clone or download the swaglabs project on Github ([https://github.com/serenity-bdd/serenity-cucumber-swaglabs](https://github.com/serenity-bdd/serenity-cucumber-starter)). This project gives you a basic project setup, along with some sample tests and supporting classes. There are two versions to choose from. The master branch uses a more classic approach, using action classes and lightweight page objects, whereas the **[screenplay](https://github.com/serenity-bdd/serenity-cucumber-starter/tree/screenplay)** branch shows the same sample test implemented using Screenplay.\n\n### The project directory structure\nThe project has build scripts for both Maven and Gradle, and follows the standard directory structure used in most Serenity projects:\n```Gherkin\nsrc\n  + main\n  + test\n    + java                        Test runners and supporting code\n    + resources\n      + features                  Feature files\n\u2028    + search                  Feature file subdirectories\u2028\n             search_by_keyword.feature\n```\n\nSerenity 2.2.13 introduced integration with WebdriverManager to download webdriver binaries.\n\n## The sample scenario\nBoth variations of the sample project uses the sample Cucumber scenario. In this scenario, Sergey (who likes to search for stuff) is performing a search on the internet:\n\n```Gherkin\nFeature: Search by keyword\n\n  Scenario: Searching for a term\n    Given Sergey is researching things on the internet\n    When he looks up \"Cucumber\"\n    Then he should see information about \"Cucumber\"\n```\n\n### The Screenplay implementation\nThe sample code in the master branch uses the Screenplay pattern. The Screenplay pattern describes tests in terms of actors and the tasks they perform. Tasks are represented as objects performed by an actor, rather than methods. This makes them more flexible and composable, at the cost of being a bit more wordy. Here is an example:\n```java\n    @Given(\"{actor} is researching things on the internet\")\n    public void researchingThings(Actor actor) {\n        actor.wasAbleTo(NavigateTo.theWikipediaHomePage());\n    }\n\n    @When(\"{actor} looks up {string}\")\n    public void searchesFor(Actor actor, String term) {\n        actor.attemptsTo(\n                LookForInformation.about(term)\n        );\n    }\n\n    @Then(\"{actor} should see information about {string}\")\n    public void should_see_information_about(Actor actor, String term) {\n        actor.attemptsTo(\n                Ensure.that(WikipediaArticle.HEADING).hasText(term)\n        );\n    }\n```\n\nScreenplay classes emphasise reusable components and a very readable declarative style, whereas Lean Page Objects and Action Classes (that you can see further down) opt for a more imperative style.\n\nThe `NavigateTo` class is responsible for opening the Wikipedia home page:\n```java\npublic class NavigateTo {\n    public static Performable theWikipediaHomePage() {\n        return Task.where(\"{0} opens the Wikipedia home page\",\n                Open.browserOn().the(WikipediaHomePage.class));\n    }\n}\n```\n\nThe `LookForInformation` class does the actual search:\n```java\npublic class LookForInformation {\n    public static Performable about(String searchTerm) {\n        return Task.where(\"{0} searches for '\" + searchTerm + \"'\",\n                Enter.theValue(searchTerm)\n                        .into(SearchForm.SEARCH_FIELD)\n                        .thenHit(Keys.ENTER)\n        );\n    }\n}\n```\n\nIn Screenplay, we keep track of locators in light weight page or component objects, like this one:\n```java\nclass SearchForm {\n    static Target SEARCH_FIELD = Target.the(\"search field\")\n                                       .locatedBy(\"#searchInput\");\n\n}\n```\n\nThe Screenplay DSL is rich and flexible, and well suited to teams working on large test automation projects with many team members, and who are reasonably comfortable with Java and design patterns. \n\n### The Action Classes implementation.\n\nA more imperative-style implementation using the Action Classes pattern can be found in the `action-classes` branch. The glue code in this version looks this this:\n\n```java\n    @Given(\"^(?:.*) is researching things on the internet\")\n    public void i_am_on_the_Wikipedia_home_page() {\n        navigateTo.theHomePage();\n    }\n\n    @When(\"she/he looks up {string}\")\n    public void i_search_for(String term) {\n        searchFor.term(term);\n    }\n\n    @Then(\"she/he should see information about {string}\")\n    public void all_the_result_titles_should_contain_the_word(String term) {\n        assertThat(searchResult.displayed()).contains(term);\n    }\n```\n\nThese classes are declared using the Serenity `@Steps` annotation, shown below:\n```java\n    @Steps\n    NavigateTo navigateTo;\n\n    @Steps\n    SearchFor searchFor;\n\n    @Steps\n    SearchResult searchResult;\n```\n\nThe `@Steps`annotation tells Serenity to create a new instance of the class, and inject any other steps or page objects that this instance might need.\n\nEach action class models a particular facet of user behaviour: navigating to a particular page, performing a search, or retrieving the results of a search. These classes are designed to be small and self-contained, which makes them more stable and easier to maintain.\n\nThe `NavigateTo` class is an example of a very simple action class. In a larger application, it might have some other methods related to high level navigation, but in our sample project, it just needs to open the DuckDuckGo home page:\n```java\npublic class NavigateTo {\n\n    WikipediaHomePage homePage;\n\n    @Step(\"Open the Wikipedia home page\")\n    public void theHomePage() {\n        homePage.open();\n    }\n}\n```\n\nIt does this using a standard Serenity Page Object. Page Objects are often very minimal, storing just the URL of the page itself:\n```java\n@DefaultUrl(\"https://wikipedia.org\")\npublic class WikipediaHomePage extends PageObject {}\n```\n\nThe second class, `SearchFor`, is an interaction class. It needs to interact with the web page, and to enable this, we make the class extend the Serenity `UIInteractionSteps`. This gives the class full access to the powerful Serenity WebDriver API, including the `$()` method used below, which locates a web element using a `By` locator or an XPath or CSS expression:\n```java\npublic class SearchFor extends UIInteractionSteps {\n\n    @Step(\"Search for term {0}\")\n    public void term(String term) {\n        $(SearchForm.SEARCH_FIELD).clear();\n        $(SearchForm.SEARCH_FIELD).sendKeys(term, Keys.ENTER);\n    }\n}\n```\n\nThe `SearchForm` class is typical of a light-weight Page Object: it is responsible uniquely for locating elements on the page, and it does this by defining locators or occasionally by resolving web elements dynamically.\n```java\nclass SearchForm {\n    static By SEARCH_FIELD = By.cssSelector(\"#searchInput\");\n}\n```\n\nThe last step library class used in the step definition code is the `SearchResult` class. The job of this class is to query the web page, and retrieve a list of search results that we can use in the AssertJ assertion at the end of the test. This class also extends `UIInteractionSteps` and\n```java\npublic class SearchResult extends UIInteractionSteps {\n    public String displayed() {\n        return find(WikipediaArticle.HEADING).getText();\n    }\n}\n```\n\nThe `WikipediaArticle` class is a lean Page Object that locates the article titles on the results page:\n```java\npublic class WikipediaArticle {\n    public static final By HEADING =  By.id(\"firstHeading\");\n}\n```\n\nThe main advantage of the approach used in this example is not in the lines of code written, although Serenity does reduce a lot of the boilerplate code that you would normally need to write in a web test. The real advantage is in the use of many small, stable classes, each of which focuses on a single job. This application of the _Single Responsibility Principle_ goes a long way to making the test code more stable, easier to understand, and easier to maintain.\n\n## Executing the tests\nTo run the sample project, you can either just run the `CucumberTestSuite` test runner class, or run either `mvn verify` or `gradle test` from the command line.\n\nBy default, the tests will run using Chrome. You can run them in Firefox by overriding the `driver` system property, e.g.\n```json\n$ mvn clean verify -Ddriver=firefox\n```\nOr\n```json\n$ gradle clean test -Pdriver=firefox\n```\n\nThe test results will be recorded in the `target/site/serenity` directory.\n\n## Generating the reports\nSince the Serenity reports contain aggregate information about all of the tests, they are not generated after each individual test (as this would be extremenly inefficient). Rather, The Full Serenity reports are generated by the `serenity-maven-plugin`. You can trigger this by running `mvn serenity:aggregate` from the command line or from your IDE.\n\nThey reports are also integrated into the Maven build process: the following code in the `pom.xml` file causes the reports to be generated automatically once all the tests have completed when you run `mvn verify`?\n\n```\n             \u003cplugin\u003e\n                \u003cgroupId\u003enet.serenity-bdd.maven.plugins\u003c/groupId\u003e\n                \u003cartifactId\u003eserenity-maven-plugin\u003c/artifactId\u003e\n                \u003cversion\u003e${serenity.maven.version}\u003c/version\u003e\n                \u003cconfiguration\u003e\n                    \u003ctags\u003e${tags}\u003c/tags\u003e\n                \u003c/configuration\u003e\n                \u003cexecutions\u003e\n                    \u003cexecution\u003e\n                        \u003cid\u003eserenity-reports\u003c/id\u003e\n                        \u003cphase\u003epost-integration-test\u003c/phase\u003e\n                        \u003cgoals\u003e\n                            \u003cgoal\u003eaggregate\u003c/goal\u003e\n                        \u003c/goals\u003e\n                    \u003c/execution\u003e\n                \u003c/executions\u003e\n            \u003c/plugin\u003e\n```\n\n## Simplified WebDriver configuration and other Serenity extras\nThe sample projects both use some Serenity features which make configuring the tests easier. In particular, Serenity uses the `serenity.conf` file in the `src/test/resources` directory to configure test execution options.  \n### Webdriver configuration\nThe WebDriver configuration is managed entirely from this file, as illustrated below:\n```java\nwebdriver {\n    driver = chrome\n}\nheadless.mode = true\n\nchrome.switches=\"\"\"--start-maximized;--test-type;--no-sandbox;--ignore-certificate-errors;\n                   --disable-popup-blocking;--disable-default-apps;--disable-extensions-file-access-check;\n                   --incognito;--disable-infobars,--disable-gpu\"\"\"\n\n```\n\nSerenity uses WebDriverManager to download the WebDriver binaries automatically before the tests are executed.\n\n### Environment-specific configurations\nWe can also configure environment-specific properties and options, so that the tests can be run in different environments. Here, we configure three environments, __dev__, _staging_ and _prod_, with different starting URLs for each:\n```json\nenvironments {\n  default {\n    webdriver.base.url = \"https://duckduckgo.com\"\n  }\n  dev {\n    webdriver.base.url = \"https://duckduckgo.com/dev\"\n  }\n  staging {\n    webdriver.base.url = \"https://duckduckgo.com/staging\"\n  }\n  prod {\n    webdriver.base.url = \"https://duckduckgo.com/prod\"\n  }\n}\n```\n\nYou use the `environment` system property to determine which environment to run against. For example to run the tests in the staging environment, you could run:\n```json\n$ mvn clean verify -Denvironment=staging\n```\n\nSee [**this article**](https://johnfergusonsmart.com/environment-specific-configuration-in-serenity-bdd/) for more details about this feature.\n\n## Want to learn more?\nFor more information about Serenity BDD, you can read the [**Serenity BDD Book**](https://serenity-bdd.github.io/theserenitybook/latest/index.html), the official online Serenity documentation source. Other sources include:\n* **[Learn Serenity BDD Online](https://expansion.serenity-dojo.com/)** with online courses from the Serenity Dojo Training Library\n* **[Byte-sized Serenity BDD](https://www.youtube.com/channel/UCav6-dPEUiLbnu-rgpy7_bw/featured)** - tips and tricks about Serenity BDD\n* For regular posts on agile test automation best practices, join the **[Agile Test Automation Secrets](https://www.linkedin.com/groups/8961597/)** groups on [LinkedIn](https://www.linkedin.com/groups/8961597/) and [Facebook](https://www.facebook.com/groups/agiletestautomation/)\n* [**Serenity BDD Blog**](https://johnfergusonsmart.com/category/serenity-bdd/) - regular articles about Serenity BDD\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fferdyciputra%2Fserenity-screenplay-practice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fferdyciputra%2Fserenity-screenplay-practice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fferdyciputra%2Fserenity-screenplay-practice/lists"}