I run Appium server:
➜ ~ appium
info: Welcome to Appium v1.3.5 (REV a124a15677e26b33db16e81c4b3b34d9c6b8cac9)
info: Appium REST http interface listener started on 0.0.0.0:4723
info: Console LogLevel: debug
info: --> POST /wd/hub/session {"desiredCapabilities":{"appPackage":"com.grindrapp.android","appActivity":".activity.SplashActivity","platformVersion":"4.4.2","browserName":"","platformName":"Android","deviceName":"10.0.0.9:5555"}}
info: Client User-Agent string: Apache-HttpClient/4.3.4 (java 1.5)
info: [debug] Didn't get app but did get Android package, will attempt to launch it on the device
info: [debug] Creating new appium session 090abe0c-36d9-4f9b-987a-f3b665045928
info: Starting android appium
info: [debug] Getting Java version
info: [debug] Cleaning up android objects
info: [debug] Cleaning up appium session
error: Failed to start an Appium session, err was: Error: Could not get the Java version. Is Java installed?
info: [debug] Error: Could not get the Java version. Is Java installed?
at /usr/local/lib/node_modules/appium/lib/devices/android/android-common.js:1040:17
at ChildProcess.exithandler (child_process.js:735:7)
at ChildProcess.emit (events.js:110:17)
at maybeClose (child_process.js:1008:16)
at Socket.<anonymous> (child_process.js:1176:11)
at Socket.emit (events.js:107:17)
at Pipe.close (net.js:476:12)
info: [debug] Responding to client with error: {"status":33,"value":{"message":"A new session could not be created. (Original error: Could not get the Java version. Is Java installed?)","origValue":"Could not get the Java version. Is Java installed?"},"sessionId":null}
info: <-- POST /wd/hub/session 500 316.738 ms - 222
^C
➜ ~ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_76.jdk/Contents/Home
I try to run this code to post to Appium server:
public class AndroidTest {
private AppiumDriver driver;
#Before
public void setUp() throws Exception {
// File classpathRoot = new File(System.getProperty("user.dir"));
// File appDir = new File(classpathRoot, "../../../data/app/");
// File app = new File(appDir, "Facebook.apk");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability("deviceName","10.0.0.9:5555");
capabilities.setCapability("platformVersion", "4.4.2");
capabilities.setCapability("platformName","Android");
//capabilities.setCapability("app", app.getCanonicalPath());
capabilities.setCapability("appPackage", "com.grindrapp.android");
capabilities.setCapability("appActivity", ".activity.SplashActivity");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
but as you can see I get this error:
info: [debug] Error: Could not get the Java version. Is Java installed?
how can I fix this?
I'm trying to automatically open an app which i downloaded from the google play and I don't have its apk.
I think this is the final solution for your problem.
As always, make a backup copy of the file before editing.
Edit the file /usr/local/lib/node_modules/appium/lib/devices/android/android-common.js
In the else if(stderr) branch around line 1034:
else if (stderr) {
var firstLine = stderr.split("\n")[0];
if (new RegExp("java version").test(firstLine)) {
javaVersion = firstLine.split(" ")[2].replace(/"/g, '');
}
}
replace the code to read:
else if (stderr){
if(new RegExp("java version").test(stderr)){
var regex = "java version \"[0-9]+\.[0-9]+\.[0-9]+";
var stderrstring = '' + stderr + '';
var regmatch = stderrstring.match(regex);
javaVersion = '' + regmatch + '' //convert object to string
javaVersion.replace(/"/g,'');
}
}
The code should work with a regular java version response message plus the one that you are receiving.
The file is located here:
/usr/local/lib/node_modules/appium/lib/devices/android/android-common.js
The code we are concerned with starting at line 1029 is:
androidCommon.getJavaVersion = function (cb) {
exec("java -version", function (err, stdout, stderr) {
var javaVersion = null;
if (err) {
return cb(new Error("'java -version' failed. " + err));
} else if (stderr) {
var firstLine = stderr.split("\n")[0];
if (new RegExp("java version").test(firstLine)) {
javaVersion = firstLine.split(" ")[2].replace(/"/g, '');
}
}
if (javaVersion === null) {
return cb(new Error("Could not get the Java version. Is Java installed?"));
}
return cb(null, javaVersion);
});
};
I am unable to test this on my system, but I think that a successful execution of java -version would return its response on stdout and not stderr. I would change the code to provide more information as to what is happening and help debug it.
You are getting the JavaVersion = null message at the end of the listing which means that there is nothing returned in err and parsing of stderr is not setting JavaVersion. It does not tell you if there is anything in stderr nor does it even look at stdout.
Here is a revised code listing. If the output is indeed returned on stderr, the code will now at least print it out so you can see what is returned. I added the same code branch for stdout as it was not checked at all.
androidCommon.getJavaVersion = function (cb) {
exec("java -version", function (err, stdout, stderr) {
var javaVersion = null;
var firstLine = null;
if (err) {
return cb(new Error("'java -version' failed. " + err));
} else if (stderr) {
firstLine = stderr.split("\n")[0];
if (new RegExp("java version").test(firstLine)) {
javaVersion = firstLine.split(" ")[2].replace(/"/g, '');
}else{
return cb(new Error("Java version stderr string parse error: " + stderr));
}
} else if(stdout){
firstLine = stdout.split("\n")[0];
if (new RegExp("java version").test(firstLine)) {
javaVersion = firstLine.split(" ")[2].replace(/"/g, '');
}else{
return cb(new Error("Java version stdout string parse error: " + stdout));
}
}
if (javaVersion === null) {
return cb(new Error("Could not get the Java version. Is Java installed?"));
}
return cb(null, javaVersion);
});
}
So:
make a backup copy of android-commons.js
make the code change and give it a try.
This might work as written or the error messages will tell you what is being returned.
The code in android-common.js is looking for the java version number on the first line.
I had the similar issue, but my java -version returns result as
[~]$ java -version
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
java version "1.7.0_76"
Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)
So I simply changed the code in android-common.js to split second line instead of first line
firstLine = stderr.split("\n")[0]; -> firstLine = stderr.split("\n")[1]
Related
I have a simple string "twist" being passed on from the backend which is not a urlimage of simulator
My code for linking is as follows
console.log(url);
let linkOpened = false;
Linking.canOpenURL(url).then((canOpen) => {
console.log("canOpen : ", canOpen);
if (canOpen) {
Linking.openURL(url);
linkOpened = true;
} else {
console.log("i am calling");
}
});
As we can see "twist" is a string and not a URL which cannot be opened.
The same code on android emulator returns false which is the correct result but true on IOS which is incorrect
IOS Watchman Output
None of the answers on github/stackoverflow/apple dev forums work for me
I have also added this in my info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>twist</string>
<string>nothing</string>
</array>
Running on
XCODE 14
Node 165.13.0
Kindly assist me. :)
Linking on backend using
https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl
It is directly linking ios nsurl TO javascript string which is causing error
for now use following code and wait for there update
const url = 'twist:';
console.log(url);
let linkOpened = false;
if (url.search(':') != -1) {
console.log('url', url.search(':'));
try {
linkOpened = await Linking.canOpenURL(url);
} catch (error) {}
}
console.log('linkOpened', linkOpened);
I am running a Jenkins pipeline script. I keep get the error that org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing Perhaps you forgot to surround the code with a step that provides this, such as: node in the stack trace. The actual credentials in my script on Jenkins are there but for the sake of this example they were given symbols.
Here is my script that I am running:
try {
node {
stage('Preparation') {
git credentialsId: 'validCredentials', url: 'repo', branch: 'branch'
}
stage('Clean Build') {
dir("directory-to-where-my gradle-wrapper-is-located") {
sh "pwd"
sh 'ls -al'
sh './gradlew clean build'
}
}
}
}catch (caughtError) {
err = caughtError
currentBuild.result = "FAILURE"
} finally {
if(currentBuild.result == "FAILURE"){
sh "echo 'Build FAILURE'"
}else{
sh "echo 'Build SUCCESSFUL'"
}
}
any ideas?
Steps I am following , to start the server is :
Created a bat file with the below command :
"C:/Program Files (x86)/Appium/node.exe" "C:/Program Files (x86)/Appium/node_modules/appium/bin/Appium.js" --address 127.0.0.1 --port 4723 --platform-name Android --platform-version 18 --automation-name Appium --no-reset --local-timezone --log E:\Android\appium.log""
Code Written to start the server :
public class Testing {
AppiumDriver driver;
#BeforeTest
public void AppiumServerStart() throws MalformedURLException, InterruptedException {
String s = null;
String Filepath = "C:\\appiumserver.bat";
// String Command = \""C:/Program Files (x86)/Appium/node.exe"
// "C:/Program Files (x86)/Appium/node_modules/appium/bin/Appium.js"
// --address 127.0.0.1 --port 4723 --platform-name Android
// --platform-version 18 --automation-name Appium --no-reset
// --local-timezone"\"
System.out.println(Filepath);
try {
Process p = Runtime.getRuntime().exec(Filepath);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Filepath);
System.out.println("Server Started");
Thread.sleep(6000);
}
Code to Add Desire Capabilities and create android driver instance :
public class DemoCalc extends Testing {
AppiumDriver driver;
#Test
public void Setup() throws MalformedURLException, InterruptedException {
File file = new File(System.getProperty("user.dir"));
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.VERSION, "4.4.4");
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
cap.setCapability(MobileCapabilityType.DEVICE_NAME, "169.254.140.101:5555");
cap.setCapability(MobileCapabilityType.APP_PACKAGE, "com.android.calculator2");
cap.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.android.calculator2.Calculator");
driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), cap);
However , the below exception is thrown on Android driver instance :
org.openqa.selenium.remote.UnreachableBrowserException: Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: '2.46.0', revision: '87c69e2', time: '2015-06-04 16:17:10'
If I manually , start the server by clicking on appium.exe ,then issue does not occur. But when the server is started from java code issue appears.
After running the bat file to start the appium server, i see the node process in task manager , which shows the appium server has been connected.
Please help
Try to run Appium server as a separate thread before executing the test.
I'm new to this forum and appium/android automation, I need help on verifying if an object exists on my app before I take the next action.
I tried using the following code below but is not even reaching my second print statement.
#Test
public void addContact() {
System.out.println( "Checking if Contact exists.... 111111 ");
WebElement e = driver.findElement(By.name("John Doe"));
System.out.println( "Checking if Contact exists.... 222222");
boolean contactExists = e.isDisplayed();
System.out.println( contactExists );
if (contactExists == true) {
System.out.println( "Contact exists.... ");
} else {
System.out.println( "Contact DOES NOT exists.... ");
}
}
Running this code here's appium console output... it just keeps looping through this and script fails.
info: [BOOTSTRAP] [info] Got command of type ACTION
info: [BOOTSTRAP] [debug] Got command action: find
info: [BOOTSTRAP] [debug] Finding John Doe using NAME with the contextId:
info: [BOOTSTRAP] [info] Returning result: {"value":"No element found","status":7}
info: Pushing command to appium work queue: ["find",{"strategy":"name","selector":"John Doe","context":"","multiple":false}]
info: [BOOTSTRAP] [info] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"name","selector":"John Doe","context":"","multiple":false}}
is isDisplayed the right approach here or is there a better alternative to do this?
Cheers.... TIA
If you are using Appium 1.0+
By.name locating strategy has been deprecated.Please use some other stuffs like By.xpath etc.
In the newer version of appium you have "accessibility id".Use these instead.
Happy automating
Maybe the following will help you. I have the methods in my TestBase class:
protected static boolean isElementPresent(By by) {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
List<WebElement> list = driver.findElements(by);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
if (list.size() == 0) {
return false;
} else {
return list.get(0).isDisplayed();
}
}
public boolean elementIsNotPresent(By by) {
try {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
return driver.findElements(by).isEmpty();
} finally {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
Also, I use the following code to wait until some certain element on the screen:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By
.xpath("//android.widget.Button[contains(#text, 'Log In')]")));
or:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.presenceOfElementLocated(By
.xpath("//android.widget.TextView[contains(#resource-id, 'action_bar_title')]")));
I am developing a new Phonegap 3 application. I find the development process very slow. Each time I want to test a change in my app, I have to run in the console:
phonegap run android
This command takes about 30 seconds to run! Any idea on how to improve the time to test each change?
If you are developing for android using ecllipse you can use an android handset, connect it with your development machine with usb cable and install necessary drivers from here
.
Drivers are required mostly for windows in mac and linux it is usually not necessary. After set up it is just a matter of clicking run in your ide.
If you have a huge amount of files (libraries with demos, non-minified files, etc.), installing on the app can take a long long time.
I created this hook (added to before_prepare) which only copies the necessary files (specified in "requirements.json" in my project).
You need to run cd hooks/before_prepare && npm install ncp to install the dependency.
hooks/before_prepare/010copy_assets.js
#!/usr/bin/env node
console.log("=== Running copy required assets hook ===");
var fs = require('fs'),
path = require('path');
var mkdirSync = function(path) {
try {
fs.mkdirSync(path);
} catch (e) {
if (e.code != 'EEXIST') throw e;
}
}
var mkdirpSync = function(dirpath) {
var parts = dirpath.split(path.sep);
for (var i = 1; i <= parts.length; i++) {
mkdirSync(path.join.apply(null, parts.slice(0, i)));
}
}
try {
var ncp = require('ncp').ncp
var requirements = require('./../../myproject/requirements.json');
ncp.limit = 200;
ncp.stopOnErr = true;
requirements.forEach(function(requirement) {
var source = './myproject/' + requirement;
var destination = './www/' + requirement;
var folders = destination.split('/');
folders.pop();
mkdirpSync(path.normalize(folders.join('/')));
ncp(source, destination, function(err) {
if (err) {
console.log('====== Error! Did not copy asset from ' + source + ' to ' + destination + ' ======');
console.error(err);
process.exit(1001);
} else
console.log('====== Copied asset from ' + source + ' to ' + destination + ' ======');
});
});
} catch (e) {
console.error(e);
console.error(e.stack);
process.exit(1000);
}
example requirements.json
[
"js",
"css",
"img",
"index.html"
]
Note that you can move stuff directly into the build www directory (inside platforms) but they have different paths under ios and android