I am unable to launch the android emulator to run my automation script.
However my automation script works when I launch the android emulator manually from the /Android/sdk/tools directory using emulator -avd Pixel_API_25 -port 5557.
I want to be able to load the android emulator within my automation script.
Please see my env.rb file below.
require 'rubygems'
require 'rspec/expectations'
require 'selenium-webdriver'
require 'pry'
require 'appium_lib'
APP_PATH = '/Users/shafiq.malik/Documents/Projects/nuff-class-booking-
mobile/platforms/ios/build/emulator/HelloCordova.app'
desired_caps = {
caps: {:platformName => "Android",
:platformVersion => "7.1.1",
:deviceName => "Pixel_API_25",
:app => "/Users/shafiq.malik/Documents/Projects/nuff-
class-booking-
mobile/platforms/android/build/outputs/apk/android-
debug.apk",
:appPackage => "com.android.settings",
#:appActivity => ".Settings",
:browserName =>''
}
}
#driver = Appium::Driver.new(desired_caps).start_driver
Appium.promote_appium_methods self.class
def server_url
'http://localhost:8000/wd/hub'
end
Does anyone have any suggestions?
Try adding this to your desired capability . You need avd capability in order to start the emulator.
In java
capabilities.setCapability("avd","AndroidTestDevice");
In case of ruby, Any one of these two.
avd: "AndroidTestDevice",
:avd => "AndroidTestDevice",
Your desired caps should something look like this
desired_caps = {
caps: {:platformName => "Android",
:platformVersion => "7.1.1",
:deviceName => "Pixel_API_25",
:app => "/Users/shafiq.malik/Documents/Projects/nuff-
class-booking-
mobile/platforms/android/build/outputs/apk/android-
debug.apk",
:appPackage => "com.android.settings",
`:avd => "AndroidTestDevice",`
#:appActivity => ".Settings",
:browserName =>''
}
}
On a side note, don't give a root directory as a file path to your application. This might later cause problems if you are using CI's , instead have a generic code where you only indicate, the .apk or .app/.ipa name.
Related
I'm trying to connect to my local server in node.js with Socket.io using Flutter. It works ok when i connect from my browser, but it doesn't connect using my Android/iOS emulators. My socket.io code is pretty simple
// socket messages
io.on("connection", client => {
console.log("New device connected!")
// print in the console when some device disconnects
client.on("disconnect", data => {
console.log("disconnected!")
})
})
Flutter code (also pretty simple too):
IO.Socket socket = IO.io('http://localhost:3000', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': false,
});
// Dart client
socket.on('connect', (_) {
print('connect');
});
socket.on('event', (data) => print(data));
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
It always displays "disconnect" every ~30 seconds (in flutter console), also in the node.js it never displays a "New device connected!"
What i'm using?
Flutter Socket.io Dependency
pubspec.xml
dependencies:
flutter:
sdk: flutter
socket_io_client: ^0.9.11
provider: ^4.3.2+2
There's different reasons of why this is not working, but here i describe a couple of them of how you can solve it.
First check if server is responding
Check if you can access it using your pc web browser, it should something like
Check if your device web browser have access
If both things are working fine, try with one of these solutions:
Solution #1
The url that you've tested in the emulator browser (not in your pc browser) is the same url that you need to use in your flutter app.
iOS
http://localhost:3000 # port can change, check your node.js config
http://<your_pc_ip:3000>:3000 # you can check it in the preferences or terminal -> ipconfig
Android
http://10.0.2.2:3000
http://localhost:3000 # port can change, check your node.js config
http://<your_pc_ip:3000>:3000 # you can check it in the preferences or terminal -> ipconfig
Solution #2
My node.js project was using socket.io version 3.0.0 (the latest), but it looks like my flutter client doesn't support it, so try to downgrade to version 2.3.0 (don't do it manually, in other words don't modify the file manually)
npm uninstall socket.io
npm install socket.io#2.3.0
and your package.json will be (in your node.js project)
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.17.1",
"socket.io": "^2.3.0"
}
Note: if you want to keep using socket.io version 3.0 instead of v2.3.0 then you should use the new version of flutter client (currently in beta): Flutter Client for Socket.io v3.0
Solution #3
For some reason the "autoConnect" not always work, so try to connect it manually.
IO.Socket socket = IO.io('http://localhost:3000', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': true,
});
// Dart client
socket.on('connect', (_) {
print('connect');
});
socket.on('event', (data) => print(data));
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
// add this line
socket.connect();
Solution #4
Maybe there's a firewall or something blocking your port (mine 3000), try to run it using another port. You need to change the config in your server and also change the url in the flutter app (also test it using your emulator/simulator browser)
and that's it... it should work.
You should see something like:
Flutter
Server
I had the same Issue using socket_io_client.
Using :Socket socket = io(SERVER_ADRESS, <String, dynamic> { 'transports':['websocket'], 'autoConnect' : true}); instead of : Socket socket = io(SERVER_ADRESS);.
I've got a selenium grid with chrome, firefox and android node running
and I have this protractor configuration within an angular cli project:
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const {SpecReporter} = require('jasmine-spec-reporter');
var HtmlScreenshotReporter = require('protractor-jasmine2-screenshot-reporter');
var screenshotReporter = new HtmlScreenshotReporter({
dest: 'target/screenshots',
filename: 'my-report.html'
});
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
multiCapabilities: [{
'browserName': 'chrome'
}, {
'browserName': 'firefox'
}, {
'browserName': 'android',
'platformName': 'Android',
'platformVersion': '7.1.1',
'deviceName': 'Nexus 5'
}],
// directConnect: true,
seleniumAddress: "http://localhost:4444/wd/hub",
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () {
}
},
beforeLaunch: function () {
return new Promise(function (resolve) {
screenshotReporter.beforeLaunch(resolve);
});
},
onPrepare: function () {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
jasmine.getEnv().addReporter(screenshotReporter);
},
afterLaunch: function (exitCode) {
return new Promise(function (resolve) {
screenshotReporter.afterLaunch(resolve.bind(this, exitCode));
})
}
};
When I launch my ng e2e task, tests are running fine on firefox and chrome node. However, I've got this error coming from the android capability:
WebDriverError: An unknown server-side error occurred while processing the command. Original error: The desired capabilities must include either an app, appPackage or browserName
...
If I get it right the android webdriver asks me to include a browserName although I already provide it one. Does anyone have an idea?
the andriod capability in your protractor config file will failed to get any matched node for you. Because you use one wrong name and one wrong value in capability.
you use 'platformVersion', but on selenium gird is 'version'.
you set 'deviceName' to 'Nexus 5', but on selenium gird is 'nexus_5_7.1.1'
please change 'platformVersion' to 'version' and correct 'Nexus 5' to 'nexus_5_7.1.1' in your protractor config file, then try again.
My last concern is on your selenium grid the browserName is 'android', I'm not sure testing can open the browser.
In most case, we install Chrome on andriod device and set browserName to 'Chrome' when register device to selenium grid and in protractor config file.
I indeed not know 'andriod' represents which browser, the build-in browser bind with andriod OS?
I am trying to automate android apps using python (or possibly ruby), by linking into the provided UIAutomator in the android SDK.
Right now I am trying to use a Python tool here, but I am having issues connecting (getting TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
Code snipped of what i am trying to do with the Python tool:
def print_info():
print('Getting info...')
d = ui.Device('SERIAL_NUMBER', adb_server_host='192.168.1.20', adb_server_port='5037')
print(d.info)
Is there something wrong with how I am trying to send commands? Alternatively, is there a better ruby/python tool for testing android devices?
Update I am now using the Appium library Ruby gem to test. Got applications to launch, however things like tapping the screen result in this error
assert_ok': A session is either terminated or not started
(Selenium::WebDriver::Error::NoSuchDriverError)`
This is the code
desired_caps = {
caps: {
appiumVersion: '1.6.5',
platformName: 'Android',
platformVersion: '4.4',
browserName: '',
deviceName: 'DEVICE_SERIAL',
app: 'APK',
appActivity: 'mainactivity',
appWaitDuration: '60000', # wait a minute (set to 20000 by default)
clearSystemFiles: 'true'
},
appium_lib: {
sauce_username: nil,
sauce_access_key: nil
}
}
$driver = Appium::Driver.new(desired_caps)
$driver.start_driver
sleep(60) # wait a minute for app to fully load, before tring to tap anything
touch_action = Appium::TouchAction.new
touch_action.press(x: 243, y: 288).wait(5).release.perform
touch_action.press(x: 311, y: 165).wait(5).release.perform
This is how I do it for an emulator
app_path = File.absolute_path('automateme.apk', 'data')
caps = {
:platformName => "android",
:deviceName => "android",
:app => app_path,
:noReset => 'true',
:newCommandTimeout => "30"
}
#driver = Appium::Driver.new(:caps => caps).start_driver
try this and let me know if it helps... :)
There is an one good mobile test automation tool available - Appium.
Currently I have been using ruby,appium,cucumber,selenium webdriver for android automation. I am suggesting that you will try to use Appium tool for mobile automation. below is important link,
http://www.software-testing-tutorials-automation.com/2015/09/appium-tutorials.html
https://community.perfectomobile.com/posts/1103155-ruby-example-for-appium-android
http://appium.io/slate/en/tutorial/android.html?ruby#troubleshooting
following is the example to start
require 'appium_lib'
desired_caps = {
caps: { appiumVersion: '1.6.0',
platformName: 'Android',
platformVersion: '4.4.2',
browserName: '',
deviceName: 'Samsung Galaxy S4 Emulator',
app: 'D:\Workspace\android-sample-app.apk',
name: 'Ruby Appium Sauce example'
} }
driver = Appium::Driver.new(desired_caps)
puts driver
begin
driver.start_driver
rescue Exception => e
puts e
end
driver.first_textfield.send_key 10
driver.last_textfield.send_key 20
driver.first_button.click
driver.driver_quit
download "android-sample-app.apk" and put in any path and also set this path
in desired_caps.
Thanks,
Kapil Chothe
i'm Working on xamarin forms simple app (CreditCardValidator) i downloaded the app from [https://developer.xamarin.com/samples/test-cloud/Quickstarts/CreditCardValidator.Droid/]
Now is it possible to start Running Test Method without providing path to (.apk File) ... if not i want to know how to start VS emulator just after Running Test method ( running test method to automatically launch VS emulator ) ?
public class Tests
{
AndroidApp app;
[SetUp]
public void BeforeEachTest()
{
app = ConfigureApp.Android.StartApp();
}
[Test]
public void CreditCardNumber_TooShort_DisplayErrorMessage()
{
app.WaitForElement(c => c.Marked("action_bar_title").Text("Enter Credit Card Number"));
app.EnterText(c=>c.Marked("creditCardNumberText"), new string('9', 15));
app.Tap(c => c.Marked("validateButton"));
app.WaitForElement(c => c.Marked("errorMessagesText").Text("Credit card number is too short."));
}
}
If there is only one device attached to the computer, and no running simulators, then UITest will automatically run the tests on the device.
This would also apply to an emulator in the sense that it would have to be already up and running.
Source: https://developer.xamarin.com/guides/testcloud/uitest/working-with/testing-on-devices/android/#Programmatically_Declaring_the_Device
However since you might need to boot an emulator up, you can do the following:
There is a tool called emulatorcmd.exe that you can use. It is found in the following directory on Windows:
C:\Program Files (x86)\Microsoft Emulator Manager\1.0
You can use emulatorcmd.exe list /sku:Android /type:device /state:installed to get a list of available emulators that are installed.
You can then use emulatorcmd.exe launch /sku:Android /id:<id> which will launch that specific emulator.
https://blogs.msdn.microsoft.com/visualstudioalm/2014/11/12/introducing-visual-studios-emulator-for-android/
I need your guidence about environmental vaariable in ruby.
================================================
I have some code that convert version of device intedtifier => device name..
in my code,
path:
Config-initilizer-android.rb
module Android
#conversion_table_of_model_id_and_device_name = {
'Anroid2,3' => 'Gingerbread',
'Android3,0' => 'Honeycomb',
'Android4,1' => 'ICS',
'Android4,2' => 'JB',
}
in the future, if there's another name of android eg.'KitKat'. i want to add it using environment variable not use the hard code.
how can i to do it? is it possible to that?
where should i put it?
regards.
agstwn
With Rails 4.1 you can use secrets.yml, check out this link
If you have earlier version, try figaro gem
What blocks you from using ENV constant?
module Android
#conversion_table_of_model_id_and_device_name = {
'Anroid2,3' => 'Gingerbread',
'Android3,0' => 'Honeycomb',
'Android4,1' => 'ICS',
'Android4,2' => 'JB',
'Android4,3' => ENV[ 'ANDROID_OS_NAME' ]
}
You have to remember that ENV vars are still variables, meaning you can use them in a similar way. I'd propose using something like the new secrets.yml in Rails 4.1, or something like config spartan to create a yml structure of the data you need:
#config/secrets.yml
development:
android:
2.3: "gingerbread"
3.0: "Honeycomb"
4.1: "ICS"
4.2: "JB"
4.4: "KK"
module Android
#conversion_table_of_model_id_and_device_name
me = {}
Rails.application.secrets.android.each do |k,v|
me[k.to_sym] = v
end
end