{"id":16321187,"url":"https://github.com/christian-draeger/basic-selenium-project","last_synced_at":"2025-07-06T23:05:10.879Z","repository":{"id":46261009,"uuid":"71291543","full_name":"christian-draeger/basic-selenium-project","owner":"christian-draeger","description":"an example selenium test project","archived":false,"fork":false,"pushed_at":"2023-08-27T14:17:20.000Z","size":308,"stargazers_count":58,"open_issues_count":1,"forks_count":153,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-08T00:35:16.830Z","etag":null,"topics":["fluentlenium","gradle","java","kotlin","maven","selenium","selenium-tests","webdriver","webdrivermanager"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christian-draeger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["christian-draeger"],"custom":["https://www.paypal.me/skrapeit"]}},"created_at":"2016-10-18T21:09:06.000Z","updated_at":"2024-08-28T12:52:30.000Z","dependencies_parsed_at":"2024-10-10T22:47:27.830Z","dependency_job_id":"9d0f8c98-f9f8-437c-87f0-0df336919651","html_url":"https://github.com/christian-draeger/basic-selenium-project","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/christian-draeger/basic-selenium-project","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christian-draeger%2Fbasic-selenium-project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christian-draeger%2Fbasic-selenium-project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christian-draeger%2Fbasic-selenium-project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christian-draeger%2Fbasic-selenium-project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christian-draeger","download_url":"https://codeload.github.com/christian-draeger/basic-selenium-project/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christian-draeger%2Fbasic-selenium-project/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263986225,"owners_count":23539808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["fluentlenium","gradle","java","kotlin","maven","selenium","selenium-tests","webdriver","webdrivermanager"],"created_at":"2024-10-10T22:46:53.930Z","updated_at":"2025-07-06T23:05:10.861Z","avatar_url":"https://github.com/christian-draeger.png","language":"Kotlin","funding_links":["https://github.com/sponsors/christian-draeger","https://www.paypal.me/skrapeit"],"categories":[],"sub_categories":[],"readme":"[![Travis](http://badges.herokuapp.com/travis/christian-draeger/basic-selenium-project?env=BROWSER=firefox\u0026label=Firefox\u0026branch=master)](https://travis-ci.org/christian-draeger/basic-selenium-project)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fchristian-draeger%2Fbasic-selenium-project.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fchristian-draeger%2Fbasic-selenium-project?ref=badge_shield)\n\n[![Travis](http://badges.herokuapp.com/travis/christian-draeger/basic-selenium-project?env=BROWSER=googlechrome\u0026label=Chrome\u0026branch=master)](https://travis-ci.org/christian-draeger/basic-selenium-project)\n\n[![Travis](http://badges.herokuapp.com/travis/christian-draeger/basic-selenium-project?env=BROWSER=safari\u0026label=Safari\u0026branch=master)](https://travis-ci.org/christian-draeger/basic-selenium-project)\n\n[![AppVeyor](https://img.shields.io/appveyor/ci/christian-draeger/basic-selenium-project.svg?label=IE11)](https://ci.appveyor.com/project/christian-draeger/basic-selenium-project)\n\nBasic Selenium Project\n===================================\n\nThis scaffold project is written in **[Kotlin](https://kotlinlang.org)** and will serve an example of implementing a \nSelenium test project with [FluentLenium](https://fluentlenium.com) (Selenium3) and [Gradle](https://gradle.org) (with kotlin DSL).\nEverything is set up and tests can be added straight away.\nUsed Testrunner is [JUnit 5](https://junit.org/junit5).\n_Since Kotlin has an excellent **Java** interop it's perfectly fine to write your Tests in Java if you want, it will work out of the box._\nTo execute the tests just browse to the path where the selenium-kotlin-example is located via terminal and type `./gradlew clean test` or execute the tests in your IDE.\nThe Project will use Chrome Browser in Headless mode by default / if no other browser is stated \n(see list of implemented browsers for more info on how to use them).\n\nIf you are looking for a pure Java project that uses maven as build tool please have a look at the [legacy branch](https://github.com/christian-draeger/basic-selenium-project/tree/legacy) of this project.\n\n\n\u003e#### ℹ️ FluentLenium is a website automation framework which extends Selenium to write reliable and resilient UI functional tests. This framework is React ready. Written and maintained by people who are automating browser-based tests on a daily basis.\n\n### Prerequisites\n* \\\u003e=**JDK8** installed\n\n#### Features:\n* [all popular browsers preconfigured](#-implemented-browsers)\n    * downloading OS specific binaries automatically\n* [full control by annotations](#-full-control-over-certain-test-methods-and-classes-by-annotations)\n* [page object pattern ready](#-page-object-pattern-ready)\n* [take screenshot on test failure](#-take-screenshots)\n* [highlight clicked elements](#-highlight-clicked-elements)\n* [pretty and highly readable console output](#-beautiful-console-output)\n* [parallel test execution ready](#-parallel-test-execution)\n* [centralized project config](#-centralized-project-config)\n* [retries](#-retries)\n* [proxy to intercept / modify / mock http-requests](#-proxy) 🔜\n* assertions, waits and test extensions\n    * [assertions with selenium specific and type safe matchers](#-assertions)\n    * [waiting functions](#-waits)\n* [meaningful test result report](#-allure-test-result-report)\n* [template testing](#-template-testing)\n\n## Benefits\n\n#### 💻 Implemented Browsers\nThanks to the awesome [webdrivermanager](https://github.com/bonigarcia/webdrivermanager) it supports the following browsers and automatically downloads OS specific binaries for:\n* Chrome Headless (default) `./gradlew clean test`\n* Chrome `./gradlew clean test -Dbrowser=chrome`\n* Firefox Headless `./gradlew clean test -Dbrowser=firefox-headless`\n* Firefox `./gradlew clean test -Dbrowser=firefox`\n* Opera `./gradlew clean test -Dbrowser=opera`\n* Internet Explorer `./gradlew clean test -Dbrowser=ie` (will work on windows machines only)\n* Edge `./gradlew clean test -Dbrowser=edge` (will work on windows machines only)\n* Safari `./gradlew clean test -Dbrowser=safari` (will work on OSX machines only)\n\n---\n\n#### 🕹️ Full control over certain test methods and classes by annotations\nThe project includes custom annotations to comfortably set some test conditions and/or assumptions\nlike skip/require certain tests on execution with specific browsers and/or override driver options like browser dimension, headers, cookies, etc.\nThis will increase the possibility to write easily readable and flexible tests.\n\n##### @Browser\nOverwrite used (default) browser by annotating test classes or test methods with:\n\n    @Browser(use = FIREFOX)\n    \nThis will always execute the annotated tests with the selected browser, no matter what has been set as default browser. \nSee the full list of possible [parameter values](https://github.com/christian-draeger/basic-selenium-project/blob/8d6d025ec895d831e76b9013c1648307edf0756f/src/test/java/config/driver/DriverFactory.kt#L115).\n\nFurthermore you can conveniently set the Browser windows dimension that is used for the test by setting the dimension field:\n\n    @Browser(dimension = XLARGE)\n    \nThis will lead to a window resize before the actual test starts and is especially helpful if the \nsite under test relies on a responsive web design. \nSee the full list of [possible dimensions](https://github.com/christian-draeger/basic-selenium-project/blob/8d6d025ec895d831e76b9013c1648307edf0756f/src/test/java/config/driver/WindowManager.kt#L8).\nThe specific values of the breakpoints can be configured in the [config.properties](https://github.com/christian-draeger/basic-selenium-project/blob/8d6d025ec895d831e76b9013c1648307edf0756f/src/test/resources/config.properties) file.\n\n##### @EnabledOnOs\nYou can control that a test will ONLY be executed on specific operating systems.\n(works on class and method level)\n\n    @EnabledOnOs(LINUX, WINDOWS)\n\nIf a test is annotated with `@EnabledOnOs` and the current OS the tests gets executed on is not matching, they will be skipped.\n\n##### @DisabledOnJre\nYou can control that a test will be skipped if running on specific JRE(s).\n\n    @DisabledOnJre(JAVA_8, JAVA_9)\n    \nIf a test is annotated with `@DisabledOnJre` it will be skipped if tests are running on specified JRE(s).\n\n##### @EnabledIfSystemProperty\nGives control over test execution relying on system properties. The following example will execute the test only\nif the current OS is a 64bit system. But it could be any either provided or self defined system property.\n\n    @EnabledIfSystemProperty(named = \"os.arch\", matches = \".*64.*\")\n    \nIf a test is annotated with `@EnabledIfSystemProperty` it will ONLY be executed if the specified system property (field `named`)\nwill match the provided regex (field `matches`), otherwise the test will be skipped.\n\n##### @EnabledIfEnvironmentVariable\nGives control over test execution relying on environment variables. The following example will execute the test only\nif the environment variable 'ENV' will be present and it's value matches 'ci'. But it could be any environment variable and regex match combination.\n\n    @EnabledIfEnvironmentVariable(named = \"ENV\", matches = \"ci\")\n    \nIf a test is annotated with `@EnabledIfEnvironmentVariable` it will ONLY be executed if the specified system property (field `named`)\nwill match the provided regex (field `matches`), otherwise the test will be skipped.\n\n---\n\n#### 📜 Page Object Pattern ready\nThe Page-Object-Pattern can be used straight away to specify elements etc.\nIt will have out-of-the-box support for typical helper methods like `isAt()`, etc...\nTo instantiate a page object in a test class just the the following:\n\n[kotlin example](https://github.com/christian-draeger/basic-selenium-project/blob/90085a3e77d0f8af9e3990fb2512a0e52255cecc/src/test/java/tests/browser/ExampleIT.kt#L29):\n\n    @Page\n    lateinit var page: StartPage\n\n[java example](https://github.com/christian-draeger/basic-selenium-project/blob/90085a3e77d0f8af9e3990fb2512a0e52255cecc/src/test/java/tests/browser/JavaExampleIT.java#L28):\n\n    @Page\n    private StartPage startPage;\n\n---\n\n#### 📸 Take Screenshots\nOn test failures screenshots will automatically be taken and stored under `build/screenshots`.\nThe screenshot files will be named with a combination of the class name and the test method name.\n\n---\n\n#### 📍 Highlight Clicked Elements\nWhen clicking an element it will be highlighted with a red border. This is helpful to easily understand what \na certain test is doing while watching a test run. This functionality is working because the project is implementing an event firing webdriver. \nTherefore you have the possibility to hook into a bunch of driver events and do custom stuff if you want to, e.g.:\n\n* `beforeClickOn` / `afterClickOn`\n* `beforeNavigateTo` / `afterNavigateTo`\n* `beforeFindBy` / `afterFindBy`\n* `beforeScript` / `afterScript`\n* `beforeGetText` / `afterGetText`\n* `register` / `unregister`\n* `onException`\n* ... and more\n\n---\n\n#### 📟 Beautiful Console Output\nThe console output is more intuitive and better readable as the default one of Gradle, jUnit and Selenium.\nA colored console output will give you a clear overview about which tests are currently running.\nFurthermore obvious markers will be set at succeeded (green marker) and failed (red marker) tests.  \nTo get an even more clear overview of the test execution the project uses the gradle TestLoggerPlugin to pretty print executed tests.\n\n---\n\n#### 👩‍👩‍👦‍👦 Parallel Test Execution\nThe Project is preconfigured to run the tests in parallel.\nThe number of test that will be executed at the same time is configurable (defaults to 4) or can be deactivated if required.\n\n---\n\n#### 🎯 Centralized Project Config\nAll global configurations are living in a properties file (`resources/config.properties`) and can be adjusted.\nIt gives you the possibility to edit the global project behaviour in one place without messing around with project/setup specific code.\nFurthermore all properties can be overridden via system properties.\n\n---\n\n#### 🔁 Retries\nConveniently run a single Test Multiple Times.\nIt's possible to rerun failing tests automatically when they are flaky with the following options:\n\n* rerun a certain number of times if a test fails\n    * usage: annotate test with `@RepeatedIfExceptionsTest(repeats = 3)` instead of `@Test`\n* rerun a certain number of times if a test fails because of a certain exception\n    * usage in kotlin: annotate test with `@RepeatedIfExceptionsTest(repeats = 2, exceptions = [NoSuchElementException::class])` instead of `@Test`\n    * usage in java: annotate test with `@RepeatedIfExceptionsTest(repeats = 2, exceptions = NoSuchElementException.class)` instead of `@Test`\n* supports display name formatting for tests that have to rerun\n    * usage: `@RepeatedIfExceptionsTest(repeats = 2, name = \"Rerun failed test. Attempt {currentRepetition} of {totalRepetitions}\")\n* includes feature to repeat certain test a bunch of times and expect to succeed a certain number of times`\n    * usage: `@RepeatedIfExceptionsTest(repeats = 100, minSuccess = 4)`\n\n---\n\n#### ⛩️ Proxy\n##### (in progress, not implemented yet)\nThe [BrowserMob Proxy](https://github.com/lightbody/browsermob-proxy) is already implemented and can be used to Mock External Requests.\nThis is especially helpful to mock dynamic data on the page under test, modify parts of the request that are not possible with some browsers (like setting custom headers in Internet Explorer) as well as speeding up \nyour tests by mocking thinks that are out of scope of a certain test (for instance tracking scripts).\n\n---\n\n#### 🚨 Assertions\nFluentlenium extends AssertJ with FluentWebElement, FluentList and FluentPage custom assertions.\nTherefore you'll be able to write more intuitive and selenium specific assertions to give you the possibility to easily assert things like if an element is displayed etc.\n\n---\n\n#### ⏱️ Waits\nTesting web applications that are asynchroniously loading / rerendering parts of the page can become hard to test with Selenium. \n[Awaitility](https://github.com/awaitility/awaitility) is a DSL that allows you to express expectations of an asynchronous system in a concise and easy to read manner and is therefore added to this project.\n\n---\n\n#### 📊 Allure Test Result Report\n[Allure](http://allure.qatools.ru) provides a good representation of test execution output and is designed to create \nreports that are clear to everyone by creating graphs regarding test execution time, \noverall test result overviews, test result history, etc.\n\n---\n\n#### 🚀 Template Testing\nFrom time to time we are writing tests that doesn't need browser interactions like clicking or \nexecution of Javascript. We'll use template testing using [skrape{it}](https://docs.skrape.it/docs/) \nto achieve these types of tests because it's much much faster and more robust then Selenium. \nPlease have a look at the [example test](https://github.com/christian-draeger/selenium-kotlin-example/blob/13c75c3a86be3b09eabf7f70a6b92c5451f95c9d/src/test/kotlin/tests/ExampleTemplateIT.kt)\n\n#### Maintenance\n#### check for dependency updates\n\n    ./gradlew dependencyUpdates\n\n____________________\n____________________\n\nHit count:\n\n![HitCount](http://hits.dwyl.io/christian-draeger/basic-selenium-project.svg)\n\n## License\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fchristian-draeger%2Fbasic-selenium-project.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fchristian-draeger%2Fbasic-selenium-project?ref=badge_large)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristian-draeger%2Fbasic-selenium-project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristian-draeger%2Fbasic-selenium-project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristian-draeger%2Fbasic-selenium-project/lists"}