{"id":21175249,"url":"https://github.com/alb-i986/selenium-tinafw","last_synced_at":"2025-08-23T05:36:28.414Z","repository":{"id":20881017,"uuid":"24168244","full_name":"alb-i986/selenium-tinafw","owner":"alb-i986","description":"A framework for writing maintainable poetry with Selenium WebDriver. Also provides features like reports with screenshots.","archived":false,"fork":false,"pushed_at":"2022-01-04T16:39:20.000Z","size":2329,"stargazers_count":6,"open_issues_count":4,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-07T23:53:56.440Z","etag":null,"topics":["java","selenium"],"latest_commit_sha":null,"homepage":"","language":"Java","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/alb-i986.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}},"created_at":"2014-09-18T00:55:57.000Z","updated_at":"2021-12-16T21:42:43.000Z","dependencies_parsed_at":"2022-08-30T15:51:37.793Z","dependency_job_id":null,"html_url":"https://github.com/alb-i986/selenium-tinafw","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/alb-i986/selenium-tinafw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alb-i986%2Fselenium-tinafw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alb-i986%2Fselenium-tinafw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alb-i986%2Fselenium-tinafw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alb-i986%2Fselenium-tinafw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alb-i986","download_url":"https://codeload.github.com/alb-i986/selenium-tinafw/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alb-i986%2Fselenium-tinafw/sbom","scorecard":{"id":177845,"data":{"date":"2025-08-11","repo":{"name":"github.com/alb-i986/selenium-tinafw","commit":"6dfcbc46acb534c32980d8c1eef51983bfab9085"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T18:08:52.682Z","repository_id":20881017,"created_at":"2025-08-16T18:08:52.682Z","updated_at":"2025-08-16T18:08:52.682Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271745602,"owners_count":24813511,"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","status":"online","status_checked_at":"2025-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["java","selenium"],"created_at":"2024-11-20T16:57:38.746Z","updated_at":"2025-08-23T05:36:28.380Z","avatar_url":"https://github.com/alb-i986.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"selenium-tinafw\n===============\n\nA minimal and effective Selenium framework, not a wrapper.\n\nThe goal is two-fold:\n- helping manage the mess inherent in a large test suite, by providing a well-defined structure for test code (see [WebTask](http://alb-i986.github.io/selenium-tinafw/javadoc/me/alb_i986/selenium/tinafw/tasks/WebTask.html))\n- helping bootstrap a test suite by providing some basic services such as:\n  - a factory of WebDriver instances, representing either a local browser or one on a Grid, based on settings in a property file\n  - an automatic mechanism to close browsers as soon as a test terminates\n  - a mechanism to retry flaky tests\n  - test reports with screenshots attached\n\nIn order to get an idea of how tests look like by using this framework, please see the [sample provided](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/).\nStart from [SampleWebTest](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/tests/SampleWebTest.java), down to the WebTasks ([OnMyAboutMePage](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/tasks/OnMyAboutMePage.java), [Search](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/tasks/Search.java), [CanCompliment](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/tasks/CanCompliment.java)), down to page objects ([SearchResultsPage](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/ui/SearchResultsPage.java), [SearchResult](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/ui/SearchResult.java), etc.)\n\n\n## Usage\nPlease see the [Tutorial](https://github.com/alb-i986/selenium-tinafw/wiki/Try-it-out) on the wiki.\n\n\n## Features\n\n- Wraps without wrapping.\n  Selenium WebDriver's API is not hidden in any way.\n  You could virtually access a WebDriver instance from a test class (although you are encouraged not to do so, unless you want to break cohesion).\n  The idea is that _Selenium WebDriver has such a beautiful API that it's a shame to hide it_.\n\n- `WebTask` hierarchy, the orchestrators of page objects:\n  - helps keeping your code organized: each concrete WebTask is supposed to be a [Given/When/Then step](http://martinfowler.com/bliki/GivenWhenThen.html))\n  - and highly readable ([fluent interface](http://www.martinfowler.com/bliki/FluentInterface.html)): see e.g. [SampleWebTest](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/tests/SampleWebTest.java)\n  - solves the following problem in an elegant way:\n\n    \u003e Given two tasks that run sequentially, the first does something and ends at a certain page.\n    \u003e How can the second task know which was the last page the first task was visiting?\n  \n    (a naive solution being \"every task restarts navigating the SUT from the home page\").\n\n- `WebDriverFactory` hierarchy: elegant solution solving the problem of\n  creating instances of WebDriver, modeled using the decorator design pattern.\n\n- BDD-style tests are not only supported but also strongly encouraged.\n  You can write BDD tests by wrapping your own WebTask's in a `given` `when` or `then` task (each of which is a `CompositeWebTask`).\n  See also [WebTasks.BDD](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/tasks/WebTasks.java)\n  Please see [SampleWebTest](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/sample/tests/SampleWebTest.java)\n  for an example of usage.\n  For an introduction to BDD, please see the article [Introducing BDD, by Dan North](http://dannorth.net/introducing-bdd/).\n\n- HTML reports with embedded screenshots for each failing test, thanks to\n  [HtmlReporter](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/tests/rules/HtmlReporter.java)\n  \n- the ability to run each test on many different browsers (or just one)\n  by simply setting a property in a file: `tinafw.browsers = chrome, firefox`\n  \n- the ability to retry a failed test for a given number of times: see [TestRetrier](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/tests/rules/TestRetrier.java)\n  \n- an automatic mechanism for closing browsers as soon as a test finishes,\n  as well as the option to disable such a mechanism by setting a property: see [BrowserManager](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/tests/rules/BrowserManager.java)\n\n- a clean directory structure, aka multilayered architecture, with:\n  - the _tests_ layer, for keeping your test cases along with their data\n  - the _domain_ layer, containing concepts like User and Browser, and supposed to contain the concepts\n    of your own domain as well, e.g. `BlogPost`, `BlogComment`\n  - the _tasks_ layer, containing the orchestrators of page objects\n  - the _ui_ layer, with [page objects](https://code.google.com/p/selenium/wiki/PageObjects)\n\n- meaningful logs, e.g.:\n\n\t\tINFO  CompositeWebTask - BEGIN subtask Given\n\t\tINFO  CompositeWebTask - BEGIN subtask OnMyAboutMePage\n\t\tDEBUG PageHelper$Navigation - Page at URL http://alb-i986.me/ loaded\n\t\tINFO  BasePage - Loading page MyAboutMePage\n\t\tDEBUG PageHelper - BEGIN Explicit wait (timeout=15s). Waiting until visibility of [[ChromeDriver: chrome on MAC (e8eac3735de18ef7920ce08755d3f6bf)] -\u003e css selector: #profile_box h1.name]\n\t\tDEBUG PageHelper - END Explicit wait: visibility of [[ChromeDriver: chrome on MAC (e8eac3735de18ef7920ce08755d3f6bf)] -\u003e css selector: #profile_box h1.name]\n\t\tINFO  CompositeWebTask - END subtask OnMyAboutMePage\n\t\tINFO  CompositeWebTask - END subtask Given\n\t\tINFO  CompositeWebTask - BEGIN subtask When\n\t\tINFO  CompositeWebTask - BEGIN subtask Search\n\t\tINFO  BasePage - Loading page SearchResultsPage\n\t\tDEBUG PageHelper - BEGIN Explicit wait (timeout=15s). Waiting until visibility of [[ChromeDriver: chrome on MAC (e8eac3735de18ef7920ce08755d3f6bf)] -\u003e css selector: #search-results div]\n\t\tDEBUG PageHelper - END Explicit wait: visibility of [[ChromeDriver: chrome on MAC (e8eac3735de18ef7920ce08755d3f6bf)] -\u003e css selector: #search-results div]\n\t\tINFO  CompositeWebTask - END subtask Search\n\t\tINFO  CompositeWebTask - END subtask When\n\t\tINFO  CompositeWebTask - BEGIN subtask Then\n\t\tINFO  CompositeWebTask - BEGIN subtask CanCompliment\n\t\tINFO  CompositeWebTask - END subtask CanCompliment\n\t\tINFO  CompositeWebTask - END subtask Then\n\n## A glimpse of the internals: UML Sequence Diagrams\n\n![Open browser SD](doc/uml/openBrowser.jpg)\n\n![Login SD](doc/uml/doLoginTask.jpg)\n\n \n## Design goals\n\n- small, clean, Object-based API ([here, quoting Simon Stewart](http://google-opensource.blogspot.ie/2009/05/introducing-webdriver.html))\n- not a wrapper\n- high cohesion.\n- flexibility\n- poetry (to be, as well as to allow for)\n\n\n## Requirements\n\n- Java 8 (see e.g. [LoadablePage](https://github.com/alb-i986/selenium-tinafw/blob/master/src/main/java/me/alb_i986/selenium/tinafw/ui/LoadablePage.java), which makes use of [static methods in interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html))\n- Maven\n- Graphviz\n\nGraphviz is actually optional: it is needed for generating javadocs with pretty cool UML class diagrams (thanks [UMLGraph](http://www.umlgraph.org)!). So you're not gonna need it unless you want to run `mvn site` or `mvn javadoc:javadoc`. \n\n\n## Dependencies\n\nThe main dependencies are:\n- selenium-java\n- junit\n- log4j\n\nPlease see the [POM file](pom.xml) for more details.\n\n\n## TODO\n\n- redesign Config\n- cleanup by leveraging Guice\n- add `PageComponent` hierarchy\n- make it a data-driven framework\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falb-i986%2Fselenium-tinafw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falb-i986%2Fselenium-tinafw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falb-i986%2Fselenium-tinafw/lists"}