Is it possible to dor UI test of a desktop application using appium and python language? - appium

I am going to do UI automation tests for a desktop application using appium. My preference is using appium python client. However there are no python test samples for a desktop application and all the examples are dedicated for android or ios apps. And I don't really know how to start with my project without a sample code. Can anyone tell me, if it is possible to do UI automation tests for desktop apps in python. I would be greatful, if you would send me also a example link.

yes you can!
You will need to download and install WinAppDriver from here: https://github.com/Microsoft/WinAppDriver/releases and Developer mode will have to be enabled on your PC, this will tell you how: https://github.com/microsoft/WinAppDriver
You will also need to ensure that you are using Selenium at v3.141.0 and appium-python-client at v1.3.0
pip install selenium==3.141.0
pip install appium-python-client==1.3.0
You can run tests with or without Appium.
To run without make sure Appium is not running and try the following example (modified from https://github.com/microsoft/WinAppDriver/tree/master/Samples/Python):
import unittest
from appium import webdriver
import os
class SimpleCalculatorTests(unittest.TestCase):
#classmethod
def setUpClass(self):
# WinAppDriver can be run independently instead if required
os.startfile('C:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe')
#set up appium
desired_caps = {}
desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
desired_caps['platformName'] = "Windows"
self.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', desired_capabilities= desired_caps)
#classmethod
def tearDownClass(self):
self.driver.quit()
def getresults(self):
displaytext = self.driver.find_element_by_accessibility_id("CalculatorResults").text
displaytext = displaytext.strip("Display is " )
displaytext = displaytext.rstrip(' ')
displaytext = displaytext.lstrip(' ')
return displaytext
def test_initialize(self):
self.driver.find_element_by_name("Clear").click()
self.driver.find_element_by_name("Seven").click()
self.assertEqual(self.getresults(),"7")
self.driver.find_element_by_name("Clear").click()
def test_addition(self):
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("Plus").click()
self.driver.find_element_by_name("Seven").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"8")
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SimpleCalculatorTests)
unittest.TextTestRunner(verbosity=2).run(suite)
To run using Appium try the following example instead:
import unittest
from appium import webdriver
class SimpleCalculatorTests(unittest.TestCase):
#classmethod
def setUpClass(self):
#set up appium
desired_caps = {}
desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
desired_caps['platformName'] = "Windows"
#self.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities= desired_caps)
#classmethod
def tearDownClass(self):
self.driver.quit()
def getresults(self):
displaytext = self.driver.find_element_by_accessibility_id("CalculatorResults").text
displaytext = displaytext.strip("Display is " )
displaytext = displaytext.rstrip(' ')
displaytext = displaytext.lstrip(' ')
return displaytext
def test_initialize(self):
self.driver.find_element_by_name("Clear").click()
self.driver.find_element_by_name("Seven").click()
self.assertEqual(self.getresults(),"7")
self.driver.find_element_by_name("Clear").click()
def test_addition(self):
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("Plus").click()
self.driver.find_element_by_name("Seven").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"8")
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SimpleCalculatorTests)
unittest.TextTestRunner(verbosity=2).run(suite)

Related

How to monitor Python Application(without django or other framework) in instana

i have a simple python application without any framework and API calls.
how i will monitor python application on instana kubernates.
i want code snippet to add with python application ,which trace application
and display on instana
how i will monitor python application on instana kubernates
There is publicly available guide, that should help you setting up the kubernetes agent.
i have a simple python application without any framework and API calls
Well, instana is for distributed tracing, meaning distributed components calling each other, each other's APIs predominantly by using known frameworks (with registered spans).
Nevertheless, you could make use of SDKSpan, here is a super simple example:
import os
os.environ["INSTANA_TEST"] = "true"
import instana
import opentracing.ext.tags as ext
from instana.singletons import get_tracer
from instana.util.traceutils import get_active_tracer
def foo():
tracer = get_active_tracer()
with tracer.start_active_span(
operation_name="foo_op",
child_of=tracer.active_span
) as foo_scope:
foo_scope.span.set_tag(ext.SPAN_KIND, "exit")
result = 20 + 1
foo_scope.span.set_tag("result", result)
return result
def main():
tracer = get_tracer()
with tracer.start_active_span(operation_name="main_op") as main_scope:
main_scope.span.set_tag(ext.SPAN_KIND, "entry")
answer = foo() + 21
main_scope.span.set_tag("answer", answer)
if __name__ == '__main__':
main()
spans = get_tracer().recorder.queued_spans()
print('\nRecorded Spans and their IDs:',
*[(index,
span.s,
span.data['sdk']['name'],
dict(span.data['sdk']['custom']['tags']),
) for index, span in enumerate(spans)],
sep='\n')
This should work in any environment, even without an agent and should give you an output like this:
Recorded Spans and their IDs:
(0, 'ab3af60079f3ca57', 'foo_op', {'span.kind': 'exit', 'result': 21})
(1, '53b67f7298684cb7', 'main_op', {'span.kind': 'entry', 'answer': 42})
Of course in a production, you wouldn't want to print the recorded spans, but send it to the well configured agent, so you should remove setting the INSTANA_TEST.

How to record screen while testing in Robot framework Appium?

I'm looking the way how to record screen on Robot framework Appium.I've check on Appium Robot Framework Doc but it doesn't describe about it but i have try to write custom lib with python but it's doesn't support.
import os
import subprocess
from appium import webdriver
from robot.api import logger
desired_caps = {}
desired_caps['platformName'] = 'iOS'
desired_caps['platformVersion'] = '12.3.2'
desired_caps['bundleId'] = 'xxxxxx'
desired_caps['udid'] = 'xxxxxxx'
desired_caps['deviceName'] = 'iPhone'
driver = webdriver.Remote("http://localhost:4723/wd/hub",desired_caps)
def start_screen_recording():
driver.start_recording_screen()
def stop_screen_recording():
filepath = os.path.join("/Users/keo.sidara/Desktop/Mobile_Test/testcases/regression", "screen_recording_110918-205655.mp4")
warning_message(filepath)
payload = driver.stop_recording_screen()
with open(filepath, "wb") as fd:
fd.write(base64.b64decode(payload))
and i got message
[W3C] Matched W3C error code 'invalid session id' to NoSuchDriverError
[W3C (1530275d)] Encountered internal error running command:
NoSuchDriverError:
Anybody experience with it ? please share me. Thanks
The Appium documentation on the start Recording method is here.
In the AppliumLibrary documentation the source code for keyword Open Application shows that the keyword returns number of the application in the registry.
This means that there is no AppiumLibrary supported way of retrieving the webdriver. This means that a modification to the original library is needed. This has been done already in a fork: nichotined / robotframework-appiumlibrary
Removing the original library from your python installation and installing this one, you then have access to the keyword Get Current Application that returns the driver. Now, you can use the below approach or add another keyword yourself in the same fashion to create the custom Start and Stop Screenrecording.
As I don't have a working Appium Setup, I'm unable to validate this myself:
*** Settings ***
Library AppiumLibrary
*** Test Cases ***
Open Application
... http://localhost:4723/wd/hub
... alias=Myapp1
... platformName=iOS
... platformVersion=7.0
... deviceName='iPhone Simulator'
... app=your.app
${driver} Get Current Application
Call Method ${driver} start_recording_screen
As of robotframework-appiumlibrary v1.5.0.6, support for screen recording has been implemented. Can check https://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html#Start%20Screen%20Recording.
Happy Coding!
I've never used Robot Framework before but I tried a lot of ways to record with the appium driver but I couldn't get it working. The only solution that I found was to use ADB SHELL Commands to record the screen of a device. You should have in mind that not all devices are capable of getting their screen recorded.
adb shell screenrecord /sdcard/test.mp4 --size 480x720 #To start recording
Once you kill the process above you can get the video from the device with these commands
adb pull /sdcard/test.mp4 "C:/"
adb shell rm /sdcard/test.mp4

How to specify os platform in waf script?

I'm new to waf build tool and I've googled for answers but very few unhelpful links.
Does anyone know?
As wscript is essentially a python script, I suppose I could use the os package?
Don't use the os module, instead use the DEST_* variables:
ctx.load('compiler_c')
print (ctx.env.DEST_OS, ctx.env.DEST_CPU, ctx.env.DEST_BINFMT)
On my machine this would print ('linux', 'x86_64', 'elf'). Then you can dispatch on that.
You can use import at every point where you could use it any other python script.
I prefer using platform for programming a function os-agnostic instead on evaluate some attributes of os.
Writing the Build-related commands example in the waf book os-agnostic, could look something like this:
import platform
top = '.'
out = 'build_directory'
def configure(ctx):
pass
def build(ctx):
if platform.system().lower().startswith('win'):
cp = 'copy'
else:
cp = 'cp'
ctx(rule=cp+' ${SRC} ${TGT}', source='foo.txt', target='bar.txt')

Functional Tests with Grails, Geb & PhantomJS not working

I am running Spock tests with Gebish & HtmlUnitDriver. So far so good.
For reasons of speed I am changing the driver to PhantomJS: http://phantomjs.org/
my GebConfigs.groovy looks like this:
import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.remote.DesiredCapabilities
import org.openqa.selenium.WebDriver
import org.openqa.selenium.Dimension
driver {
ArrayList cliArgsCap = new ArrayList();
cliArgsCap.add("--web-security=false");
cliArgsCap.add("--ssl-protocol=any");
cliArgsCap.add("--ignore-ssl-errors=true");
DesiredCapabilities desiredCapabilities = new DesiredCapabilities()
desiredCapabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
PhantomJSDriver d = new PhantomJSDriver(desiredCapabilities)
d
}
as you see, no matter what a PhantomJSDriver should be used for tests.
my BuildConfig.groovy
test "org.gebish:geb-spock:$gebVersion"
test "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
test "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion"
test "org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion"
test "org.seleniumhq.selenium:selenium-support:$seleniumVersion"
test "org.spockframework:spock-grails-support:0.7-groovy-2.0"
test "org.grails:grails-datastore-test-support:1.0-grails-2.4"
test( "com.github.detro.ghostdriver:phantomjsdriver:1.1.0" ) {
transitive = false
}
the phantomjs.exe is located in:
C:\Apps\selenium\phantomjs\phantomjs.exe
and C:\Apps\selenium\phantomjs is in my PATH. i can run it through cmd: phantomjs in interactive mode.
problem
for some unclear reason geb is still using a HtmlUnitDriver. see log:
Error |
2014-08-15 14:01:26,630 [JS executor for com.gargoylesoftware.htmlunit.WebClient#527a4013] ERROR
javascript.StrictErrorReporter - runtimeError: message=[The data necessary to complete this
operation is not yet available.] sourceName=[http://localhost:8080/myapp/aui/js/aui-all.js] line=
[1] lineSource=[null] lineOffset=[0]
any ideas why phantomjsdriver is not used in this case?
I have phantomjs up and running with a Grails 2.0.4 app. My buildConfig.groovy looks like this:
def gebVersion = "0.9.2"
def seleniumVersion = "2.35.0"
...
test "org.gebish:geb-spock:$gebVersion"
test "org.gebish:geb-junit4:$gebVersion"
test( "com.github.detro.ghostdriver:phantomjsdriver:1.0.1" ) {
transitive = false
exclude "xml-apis"
exclude "xercesImpl"
}
test ("org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion") { // Needed by phantomjsdriver
exclude "xerces"
exclude "xercesImpl"
}
hope that helps
Update: had to work a little bit on my own example, but the result is a working Grails 2.4.2 app with phantomjs: https://github.com/rdmueller/SO25324259 (sorry for the horrible formatting - only saw it after my checkin).
btw: I didn't get your DesiredCapabilities to work :-(
PS: did you know the report feature? https://github.com/rdmueller/SO25324259/blob/master/test/functional/DemoSpec.groovy#L14
It takes a screenshot with your headless phantomjs browser - really cool feature!

Error trying to run geb tests with cucumber-jvm

I am trying to get some geb tests running in a Grails project within IntelliJ but am having trouble & after 2 days of web searching & trying different things am still stuck. We did have some Groovy tests running fine, previously, but no luck so far with geb. We're using cucumber-jvm.
Currently I am getting the following error:
Error Error executing script TestApp: groovy.lang.MissingMethodException:
No signature of method: GebConfig.environments() is applicable for argument types:
(GebConfig$_run_closure2) values: [GebConfig$_run_closure2#4ad3727e]
My GebConfig.groovy file is in test/functional, and contains:
import org.openqa.selenium.htmlunit.HtmlUnitDriver
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.chrome.ChromeDriver
// Use htmlunit as the default
// See: http://code.google.com/p/selenium/wiki/HtmlUnitDriver
driver = {
def driver = new HtmlUnitDriver()
driver.javascriptEnabled = true
driver
}
environments {Not sure
chrome {-Dgeb.env=chrome
driver = { new ChromeDriver() }
}
firefox {
driver = { new FirefoxDriver() }
}
}
I have the .feature file also in test/functional. The step def's are in test/functional/steps & contains:
package steps
import geb.*
this.metaClass.mixin (cucumber.runtime.groovy.EN)
this.metaClass.mixin (cucumber.runtime.groovy.Hooks)
def browser = new Browser()
Given (~"I am on the front page") {
browser.go("http://localhost:8081/whereisOne")
}
There is also a shared_driver.groovy class in test/functional/setup that was created for the straight Groovy tests, & I'm not sure if this is still needed.
The run config command is: test-app --stacktrace, with VM options: -Dgeb.env=chrome
Any help appreciated, thank you!
Is the -Dgeb.env=chrome in the code? If so, you have to remove this line. Everything else looks fine.

Resources