We have just started working with Appium in my company, using it to automate testing on websites and webapps.
Testing Framework = Nunit 2.6.4
Language used = C#
Mobile Device = Samsung Galaxy S4
Android version = 5.0.1
I've used Selenium and Nunit to test on Desktop before on a simple website, using [Test], [TestCase] and [TestCaseSource] attributes in my tests.
Following the advice in the article of the answer to:
How to integrate Appium with C#?
(Quicker article link here:
http://blogs.technet.com/b/antino/archive/2014/09/22/how-to-set-up-a-basic-working-appium-test-environment.aspx)
An associate set up a solution that would do a simple navigation to StackOverflow, click a link and assert:
namespace AppiumTests
{
using System;
using NUnit.Framework;
using AppiumTests.Helpers;
using AppiumTest.Framework;
using OpenQA.Selenium; /* Appium is based on Selenium, we need to include it */
using OpenQA.Selenium.Appium; /* This is Appium */
using OpenQA.Selenium.Appium.Interfaces; /* Not needed for commands shown here. It might be needed in single tests for automation */
using OpenQA.Selenium.Appium.MultiTouch; /* Not needed for commands shown here. It might be needed in single tests for automation */
using OpenQA.Selenium.Interactions; /* Not needed for commands shown here. It might be needed in single tests for automation */
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.Android;
[TestFixture]
public class AndroidAppiumTestSuite
{
private AppiumDriver driver;
private static Uri testServerAddress = new Uri(TestServers.WindowsServer);
private static TimeSpan INIT_TIMEOUT_SEC = TimeSpan.FromSeconds(180); /* Change this to a more reasonable value */
private static TimeSpan IMPLICIT_TIMEOUT_SEC = TimeSpan.FromSeconds(10); /* Change this to a more reasonable value */
[SetUp]
public void BeforeAll()
{
DesiredCapabilities capabilities = new DesiredCapabilities();
TestCapabilities testCapabilities = new TestCapabilities();
//testCapabilities.App = "";
testCapabilities.AutoWebView = true;
testCapabilities.AutomationName = "<just a name>";
testCapabilities.BrowserName = "Chrome"; // Leave empty otherwise you test on browsers
testCapabilities.DeviceName = "Needed if testing on IOS on a specific device. This will be the UDID";
testCapabilities.FwkVersion = "1.0"; // Not really needed
testCapabilities.Platform = TestCapabilities.DevicePlatform.Android; // Or IOS
testCapabilities.PlatformVersion = "5.0.1"; // Not really needed
testCapabilities.AssignAppiumCapabilities(ref capabilities);
driver = new AndroidDriver(testServerAddress, capabilities, INIT_TIMEOUT_SEC);
driver.Manage().Timeouts().ImplicitlyWait(IMPLICIT_TIMEOUT_SEC);
}
[TearDown]
public void AfterAll()
{
TestContext.CurrentContext.Result.ToString();
driver.Quit(); // Always quit, if you don't, next test session will fail
}
/// <summary>
/// Just a simple test to heck out Appium environment.
/// </summary>
[Test]
public void CheckTestEnvironment()
{
driver.Navigate().GoToUrl("http://stackoverflow.com");
driver.FindElementByCssSelector("body > div.topbar > div.network-items > div.login-links-container > a").Click();
Assert.AreEqual("Log in using any of the following services", (driver.FindElementByCssSelector("h2.title")).Text);
}
Many thanks to Andrea Tino for this starting point.
Now this worked fine, and my colleague who set this up and showed it to me has gone on holiday leaving me the task of adding in our existing tests and tweaking bits here and there.
I added in my testclass which requires the Webdriver.Support pacakge to be installed, which depends on Webdriver >= 2.46.0
Now, when I run my code, I get a null reference exception on this line:
driver = new AndroidDriver(testServerAddress, capabilities, INIT_TIMEOUT_SEC);
This is the error I'm getting:
AppiumTests.AndroidAppiumTestSuite.CheckTestEnvironment:
SetUp : System.NullReferenceException : Object reference not set to an instance of an object.
TearDown : System.NullReferenceException : Object reference not set to an instance of an object.
So my thought was that something in 2.46.0 meant I need to supply another capability, but I've been banging my head against this for two days now with no progress.
I have a screenshot of the appium server communication, but I'm not able to link images yet XD so here is it pasted in:
info: [debug] Device launched! Ready for commands
info: [debug] Setting command timeout to the default of 60 secs
info: [debug] Appium session started with sessionId 4575272bba7d11c85414d48cf53ac8e3
info: <-- POST /wd/hub/session 303 10828.204 ms - 70
info: --> GET /wd/hub/session/4575272bba7d11c85414d48cf53ac8e3 {}
info: Proxying [GET /wd/hub/session/4575272bba7d11c85414d48cf53ac8e3] to [GET http://127.0.0.1:9515/wd/hub/session/4575272bba7d11c85414d48cf53ac8e3] with body: {}
info: Got response with status 200: {"sessionId":"4575272bba7d11c85414d48cf53ac8e3","status":0,"value":{"acceptSslCerts":true,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{},"cssSelect...
info: <-- GET /wd/hub/session/4575272bba7d11c85414d48cf53ac8e3 200 6.770 ms - 506
info: --> POST /wd/hub/session {"desiredCapabilities":{"javascriptEnabled":true,"device":"Android","platformName":"Android","deviceName":"d5cb5478","browserName":"Chrome","platformVersion":"5.0.1","browserVersion":"43.0.2357.93"}}
error: Failed to start an Appium session, err was: Error: Requested a new session but one was in progress
So from here I can see that its trying to start a new session when I've already started one, but I can't figure out the cause!
So here's how to get around the Appium-specific half of the problem -- I don't have an answer for your NullReferenceException.
That Appium error is caused when the port you're trying to start Appium WebDriver on is already in use.
To manually fix this
You can do $telnet ip port to figure out what Process ID you need to kill.
You can find the address/port by checking the value for what new Uri(TestServers.WindowsServer); returns.
Exit any emulators
Once you have the PID then you can do $kill -9 pid and start your Appium server like normal.
A proper solution
If you are having this problem regularly, it may be because your script is ending without quitting the Appium WebDriver.
Usually you put the teardown code for the WebDriver (driver.quit()) in the #After section of your tests, or in your base TestCase class.
I see that you have a teardown section there -- so maybe you got into this bad state during a previous session? Either way, the manual fix should get you back to working order.
Related
I'm having issues testing iPhone on BrowserStack with tests written in C# with Selenium and Protractor-net.
The test starts running and after it opens the webpage to my website, it just hangs and never moves on to the StringAssert step. There are no errors when this happens. I must manually stop my test and the session in BrowserStack to continue.
I tried turning on logging from within BrowserStack's capabilities, but no errors are returning and the console log is empty. I've tried multiple configs of iPhones too.
Note, this sample test works fine with Android Google Pixel 2 and Windows 10 testing on BrowserStack, just iPhone's are giving me this problem.
Here is my sample test:
class Class1
{
[Test]
public static void FirstTest()
{
IWebDriver driver;
DesiredCapabilities capability = new DesiredCapabilities();
capability.SetCapability("browserName", "iPhone");
capability.SetCapability("device", "iPhone 6S");
capability.SetCapability("realMobile", "true");
capability.SetCapability("os_version", "11.4");
capability.SetCapability("browserstack.console", "errors");
capability.SetCapability("browserstack.user", "");
capability.SetCapability("browserstack.key", "");
driver = new RemoteWebDriver(new Uri("http://hub-cloud.browserstack.com/wd/hub/"), capability);
driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromSeconds(10);
NgWebDriver ngdriver = new NgWebDriver(driver);
ngdriver.Navigate().GoToUrl("https://myproduction.website/");
StringAssert.Contains("MyTitle", ngdriver.Title);
NgWebElement query = ngdriver.FindElement(NgBy.Model("employeeCode"));
query.Clear();
query.SendKeys("Browserstack");
Console.WriteLine(ngdriver.Title);
ngdriver.Quit();
}
}
I understand you are running Protractor tests on real iOS devices. Protractor injects JavaScripts using execute_async method. The execute_async method is not fully supported by Appium due to which you may be seeing failures. You will find more details on the issue at the links below:
https://github.com/angular/protractor/issues/2840
https://github.com/angular/protractor/issues/1736
So I have one .feature file in which I added 4 scenario's.
.feature file
Feature: BleKeys beheren
Het beheren van BLE-keys
d.m.v. de WebInterface.
#notfs
Scenario: BLE-key toevoegen aan database
Given I'm at the BleKey/Create page.
And I have entered acceptable BLE-data.
When I press Create
Then The BLE-key should be added to the database.
#notfs
Scenario: BLE-key data aanpassen
Given There is a BleKey in the database.
And I'm at the BleKey/Edit page of that BleKey
When I edit the MAC-Adress
And I edit the Conditional Report
And I edit the Flag
And I edit the Distance
And I edit the Reference
And I edit the ExtraCfg
And I press Save
Then The BleKey should have changed correctly.
#notfs
Scenario: BLE-key data verwijderen
Given There is a BleKey in the database.
And I navigate to the Delete page of that BleKey
When I press Delete
Then The BleKey should be deleted.
#notfs
Scenario: BLE-key data van 1 sleutel bekijken
Given There is a BleKey in the database.
And I navigate to the Details page of that BleKey
Then The correct data of that BleKey should be displayed
Now when I run these tests in Visual Studio (ReSharper Unit Test Sessions Window) individually they all succeed, but when run consecutively the first one succeeds but any consecutive test fails with the following exception:
OpenQA.Selenium.WebDriverException : Unexpected error. System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:5595
As you can see the test tries to connect to some local IP-adress while it should be navigating to the base URL of:
http://localhost:58759/ + controller + method depending on the test.
I create the WebDriver instance in my steps file. Like so:
public class BleKeyBeherenSteps
{
public static RemoteWebDriver RemoteWebDriver = new ChromeDriver();
public WebinterfaceSelenium SeleniumTest = new
WebinterfaceSelenium(RemoteWebDriver);
public Navigate Navigate = new Navigate(RemoteWebDriver);
public Check Check = new Check(RemoteWebDriver);
public Edit Edit = new Edit(RemoteWebDriver);
public Delete Delete = new Delete(RemoteWebDriver);
private readonly BeheerContext _db = new BeheerContext();
}
And in my methods I navigate like this:
Driver.Navigate().GoToUrl(Adress + BleKeyIndexUrl);
Where Adress = "http://localhost:58759/"
And BleKeyIndexUrl = "BleKeys/Index"
So for some reason the WebDriver navigates to a local IP-adress instead of the localhost adress.
Edit: After every test i close the driver with: Driver.Quit();
My guess is that for some reason after the first test the Driver.Url property gets lost.
Don't worry about the localhost to IP address ambiguity, localhost typically resolves to 127.0.0.1.
Failing consecutive unit tests are frequently caused by use of static declarations in application program code. I dealt with this problem this morning and I had to reset a troublesome static variable deep in my application at the start of each unit test.
Attempting to make the code from http://blogs.windows.com/msedgedev/2015/07/23/bringing-automated-testing-to-microsoft-edge-through-webdriver/ work.
Getting an ugly exception.
Repro steps.
Install web driver from links provided ( July 24 2015 WebDriver )
Create console app.
Nuget in Selenium.WebDriver, Selenium.Support.
Run code, console window comes up fine.
When code hits the driver.Url="https://www.bing.com" it throws an exception, as noted below.
NoSuchWindowException - An unhandled exception of type 'OpenQA.Selenium.NoSuchWindowException' occurred in WebDriver.dll
My snippet is below:
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace WebDriverPlay
{
public class msedgedev_sample
{
public static void RunMSEdgeDevSample()
{
Console.WriteLine("running MSEdgeDev Sample");
RemoteWebDriver driver = null;
string serverPath = "Microsoft Web Driver";
try
{
if (System.Environment.Is64BitOperatingSystem)
{
serverPath = Path.Combine(System.Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%"), serverPath);
}
else
{
serverPath = Path.Combine(System.Environment.ExpandEnvironmentVariables("%ProgramFiles%"), serverPath);
}
// location for MicrosoftWebDriver.exe
EdgeOptions options = new EdgeOptions();
options.PageLoadStrategy = EdgePageLoadStrategy.Eager;
driver = new EdgeDriver(serverPath, options);
//Set page load timeout to 5 seconds
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5));
//string _url = #"https://www.bing.com/";
string _url = #"http://www.google.com";
Console.WriteLine("_url=" + _url);
driver.Url = _url;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
if (driver != null)
{
driver.Close();
}
}
}
}
}
After the line:
driver = new EdgeDriver(serverPath, options);
executes, you should see a command window open and connect to Edge. If the Edge browser is already open, it will close it and open a new instance. Based on your error, I don't believe you are seeing this behavior, am I correct? If so, something may be blocking the WebDriver Server from launching locally (Defender??). Check the conditional setting serverPath. I could not get the Is64BitOperatingSystem to resolve, so I chose the correct path and removed the rest of the conditional, setting serverPath to the location of the MicrosoftWebDriver.exe.
If you have the incorrect path it will not make it past the "driver" instantiation. Somehow you are making it to the driver.Url call, I assume you are getting some resolution with that serverPath. So it is possible something on the local device is blocking MicrosoftWebDriver.exe from running.
Again, you should see a command prompt with proper communication logging displayed.
One last tip, you can go to MicrosoftWebDriver.exe and run it. Then you can go to: http://dev.modern.ie/testdrive/demos/webdriver/ and "Send Request" with the default values, which should be to create a session. You will see the results posted to the page and also see the logging of the communications in the command window.
Be sure to go to that page from a different browser than Edge since it will kill the existing Edge windows, including itself.
I have a little insight, but not a workaround or fix, yet...
in my case, the web driver server for IE conflicted with my web driver server for edge... and I still do not have a workaround... I have a cycle of tests that run on five different browsers.
when I tried to add edge, it would not run edge without crashing.
the web driver in the debug folder (for the base five including IE) name is IDENTICAL to the one that is included when I run Edge.
I do not know how to fix it and meet the testing requirements... YET.
bro mak
I have some strange problem. I think I followed documentation correctly but my code doesn't work. I have this very simple hard coded test (NUnit):
[TestFixture]
public class MQQueueTests {
public const string MessageContent = "<test>This is test message</test>";
public static void Main(string[] args) {
var tests = new MQQueueTests();
tests.PutAndGetMessage();
}
[Test]
public void PutAndGetMessage() {
var properties = new Hashtable
{
{MQC.HOST_NAME_PROPERTY, "TestServer"},
{MQC.CHANNEL_PROPERTY, "Test.Channel"},
{MQC.PORT_PROPERTY, 1415},
// Is this correct? It looks like it is not
// enough because adding this line didn't solve
// the problem.
{MQC.CCSID_PROPERTY, 437}
};
using (var manager = new MQQueueManager("Test.Queue.Manager", properties)) {
using (MQQueue queue = manager.AccessQueue("Test.Queue",
MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_AS_Q_DEF)) {
MQMessage message = new MQMessage();
message.WriteUTF(MessageContent);
queue.Put(message);
MQMessage readMessage = new MQMessage();
queue.Get(readMessage);
Assert.AreEqual(MessageContent, readMessage.ReadUTF());
queue.Close();
}
manager.Disconnect();
}
}
}
I'm running the test application either from console or through Resharper 6 test runner. If I run the application in test runner I always get following exception:
IBM.WMQ.MQException : MQRC_CHANNEL_CONFIG_ERROR (reason code is 2539)
The exception is thrown by MQQueueManager.Connect (called by its constructor).
If I check MQ logs I see:
AMQ9541: CCSID supplied for data conversion not supported.
EXPLANATION: The program ended because, either the source CCSID '437'
or the target CCSID '852' is not valid, or is not currently supported.
ACTION: Correct the CCSID that is not valid, or ensure that the
requested CCSID can be supported.
If I run the application from the console I got the same error but if I change the code page for console by calling
chcp 437
My test application works. How can I configure code page from code?
Well I found a workaround - it can probably solve my problem but I'm not very satisfied with it. I can set up MQCCSID environment variable either globally or by calling:
Environment.SetEnvironmentVariable("MQCCSID", "437");
That will configure code page. Still I would like to use properties of a new MQQueueManager instance to setup code page.
Both of these are answers correct. For Windows Forms Project setting the environment variable MQCCSID the same as the ccsid of the Queue Manager that you are trying to connect will be enough.
- the 2nd solution
HKEY_LOCAL_MACHINE->SYSTEM->CurrentControlSet->Control->Nls->CodePage>OEMCP value.
i had a web application(web forms) that only worked with the 2nd solution
change your system locale to English(United States), on windows 7 Regional Settings -> Administrative->Change System locale. also after do that you can check it in regedit value.
regedit->HKEY_LOCAL_MACHINE->SYSTEM->CurrentControlSet->Control->Nls->CodePage check OEMCP value.
I'm using selenium-rc with C# to test my asp.net mvc2 application. Currently all I am doing is opening the home page with selenium RC.
when I run my test I see the selenium remote control open in a browser and I see my application open correctly in a browser but selenium shows a 404 error and aborts the test.
In an attempt to get this working I have cut the test down to a simple console app and have changed the default selenium port here is my code:
static void Main(string[] args)
{
try
{
var _selenium = new DefaultSelenium("localhost", 1234, "*chrome", "http://localhost:6666");
_selenium.Start();
_selenium.Open("/");
try
{
_selenium.Stop();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("Done.");
Console.ReadKey();
}
this fails with the error "XHR ERROR: URL = /localhost:6666/ Response_Code = 404 Error_Message = Not Found on session 5f2e59798ae74e7cb741d50cae7e817a"
and if you look in the running selenium console you see
15:53:16.238 INFO - Allocated session 5f2e59798ae74e7cb741d50cae7e817a for http://localhost:6666, launching...
15:53:16.265 INFO - Preparing Firefox profile...
15:53:18.325 INFO - Launching Firefox...
15:53:20.977 INFO - Got result: OK,5f2e59798ae74e7cb741d50cae7e817a on session 5f2e59798ae74e7cb741d50cae7e817a
15:53:20.980 INFO - Command request: open[/, ] on session 5f2e59798ae74e7cb741d50cae7e817a
15:53:22.654 INFO - Got result: XHR ERROR: URL = http://localhost:6666/ Response_Code = 404 Error_Message = Not Found on session 5f2e59798ae74e7cb741d50cae7e817a
Interesting things that I have tried are:
change the site to "google" - then my test works
change the site to "google" port 80 then it doesnt work.
moved my site from cassini to iis 7 - didnt work
made my site the default site on iis 7 eg http://localhost/ - didnt work
I've used fiddler to watch the session - all requests fired return successfully.
I've tried passing -avoidProxy and -ensureCleanSession when starting the RC server. Hasn't made any noticable difference.
If I reconfigure selenium to use the default port I get the following exception repeated over and over (once every 10 seconds / different sessionid each time). This doesn't happen once I've changed the default port but i've included it just in case.
16:26:38.019 WARN - POST /selenium-server/driver/?seleniumStart=true&localFrameAddress=top&seleniumWindowName=&uniqueId=sel_48694&sessionId=a87b8d6a9e444a5485a5044ef6370e2d&counterToMakeURsUniqueAndSoStopPageCachingInTheBrowser=1286810798016&sequenceNumber=4115 HTTP/1.1
java.lang.RuntimeException: sessionId a87b8d6a9e444a5485a5044ef6370e2d doesn't exist; perhaps this session was already stopped?
at org.openqa.selenium.server.FrameGroupCommandQueueSet.getQueueSet(FrameGroupCommandQueueSet.java:220)
at org.openqa.selenium.server.SeleniumDriverResourceHandler.handleBrowserResponse(SeleniumDriverResourceHandler.java:165)
at org.openqa.selenium.server.SeleniumDriverResourceHandler.handle(SeleniumDriverResourceHandler.java:131)
at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1530)
at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1482)
at org.openqa.jetty.http.HttpServer.service(HttpServer.java:909)
at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820)
at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837)
at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:245)
at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:357)
at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:534)
Can anybody shed some light?
I am using C# and had similar problem with selenium.open method. I have refered the thread haroonzone posted in his answer above. and have made following changes in my code
Declare selenium as
private DefaultSelenium selenium;
instead of
private ISelenium selenium;
and call open method as
selenium.Processor.DoCommand("open", new String[] { YOUR_URL, "true" });
instead of
selenium.Open("YOUR_URL");
Additionally, you may want to call
selenium.SetTimeout("600000");
before DoCommand
What version of Selenium Server are you using? We get this problem with Selenium Server 2.0a2. It is fixed in later versions of Selenium, so if you download the latest version of the Selenium Server and run this test against it then you wont get the XHR exception. But if you cannot update the selenium version then you can do the following. The code snippet is in Java you can have a similar in C#.
The problem is with the selenium.open method. You can find more information on the following URL.
http://code.google.com/p/selenium/issues/detail?id=408
selenium = new DefaultSelenium("localhost", port, browserString, url) {
public void open(String url) {
commandProcessor.doCommand("open", new String[] {url,"true"});
}
};