Starting Appium programatically using javascript - appium

I am using Javascript with Node.JS and WDIO and trying to start appium programatically in beforeTest hook and stop it in afterTest hook.
I've tried doing so with child_process or some appium-service builder but without any success.
Is there a possibility to start/stop appium server programatically using certain portion of code?
Thanks

You can install appium in your project directory. Import appium and call appium.main(). This will start appium in the default port.
Start appium :
const appium = require('appium');
await appium.main({port : 4723, address : "127.0.0.1"})
Stop appium :
To stop appium programatically, you can kill the process. I used this package - https://www.npmjs.com/package/find-process to find the pid and kill process.
const findProcess = require('find-process')
let processList = await findProcess('port', 4723)
if(processList.length > 0) {
processList.forEach(proc => {
process.kill(proc.pid)
})
}

Related

I need to use Appium 2 for CodeceptJS mobile tests

Because latest iOS is making problems with Appium 1.x, Appium team is no longer supporting it,
and Appium 2 is working ok - I need to use v2...
CodeceptJS 3.3.x is using Appium 1.x now and because of the '/wd/path' used by default in CodeceptJS Appium helper, I can't set it to use Appium 2.
When starting a test, CodeceptJS fails with:
Error: Failed to create session.
The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource
Please make sure Selenium Server is running and accessible
Error: Can't connect to WebDriver.
Error: Failed to create session.
The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource
Please make sure Selenium Server is running and accessible
And Appium 2 fails with:
[debug] [HTTP] No route found for /wd/hub/session
[HTTP] <-- POST /wd/hub/session 404 1 ms - 211
Is there a way to change the default '/wd/path' to just '/' ?
Or is there another helper or something for Appium 2?
Part of the codecept.config.js file:
Appium: {
host: process.env.CLOUD_HOST || 'localhost',
port: parseInt(process.env.CLOUD_PORT) || 4723,
app: (PLATFORM_NAME === 'iOS') ? APP_PATH_IOS || 'com.mobile.beta' : APP_PATH_ANDROID,
desiredCapabilities: {
platformName: process.env.PLATFORM_NAME || 'iOS',
platformVersion: process.env.PLATFORM_VERSION || '16.0',
automationName: process.env.AUTOMATION_NAME || 'xcuitest',
deviceName: process.env.DEVICE_NAME || 'iPhone Xs',
appPackage: process.env.APP_PACKAGE,
appActivity: process.env.APP_ACTIVITY,
xcodeOrgId: process.env.XCODE_ORG_ID,
// udid: process.env.UDID, // used only for real iOS device
},
},
=========================================
UPDATE:
I started Appium with --base-path /wd/hub (appium --base-path /wd/hub) but now another error appears:
Error: Can't connect to WebDriver.
Error: Failed to create session.
All non-standard capabilities should have a vendor prefix. The following capabilities did not have one: platformVersion,automationName,deviceName,appPackage,appActivity,xcodeOrgId,app
Please make sure Selenium Server is running and accessible
I tried updating the capabilities in codecept.conf.js with appium: prefix, but either I do it wrong or it doesn't work:
The Update:
Appium: {
host: process.env.CLOUD_HOST || 'localhost',
port: parseInt(process.env.CLOUD_PORT) || 4723,
app: (PLATFORM_NAME === 'iOS') ? APP_PATH_IOS || 'com.mobile.beta' : APP_PATH_ANDROID,
desiredCapabilities: {
'appium:platformName': process.env.PLATFORM_NAME || 'iOS',
'appium:platformVersion': process.env.PLATFORM_VERSION || '16.0',
'appium:automationName': process.env.AUTOMATION_NAME || 'xcuitest',
'appium:deviceName': process.env.DEVICE_NAME || 'iPhone Xs',
'appium:appPackage': process.env.APP_PACKAGE, // not needed for iOS
'appium:appActivity': process.env.APP_ACTIVITY, // not needed for iOS
'xcodeOrgId': process.env.XCODE_ORG_ID, // not needed for Android
udid: process.env.UDID, // used only for real iOS device testing
},
},
Error:
Error: Can't connect to WebDriver.
Error: Invalid or unsupported WebDriver capabilities found ("platformVersion", "deviceName", "appPackage", "appActivity", "xcodeOrgId", "app", "tunnelIdentifier"). Ensure to only use valid W3C WebDriver capabilities (see https://w3c.github.io/webdriver/#capabilities).If you run your tests on a remote vendor, like Sauce Labs or BrowserStack, make sure that you put them into vendor specific capabilities, e.g. "sauce:options" or "bstack:options". Please reach out to to your vendor support team if you have further questions.
Please make sure Selenium Server is running and accessible
Error#2:
Error: Can't connect to WebDriver.
Error: Invalid or unsupported WebDriver capabilities found ("deviceName", "app", "tunnelIdentifier"). Ensure to only use valid W3C WebDriver capabilities (see https://w3c.github.io/webdriver/#capabilities).If you run your tests on a remote vendor, like Sauce Labs or BrowserStack, make sure that you put them into vendor specific capabilities, e.g. "sauce:options" or "bstack:options". Please reach out to to your vendor support team if you have further questions.
Please make sure Selenium Server is running and accessible
If you are starting Appium server using the CLI you can use something like appium -p 4726 --base-path /wd/hub which will make it accept requests on the old endpoint
Update:
With Appium 2.0, the Appium server will enforce strict compability with the W3C WebDriver specification when it comes to Capabilities. They can be found here. Anything else that you provide for Appium should have the appium: prefix (like appium:platformVersion, appium:appPackage and so on)
This is most probably a problem with the CodeceptJS's Appium helper and needs to be updated to follow the Appium's more strict compability with the W3C WebDriver specification.
The update needs a support for prefixes like:
...
appium:platformName: 'iOS'
appium:automationName: 'xcuitest'
...
or
...
browserstack:platformName: 'Android'
saucelabs:automationName: 'uiautomator2'
...
for now, we can't configure variables with prefixes.
There's also no way I know of, to contact the CodeceptJS maintainers for making this update.

The neo4j cypher shell and the browser connections are working but the golang client connection is not working

I have disabled the authentication on my neo4j server, so I can connect using the cypher shell using no credentials as it follows and is working.
$ ./bin/cypher-shell -a 192.168.0.89
This is how I'm declaring my driver and the session, I also tried using neo4j://* instead of bolt://*:
driver, err := neo4j.NewDriver("bolt://192.168.0.89:7687", neo4j.NoAuth())
if err != nil {
return "", err
}
defer driver.Close()
session, _ := driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite})
defer session.Close()
But that doesn't work either. I'm getting this error when running the hello world from the neo4j olang driver page https://neo4j.com/developer/go/
TLS error: Remote end closed the connection, check that TLS is enabled on the server
There are the logs of the server when it starts:
2021-03-07 23:17:23.227+0000 INFO ======== Neo4j 4.2.3 ========
2021-03-07 23:17:24.119+0000 INFO Performing postInitialization step for component 'security-users' with version 2 and status CURRENT
2021-03-07 23:17:24.119+0000 INFO Updating the initial password in component 'security-users'
2021-03-07 23:17:24.243+0000 INFO Bolt enabled on 192.168.0.89:7687.
2021-03-07 23:17:25.139+0000 INFO Remote interface available at http://192.168.0.89:7474/
2021-03-07 23:17:25.140+0000 INFO Started.
These are all my config settings:
dbms.connector.bolt.advertised_address=192.168.0.89:7687
dbms.connector.bolt.enabled=true
dbms.connector.bolt.listen_address=192.168.0.89:7687
dbms.connector.bolt.tls_level=DISABLED
dbms.connector.http.advertised_address=192.168.0.89:7474
dbms.connector.http.enabled=true
dbms.connector.http.listen_address=192.168.0.89:7474
dbms.connector.https.enabled=false
dbms.default_advertised_address=192.168.0.89
dbms.default_database=neo4j
dbms.default_listen_address=192.168.0.89
dbms.directories.import=/home/eduardo/NEO4J/import
dbms.directories.neo4j_home=/home/eduardo/NEO4J
dbms.jvm.additional=-Dlog4j2.disable.jmx=true
dbms.security.auth_enabled=false
dbms.tx_log.rotation.retention_policy=1 days
dbms.tx_state.memory_allocation=ON_HEAP
dbms.windows_service_name=neo4j
Again, I can connect to the same host and the browser is also working fine:
Thanks in advance for any help :)
Adding to your answer: it is likely you're using the v1.x of the Go driver. If you switch to using the v4.x driver instead, you will not have to specify this config value.
You can upgrade by simply adding v4 in your import statement like so:
import github.com/neo4j/neo4j-go-driver/v4/neo4j
More info: https://github.com/neo4j/neo4j-go-driver/blob/4.2/MIGRATIONGUIDE.md
For anyone looking for the answer, the bolt driver will try to use TLS by default and since in my case is not configured, the encryption needs to be disabled in the driver constructor call.
driver, err := neo4j.NewDriver("bolt://192.168.0.89:7687", neo4j.NoAuth(), func(c *neo4j.Config) { c.Encrypted = false })
Hope this helps other people experiencing the same issue :)

Appium Server not connected and throwing org.openqa.selenium.remote.UnreachableBrowserException

I have recently started mobile devices automation on appium with the java language.
I am trying to run the initial setup code through program it is returning this failure message.
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:4723 [/127.0.0.1] failed: Connection refused: connect
When Manual run Appium server it doesn't have any errors and server started; the android apk file is installed.
Below is my code; Eclipse doesn't show any errors. I use Android Emulator for this Initial test. Appium and Java Project code in same host machine.
public void setup() throws MalformedURLException {
WebDriver AppWebDriver = null;
AppiumDriver ApUMDriver = null;
AndroidDriver AppiumURLDriver;
URL Serverurl;
// TODO Auto-generated method stub
DesiredCapabilities Appiumcapabiliy = new DesiredCapabilities();
File appDir = new File("c:\ApkbuildsDir");
File app = new File(appDir, "xxx.apk");
Appiumcapabiliy.setCapability("devicename","Device11");
Appiumcapabiliy.setCapability("platformname","Android");
Appiumcapabiliy.setCapability("platformVersion","4.2.2");
Appiumcapabiliy.setCapability("app-package","packagename");
Appiumcapabiliy.setCapability("app-activity","activityscreen");
Appiumcapabiliy.setCapability("app", app.getAbsolutePath());
Serverurl = new URL("http://127.0.0.1:4723/wd/hub");
AppWebDriver = new AndroidDriver(Serverurl,Appiumcapabiliy);
AppWebDriver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);
ApUMDriver.findElement(By.name("My Card"));
}
Could you please guide me how to eliminate this server connect error through program.
Regards, Kiran
Looks like "Appium server" instance is NOT running in your machine. That is, http://127.0.0.1:4723/wd/hub
Please start the Appium server on 4723 port and try execute your code.

How to start the Appium server from command prompt in MAC machine?

I am automating ios native mobile application using appium. Until now I was launching the server from the Appium GUI by clicking on the Launch button. Now I want to start the server from a command prompt.
I was able to do the same in Windows machine by following the below steps:
Launch Node.js command prompt
Navigate till the Appium bin folder
Use the command node appium
I got blocked on how to start the Node.js command prompt on a Mac. Can you pleases tell me how I can start the Appium server from a command prompt on a Mac.
if you used npm install -g appium then you should be able to directly open one with the command
appium //plus any server args you want ex: appium -p 4474
Or you can still navigate to the folder of your node_modules and into appium and go with
node . //plus any server args you want
if you want to have additional server flags, all are available at their site with documentations.
Open the terminal and type in the following command
appium --address 127.0.0.1 --port 4723
Press enter then it will register itself to 127.0.0.1 and will listen 4723 port. You can extend this command by adding app type etc.
Hope this will help you
cheers
/Applications/Appium.app/Contents/Resources/node/bin/node /Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js --address 127.0.0.1 --chromedriver-port 9516 --bootstrap-port 4725 --no-reset --local-timezone --command-timeout 7200 --session-override --debug-log-spacing --platform-version 9.0 --platform-name iOS --app /Users/chennareddy/u/apps/TestApp/build/release-iphonesimulator/Handstand/Handstand.app --show-ios-log --device-name iPhone-6s --native-instruments-lib --orientation Portrait
To start appium in MAC, all you need to do is to type => appium & in the terminal application. In order for the above command to work, you have to install appium in terminal mode. However there are 2 ways of doing it, one is with HomeBrew and the other directly with Node.js . You can find the tutorial of installing HomeBrew online. Follow the steps below to install it directly with node.js -
Go to https://nodejs.org/
Download and install the latest stable version of node.js package in your mac
Now open the terminal application
Run the following command => npm install -g appium
This should install Appium in your system with global privileges. After installation of appium, you can run the command => appium-doctor in the same terminal window to verify if everything is installed properly.
If everything is in green ticks, run => appium & to start the appium server
Hope this helped.
As other answers points out, if you have installed Appium thru terminal then simply type appium & on a terminal window to start appium server. Here all you need to know, how to install appium thru terminal.
1. Install Homebrew.
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2. Give Following commands one by one to install appium
brew install node # get node.js
npm install -g appium # get appium
npm install wd # get appium client
appium & # start appium
You can find refer to step by guide for appium download osx here.
String tellCommand = "tell application \"Terminal\" to do script \"/usr/bin/node_modules/appium/bin/appium.js";
String parameters = " -p "+port;
parameters += " "+ (fullReset ? "--full-reset" : "--no-reset")+"\"";
tellCommand += parameters;
String[] command = { "osascript", "-e",
tellCommand };
ProcessBuilder pBuilder = new ProcessBuilder(command);
pBuilder.start();
Try this to launch your appium server programmatically for mac os, it includes automating the webkit debug proxy as well which is needed for debugging.
//customize the below in start server method
//Webkit Proxy command
CommandLine iOSProxyCommand = new CommandLine("ios_webkit_debug_proxy");
iOSProxyCommand.addArgument("-c");
iOSProxyCommand.addArgument(udid+":27753");//provide your udid of the device
iOSProxyCommand.addArgument("-F");//to disable console output in eclipse
DefaultExecuteResultHandler iOSProxyresultHandler = new DefaultExecuteResultHandler();
DefaultExecutor iOSProxyexecutor = new DefaultExecutor();
iOSProxyexecutor.setExitValue(1);
try {
iOSProxyexecutor.execute(iOSProxyCommand, iOSProxyresultHandler);
iOSProxyCommand.toString()));
Thread.sleep(5000);
System.out.println("iOS Proxy started.");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
CommandLine command = new CommandLine(
"/Applications/Appium.app/Contents/Resources/node/bin/node");
command.addArgument( "/Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js",
false);
command.addArgument("--address", false);
command.addArgument("127.0.0.1");
command.addArgument("--port", false);
command.addArgument("4723");
command.addArgument("--full-reset", false);
command.addArgument("--log-level", false);//to disable console output in eclipse
command.addArgument("error");
command.addArgument("--log", false);
Timestamp currentTimestamp = new java.sql.Timestamp(Calendar.getInstance().getTime().getTime());
command.addArgument("/Users/sethupandi/appium"+currentTimestamp+".log");
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
try {
executor.execute(command, resultHandler);
Thread.sleep(5000);
System.out.println("Appium server started.");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//customize the below in stop appium server-
//kill appium node after end of your execution
String[] command = { "/usr/bin/killall", "-9", "node" };
try {
Runtime.getRuntime().exec(command);
System.out.println("Appium server stopped.");
} catch (IOException e) {
e.printStackTrace();
}
//Kill webkit proxy for iOS
String[] commandProxy = { "/usr/bin/killall", "-9", "ios_webkit_debug_proxy" };
try {
Runtime.getRuntime().exec(commandProxy);
System.out.println("iOS Webkit proxy stopped");
} catch (IOException e) {
e.printStackTrace();
}
For anybody reading this who happens to be using npm (node/js/typescript), I've created a module called appium-controller that starts and stops appium in the background programmatically (mac or windows). It has an option to pass in a specific port either through a node call to the method or through cli.

grails + selenium-rc plugin - cannot run sample test

I have no idea what I do wrong. I would like to use selenium-RC plugin for Grails to do some functional testing. I have created sample test using build-in script (i guess add-selenium-test), which generated (i modified it slighty):
import grails.plugins.selenium.*
import org.junit.*
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
#Mixin(SeleniumAware)
class FirstTestTests {
#Before void setUp() {
}
#After void tearDown() {
super.tearDown()
}
#Test void something() {
selenium.open "/activate"
assertTrue selenium.isTextPresent("activate")
}
}
I configured SeleniumConfig
selenium {
slow = false // true to run tests in slow resources mode
singleWindow = true // true for single window mode, false for multi-window mode
browser = "*firefox" // can include full path to executable, default value is *firefox or *iexplore on Windows
url = "http://localhost:8080" // the base URL for tests, defaults to Grails server url
defaultTimeout = 3000 // the timeout after which selenium commands will fail
windowMaximize = true // true to maximize browser on startup
screenshot {
dir = "./target/test-reports/screenshots" // directory where screenshots are placed relative to project root
onFail = true // true to capture screenshots on test failures
}
server {
host = "localhost" // the host the selenium server will run on
port = 4444 // the port the selenium server will run on
}
userExtensions = "" // path to user extensions javascript file
}
and I then I typed
grails test-app :selenium
and it seems that everything is done correctly:
INFO 19:30:08,304 RemoteWebDriver instances should connect to: http://127.0.0.1:
4444/wd/hub org.openqa.selenium.server.SeleniumServer
Starting Selenium server on port 4444 ...
INFO 19:30:08,312 Version Jetty/5.1.x org.openqa.jetty.http.HttpServer
INFO 19:30:08,315 Started HttpContext[/selenium-server/driver,/selenium-server/d
river] org.openqa.jetty.util.Container
INFO 19:30:08,318 Started HttpContext[/selenium-server,/selenium-server] org.ope
nqa.jetty.util.Container
INFO 19:30:08,321 Started HttpContext[/,/] org.openqa.jetty.util.Container
INFO 19:30:08,326 Started org.openqa.jetty.jetty.servlet.ServletHandler#55881a8f
org.openqa.jetty.util.Container
INFO 19:30:08,328 Started HttpContext[/wd,/wd] org.openqa.jetty.util.Container
INFO 19:30:08,338 Started SocketListener on 0.0.0.0:4444 org.openqa.jetty.http.S
ocketListener
INFO 19:30:08,340 Started org.openqa.jetty.jetty.Server#42aefb01 org.openqa.jett
y.util.Container
Starting Selenium session for http://localhost:8080 ...
INFO 19:30:08,502 Checking Resource aliases org.openqa.jetty.util.Credential
INFO 19:30:08,510 Command request: getNewBrowserSession[*firefox, http://localho
st:8080, ] on session null org.openqa.selenium.server.SeleniumDriverResourceHand
ler
INFO 19:30:08,512 creating new remote session org.openqa.selenium.server.Browser
SessionFactory
INFO 19:30:08,586 Allocated session 9250557308cc4886a25100eb6c5f3d7e for http://
localhost:8080, launching... org.openqa.selenium.server.BrowserSessionFactory
INFO 19:30:08,717 Preparing Firefox profile... org.openqa.selenium.server.browse
rlaunchers.FirefoxChromeLauncher
INFO 19:30:11,726 Launching Firefox... org.openqa.selenium.server.browserlaunche
rs.FirefoxChromeLauncher
The firefox window is opened, but nothing loads and nothing seems to proceed. Do I miss something?
Sounds to me like an incompatibility between the Selenium RC plugin and the current version of your web browser. You might want to dig into the plugin's dependencies and update everything to the latest versions if you're using a newer version of the browser.
We see this with Geb ( http://www.gebish.org ) when trying to run a webdriver version that is not compatible with the driver version.
Just to add, if you use Chrome and your OS is Ubuntu, then make sure you put the full path to Chrome and make sure that the executable path references chromium-browser and NOT google-chrome.
So your SeleniumConfig should look like this with the relevant line in double asterisks:
selenium {
slow = false
singleWindow = true
**browser = "*googlechrome /usr/bin/chromium-browser"**
url = null
defaultTimeout = 60000
windowMaximize = false
screenshot {
dir = "./target/test-reports/screenshots"
onFail = false
}
server {
host = "localhost"
port = 4444
}
userExtensions = ""
}

Resources