How does one attach a specific app which is to be tested to Selendroid?
I've seen the example with the test app which is displayed virtually everywhere, but well, where do I have to place that apk under test?
I tried to use the id of the app like this:
SelendroidConfiguration config = new SelendroidConfiguration();
config.addSupportedApp("io.selendroid.testapp:0.17.0");
SelendroidLauncher selendroidServer = new SelendroidLauncher(config);
selendroidServer.launchSelendroid();
DesiredCapabilities caps = io.selendroid.common.SelendroidCapabilities.android();
SelendroidCapabilities cap = new SelendroidCapabilities("io.selendroid.testapp:0.17.0");
But I keep receiving errors: SessionNotCreatedException. What is causing this?
How do I attach a specific app to the Java project with the tests?
Seems like the issue is caused by not giving the correct path to your apk.
Here you should give the path to the apk, but you are giving it the package name of the app
config.addSupportedApp("io.selendroid.testapp:0.17.0");
The fix would be then
config.addSupportedApp("C:/Users/Madis/Documents/selendroid.apk");
Related
I am testing a website on Chrome (v65) installed on Android (7.1.1 API 25).
Chromedriver version 2.37.
Appium latest desktop version (v1.5.0, shows server version 1.7.2)
I need to upload an image from the device itself.
Although on the web-browser I am able to upload an image with sendKeys, its not working on the android emulator.
This is what the image selection page in the emulator looks like:
I used UiAutomator to get the resource id: "com.android.chrome:id/bitmap_view" and the class: "android.widget.ImageView"
I have used the following line(s) of code to try and look for the element:
(a)
driver.findElement(By.xpath("//android.widget.ImageView[contains(#resource-id,'com.android.chrome:id/bitmap_view')]")).click();
(b) When I use below, I get an empty list
List<WebElement> elements = driver.findElementsByClassName("android.widget.ImageView");
(c) I got this xpath from Appium Inspector Session
MobileElement el8 = (MobileElement) driver.findElementByXPath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.support.v7.widget.Af/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[3]/android.widget.FrameLayout/android.widget.ImageView");
el8.click();
I don't know what I am missing.
[Update] []2
Did you change the context to the NATIVE_APP in your test?
Since you mentioned you test chrome, it means your test is using WEBVIEW context. But as soon as you open Upload files screen it is a NATIVE_APP view and you need to switch to it before start searching:
AndroidDriver<MobileElement> driver = new AndroidDriver<>(
new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
driver.get(<your_web_site>);
// do what you need in browser, open Upload files screen
// switch to Native context to search inside it
Set<String> contexts = driver.getContextHandles();
for (String context : contexts) {
System.out.println(contexts);
if (context.equals("NATIVE_APP")) {
driver.context(context);
break;
}
}
List<MobileElement> images = driver.findElementsByClassName("android.widget.ImageView");
// click the last image in view if exist
images.stream()
.reduce((first, second) -> second)
.orElseThrow(NotFoundException::new)
.click();
I have been trying a ( i hope) simple bit of Android hyperloop code directly within a titanium project (using SDK 7.0.1.GA and hyperloop 3).
var sysProp = require('android.os.SystemProperties');
var serialNumber = sysProp.get("sys.serialnumber", "none");
But when the app is run it reports
Requested module not found:android.os.SystemProperties
I think this maybe due to the fact that when compiling the app (using the cli) it reports
hyperloop:generateSources: Skipping Hyperloop wrapper generation, no usage found ...
I have similar code in a jar and if I use this then it does work, so I am wondering why the hyperloop generation is not being triggered, as I assume that is the issue.
Sorry should have explained better.
This is the jar source that I use, the extraction of the serial number was just an example (I need access to other info manufacturer specific data as well), I wanted to see if I could replicate the JAR functionality using just hyperloop rather that including the JAR file. Guess if it's not broke don't fix it, but was curious to see if it could be done.
So with the feedback from #miga and a bit of trial and error, I have come up with a solution that works really well and will do the method reflection that is required. My new Hyperloop function is
function getData(data){
var result = false;
var Class = require("java.lang.Class");
var String = require("java.lang.String");
var c = Class.forName("android.os.SystemProperties");
var get = c.getMethod("get", String.class, String.class);
result = get.invoke(c, data, "Error");
return result;
}
Where data is a string of the system property I want.
I am using it to extract and match a serial number from a Samsung device that is a System Property call "ril.serialnumber" or "sys.serialnumber". Now I can use the above function to do what I was using the JAR file for. Just thought I'd share in case anyone else needed something similar.
It is because android.os.SystemProperties is not class you can import. Check the android documentation at https://developer.android.com/reference/android/os/package-summary.html
You could use
var build = require('android.os.Build');
console.log(build.SERIAL);
to access the serial number.
I'm working on Ionic mobile app development.
My requirement is to create client side logger to track issues in app. I used the methods mentioned in https://github.com/pbakondy/filelogger, and I could able to create the log file in both Android and iOS.
For the first time when I open the app, it creates the log file in cordova.file.dataDirectory, when I close and reopen the app in i*OS, I'm trying to read the content of the file which was created using the below
$fileLogger.getLogfile().then(function (loggerContent) {
var temp =loggerContent;
});
But the application says
{
"applicationDirectory":null,
"applicationStorageDirectory":null,
"dataDirectory":null,
"cacheDirectory":null,
"externalApplicationStorageDirectory":null,
"externalDataDirectory":null,
"externalCacheDirectory":null,
"externalRootDirectory":null,
"tempDirectory":null,
"syncedDataDirectory":null,
"documentsDirectory":null,
"sharedDirectory":null
}
So I couldn't able to find the file where i saved my logs.
Please help me resolve this issue or if you could recommend me a different method to get around this issue, that would be great!
Thanks for the answers
There is a check list here and should solve your problem :
1-Be sure that the cordova-file-plugin is installed and works in your test environment.
2-Be sure that the cordova.js file is refrenced by your html and before your code usage.
3-Be sure to call your codes after device_ready state :
check this
4-Call your function after a short delay (use setTimeOut in Javascirpt)
Ali's item 4 is very important:
I had a similiar problem on different platforms: cordova.file.dataDirectory was null.
I tracked cordova.file.dataDirectory over the lifecycle and it was first accessed by my Ionic 2 code BEFORE the device ready event was fired.
My "mistake": I wanted to load data during the constructor(!) of a service. Seems too early.
I'm using logback for android, and I'm configuring it in code because I want the log directory to dynamically change depending on the phone (e.g. some phones have external storage and I want to write to that, but other phones don't so we have to redirect to internal storage).
Here is my config code:
File logFilesDir = getLogFilesDir(this);
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
lc.reset();
RollingFileAppender<ILoggingEvent> fileAppender = null;
lc.putProperty("LOG_DIR", logFilesDir.getAbsolutePath());
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(lc);
encoder.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
encoder.start();
File logFile = new File(logFilesDir, "MyApplication.log");
FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
rollingPolicy.setContext(lc);
rollingPolicy.setFileNamePattern("${LOG_DIR}/MyApplication.%i.log");
rollingPolicy.setMinIndex(1);
rollingPolicy.setMaxIndex(5);
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
triggeringPolicy.setContext(lc);
triggeringPolicy.setMaxFileSize("1KB"); // for testing; would otherwise be 5MB
fileAppender = new RollingFileAppender<>();
fileAppender.setContext(lc);
fileAppender.setFile(logFile.getAbsolutePath());
fileAppender.setEncoder(encoder);
fileAppender.setRollingPolicy(rollingPolicy);
fileAppender.setTriggeringPolicy(triggeringPolicy);
rollingPolicy.setParent(fileAppender);
fileAppender.start();
rollingPolicy.start();
triggeringPolicy.start();
// add the newly created appenders to the root logger;
// qualify Logger to disambiguate from org.slf4j.Logger
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.addAppender(fileAppender);
root.info("----- Application onCreate -----");
StatusPrinter.print(lc);
The log writes to the correct folder and it's all working ok, except when my log file exceeds the max file size (in my testing case 1KB) it fails to roll over. Instead, the file just keeps growing.
StatusPrinter.print writes the following output, which looks like everything's ok
|-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [assets/logback.xml]
|-INFO in ch.qos.logback.core.rolling.RollingFileAppender[null] - Active log file name: /storage/emulated/0/MyApplication/logs/MyApplication.log
|-INFO in ch.qos.logback.core.rolling.RollingFileAppender[null] - File property is set to [/storage/emulated/0/MyApplication/logs/MyApplication.log]
|-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy#34b71b53 - No compression will be used
I've looked at as many other similar issues as I can find, and usually people seem to miss out the RollingFileAppender or don't have WRITE_EXTERNAL_STORAGE permission... It doesn't seem to me like I'm hitting any of those cases. Is something about my code (vs the XML people normally use) different?
Is there anything I can do to fix this or troubleshoot it further?
Thanks
I can't immediately tell what the problem is, but it would be helpful add an OnConsoleStatusListener to see what happens during the rollover:
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
lc.reset();
OnConsoleStatusListener.addNewInstanceToContext(lc);
Rollover problems from RollingFileAppender are typically caused by a mix of absolute and relative paths in their configuration (Issue #117, Issue #110) or missing the WRITE_EXTERNAL_STORAGE permission (which is not the case for you). The debug output from OnConsoleStatusListener might shed some light. If not, I can try to debug it if you create a GitHub Issue, preferably with an Android Studio project that reproduces the problem.
So I was trying to use rpush for the push notifications of my mobile app using this gem : https://github.com/rpush/rpush. I'm using the sinatra framework. But I keep getting this error, even though I wrote --> require 'rpush' on the top of my file. Can someone experienced in ruby help me? I'm new to ruby so please bear with me. Here's my code
require 'rpush'
Module Notifier
def rpush_client
app = Rpush::Gcm::App.new
app.name = "App-Name"
app.auth_key = "XXXXXXXXXXXXXXX"
app.connections = 1
app.save!
end
def notify(user_id,alert)
rpush_client
session = db_find_one('dbname.sessions',{user_id: user_id})
if session.present?
device = session['devices'].first
token = device['device_token']
n = Rpush::Gcm::Notification.new
n.app = Rpush::Gcm::App.find_by_name("App-Name")
n.registration_ids = ["token", token]
n.data = { message: alert }
n.save!
Rpush.push
end
end
end
I know its a dumb question but tired of looking for it on here.
Are you using bundler with Sinatra? If so, you shouldn't need to explicitly require Rpush. See here: http://bundler.io/sinatra.html
What I did wrong
In my case, I just installed rpush with
bundle add rpush
and faced the same error.
What I should've done
As clearly mentioned in README.md, you have to run the following command after add rpush to Gemfile:
$ bundle
$ bundle exec rpush init
What you'll get for correct installation
This will generate config/initializers/rpush.rb and (lots of) migration files.
You may want to run migration after that.
Tips
I recommend to use rpush-redis.
You don't need to run extra migrations with it. You can safely get rid of garbage migration files.
config.redis_options may resemble the following:
Rpush.configure do |config|
# Supported clients are :active_record and :redis
config.client = :redis
# Options passed to Redis.new
config.redis_options = {
url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0'),
password: ENV.fetch('REDIS_PASSWORD', '')
}
end