Is it possible to use the Xamarin Calabash with a programming language something other than Ruby, for example C#?
I want to automate tests for mobile devices.
If you want Ghekin as a language to describe your tests, you can use Specflow on top of Xamarin.UITest.
http://specflow.org/getting-started/
You can see an example here: https://github.com/smstuebe/xamarin-testing-demo/tree/master/Todo.Tests.UI.Specflow
A test would then look like this.
Feature: Todo
In order to remember what I have to do
As a user
I want to maintain tasks in a list
Scenario: Add a task
When I enter "Added Task"
And I press add
Then the task "Added Task" should be added to the list
The step definitions then use Xamarin.UITest
[Binding]
public sealed class TodoPageSteps
{
private TodoPage _page;
private IApp _app;
public TodoPageSteps()
{
_page = new TodoPage();
_app = FeatureContext.Current.Get<IApp>("App");
}
[When(#"I enter ""(.*)""")]
public void WhenIEnter(string task)
{
_app.Tap(_page.AddEntry);
_app.EnterText(_page.AddEntry, task);
}
[When(#"I press add")]
public void WhenIPressAdd()
{
_app.Tap(_page.AddButton);
}
[Then(#"the task ""(.*)"" should be added to the list")]
public void ThenTheTaskShouldBeAddedToTheList(string task)
{
_app.WaitForElement(_page.LabelOfTask(task));
}
}
Xamarin.UITest is C#-based Calabash
Xamarin.UITest, an Automated UI Acceptance Testing framework based on Calabash that allows programmers to write and execute tests in C# and NUnit that validate the functionality of iOS and Android Apps.
Ref: https://developer.xamarin.com/guides/testcloud/uitest/
Related
Could someone please help with how to enable / develop custom action with latest preview / 2.0 version of Bot Framweork. The microsoft documentation only seems to work for v1.4.1
Thanks
So, BotComponents are the new route for custom actions. Please follow the directions here. The two things you will likely have to change are:
Update/add a newer package for Microsoft.Azure.KeyVault.Core. I went with 3.0.5 for both projects.
Use "components":[{"name":"MultiplyDialog"}] instead of "components":[{"name":"CustomAction.MultiplyDialog"}].
On point #2, I was getting a build error (FileNotFoundException: Could not load file or assembly 'CustomAction.MultiplyDialog) and thefore did the above to resolve. Odd thing here is that once I was able to build in VS, then run and test in Composer, it's once again back to CustomAction.MultiplyDialog, but it works.
This documenation should make it's way to the Composer documentation once 2.0 is released.
Please find the documentation here.
Add a new project named MultiplyDialog to your solution. In Visual
Studio right-click on the solution in the Solution Explorer and
select Add > New Project. Use the Class Library project template.
Add a reference to the Microsoft.Bot.Builder.Adaptive.Runtime
package. Use the same version as the bot depends on.
Add a project reference from the bot project to the component
project. Right-click on the project and select Add > Project
Reference. Choose the MultiplyDialog project and click OK.
Build the entire solution to restore all packages and validate the
dependency tree.
Create the custom action
Actions in Composer are special implementations of the Dialog base class. This allows each action in the trigger to be pushed onto the dialog stack, and executed in turn.
In the new project, rename the Class1.cs file to MultiplyDialog.cs, and update it's contents to look like the below:
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs;
using Newtonsoft.Json;
public class MultiplyDialog : Dialog
{
[JsonConstructor]
public MultiplyDialog([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
{
// enable instances of this command as debug break point
RegisterSourceLocation(sourceFilePath, sourceLineNumber);
}
[JsonProperty("$kind")]
public const string Kind = "MultiplyDialog";
[JsonProperty("arg1")]
public NumberExpression Arg1 { get; set; }
[JsonProperty("arg2")]
public NumberExpression Arg2 { get; set; }
[JsonProperty("resultProperty")]
public StringExpression ResultProperty { get; set; }
public override Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
var arg1 = Arg1.GetValue(dc.State);
var arg2 = Arg2.GetValue(dc.State);
var result = Convert.ToInt32(arg1) * Convert.ToInt32(arg2);
if (this.ResultProperty != null)
{
dc.State.SetValue(this.ResultProperty.GetValue(dc.State), result);
}
return dc.EndDialogAsync(result: result, cancellationToken: cancellationToken);
}
}
Create the schema file
The .schema file for the component is a partial schema that will be merged into the main .schema file for the bot. Although it is possible to edit the main sdk.schema file for the bot directly, doing so is not recommended. Merging partial schema files will isolate changes, allow for easier recovery from errors, and enable easier packaging of your component for reuse.
Create a new file in the project named MultiplyDialog.schema and update the contents to the below:
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Multiply",
"description": "This will return the result of arg1*arg2",
"type": "object",
"additionalProperties": false,
"properties": {
"arg1": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Arg1",
"description": "Value from callers memory to use as arg 1"
},
"arg2": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Arg2",
"description": "Value from callers memory to use as arg 2"
},
"resultProperty": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Result",
"description": "Value from callers memory to store the result"
}
}
}
Create the BotComponent class
The adaptive runtime will dynamically discover and inject components at startup time.
Create a new MultiplyDialogBotComponent.cs file in the project and update the contents to
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs.Declarative;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
public class MultiplyDialogBotComponent : BotComponent
{
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// Anything that could be done in Startup.ConfigureServices can be done here.
// In this case, the MultiplyDialog needs to be added as a new DeclarativeType.
services.AddSingleton<DeclarativeType>(sp => new DeclarativeType<MultiplyDialog>(MultiplyDialog.Kind));
}
}
In the appsettings.json file of the bot project (located at \settings)to include the MultiplyDialogBotComponent in the runtimeSettings/components array.
"runtimeSettings": {
"components": [
{
"name": "MultiplyDialog"
}
]
}
Merge schema files
The final step is to merge the partial schema file from the MultiplyDialog project into the main sdk.schema file for the bot. This makes the custom action available for use in Composer.
Navigate to the schemas folder in the myBot project. This folder contains a PowerShell script and a bash script. Use an elevated PowerShell terminal to execute the PowerShell script. You will need to either copy/paste the contents of the script, or ensure your execution-policy allows for running unsigned scripts.
To validate the script executed successfully, search for MultiplyDialog inside the MyBot\schemas\sdk.schema file and validate that the partial schema from the MultiplyDialog.schema file is included in sdk.schema.
I created a xamarin.forms project. Suppose I have a button, and I want this button to call different platforms' APIs (third-party ios / android skd) on different platforms.
How to import jar for xamarin.android/ios sdk for xamarin.ios?
Assuming this button is in a page of xamarin.forms, how do I bind different events for different platforms so that it can call different APIs on different platforms?
Project structure:
Xamarin has documentation about binding native libraries. You can find android here and ios here.
You can do different things in button click event for different platforms with using Xamarin.Forms Device Class.
private void Button_Clicked(object sender, EventArgs e)
{
switch (Device.RuntimePlatform)
{
case Device.iOS:
//Do iOS thing
break;
case Device.Android:
//Do Android thing
break;
default:
break;
}
}
3.If you want to work with different platform api then you can use Dependency Service just like Adlorem's answer. Documentation is here.
In this case you must implement dependency service
Pseudo code example
In shared code create public interface
public interface IService
{
void DoSomething();
}
In specific platform code create dependency service
[assembly: Xamarin.Forms.Dependency(typeof(MyServiceIOS))]
namespace MyNamespace.iOS
{
public class MyServiceIOS : IService
{
public void DoSomething()
{
//your code here
}
}
}
I am monitoring the user's location every 15 minutes and I just want the application to continue sending the location even if the user closes the application in the taskbar.
I tried this sample but it's in Xamarin.Android https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/services/foreground-services i have to create a dependencyservice but i don't know how.
i have to create a dependencyservice but i don't know how.
First, create an Interface in the Xamarin.forms project:
public interface IStartService
{
void StartForegroundServiceCompat();
}
And then create a new file let's call it itstartServiceAndroid in xxx.Android project to implement the service you want:
[assembly: Dependency(typeof(startServiceAndroid))]
namespace DependencyServiceDemos.Droid
{
public class startServiceAndroid : IStartService
{
public void StartForegroundServiceCompat()
{
var intent = new Intent(MainActivity.Instance, typeof(myLocationService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
MainActivity.Instance.StartForegroundService(intent);
}
else
{
MainActivity.Instance.StartService(intent);
}
}
}
[Service]
public class myLocationService : Service
{
public override IBinder OnBind(Intent intent)
{
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// Code not directly related to publishing the notification has been omitted for clarity.
// Normally, this method would hold the code to be run when the service is started.
//Write want you want to do here
}
}
}
Once you want to call the StartForegroundServiceCompat method in Xamarin.forms project, you can use:
public MainPage()
{
InitializeComponent();
//call method to start service, you can put this line everywhere you want to get start
DependencyService.Get<IStartService>().StartForegroundServiceCompat();
}
Here is the document about dependency-service
For iOS, if the user closes the application in the taskbar, you will no longer be able to run any service. If the app is running, you can read this document about ios-backgrounding-walkthroughs/location-walkthrough
You might want to have a look at Shiny by Allan Ritchie. It's currently in beta but I would still suggest using it, as it will save you a lot of trouble writing this code yourself. Here's a blog post by Allan, explaining what you can do with Shiny in terms of background tasks - I think Scheduled Jobs are the thing you're looking for.
I have created a Serenity Test. What it does is Open Google then search for online calculator. Then it should:
Click 1
Click +
Click 1
Click =
My code is :
givenThat(gdguradio).wasAbleTo(openTheApplication);
when(gdguradio).attemptsTo(Search.forTheTerm("online calculator"));
when(gdguradio).attemptsTo(EnterInFormula.forEnteringinFormula());
//guradio.AddingTwoNumbers();
guradio.shouldSeeSumEquals("3");
Then my EnterInFormula.forEnteringinFormula()
#Step("{0} clears all the completed items")
public <T extends Actor> void performAs(T actor) {
actor.attemptsTo(Click.on(SearchBox.NumberOne));
actor.attemptsTo(Click.on(SearchBox.NumberPlus));
actor.attemptsTo(Click.on(SearchBox.NumberTwo));
actor.attemptsTo(Click.on(SearchBox.NumberEquals));
}
public static EnterInFormula forEnteringinFormula() {
return instrumented(EnterInFormula.class);
}
My SearchBox :
public class SearchBox {
public static Target SEARCH_FIELD = Target.the("search field").located(By.name("q"));
public static Target CalculatorFormula = Target.the("Calculator Formula").located(By.id("cwos"));
public static Target NumberOne = Target.the("1").located(By.id("cwbt33"));
public static Target NumberTwo = Target.the("2").located(By.id("cwbt34"));
public static Target NumberPlus = Target.the("+").located(By.id("cwbt46"));
public static Target NumberEquals = Target.the("=").located(By.id("cwbt45"));
}
It looks OK until the pressing of keys. It only presses number 2 so the test fails.
How to correctly write the clicking of buttons?
The code looks fine. This looks like a normal Selenium automation issue - Selenium says the element is not enabled, so for Selenium, it probably isn’t. You may need to wait for some event or state before the button becomes ready to click.
I've inherited a web application written in ASP.NET that has an incomplete implementation of a localization scheme (not using resource files). Here's a micro version:
public class Useful
{
public void DoSomething()
{
return Localizations.Do_Something_Message_vx7Hds8i;
}
}
public class Localizations
{
public const string Do_Something_Message_vx7Hds8i = "Some text!";
}
In almost all cases, these localized strings aren't even used in more than one place. I'd like to factor out this annoying localization layer before properly localizing the app.
The end result I want is just:
public class Useful
{
public void DoSomething()
{
return "Some text!";
}
}
This is proving tediously slow and I have over 1000 in this app.
What would be awesome would be a one-click way of selecting the reference and have it automatically suck in the string contents. I'm using Visual Studio 2008 and ReSharper 5.1.
Does anyone know if there's a way to accomplish this? It seems like there should be a proper name for what I'm trying to do (anti-modularization?) but I'm a little stumped where to start.
The default key command in Resharper is Ctrl+Alt+N for inline refactoring.