When I invoke code like this on blackberry using (compiling) JDE 4.5.
public void invokeCall() {
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
PhoneArguments phoneArgs = new PhoneArguments(
PhoneArguments.ARG_CALL, "12345");
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE, phoneArgs);
}
});
}
The result was that a pop up screen showed up and told that the phone number used to access extensions within my corporation has not been set.
In order to disable it I set the smart dialing country code to unknown.
(This problem did not occur when compiling on JDE 5.0)
Is there any blackberry code to set this automatically?
First of all, thanks for pointing out that smart dialing matters when making calls to extensions and injecting DTMF tones, because I have a similar project where this may cause problems.
In 4.5, you can configure smart dialing aswell, but the menu is not shown in main options menu, only in the phone app options. From the "Desktop", press a numeric key to bring the phone app to foreground, then press menu -> Options -> Smart Dialing -> Country Code.
Now, to set it programmatically, use this version of PhoneArguments constructor. So in your code, replace your arguments with this line to disable smart dialing:
PhoneArguments phoneArgs = new PhoneArguments(PhoneArguments.ARG_CALL, "12345", false);
Related
I'm looking to implement where a OTP is made a suggestion at the top of the keyboard for an OTP Entry in an IOS app.
The IOS version on the phone is 12.2.
THE ISO SDK Version of my App is 12.1.
Using Visual Studio (Windows) 2017 15.9.13
Now I have done the following......
Created an new control public class OTPEntry : Xamarin.Forms.Entry
Created a renderer for the control and in this I do Control.TextContentType = UITextContentType.OneTimeCode;
I then use this control on a ContentPage with the correct namespace etc.
SO when I am on the form with this control, I send a text to the phone with an OTP. On the phone if I click on the code it offers a "Copy Code" option so it is recognised as an OTP.
However, for the life of me, when I tap in the control, to bring up the keyboard, I do not see the code in the top of the keyboard as expected.
What could I possibly be missing?
It seems the steps to implement this are relatively straightforward but I cannot seem to get it working.
Any ideas, pointers would be very greatly appreciated.
Code below...
CONTROL - IN Xamarin Forms Project
namespace XXXX
{
public class OTPEntry : Xamarin.Forms.Entry
{
public OTPEntry()
{
}
}
}
RENDERER - IN IOS Project
namespace XXXX.YYYY.ZZZZ
{
public class OTPEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.TextContentType = UITextContentType.OneTimeCode;
}
...
...
}
}
}
USAGE - IN CONTENT PAGE IN Xamarin Forms Project
<XXXX:OTPEntry x:Name="txtToken" Keyboard="Numeric" Placeholder="Two Factor Code" HeightRequest="50" WidthRequest="300" TextColor="#2A295B" BackgroundColor="White" Margin="0"/>
Firstly,OneTimeCode is available after iOS 12.0.So I suggest add the following code in CustomRenderer
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
{
Control.TextContentType = UITextContentType.OneTimeCode;
}
What happens is that when an OTP message receives into the Message Inbox, iOS runs a simple text matching algorithm that determines if that message is a valid OTP message or not and based on that keep a track of it in the memory, then when the user clicks on the OTP AutoFill enabled text field in an app, iOS keyboard popup that OTP as a suggestion in the keyboard. So that your users can fill up the OTP into the app without leaving the app or going back into the Messaging app.
You need to check if the format of OTP is correct .One way to verify whether the text message captcha format is legal is to open [SMS] on the iPhone, click on the message captcha, if from the bottom of the call option copy captcha option, can indicate that it is possible;
And don't forget to open the Autofill Passwords in system setting ->account and password .
So - after verification that the code seemed to be OK and has worked for others I was beginning to think I was going crazy.
I then had a look through the phone settings and discovered "Autofill Passwords" which was turned off.
Once I turned it on, this seems to work as expected.
I am doing some automation with Appium on a iOS mobile app.
I need to:
open the app
do some tasks
open safari
I looked around how to do it but I've been reading that it's impossible due to a limitation in apple's framework, it doesn't allow you to sent commands to more than one app per session.
Does anyone know a way around this? Or if what I read is just not 100% true.
it doesn't allow you to sent commands to more than one app per session
Thats true, but you can run 2 sessions in a single test:
create instance of appium driver with app-based capabilities
do what you need in the app
quit driver
create instance of appium driver with browser-based capabilities
do what you need in the safari
quit driver
In a quick way it may look like:
#Test
public void testBothAppAndSafari() throws MalformedURLException {
URL appiumServerUrl = new URL("<your appium server host>");
DesiredCapabilities appCaps = new DesiredCapabilities();
// put required native app capabilities in appCaps
DesiredCapabilities safariCaps = new DesiredCapabilities();
// put required safari capabilities in safariCaps
IOSDriver driver = new IOSDriver(appiumServerUrl, appCaps);
driver.findElement(<locator for element in native app>).click();
// do whatever you want with mobile app
driver.quit();
driver = new IOSDriver(appiumServerUrl, safariCaps);
driver.findElement(<locator for element in web>).click();
// do whatever you want in safari
driver.quit();
}
You can use following approach,
Created two setup one for app and other for safari.
First launch application and perform task
clear first session
Created again new Appium object for safari ( call second setup )
Perform browser activity
Close safari appium session
You also can follow my approach without quit driver.
Go terminate application. (I've used javascript to run terminateApp cause native method not work for me.)
Find Safari on Home screen and then click on it
Use drive.get to open website as you expected.
In there you can change to WEBVIEW_*** to inspect web element.
Back to native context by NATIVE_APP keyword
Sample code:
System.out.println("Run application");
Map<String, Object> params = new HashMap<>();
params.put("bundleId", "com.example");
boolean terminalApp = (boolean) driver.executeScript("mobile: terminateApp", params);
System.out.println("terminateApp: " + terminateApp);
driver.findElementById("Safari").click();
Set<String> contextNames = appDriver.getContextHandles();
// Change context to WEBVIEW_***
appDriver.context(String.valueOf(contextNames.toArray()[1]));
driver.get("https://www.google.com.vn");
Thread.sleep(20000);
// Do something.
// ...
// If you want to communicate with NATIVE context just change to NATIVE_APP.
appDriver.context("NATIVE_APP");
you can activate system apps via driver.activateApp(BUNDLE_ID);
there is no need to kill the app driver and start browser driver to access browser, just switch between apps.
safari
driver.activateApp("com.apple.mobilesafari");
Here is how I resolved the issue:
driver2.activateApp("com.apple.mobilesafari");
Thread.sleep(5000);
boolean openSafariTab =
driver2.findElements(By.xpath("//XCUIElementTypeButton[#name=\"AddTabButton\"]")).size() > 0;
if (openSafariTab) {
driver2.findElement(By.xpath("//XCUIElementTypeButton[#name=\"AddTabButton\"]")).click();
} else { }
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeTextField[#name=\"TabBarItemTitle\"]")).click();
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeOther[#name=\"CapsuleViewController" +
"\"]/XCUIElementTypeOther[3]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]")).sendKeys("https://www.golfbpm.com");
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeButton[#name=\"Go\"]")).click();
In my initial proof of concept for testing a React Native mobile app using Appium, I noticed that when I load the APK to start my test, I am presented with an Android prompt to "Permit drawing over other apps" as I am creating my AndroidDriver driver. If I move the slider manually, then click the back button, all is good -- the app loads fully, and my test proceeds. However, I don't see how to do this with automation using my Appium script because it looks like the driver instantiation will not complete until the slider is moved.
Most people don't see this in Appium testing as it appears to be specific to React Native in dev mode, as seen here...
Here's my code where I've put in conditional code to click the slider, but I never get there because it waits at the "driver = ..." line:
AndroidDriver driver = null;
#Before
public void setUp() throws Exception {
// < defining capabilities (emulator6p) up here...>
// initialize driver object
try {
driver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), emulator6p);
} catch (MalformedURLException e) {
System.out.println(e.getMessage());
}
}
#Test
public void test1() throws Exception {
By BY_slider_permitDrawing = By.id("android:id/switchWidget");
boolean present = (driver.findElements(BY_slider_permitDrawing).size() == 1);
if (present) {
driver.findElement(BY_slider_permitDrawing).click();
driver.navigate().back();
}
WebElement button_begin = driver.findElementByAccessibilityId("button-lets-begin");
button_begin.click();
}
I definitely hear plenty of people say that Appium is a viable solution for React Native testing, and really need to get over this hump.
Thanks in advance for any suggestions!
jph
p.s. In case it wasn't really clear, the test does NOT hang at the "driver = " line if I am not loading the APK from scratch, but I will need to do that for CI testing in the future.
Setting right capabilities helped me to run Appium tests in Debug mode on Android:
{
...
"appWaitPackage": "com.android.settings, com.yourPackage",
"appWaitActivity": "com.android.settings.Settings$AppDrawOverlaySettingsActivity, com.yourPackage.MainActivity",
}
Replace yourPackage with your real package name used in Android app. Some docs here: https://appium.io/docs/en/writing-running-appium/caps/#android-only
As per project requirement i am working on Mobile App automation. Not problem arises when i executed same code which worked fine on emulator but when it comes to real device the same code were getting failed.the problem is UiAutomator is not able to locate element because of native keyboard come before an application during simulation. I executed this entire thing into Galaxy nexus which works on ANDROID API 18.hence no point to execute whole automation suites in Selendroid mode. in below code after filling value in first editbox,control should have reached to second editbox to fill value and so on. But it does not fill value there because native keyboard appear before application.
SwipeableWebDriver driver = new SwipeableWebDriver(
new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
List<WebElement> editTextList = driver.findElements(By
.className("android.widget.EditText"));
editTextList.get(0).sendKeys(c + "Bob");
editTextList.get(1).sendKeys("123");
editTextList.get(2).sendKeys("456");
el = driver.findElement(By.className("android.widget.Button"));
el.click();
Please anyone who have idea to resolve this issue?
Thanks in advance.
Priyank Shah
First of all you should realize whether the soft keyboard is active or not - Use the following command from your code to check "mInputShown" parameter - If "true" - Active Soft Keyboard.
adb shell dumpsys input_method | grep mInputShown
Use this code for hiding the native keyboard in Java-appium running older versions of appium.
driver.navigate().back()
P.S - The adb command is useless for emulators as the flag whose value is being checked is always set to true, whether your keyboard is active or not.
I don't think you can, and and it is not a appium limitation.
From what I observed even the UIAutomator can not find the elements hidden by the keyboard.
I know 2 solutions for this:
Dismiss the keyboard. (I didn't find any elegant ways of doing that so I'm not using this.
Swipe/scroll on the view until the element is exposed, and then you can action it. This works fine for me.
you should be able to dismiss the keyboard by sending
driver.findElement(By.name("Return")).click();
adding new line character works too
editTextList.get(2).sendKeys("456\n");
If you can detect that the keyboard is open, I would suggest calling UiDevice.pressBack() to dismiss the keyboard.
You could be able to dismiss the keyboard by using the following code
driver.hideKeyboard();
Put the following two lines:
driver.getKeyboard();
driver.hideKeyboard();
Here is a uiautomator ready fully functional method that will respond with true if the keyboard is Open and false if it is closed:
public static boolean isKeyboardDisplayed() {
String checkKeyboardCommand = "dumpsys input_method | grep mInputShown";
try {
Process process = Runtime.getRuntime().exec(checkKeyboardCommand);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
if (output.toString().contains("mInputShown=true")) {
return true;
} else {
return false;
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
You may need to enable unicodeKeyboard: true in your android capabilities and use the keyboard button Return to hide the keyboard if shown (this work for me on iOS and Android)
For example, I am using ruby:
element = $appium.find_element(id: field_id)
element.clear
element.send_keys(data)
element.send_keys(:return) if driver.is_keyboard_shown
I have one application by using which i will block the foreground application. It means when i am clicking any icon in the home screen it should not start. And my application is running in the background and will start when phone will start booting up. So i checked the Auto-run on start up. This is working fine in the simulator but not working in the device after running the cod file. I am running in Blackberry Storm. Here i am putting my code:
public class BlockApplication extends Application
{
int mForegroundProcessId = -1;
public BlockApplication() {
Timer timer = new Timer();
timer.schedule(mCheckForeground, 1000, 1);
}
public static void main(String[] args) {
BlockApplication app = new BlockApplication();
app.enterEventDispatcher();
}
TimerTask mCheckForeground = new TimerTask() {
public void run() {
int id = getForegroungProcessID();
ApplicationManager appMan = ApplicationManager.getApplicationManager();
appMan.requestForegroundForConsole();
KeyEvent inject = new KeyEvent(KeyEvent.KEY_DOWN, Characters.ESCAPE, 0);
inject.post();
};
};
private int getForegroungProcessID()
{
return ApplicationManager.getApplicationManager().getForegroundProcessId();
}
}
Can any one help? What is the problem?
Just an idea - have you setup permissions for your app?
For instance, your app uses KeyEvent injection - something that is potentially dangerous and thus requires an explicit permission from user. In device Options (on my Storm 9530 simulator it is in the 'Options' -> 'Security Options' -> 'Application Permissions' -> select your app -> 'Edit Permissions' menu item) the permissoin for KeyEvent injection is named as "Input Simulation". It is also possible to set up permissions for the app using programmatic way (check ApplicationPermissionsManager class for this, also you can review ApplicationPermissionsDemo project that is included with the JDE).
Note that it is impossible to simulate permission framework on simulator (simulator acts as if all permissions are always set to "Allow"), so to test permissions you need real device.