{"id":13744126,"url":"https://github.com/Stray/RobotEyes","last_synced_at":"2025-05-09T02:32:41.139Z","repository":{"id":775648,"uuid":"462816","full_name":"Stray/RobotEyes","owner":"Stray","description":"UI end-to-end testing gubbins to use within test cases","archived":false,"fork":false,"pushed_at":"2010-12-08T18:28:18.000Z","size":663,"stargazers_count":49,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-15T15:42:10.035Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"ActionScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Stray.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-01-07T19:51:05.000Z","updated_at":"2021-12-17T15:34:53.000Z","dependencies_parsed_at":"2022-07-18T13:00:54.497Z","dependency_job_id":null,"html_url":"https://github.com/Stray/RobotEyes","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stray%2FRobotEyes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stray%2FRobotEyes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stray%2FRobotEyes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stray%2FRobotEyes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Stray","download_url":"https://codeload.github.com/Stray/RobotEyes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253177839,"owners_count":21866405,"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":[],"created_at":"2024-08-03T05:01:03.481Z","updated_at":"2025-05-09T02:32:40.812Z","avatar_url":"https://github.com/Stray.png","language":"ActionScript","funding_links":[],"categories":["Frameworks"],"sub_categories":["Unit Testing"],"readme":"## RobotEyes can help you end-to-end test your AS3 app\n\nInspired by a hybrid of WindowLicker (for Java) and Drew Bourne's Mockolate (for AS3).\n\nRobotEyes should really be called RobotEyes and RobotFingers. It's called RobotEyes because it was developed for RobotLegs... but then I removed all the RobotLegs dependencies. Ho hum.\n\nThe aim is to deliver end-to-end testing to AS3 applications.\n\nCurrently I'm only adding functionality as I actually need to make use of it, so feel free to fork and expand.\n\nFunctionality included in this version has been tested by incorporation in an end-to-end test of an application. It may well do unexpected things.\n\n## What's an end-to-end test?\n\nIn TDD speak (Test Driven Development), an end-to-end test is one that proves that your application carries out one of your user stories successfully.\n\nA good example would be that, given a certain viable user/password combination, when the login button is clicked the login procedure completes and whatever application state change is required occurs. Or - that given a blank username, clicking doesn't submit the details to the login service. Or - that given a crappy user/password combination, the login fails and the application handles this gracefully, with user feedback... you get the idea.\n\nEnd-to-end testing is different from Unit Testing and is additional to it - not a replacement for it. It aims to provide certainty that your actual application works, not just your individual classes, and, in doing so, it'll usually include coverage of any backend services as well.\n\n## How do I use RobotEyes?\n\nRobotEyes is designed to integrate with your Unit Testing framework - it was developed for ASUnit 3 but doesn't have any dependencies.\n\nThe idea is that you set your tests up to use RobotEyes as the user: both to visually verify that certain things appear how they should, and to enter text, press buttons, operate scrollers and so on. RobotEyes provides for this by supplying you with a driver wrapping your UIElements / Views.\n\nIf your test requires a TextField nested within a certain view you can grab a driver for that view using:\n\n\tvar textDriver:TextFieldDriver = inViewOf(LoginPanel).getA(TextField).named(\"username_txt\");\n\nThe TextFieldDriver provides some useful functions:\n\n\ttextDriver.enterText('User A');\n\t\n... this sets the text, but also fires the TextEvent.TEXT_INPUT event before, and the Event.CHANGE event after, just as if a real people type person had edited it.\n\nThen you can also use the TextFieldDriver.checkText('Blah') function in a test:\n\t\n\tassertTrue('TextField starts blank', (textDriver.(checkText(''))));\n\nIf you want to be specific about the view containing the view you're hooking into - for example, if you have a view that recurs in your app you can nest 'inViewOf' - start at the outside and work inward:\n\n\tvar textDriver:TextFieldDriver = inViewOf(StatsReportScreen).inViewOf(DateTimeWidget).getA(TextField).named(\"weekdayAbbreviation_txt\");\n\n## You can also:\n\n### Get an interactive object (in this case by specifying a property) and click it:\n\n\tvar buttonDriver:InteractiveObjectDriver = inViewOf(InterestingView).getA(Sprite).withProperty('name', 'btn_login');\n\tbuttonDriver.click();\n\nThis will dispatch a MouseEvent.CLICK from the button / sprite / whatever you specified.\n\nList of helpers for the InteractiveObjectDriver:\n\tclick();\n\tmouseOver();\n\tmouseOut();\n\tmouseDown();\n\tmouseUp();\n\trollOver();\n\trollOut();\n\n### Get a general view and check something about it:\n\n\tvar loginScreenDriver:DisplayObjectDriver = inViewOf(ShellContextView).getA(LoginPanel);\n\tvar loginScreen:DisplayObject = loginScreenDriver.view;\n\tassertTrue('LoginPanel is off screen', (loginScreen.y \u003c (-loginScreen.height)));\n\n### Count instances of a specific type - for example to check that the correct number of instances have been added to a list\n\n        var listHolderDriver:DisplayObjectDriver = inViewOf(SomeApp).getA(ListHolder);\n        assertEquals('Correct number of items added to the list', 8, listHolderDriver.countInstancesOf(ListItem));\n\n### TestCase Examples:\n\nTo use RobotEyes you need to grab an instance of it and tell it which class to use to start up your application.\nYou probably don't want to start your tests instantly - give the app a little room to breathe if it has async startup stuff.\n\nIn AsUnit 3 this is done with:\n\n\t// these are the really important RobotEyes classes\n\timport com.newloop.roboteyes.core.RobotEyes;\n\timport com.newloop.roboteyes.inViewOf;\n\n\t// grab any drivers that you need to use - currently there are only 3 but more to come...\n\timport com.newloop.roboteyes.drivers.DisplayObjectDriver;\n\timport com.newloop.roboteyes.drivers.InteractiveObjectDriver;\n\timport com.newloop.roboteyes.drivers.TextFieldDriver;\n\n\t// the main class for the app you want to test\n\timport com.client.app.AcademyShell;\n\n\tpublic class RobotEyesTest extends TestCase {\n\t\tprivate var robotEyes:RobotEyes;\n\n\t\tpublic function RobotEyesTest(methodName:String=null) {\n\t\t\tsuper(methodName)\n\t\t}\n\t\n\t\toverride public function run():void{\n\t\t\tif(robotEyes==null){\n\t\t\t\t// AcademyShell is the main class for this application (ie the one the compiler gets fed)\n\t\t\t\trobotEyes = new RobotEyes(AcademyShell);\n\t\t\t\taddChild(robotEyes);\n\t\t\t}\n\t\t\t// need to wait a while\n\t\t\tvar timer:Timer = new Timer(1000,1);\n\t\t\ttimer.addEventListener(TimerEvent.TIMER, timerHandler);\n\t\t\ttimer.start();\n\t\t}\n\t\n\t\t// we run the tests after a second has passed just to give the application a chance to step through any set up\n\t\tprivate function timerHandler(e:TimerEvent):void{\n\t\t\tsuper.run();\n\t\t}\n\t\n\t\t....   \n\t\nIn an end-to-end test you'll probably need to test some stuff asynchronously, and in ASUnit you'd do this by:\n\n  \t\tpublic function testEndToEndProcessPass():void{\n\t\t\tvar textFieldDriver:TextFieldDriver = inViewOf(ShellContextView).inViewOf(LoginPanel).getA(TextField).named(\"username_txt\") as TextFieldDriver;\n\t\t\ttextFieldDriver.enterText('Pass');\n\t\t\n\t\t\tvar buttonDriver:InteractiveObjectDriver = inViewOf(ShellContextView).inViewOf(LoginPanel).getA(Sprite).withProperty(\"name\", \"btn_login\") as InteractiveObjectDriver;\n\t   \t\n\t\t\t// we're going to wait 4 seconds for the dummy service to return, and the login screen to tween away before we test this\n\t\t\tvar asyncTest:Function = addAsync(null, 4000,loginShouldBeOffScreen);\n\t    \n\t\t    // simulate clicking the button\n\t\t\tbuttonDriver.click();\n\t\t}\n\t\n\t    public function loginShouldBeOffScreen(e:Event):void{\n\t\t\tvar loginScreenDriver:DisplayObjectDriver = inViewOf(ShellContextView).getA(LoginPanel);\n\t\t\tvar loginScreen:DisplayObject = loginScreenDriver.view;\n\t\t\tassertTrue('LoginPanel is off screen', (loginScreen.y \u003c (-loginScreen.height)));\n\t\t}\n    \n## What if I ask for something that doesn't exist?\n\nRobotEyes generally currently returns null whenever it can't find something. This will almost certainly then cause your test to throw a null pointer error, so first it will throw an Error with message: 'RobotEyes can't find an instance of [Class:WidgetView] inside [Object:SpiffingSectionView]'.\n\n## Get in touch\n\nFork, message me on git or email dailystraying@gmail.com. I'm @stray_and_ruby on twitter.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStray%2FRobotEyes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStray%2FRobotEyes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStray%2FRobotEyes/lists"}