aurum: re-arrange files and add guide & scripts for TV 77/263077/7 accepted/tizen/6.5/unified/20211028.113644 accepted/tizen/unified/20210901.050233 submit/tizen/20210831.022718 submit/tizen_6.5/20211028.163101 tizen_6.5.m2_release
authorWoochanlee <wc0917.lee@samsung.com>
Wed, 25 Aug 2021 11:46:48 +0000 (20:46 +0900)
committerWoochanlee <wc0917.lee@samsung.com>
Mon, 30 Aug 2021 06:22:11 +0000 (15:22 +0900)
Change-Id: Ibdc2684cfcc984fabf7f02a80143abb2cf2b3c88

32 files changed:
README.md [new file with mode: 0644]
protocol/misc/down_grpc.sh [moved from misc/down_grpc.sh with 100% similarity]
protocol/misc/env.sh [moved from misc/env.sh with 100% similarity]
protocol/misc/setup_device.sh [moved from misc/setup_device.sh with 100% similarity]
protocol/resources/node/README [moved from protocol/examples/node/README with 100% similarity]
protocol/resources/node/client.js [moved from protocol/examples/node/client.js with 100% similarity]
protocol/resources/node/gen.sh [moved from protocol/examples/node/gen.sh with 100% similarity]
protocol/resources/node/package-lock.json [moved from protocol/examples/node/package-lock.json with 100% similarity]
protocol/resources/node/package.json [moved from protocol/examples/node/package.json with 100% similarity]
protocol/resources/python/README [moved from protocol/examples/python/README with 67% similarity]
protocol/resources/python/gen.sh [moved from protocol/examples/python/gen.sh with 100% similarity]
protocol/resources/python/legacySamples/org.tizen.uicomponents.arm.tpk [moved from protocol/examples/python/org.tizen.uicomponents.arm.tpk with 100% similarity]
protocol/resources/python/legacySamples/sample01.py [moved from protocol/examples/python/legacySamples/sample01.py with 100% similarity]
protocol/resources/python/legacySamples/sample02.py [moved from protocol/examples/python/legacySamples/sample02.py with 100% similarity]
protocol/resources/python/legacySamples/sample03.py [moved from protocol/examples/python/legacySamples/sample03.py with 100% similarity]
protocol/resources/python/legacySamples/sample04.py [moved from protocol/examples/python/legacySamples/sample04.py with 100% similarity]
protocol/resources/python/legacySamples/sample05.py [moved from protocol/examples/python/legacySamples/sample05.py with 100% similarity]
protocol/resources/python/legacySamples/testFeatures.py [moved from protocol/examples/python/testFeatures.py with 100% similarity]
protocol/resources/python/legacySamples/testInternal.py [moved from protocol/examples/python/testInternal.py with 100% similarity]
protocol/resources/python/mobile/NUITizenGallery/NUITizenGallery.py [new file with mode: 0644]
protocol/resources/python/mobile/NUITizenGallery/org.tizen.example.NUITizenGallery-1.0.0.tpk [new file with mode: 0644]
protocol/resources/python/mobile/mobileDemoTest/mobileDemoTest.py [moved from protocol/examples/python/mobileDemoTestTM1/mobileDemoTest.py with 98% similarity]
protocol/resources/python/mobile/mobileDemoTest/org.tizen.elm-demo-tizen-mobile-0.2-1.armv7l.rpm [moved from protocol/examples/python/mobileDemoTestTM1/org.tizen.elm-demo-tizen-mobile-0.2-1.armv7l.rpm with 100% similarity]
protocol/resources/python/mobile/mobileSetup.py [new file with mode: 0644]
protocol/resources/python/requirements.txt [moved from protocol/examples/python/requirements.txt with 100% similarity]
protocol/resources/python/tv/NUITizenGalleryTV/NUITizenGalleryTV.py [new file with mode: 0644]
protocol/resources/python/tv/NUITizenGalleryTV/org.tizen.example.NUITizenGallery-1.0.0.tpk [new file with mode: 0644]
protocol/resources/python/tv/multiView.py [new file with mode: 0644]
protocol/resources/python/tv/searchAll.py [new file with mode: 0644]
protocol/resources/python/tv/tvSetup.py [new file with mode: 0644]
ui_automation/python/mobile/README [new file with mode: 0644]
ui_automation/python/tv/README [new file with mode: 0644]

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..24895ec
--- /dev/null
+++ b/README.md
@@ -0,0 +1,52 @@
+# AURUM(Tizen UI Automator)
+- Aurum is a UI automation framework without UI Toolkit dependency.
+
+  Provides Commands to interact with the device¡¯s UI by simulation user actions and introspection of the screen content.
+
+  It relies on the platform accessibility APIs to introspect the screen.
+
+- User can use the IDL defined in Proto to create an automation app or script in a variety of languages without a language dependency.
+
+  [List of Supported Command With Python Example](https://code.sec.samsung.net/confluence/pages/viewpage.action?pageId=212993496)
+
+
+### Running on TV
+- Pre-condition
+
+  The TV device and Host PC should be already connected through SDB
+
+- Gets Aurum latest version and checkout to tizen branch
+
+  [Aurum Github](https://github.sec.samsung.net/tizen/aurum)
+
+- Set up a python virtual environment and run UI Automation (working directory: aurum/)
+
+  (host) cd ui_automation/python/tv
+
+  #### Create virtual env
+  (host) python3 -m venv v
+
+  #### Activate a virtual env
+  Linux
+  (host) source v/bin/activate
+  Window
+  (host) v/Scripts/activate.bat
+
+  #### Install required pkg (only once)
+  (python_virtual) pip3 install -r ../../../protocol/resources/python/requirements.txt
+
+  #### Generate aurum.proto file for python (only once)
+  (python_virtual) python3 -m grpc_tools.protoc --python_out=./ --grpc_python_out=./ -I ./../../../protocol/ ../../../protocol/aurum.proto
+
+  #### Target setup such as sdb forward, bootstrap execution
+  (python_virtual) python3 ../../../protocol/resources/python/tv/tvSetup.py
+
+  #### Then Run your test script (Please refer sample scripts in 'aurum/protocol/resources/python/tv')
+  (python_virtual) python3 myTest.py
+
+  #### Deactivate a virtual env
+  (python_virtual) deactivate
+
+### Reference and Tip
+- [How to run aurum on TM1](https://code.sec.samsung.net/confluence/display/GFX/04.+NUITizenGallery+Test+Script+Guide)
+
similarity index 100%
rename from misc/down_grpc.sh
rename to protocol/misc/down_grpc.sh
similarity index 100%
rename from misc/env.sh
rename to protocol/misc/env.sh
similarity index 67%
rename from protocol/examples/python/README
rename to protocol/resources/python/README
index 5761fd1..3721f1d 100644 (file)
@@ -1,3 +1,5 @@
+* test python script must be in same location as aurum_pb2.py
+
 ```sh
 
 python3 -m venv v
 ```sh
 
 python3 -m venv v
diff --git a/protocol/resources/python/mobile/NUITizenGallery/NUITizenGallery.py b/protocol/resources/python/mobile/NUITizenGallery/NUITizenGallery.py
new file mode 100644 (file)
index 0000000..3db24ab
--- /dev/null
@@ -0,0 +1,140 @@
+from __future__ import print_function
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(os.path.dirname(__file__)))))
+from aurum_pb2 import *
+from aurum_pb2_grpc import BootstrapStub
+import logging
+import grpc
+import time
+
+# Check the object in the screen(TM1) or not
+def inScreen(size):
+    if size.x < 0: return False
+    if size.y < 0: return False
+    if size.x >= 720: return False
+    if size.y >= 1280: return False
+    return True
+
+# 1. Find TextField(entry)
+# 2. Set Text as Picker
+# 3. Click Run button
+# 4. Find PickerTest1 item on the result list
+# 5. Find 'Black' textlabel on the layout
+def PickerExecuteTestWithText(stub):
+    # 1
+    response = stub.findElement(ReqFindElement(widgetType='TextField'))
+    if len(response.elements) <= 0: return False
+    # 2
+    targetObj = response.elements[0].elementId
+    testString = 'Picker'
+    stub.setValue(ReqSetValue(elementId=targetObj, stringValue=testString))
+    # 3
+    response = stub.findElement(ReqFindElement(textField='Run'))
+    if len(response.elements) <= 0: return False
+    targetObj = response.elements[0].elementId
+    stub.click(ReqClick(type='ELEMENTID', elementId=targetObj))
+    # 4
+    response = stub.findElement(ReqFindElement(textField='PickerTest1'))
+    if len(response.elements) <= 0: return False
+    targetObj = response.elements[0].elementId
+    stub.click(ReqClick(type='ELEMENTID', elementId=targetObj))
+    # 5
+    response = stub.findElement(ReqFindElement(textField='Black'))
+    if len(response.elements) <= 0: return False
+
+    return True
+
+# 1. Find PickerTest1 item on the list
+# 2. Click PickerTest1 item
+# 3. Find 'Black' textlabel on the layout
+def PickerExecuteTest(stub):
+    for tryCnt in range(10):
+        # 1
+        stub.flick(ReqFlick(startPoint=Point(x=300, y=750), endPoint=Point(x=300, y=200), durationMs=150))
+        response = stub.findElement(ReqFindElement(textField='PickerTest1'))
+        if len(response.elements) <= 0: continue
+        targetObj = response.elements[0].elementId
+        response = stub.getSize(ReqGetSize(elementId=targetObj))
+        if inScreen(response.size):
+            # 2
+            stub.click(ReqClick(type='ELEMENTID', elementId=targetObj))
+            break
+
+    # 3
+    response = stub.findElement(ReqFindElement(textField='Black'))
+    if len(response.elements) <= 0: return False
+    return True
+
+# 1. Find PickerScroller(Picker's internal scroller)
+# 2. Find 'Black' textlabel on the layout
+# 3. Get PickerScroller geometry value for flick event
+# 4. Check the loop works well while changing the picker item by flick event
+def PickerScrollTest(stub):
+    # 1
+    response = stub.findElement(ReqFindElement(widgetType='PickerScroller'))
+    if len(response.elements) <= 0: return False
+    # 2
+    responseText = stub.findElement(ReqFindElement(textField='Black'))
+    if len(response.elements) <= 0: return False
+    # 3
+    pickerCenterX = response.elements[0].geometry.x + (response.elements[0].geometry.width / 2)
+    pickerCenterY = response.elements[0].geometry.y + (response.elements[0].geometry.height / 2)
+
+    for tryCnt in range(30):
+        # 4
+        stub.flick(ReqFlick(startPoint=Point(x=int(pickerCenterX), y=int(pickerCenterY)), endPoint=Point(x=int(pickerCenterX), y=int(pickerCenterY-70)), durationMs=100))
+        response = stub.findElement(ReqFindElement(textField='Black'))
+        if len(response.elements) > 0:
+            if response.elements[0].elementId == responseText.elements[0].elementId:
+                return True
+
+    return False
+
+# Launch application. it returns application running state
+def launchAppTest(stub):
+    stub.launchApp(ReqLaunchApp(packageName='org.tizen.example.NUITizenGallery'))
+    return stub.getAppInfo(ReqGetAppInfo(packageName='org.tizen.example.NUITizenGallery')).isRunning
+
+# Close application. it returns application running state
+def closeAppTest(stub):
+    stub.closeApp(ReqCloseApp(packageName='org.tizen.example.NUITizenGallery'))
+    return stub.getAppInfo(ReqGetAppInfo(packageName='org.tizen.example.NUITizenGallery')).isRunning != True
+
+def defaultSetup(stub):
+    if stub.getAppInfo(ReqGetAppInfo(packageName='org.tizen.example.NUITizenGallery')).isRunning:
+        stub.closeApp(ReqCloseApp(packageName='org.tizen.example.NUITizenGallery'))
+
+    stub.launchApp(ReqLaunchApp(packageName='org.tizen.example.NUITizenGallery'))
+
+def defaultTearDown(stub):
+    stub.closeApp(ReqCloseApp(packageName='org.tizen.example.NUITizenGallery'))
+
+def runTest(stub, testFunc, setup=defaultSetup, tearDown=defaultTearDown, alwaySucceed=False):
+    print("Testing started :", testFunc)
+
+    setup(stub)
+    result = testFunc(stub)
+    tearDown(stub)
+
+    print("Testing result :", result)
+    if alwaySucceed: return True
+
+def runTestWithoutSetupAndTearDown(stub, testFunc, setup=defaultSetup, tearDown=defaultTearDown):
+    def Empty(stub):
+        pass
+
+    runTest(stub, testFunc, Empty, Empty)
+
+def run():
+    with grpc.insecure_channel('127.0.0.1:50051') as channel:
+        stub = BootstrapStub(channel)
+        # Picker Test
+        runTestWithoutSetupAndTearDown(stub, launchAppTest)
+        runTestWithoutSetupAndTearDown(stub, PickerExecuteTestWithText)
+        runTestWithoutSetupAndTearDown(stub, PickerScrollTest)
+        runTestWithoutSetupAndTearDown(stub, closeAppTest)
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    run()
diff --git a/protocol/resources/python/mobile/NUITizenGallery/org.tizen.example.NUITizenGallery-1.0.0.tpk b/protocol/resources/python/mobile/NUITizenGallery/org.tizen.example.NUITizenGallery-1.0.0.tpk
new file mode 100644 (file)
index 0000000..d530fbd
Binary files /dev/null and b/protocol/resources/python/mobile/NUITizenGallery/org.tizen.example.NUITizenGallery-1.0.0.tpk differ
@@ -1,4 +1,8 @@
 from __future__ import print_function
 from __future__ import print_function
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(os.path.dirname(__file__)))))
+from __future__ import print_function
 from aurum_pb2 import *
 from aurum_pb2_grpc import BootstrapStub
 import logging
 from aurum_pb2 import *
 from aurum_pb2_grpc import BootstrapStub
 import logging
diff --git a/protocol/resources/python/mobile/mobileSetup.py b/protocol/resources/python/mobile/mobileSetup.py
new file mode 100644 (file)
index 0000000..ca22373
--- /dev/null
@@ -0,0 +1,16 @@
+import os
+import subprocess
+import re
+import sys
+import time
+
+def run_command(command):
+    stream = os.popen(command)
+    output = stream.read()
+
+# Start scrip here
+run_command("sdb root on")
+run_command("sdb forward tcp:50051 tcp:50051")
+run_command("sdb shell app_launcher -s org.tizen.aurum-bootstrap")
+# Wait 1 sec till bootstrap launched
+time.sleep(1)
diff --git a/protocol/resources/python/tv/NUITizenGalleryTV/NUITizenGalleryTV.py b/protocol/resources/python/tv/NUITizenGalleryTV/NUITizenGalleryTV.py
new file mode 100644 (file)
index 0000000..304ffa8
--- /dev/null
@@ -0,0 +1,142 @@
+from __future__ import print_function
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(os.path.dirname(__file__)))))
+from aurum_pb2 import *
+from aurum_pb2_grpc import BootstrapStub
+import logging
+import grpc
+import time
+
+# Check the object in the screen(TV) or not
+def inScreen(size):
+    if size.x < 0: return False
+    if size.y < 0: return False
+    if size.x >= 1920: return False
+    if size.y >= 1080: return False
+    return True
+
+# 1. Find TextField(entry)
+# 2. Set Text as Picker
+# 3. Click Run button
+# 4. Find PickerTest1 item on the result list
+# 5. Find 'Black' textlabel on the layout
+def PickerExecuteTestWithText(stub):
+    # 1
+    response = stub.findElement(ReqFindElement(widgetType='TextField'))
+    if len(response.elements) <= 0: return False
+    # 2
+    targetObj = response.elements[0].elementId
+    testString = 'Picker'
+    stub.setValue(ReqSetValue(elementId=targetObj, stringValue=testString))
+    # 3
+    response = stub.findElement(ReqFindElement(textField='Run'))
+    if len(response.elements) <= 0: return False
+    targetObj = response.elements[0].elementId
+    stub.click(ReqClick(type='ELEMENTID', elementId=targetObj))
+    # 4
+    response = stub.findElement(ReqFindElement(textField='PickerTest1'))
+    if len(response.elements) <= 0: return False
+    targetObj = response.elements[0].elementId
+    stub.click(ReqClick(type='ELEMENTID', elementId=targetObj))
+    # 5
+    response = stub.findElement(ReqFindElement(textField='Black'))
+    if len(response.elements) <= 0: return False
+
+    return True
+
+# 1. Find PickerTest1 item on the list
+# 2. Click PickerTest1 item
+# 3. Find 'Black' textlabel on the layout
+def PickerExecuteTest(stub):
+    for tryCnt in range(10):
+        # 1
+        stub.flick(ReqFlick(startPoint=Point(x=300, y=750), endPoint=Point(x=300, y=200), durationMs=150))
+        response = stub.findElement(ReqFindElement(textField='PickerTest1'))
+        if len(response.elements) <= 0: continue
+        targetObj = response.elements[0].elementId
+        response = stub.getSize(ReqGetSize(elementId=targetObj))
+        if inScreen(response.size):
+            # 2
+            stub.click(ReqClick(type='ELEMENTID', elementId=targetObj))
+            break
+
+    # 3
+    response = stub.findElement(ReqFindElement(textField='Black'))
+    if len(response.elements) <= 0: return False
+    return True
+
+# 1. Find PickerScroller(Picker's internal scroller)
+# 2. Find 'Black' textlabel on the layout
+# 3. Get PickerScroller geometry value for flick event
+# 4. Check the loop works well while changing the picker item by flick event
+def PickerScrollTest(stub):
+    # 1
+    response = stub.findElement(ReqFindElement(widgetType='PickerScroller'))
+    if len(response.elements) <= 0: return False
+    # 2
+    responseText = stub.findElement(ReqFindElement(textField='Black'))
+    if len(response.elements) <= 0: return False
+    # 3
+    pickerCenterX = response.elements[0].geometry.x + (response.elements[0].geometry.width / 2)
+    pickerCenterY = response.elements[0].geometry.y + (response.elements[0].geometry.height / 2)
+
+    for tryCnt in range(30):
+        # 4
+        stub.flick(ReqFlick(startPoint=Point(x=int(pickerCenterX), y=int(pickerCenterY)), endPoint=Point(x=int(pickerCenterX), y=int(pickerCenterY-70)), durationMs=100))
+        # Wait until view update
+        time.sleep(0.3)
+        response = stub.findElement(ReqFindElement(textField='Black'))
+        if len(response.elements) > 0:
+            if response.elements[0].elementId == responseText.elements[0].elementId:
+                return True
+
+    return False
+
+# Launch application. it returns application running state
+def launchAppTest(stub):
+    stub.launchApp(ReqLaunchApp(packageName='org.tizen.example.NUITizenGallery'))
+    return stub.getAppInfo(ReqGetAppInfo(packageName='org.tizen.example.NUITizenGallery')).isRunning
+
+# Close application. it returns application running state
+def closeAppTest(stub):
+    stub.closeApp(ReqCloseApp(packageName='org.tizen.example.NUITizenGallery'))
+    return stub.getAppInfo(ReqGetAppInfo(packageName='org.tizen.example.NUITizenGallery')).isRunning != True
+
+def defaultSetup(stub):
+    if stub.getAppInfo(ReqGetAppInfo(packageName='org.tizen.example.NUITizenGallery')).isRunning:
+        stub.closeApp(ReqCloseApp(packageName='org.tizen.example.NUITizenGallery'))
+
+    stub.launchApp(ReqLaunchApp(packageName='org.tizen.example.NUITizenGallery'))
+
+def defaultTearDown(stub):
+    stub.closeApp(ReqCloseApp(packageName='org.tizen.example.NUITizenGallery'))
+
+def runTest(stub, testFunc, setup=defaultSetup, tearDown=defaultTearDown, alwaySucceed=False):
+    print("Testing started :", testFunc)
+
+    setup(stub)
+    result = testFunc(stub)
+    tearDown(stub)
+
+    print("Testing result :", result)
+    if alwaySucceed: return True
+
+def runTestWithoutSetupAndTearDown(stub, testFunc, setup=defaultSetup, tearDown=defaultTearDown):
+    def Empty(stub):
+        pass
+
+    runTest(stub, testFunc, Empty, Empty)
+
+def run():
+    with grpc.insecure_channel('127.0.0.1:50051') as channel:
+        stub = BootstrapStub(channel)
+        # Picker Test
+        runTestWithoutSetupAndTearDown(stub, launchAppTest)
+        runTestWithoutSetupAndTearDown(stub, PickerExecuteTestWithText)
+        runTestWithoutSetupAndTearDown(stub, PickerScrollTest)
+        runTestWithoutSetupAndTearDown(stub, closeAppTest)
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    run()
diff --git a/protocol/resources/python/tv/NUITizenGalleryTV/org.tizen.example.NUITizenGallery-1.0.0.tpk b/protocol/resources/python/tv/NUITizenGalleryTV/org.tizen.example.NUITizenGallery-1.0.0.tpk
new file mode 100644 (file)
index 0000000..d530fbd
Binary files /dev/null and b/protocol/resources/python/tv/NUITizenGalleryTV/org.tizen.example.NUITizenGallery-1.0.0.tpk differ
diff --git a/protocol/resources/python/tv/multiView.py b/protocol/resources/python/tv/multiView.py
new file mode 100644 (file)
index 0000000..a6f2a9a
--- /dev/null
@@ -0,0 +1,82 @@
+from __future__ import print_function
+import os
+import sys
+sys.path.append(os.path.abspath(os.path.dirname(os.path.dirname(__file__))))
+from aurum_pb2 import *
+from aurum_pb2_grpc import BootstrapStub
+import logging
+import grpc
+import time
+
+# Second view size change and check
+# Please refer key codes below page
+# https://code.sec.samsung.net/confluence/display/GFX/VD+Key+Code+Table
+def MultiViewSizeTest(stub):
+    response = stub.findElement(ReqFindElement(textField='VSComponent2'))
+    if len(response.elements) <= 0: return False
+
+    responseGuide = stub.findElement(ReqFindElement(textField='Guide TextBox'))
+    if len(response.elements) <= 0:
+        stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Return'))
+
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Right'))
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Up'))
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Return'))
+    # Wait until render finished
+    time.sleep(1)
+
+    responseAfter = stub.findElement(ReqFindElement(textField='VSComponent2'))
+    if len(responseAfter.elements) <= 0: return False
+
+    if response.elements[0].geometry.width < responseAfter.elements[0].geometry.width:
+        return True
+
+    return False
+
+# Launch 3rd-party app and long press back key test
+def MultiViewContentsTest(stub):
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Return'))
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Left'))
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Up'))
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='Return'))
+    # Wait until render finished
+    time.sleep(10)
+
+    # It fails if there is a View
+    response= stub.findElement(ReqFindElement(textField='VSComponent2'))
+    if len(response.elements) > 0: return False
+
+    stub.sendKey(ReqKey(type='XF86', actionType='LONG_STROKE', XF86keyCode='XF86Back'))
+
+    return True
+
+# Launch application. it returns application running state
+def launchAppTest(stub):
+    stub.launchApp(ReqLaunchApp(packageName='com.samsung.tv.multiscreen'))
+    time.sleep(5)
+    return stub.getAppInfo(ReqGetAppInfo(packageName='com.samsung.tv.multiscreen')).isRunning
+
+# Close application. it returns application running state
+def closeAppTest(stub):
+    stub.closeApp(ReqCloseApp(packageName='com.samsung.tv.multiscreen'))
+    return stub.getAppInfo(ReqGetAppInfo(packageName='com.samsung.tv.multiscreen')).isRunning != True
+
+def runTest(stub, testFunc):
+    print("Testing started :", testFunc)
+
+    result = testFunc(stub)
+
+    print("Testing result :", result)
+    return True
+
+def run():
+    with grpc.insecure_channel('127.0.0.1:50051') as channel:
+        stub = BootstrapStub(channel)
+        runTest(stub, launchAppTest)
+        runTest(stub, MultiViewSizeTest)
+        runTest(stub, MultiViewContentsTest)
+        runTest(stub, closeAppTest)
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    run()
diff --git a/protocol/resources/python/tv/searchAll.py b/protocol/resources/python/tv/searchAll.py
new file mode 100644 (file)
index 0000000..4b9ccc3
--- /dev/null
@@ -0,0 +1,73 @@
+from __future__ import print_function
+import os
+import sys
+sys.path.append(os.path.abspath(os.path.dirname(os.path.dirname(__file__))))
+from aurum_pb2 import *
+from aurum_pb2_grpc import BootstrapStub
+import logging
+import grpc
+import time
+
+# Find TextField and input "Movie" text
+def SearchTestWithText(stub):
+    response = stub.findElement(ReqFindElement(widgetType='TextField'))
+    if len(response.elements) <= 0: return False
+    targetObj = response.elements[0].elementId
+    testString = 'Movie'
+    stub.setValue(ReqSetValue(elementId=targetObj, stringValue=testString))
+
+    # Wait until result upload
+    time.sleep(2)
+
+    return True
+
+# Find Foused item and move focus to right then compare focused item with previous one
+def SearchFocusedObject(stub):
+    response = stub.findElement(ReqFindElement(isFocused=True))
+    if len(response.elements) <= 0: return False
+
+    prevObj = response.elements[0].elementId
+    stub.sendKey(ReqKey(type='XF86', actionType='LONG_STROKE', XF86keyCode='Right'))
+    time.sleep(1)
+
+    response = stub.findElement(ReqFindElement(isFocused=True))
+    if len(response.elements) <= 0: return False
+
+    if prevObj != response.elements[0].elementId:
+        return True
+
+    return False
+
+
+# Launch application. it returns application running state
+def launchAppTest(stub):
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='XF86Search'))
+    # Wait until app launch
+    time.sleep(5)
+    return stub.getAppInfo(ReqGetAppInfo(packageName='com.samsung.tv.searchall')).isRunning
+
+# Close application. it returns application running state
+def closeAppTest(stub):
+    stub.sendKey(ReqKey(type='XF86', actionType='STROKE', XF86keyCode='XF86Exit'))
+    time.sleep(2)
+    return stub.getAppInfo(ReqGetAppInfo(packageName='com.samsung.tv.searchall')).isRunning != True
+
+def runTest(stub, testFunc):
+    print("Testing started :", testFunc)
+
+    result = testFunc(stub)
+
+    print("Testing result :", result)
+    return True
+
+def run():
+    with grpc.insecure_channel('127.0.0.1:50051') as channel:
+        stub = BootstrapStub(channel)
+        runTest(stub, launchAppTest)
+        runTest(stub, SearchTestWithText)
+        runTest(stub, SearchFocusedObject)
+        runTest(stub, closeAppTest)
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    run()
diff --git a/protocol/resources/python/tv/tvSetup.py b/protocol/resources/python/tv/tvSetup.py
new file mode 100644 (file)
index 0000000..a888f48
--- /dev/null
@@ -0,0 +1,22 @@
+import os
+import subprocess
+import re
+import sys
+import time
+
+def run_command(command):
+    stream = os.popen(command)
+    output = stream.read()
+
+# Start scrip here
+run_command("sdb root on")
+# To run bootstrap as command
+run_command("sdb shell tpk-backend -y org.tizen.aurum-bootstrap --preload")
+# TV need to enable touch
+run_command("sdb shell vconftool set -f -t bool memory/window_system/input/force_enable_touch 1")
+# Dut to input generator issue, temporarily do below command
+run_command("sdb shell winfo -init_device --type=touch")
+run_command("sdb forward tcp:50051 tcp:50051")
+run_command("sdb shell app_launcher -s org.tizen.aurum-bootstrap")
+# Wait 1 sec till bootstrap launched
+time.sleep(1)
diff --git a/ui_automation/python/mobile/README b/ui_automation/python/mobile/README
new file mode 100644 (file)
index 0000000..cb5146a
--- /dev/null
@@ -0,0 +1,9 @@
+python3 -m venv v
+
+source v/bin/activate
+
+pip3 install -r ../../../protocol/resources/python/requirements.txt
+
+python3 -m grpc_tools.protoc --python_out=./ --grpc_python_out=./ -I ./../../../protocol/ ../../../protocol/aurum.proto
+
+python3 ../../../protocol/resources/python/mobile/mobileSetup.py
diff --git a/ui_automation/python/tv/README b/ui_automation/python/tv/README
new file mode 100644 (file)
index 0000000..0048014
--- /dev/null
@@ -0,0 +1,9 @@
+python3 -m venv v
+
+source v/bin/activate
+
+pip3 install -r ../../../protocol/resources/python/requirements.txt
+
+python3 -m grpc_tools.protoc --python_out=./ --grpc_python_out=./ -I ./../../../protocol/ ../../../protocol/aurum.proto
+
+python3 ../../../protocol/resources/python/tv/tvSetup.py