{"id":34200588,"url":"https://github.com/devlabfoundry/uistrategy","last_synced_at":"2026-03-11T07:02:34.361Z","repository":{"id":62636319,"uuid":"555324172","full_name":"DevLabFoundry/uistrategy","owner":"DevLabFoundry","description":"Declarative Config driven UI driver for automated UI tests, and data seeding / UI configuration","archived":false,"fork":false,"pushed_at":"2024-03-11T09:10:36.000Z","size":165,"stargazers_count":3,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-18T20:47:33.432Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","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/DevLabFoundry.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-21T11:03:55.000Z","updated_at":"2025-03-14T14:48:18.000Z","dependencies_parsed_at":"2024-03-11T10:44:39.151Z","dependency_job_id":null,"html_url":"https://github.com/DevLabFoundry/uistrategy","commit_stats":{"total_commits":21,"total_committers":1,"mean_commits":21.0,"dds":0.0,"last_synced_commit":"8e0fdbec715f0ca08c50ac009b4a9cbe2b824180"},"previous_names":["devlabfoundry/uistrategy"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/DevLabFoundry/uistrategy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevLabFoundry%2Fuistrategy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevLabFoundry%2Fuistrategy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevLabFoundry%2Fuistrategy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevLabFoundry%2Fuistrategy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DevLabFoundry","download_url":"https://codeload.github.com/DevLabFoundry/uistrategy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevLabFoundry%2Fuistrategy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30373510,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-11T06:09:32.197Z","status":"ssl_error","status_checked_at":"2026-03-11T06:09:17.086Z","response_time":84,"last_error":"SSL_read: 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":[],"created_at":"2025-12-15T18:19:27.222Z","updated_at":"2026-03-11T07:02:34.355Z","avatar_url":"https://github.com/DevLabFoundry.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=dnitsch_uistrategy\u0026metric=bugs)](https://sonarcloud.io/summary/new_code?id=dnitsch_uistrategy)\n[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=dnitsch_uistrategy\u0026metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=dnitsch_uistrategy)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=dnitsch_uistrategy\u0026metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=dnitsch_uistrategy)\n[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=dnitsch_uistrategy\u0026metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=dnitsch_uistrategy)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=dnitsch_uistrategy\u0026metric=coverage)](https://sonarcloud.io/summary/new_code?id=dnitsch_uistrategy)\n\n# UI Strategy - Beta\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/dnitsch/uistrategy)](https://goreportcard.com/report/github.com/dnitsch/uistrategy)\n\nConfig driven UI driver for front end testing, target agnostic, stored in declarative configuration files.\n\n*Can be user for data seeding in cases where there isn't an REST API available.*\n\n\u003e Disclaimer:\nPart of strategy series :D - see [reststrategy](https://github.com/dnitsch/reststrategy) :wink: - there is a [module](https://github.com/dnitsch/reststrategy/tree/main/seeder) and a [published CLI](https://github.com/dnitsch/reststrategy/releases) which functions in a similar way for REST calls. Always prefer to use that for any kind of configuration/data seeding where possible!\n\n## Features\n\nThe program splits the instructions into a top level slice which includes a navigation to a part of the app where it will include all the actions against the elements present. \n\nIt will go through all of them in sequence as they are defined in the YAML.\n\nCurrently all the actions are performed against a single instance of the logged in page. for larger systems where order isn't important separate instances of the CLI can be triggered. \n\n- Authentication\n  - optional authentication\n    - supply username/password/submit elements - see [test/integration.yml](./test/integration.yml) for an example.\n- Driving UI\n  - page Navigation\n  - element lookups using a selector either a CSS Style selector or XPath\n    - CSSSelector will be tried first and then XPath\n  - actions on element currently input + click/swipe\n        - would be nice to include double click/right click, etc...\n- Report\n  - report with all steps\n  - screenshots on errors attached to the step.\n  - report.json - can be used in an HTML template creation, additionally JUnit or any other kind of format  can be parsed from that base.\n- [ConfigManager](https://github.com/dnitsch/configmanager) integrated for easy storage of secrets in YMLs that can be committed - see this [example](./test/integration-with-configmanager.yml) of a password for auth.\n\nAs this is still in *beta* expect bugs and the interface to change. \n\n\u003eImprovement/Feature:\n\n- accept multiple yaml docs and run them in parallel.\n- allow composing of complete strategies from multiple YAML documents - AVOID 1k+ YAML lines\n\n## Configuration\n\n### `setup`\n\nTop level config item to initiate a webBrowser session\n\n#### `baseUrl`\n\nmust be provided acts as a baseUrl for all navigations, including login.\n  \n#### `continueOnError`\n\nDefault: false\n\nWill stop execution if an error occurs, useful to set this to \n  true if a large execution sequence \n\n### `auth`\n\n... \n\n### `actions`\n\nIs a list of actions to execute - the order in which they are provided. \n\nSingle `action` block has the below structure, at this level the action is only a navigation action/view action. it can contain 0 or more `elementActions`\n\n#### `name` (required)\n\nName of the view action - will be used in reports\n\n#### `navigate` (required)\n\nThe path to append to the baseUrl to navigate to perform actions against elements on that page.\n\n\u003enavigate string is appended to the baseUrl without any slashes - ensure you either specify the baseUrl with a trailing slash or all your `navigate`s should include a preceeding slash.\n\n#### `iframe` (optional)\n\nobject with following properties. when the actions you want to perform on that page/view are within an iframe it must be specifed here\n\n##### `selector`\n\nthe selector for the iframe - using either CSS or Xpath e.g.: `(//*/iframe)[1]` - i.e. give me the first iframe on the page\n\n##### `waitEval`\n\noftentimes older apps (e.g. timesheet portals :wink: ) include iframes and they are often loaded slower to avoid losing the context, specify the eval to wait for contents inside the iframe. \n\nthis could be a `myVar !== null` - more info in the godoc or below.\n\n```go\n// IframeAction \ntype IframeAction struct {\n  Selector string `yaml:\"selector,omitempty\" json:\"selector,omitempty\"`\n  // WaitEval has to be in the form of a boolean return\n  // e.g. `myVar !== null` or `(myVar !== null || document.title == \"ready\")`\n  // the supplied value will be appended to an existing\n  // `return document.readyState === 'complete' \u0026\u0026 ${WaitEval};`\n  WaitEval string `yaml:\"waitEval,omitempty\" json:\"waitEval,omitempty\"`\n}\n```\n\n#### `elementActions`\n\nlist of actions to perform within the page/view, each `elementAction` has the following structure\n\n#### `name` (required)\n\nName of the action on the element - will be used in reports\n\n#### `element` (required)\n\nthe element to identifier - an object with below attrs\n\n##### `selector` (required)\n\nCSS or XPath style selector to attempt to locate the element on the page.\n\nif not found and running `continueOnError` mode the execution will move on to the next element in the sequence.\n\n##### `value` (optional)\n\nif value is not provided it will be a click type action, if value is provided it will be an input type action\n\n##### `assert` (bool)\n\nDefaults to false.\n\nWhen running in UI test mode only this should be set to true...\n\nWhen set to true elements presence is only asserted and any input/click actions will be skipped.\n\n## Usage\n\nDownload the correct binary for your architecture - [instructions](./docs/installation.md)\n\n`uiseeder -h` for help\n\n`uiseeder -i path/to/yaml -v`\n\nSee test/integration.yml for an [example with auth](#with-auth) you can use with pocketbase.io.\n\n## Internals\n\nCurrently the entire loop through of Actions is using pointers to allow for an easier report builder output - adding concurency via go routines may be problematic and is not really desired at this point.\n\n### Underlying Web Driver\n\nThis module and CLI use the [Go-Rod](https://github.com/go-rod/rod) which uses the CPD protocol.\n\n## Example\n\n### With Auth\n\nMost scenarios for UI tests will require a login of sorts, for easy simulation of how this \n\nTo run integration style tests you must have the sample app running, you can run it docker locally.\n\n`docker run --name=pb-app --detach -p 8090:8090 dnitsch/reststrategy-sample:latest`\n\nThen navigate to this [page](http://127.0.0.1:8090/_/?installer#)\n\nAdd you user name and password and replace it in the YAML with whatever you chose.\n\nExplore any parts of the app and grab elements by XPath or CSS and add new page or element actions within a page.\n\n## Help\n\nalways wanted and welcomed\n\n- Still TODO lots more tests\n- report formats and outcomes need fixing up\n- any current/new features...","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlabfoundry%2Fuistrategy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevlabfoundry%2Fuistrategy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlabfoundry%2Fuistrategy/lists"}