{"id":22624683,"url":"https://github.com/barrettotte/dsl-5250","last_synced_at":"2025-03-29T03:17:01.375Z","repository":{"id":114090323,"uuid":"257456212","full_name":"barrettotte/DSL-5250","owner":"barrettotte","description":"A simple DSL for headless interaction with a 5250 emulator providing a method to automate IBM i display file testing.","archived":false,"fork":false,"pushed_at":"2021-05-03T16:55:13.000Z","size":182,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T13:13:24.359Z","etag":null,"topics":["5250","automation","dsl","groovy","ibmi"],"latest_commit_sha":null,"homepage":"","language":"Groovy","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/barrettotte.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":"2020-04-21T02:11:36.000Z","updated_at":"2022-01-27T14:20:37.000Z","dependencies_parsed_at":"2023-06-12T13:45:23.079Z","dependency_job_id":null,"html_url":"https://github.com/barrettotte/DSL-5250","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FDSL-5250","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FDSL-5250/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FDSL-5250/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FDSL-5250/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barrettotte","download_url":"https://codeload.github.com/barrettotte/DSL-5250/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246131335,"owners_count":20728303,"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":["5250","automation","dsl","groovy","ibmi"],"created_at":"2024-12-09T00:17:25.272Z","updated_at":"2025-03-29T03:17:01.353Z","avatar_url":"https://github.com/barrettotte.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DSL-5250\n\nA dummy's approach to making a simple DSL for headless interaction with a 5250 emulator.\n\n## Purpose\n\nThis project was used to reinforce my limited knowledge of Groovy and learn how to make a Domain Specific Language (DSL).\nAdditionally, 5250 emulator automation seemed like a fascinating topic to screw around with.\n\nPossible applications could be basic automated tasks/testing and general screen scraping.\n\nMy coworker ([Ryan Eberly](https://github.com/ryaneberly)) sparked the motivation for this project, he has an awesome 5250\ntesting project built around TN5250J called [Terminal Driver](https://github.com/terminaldriver/terminaldriver).\n\nI think I could have taken this project a lot further (this is a super shallow implementation), but for now I am satisfied with it; Time to move onto the next \"shiny\".\n\n## DSL Features\n\n* Get and set cursor position\n* Enter strings at position\n* Scrape screen for string or list of strings\n* Scrape screen contents to text file\n* Check screen position for string\n* Press command keys F1-F24 and other keys ENTER, TAB, ESCAPE, PAGEUP, PAGEDOWN, etc.\n\n## Setup\n\n* Download TN5250J jar and place in **libs/**\n\n## Example DSL\n\nA simple example to showcase various operations the DSL can perform\n```groovy\n  final config = new JsonSlurper().parse(new File(this.getClass().getResource('/config.json').toURI()))\n  final List\u003cString\u003e qrpgleMembers = []\n\n  Dsl5250.eval{\n    environment{\n      outputPath = 'out'\n      host = config['host']\n      user = config['user']\n      password = config['password']\n    }\n    stages{\n      stage('LOGIN'){\n        steps{env-\u003e\n          position 6,53\n          send env.user\n          capture()\n          position 7,53\n          send env.password,true  // true -\u003e masks text in log\n          press Key.ENTER\n          waitms 2500\n          if(check('Display Program Messages',1,28) || check('Display Messages',1,33)){\n            press Key.ENTER\n            waitms 1000\n          }\n          capture()\n          waitms 1000\n        }\n      }\n      stage('DSPLIBL'){\n        steps{\n          send 20,7,'DSPLIBL'\n          press Key.ENTER\n          waitms 1000\n          capture()        \n          cmd 12\n          waitms 1000\n        }\n      }\n      stage('EXTRACT'){\n        steps{\n          def system = extract(2,72,10) // testing extract method  (row, col, length)\n          println \"system - $system\"\n          position 20,7\n          send 'WRKMBRPDM BOLIB/QRPGLESRC'\n          press Key.ENTER\n          waitms 1000\n\n          while(!(check('You have reached the bottom of the list.',24,2))){\n            capture()\n            qrpgleMembers.addAll(extract(11,7,10,8).collect{i-\u003e i.replaceAll('\\\\s','')}.findAll{i-\u003e i.length() \u003e 0})\n            press Key.PG_DOWN\n            waitms 1000\n          }\n          cmd 3\n          waitms 1000\n        }\n      }\n      stage('LOGOFF'){\n        steps{\n          position 20,7\n          send 'SIGNOFF'\n          press Key.ENTER\n          waitms 1000\n          capture()\n        }\n      }\n    }\n  }\n  println 'BOLIB/QRPGLESRC\\n' + qrpgleMembers\n```\n\n## Approach\n\nI took a few other approaches before the current implementation, skim through them in [dev/approaches](dev/approaches). Here is the outline:\n1. JNA and EHLAPI32.dll - **failed**\n2. JRuby and EHLAPI32.dll - **failed**\n3. JNA and Win32 Programming - **barely worked...abandoned**\n4. TN5250J - **current**\n\n## Possible Enhancements\n\n* Set and get field by name\n* Smarter field traversing - next,prev,first,last\n* HOD macro generation\n* Image screenshots\n\n## Commands\n\n* clean build - ```gradlew clean shadowjar```\n* run - ```gradlew run```\n\n## References\n\n* [Groovy Domain Specific Languages](http://docs.groovy-lang.org/docs/latest/html/documentation/core-domain-specific-languages.html)\n* [Groovy DSL Builders](https://medium.com/@musketyr/groovy-dsl-builders-1-the-concept-2d5a97fa0a51)\n* [IBM Emulator Programming](https://www.ibm.com/support/knowledgecenter/SSEQ5Y_5.9.0/com.ibm.pcomm.doc/books/html/emulator_programming08.htm)\n* [IBM Introduction to Emulator APIs](https://www.ibm.com/support/knowledgecenter/SSEQ5Y_6.0.0/com.ibm.pcomm.doc/books/html/emulator_programming06.htm)\n* [JNA API Documentation](https://java-native-access.github.io/jna/4.2.1/overview-summary.html)\n* [Mockito Behavior](https://www.baeldung.com/mockito-behavior)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarrettotte%2Fdsl-5250","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarrettotte%2Fdsl-5250","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarrettotte%2Fdsl-5250/lists"}