Accessing resources for Android UI Automator tests - java

I'm working on a set of tests using UI Automator on Android. I have it working, but my current tests are made with lots of string literals.
The string literals were fine when I was just trying to get things to work in the first place, but they will be bad going forward. If the app is changed, the string literals will need to be changed to match. Also, it's stupid that my tests would have to be completely redone to test localized builds in other languages.
The app itself has all strings stored in resources. Every string has an invariant identifier... here's an example:
<string name="more_options">More options</string>
The app code will always use the name more_options to look up the string resource, rather than hard-coding "More options" into the code.
So what I want is to import all the string resources, store them in some kind of map object, and then in my UI Automator test code use something like m.get("more_options") rather than a literal string "More options" as I do now.
Whatever I do, I want it to just be part of the JAR file that gets built and pushed to the device to run the tests. I don't want to, for example, push the XML string resource files to the device and try to read them at test runtime. I want to have the data built in when the JAR file is built.
I looked at the files produced by building the app, and the names like more_options are just set to integers. These must be indexes or pointers into a store of resources, but I'm not sure how I could copy that store into my UI Automator project and get it connected up; in an Android app you use a Context object to access resources, and a UI Automator JAR file doesn't have a Context.
This has to be a common problem, and people must have solved it already, but my Google searches haven't found any discussions of how people are solving this.
If I don't get any advice, I'm going to write a Python script that imports the XML file and writes a Java file that has a function that builds the map I need, then call that from my UI Automator test programs. (I have a Python script that runs the sequence of command-line tools to kick of a UI Automator test, anyway... I don't mind making that do more work.) But I figure there should be a pure-Java solution for this, probably one that involves grabbing the already-compiled files out of the application's source directory.

You can get context:
val context = InstrumentationRegistry.getTargetContext()
and then in your tests:
context.getString(R.string.more_options)

I usually target a UI element through a resource ID. Those are pretty static. Am I missing something?

I was stuck up with a similar problem.
I ended up creating a static hash map in Java for all the string literals.
So I had files for different languages with the same key and their localized values.
Then wrote a module to manipulate the device language at runtime and return the corresponding localized value for a key.

Related

How can I watch any particular file / directory based upon any file(located under specific directory if directory base watching) attempt for OPEN?

I want to execute few task based open targeted file's OPEN event.
For example, I am watching Sample.docx & whenever user will go for OPEN it, few subsequent task will be performed based upon it's OPEN action.
I have searched on internet & find out few solution but that are based upon file's MODIFICATION & DELETION operation. none of them shows based upon OPEN action which is actually I am looking for.
Any hint/suggestion would help me.
Thanks.
That is an operating-system specific functionality and is not something Java comes with out of the box. If you are on Windows you would use a FileSystemWatcher which exists in .NET, but if you need it in Java you would have to create native bindings if there isn't a library that already exists. Chances are this does not exist as not many people would have a valid use-case to do this and I don't think security people would be happy to see this either.
You could I suppose, in a specific thread, regularly poll currently running processes to see if the file name is contained within a process title.
As for .docx files for example, WORD would have this as its process title:
Sample.docx - Microsoft Word
You would need to utilize a JNA method named getAllWindowNames() to acquire a list of Window Names. This method works quite well. When Sample.docx is detected within the acquired list then start whatever file or files you like.
Keep in mind however, your Java application would need to always be running in the background and because of file association (as mentioned to you in a previous post) this technique would run the files you have associated with Sample.docx regardless of how the file was run (from a double-click in Windows Explorer, a shortcut on Desktop, opened from MS WORD itself, etc).
I have actually created a small demo application that does exactly what you are trying to accomplish however it is too large to post here. There is no tutorial that I know of for this sort of thing, it's just a matter of doing it....that is if the concept appeals to you.
Yes!...most people would not want this sort of thing dancing around on their System(s).

How to generate UI tests from a dsl ?

I'm not sure this question belongs to SO since it is maybe to broad, but I don't know where to ask it (I did not find a better stackexchange site).
Context
I'm using UiAutomator to write some Ui test on android. I created some functions to simplify the write of the tests like the one in the doc
public void startMainActivityFromHomeScreen() {
/*Start the app from the home screen*/
}
As a developper, this works fine. But non technical peoples (contracting owner) can't easily use this functions to write tests.
Needs
I'm searching for a way for non technical users to write some scripts using the function I already defined. Here is a dummy example (both script format and actions)
Suite: Launch the app twice from the home screen
Case: Launch the app for the first time
Do startMainActivityFromHomeScreen
Expect ...
Case: Launch the app for the second time
Do startMainActivityFromHomeScreen
Expect ...
The important point here is to interact with java functions. I know other tools like calabash but it does not provide java interfaces.
Current approach
Here is an idea (nothing implemented)
Put all the functions in a lib
Write a groovy dsl (because groovy interact well with java) which allows non technical users to easily write scripts
Create a java program which will evaluate the groovy script and generate the android code source associated (with the lib (from (1)) as a gradle dependency).
Run gradle androidTestCompile
Since the functions are in a lib, developers can easily include and use it into their projects. So the same lib can be used for all users.
I hate this idea since I have to generate code source from my code, but this is the only one I have.
Questions
Is this approach as horrible as I think it is ?
Do you know another way to do it ?
I'd check out https://cucumber.io/docs/reference/jvm#java, it's a library that accomplishes pretty much exactly what you're looking for by letting you associate regex's with Java test methods.
Your Java code would look something like:
#When("^I open the app from the (main|home) screen$")
public void openApp(String launchScreen) {
...
}
And the testing file would look like:
Feature: Launching app
Scenario: Launching from first screen
When I open the app from the main screen
Then I see a blue icon...
Scenario: Launching from second screen
When I open the app from the second screen
Then I see a green icon...

Java inexplicably writes to file with good or wrong codepage depending on web API call URL

Good evening,
I am thoroughly baffled by a behaviour that happens with a Java application of mine.
The application is to be used to connect to a web API and download a table of data from there to be further used in academic research.
I was trying to set the export to correct encoding, to save time, I disabled iteration in calls to web API by disabling some methods and removing a variable from a URL string construction - placing an integer 42 in its place.
Upon this, I was surprised to see the correct encoding.
A bit down the road, and I can confirm - if I use this URL:
new URL("http://www.foo.bar/api/unit?id="+scraper.ujList[i]);
where ujList[] is an array of integers,
then the output has typical wrong encoded characters like this ÄŤasĹĄ RuĹľinov
meanwhile, if I use
new URL("http://www.foo.bar/api/unit?id="+42);
then the output is proper, like Ružinov.
I have also tried Integer.toString() as well as String.valueOf() on ujList member, but it didn't help.
FWIW it does not matter if I run a jar file, a class file, or from within Eclipse.
I have no idea how to continue.

How to simulate File::Stat.ino in jruby or java?

I am currently trying to have Logstash work on Solaris with the File Input method. But I am encountering some bugs (see LOGSTASH-665). After digging a lot, it appears that native support for File.stat on my system (SunOS 5.10, JDK 1.6.0_21, 32 bit) is totally deficient, so I am looking for a way to properly handle it.
Specifically I want to access the inode information. Based on the metadata I can gather about the file (like its path and whatever is available on solaris), I want to calculate a number which is unique for that file, and which changes when the file is replaced by another file which has the same name. At first I thought about simply using a hash of the file path and used this function as a replacement, but indeed, when the file is rolled over the number does not change, so I need to also access the ctime information...
..Or make a system call to get the ls -li result to get the real inode number by another way.
Problem is that I never used ruby before, I am more used to java, so I am struggling to find a solution. Every suggestion will be appreciated.
The best solution I know of is to wrap the native call using JNI or JNA.
There do appear to be a couple of projects that have done this, although I haven't used either of them. See this question: Is there a Java library of Unix functions?

Java save method stops working when .jar is moved

I’m coding my first java Desktop application using eclipse and I’m having difficulty deploying it. My project uses JavaFX2 and the e(fx)clipse plugin, the latter is in charge of generating the build.xml file.
ABOUT THE APP
The app, amongst other things, provides an interface where the user can create categories and associate these with labels. All modifications are saved within a single file (the data is stored as a serialized object.) and are supposed to be loaded automatically when the app is reopened.
THE PROBLEM
When build as an executable jar using a .xml file (Ant), the project runs fine within the folder where it gets created. I can run my application, modify data, and save everything once I’m done. When I reopen the app everything gets loaded as it should.
However, if I copy the folder elsewhere, I can no longer save any data. Everything else seems to work; the app will even load the data that was saved when it was in its original directory. I assume that this means that the app can still see the data file, but can no longer write to it.
WHAT IVE TRIED
I’ve read that warping the .jar around an installer may fix the issue; however, one of the goals for the app was to make it as portable as possible. Meaning that it should be possible to move it around from one directory/computer to another, ideally in a manner that is cross-platform friendly, without the need of installing it.
I’ve tried various things to get it to work. I’ve shifted the whole project to Netbeans (to produce a different build), I’ve modified the save/load method file path to make sure the right document is targeted, I’ve tweaked the .xml file the best I could, and I even tried to build the project using the javafxpackager. No matter what I do, when the build works, I get the same results.
Right now, I’m thinking that there may still be something wrong with the .xml file but I’ve got a hard time understanding how to modify it. Perhaps the problem is somehow caused by the way the data gets serialized. I know that at one point when I moved things around within my project, both the save and load methods could no longer interact with the data.
What I find strange is that when the project is moved the load method still works. If the problem is caused by changing the file path, how come only the save method ceases to function?
APP FILES AND STRUCTURE
+src
-(Main.java)
+controller
-(misc.javas)
+modelData
-(Library.java) -->the object that is serialized
+modelLogic
-(misc.javas)
+view
-(misc.javas)
+files
-(library.data) -->the file where the serialized object is saved
+lib
-(empty.empty)
So, is their anything I can do to solve my problem?
Thanks in advance.
In the end, the problem was rather simple. When I was moving the app, I was always putting it on the desktop, which, in the case of my PC, sets by default all content as read-only (in relation to the app's privileges). Because of this, the app could not modify any files that were within folders on the desktop.
Therefore, all I had to do was to move the app to another directory, such as C:\randomFolder, and the problem was solved.
So, if anyone has a similar problem, moving the app elsewhere may be the solution. Alternatively, taking full ownership of the folder and its content can also work.
When possible, it is usually better to have the app ask its user for a specific location to save its data.

Categories