This guide helps you implement and integrate poco-sdk with your game/app step by step.
Poco-sdk now supports following languages:
More language will come in future.
Getting Poco SDK¶
First clone the poco-sdk repo. Each languages are located in
git clone https://github.com/AirtestProject/Poco-SDK.git
You can just copy the source code of corresponding language to your project script folder.
Implement the Abstract Method¶
In your SDK, you need to implement several important functions to drive the entire SDK.
This function must be implemented. But, it is very simple to implement. The onlyVisibleNode argument is not required, but must receive an argument.
def Dump(onlyVisibleNode): return YourDumper().dumpHierarchy(onlyVisibleNode) # or like this def Dump(_): return YourDumper().dumpHierarchy()
If needed, can implement this function so that it can be called correctly in Poco. The return is a string of base64 encrypted strings and its format.
def Screenshot(self, width): return [base64.b64encode(YourAPI.GetScreenshot(width)), "bmp"]
Click, Swipe, LongClick¶
These functions are also required to make all of Poco’s features work.
Note that the form of the argument passed in is a percentage.If your API does not support this form of input, calculate the correct coordinates yourself.Just Like this
x = Left + Width * x,
y = Top + Height * y
def Click(self, x, y): # x = Left + Width * x # y = Top + Height * y YourAPI.Click(x, y) def Swipe(self, x1, y1, x2, y2, duration): YourAPI.Swipe(x1, y1, x2, y2, duration) def LongClick(self, x, y, duration): YourAPI.LongClick(x1, y1, x2, y2, duration)
Other optional functions are
GetSDKVersion, and if your Poco driver needs other functions, you can add it yourself.
Initialize poco-sdk after game launched¶
A variety of basic functions have been implemented, and the final step is to establish communication between the client and the server. Poco offers a simple RPC service, you can use it like below.
from poco.sdk.std.rpc.controller import StdRpcEndpointController from poco.sdk.std.rpc.reactor import StdRpcReactor from poco.utils.net.transport.tcp import TcpSocket reactor = StdRpcReactor() reactor.register('Dump', Dump) reactor.register('Screenshot', Screenshot) reactor.register('Click', Click) reactor.register('Swipe', Swipe) reactor.register('LongClick', LongClick) # If you have implemented other functions, don't forget to register it. transport = TcpSocket() transport.bind(("localhost", 15004)) # Listening to a port rpc = StdRpcEndpointController(transport, reactor) rpc.serve_forever() # Enable RPC listening service and listen for messages sent by the client.
You can use other RPC frameworks, but I would recommend using our Poco RPC framework.
Abstract Class/Interface Implementation¶
To implement your own version of poco sdk, you only need to implement the following 2 classes/interfaces and override its abstract method. This section shows the details about implementing the abstract method in classes or interfaces.
class YourNode(AbstractNode): def __init__(self, yourElement): self.Element = yourElement def getParent(self): pass def getChildren(self): pass def getAttr(self, attrName): pass def setAttr(self, attrName, val): pass # Can override this function if needed def getAvailableAttributeNames(self): pass class YourDumper(AbstractDumper): def __init__(self, root): pass def getRoot(self): pass
4 methods should be override
This function returns the parent of a node, so it is very simple to overwrite. According to your own API function, return a parent node.
def getParent(self): return YourNode(self.YourElement.GetParentElement)
This function returns an iterator of all child nodes of a node. It’s also very simple to implement, you can write a code similar to the following
def getChildren(self): Children = self.Element.GetChildren() for node in Children: yield YoueNode(node)
This function role is to return a property value of the node. So you have to return the corresponding property value based on the given argument.
def getAttr(self, attrName): if attrName == 'name': return self.Element.GetName() if attrName == 'type': return self.Element.GetType() if attrName == 'pos': return self.Element.GetPos() return super(YourNode, self).getAttr(attrName)
The attributes of
size are well defined, and you must return a value in the specified format. For more information, please read the comments in
The purpose of this function is to set an attribute. You can override this function as needed. Sometimes not all properties can be set. At this point you can throw the error appropriately.
def setAttr(self, attrName, val): if attrName == 'text': self.Element.SetText(val) if attrName == 'name': self.Element.SetName(val) raise UnableToSetAttributeException(attrName, self)
This function is optional. If your API provides more property access, you can override this function and add other properties.
def getAvailableAttributeNames(self): return super(YourNode, self).getAvailableAttributeNames() + ('yourNewattr1', 'yourNewattr2')
1 method should be override
You only need to override this function. This function is also very simple to implement, just return the root surface of the device. So, Poco can access the properties of all child elements through this root surface and your overloaded functhons
def getRoot(self): return YourNode(YourAPI.GetRootElement())