How to add something like isClickable() in my appium native app tests - appium

How to add something like isClickable() in my appium native app tests. I have written my tests, however they are very flaky and fail sometimes because it cannot find the element. I am thinking about making custom click and set value functions with the implicit wait times.
I thought about using isClickable() but the appium documentation says - Please note that isClickable works only in web and webviews, it doesn't work in mobile app native context.
Is there any other alternative i can use? can i use smartwait? if yes how can i implement that
Here is how i am defining home.screen.js
import AppScreen from './app.screen';
const SELECTORS = {
HOME_SCREEN: '~homeBarButton',
PRODUCTSEARCH_SCREEN: '~productSearchBarButton',
CUSTOMERSEARCH_SCREEN: '~customersBarButton',
STOREHUB_SCREEN: '~storeHubBarButton',
SETTING_ICON: '~SettingsIcon',
LOGOUT_BUTTON: '~settingsMainLogoutButton'
};
class HomeScreen extends AppScreen {
constructor () {
super(SELECTORS.HOME_SCREEN);
}
get homescreenButton () {
return $(SELECTORS.HOME_SCREEN);
}
get productsearchField () {
return $(SELECTORS.PRODUCTSEARCH_SCREEN);
}
get customersearchButon () {
return $(SELECTORS.CUSTOMERSEARCH_SCREEN);
}
get storehubButon () {
return $(SELECTORS.STOREHUB_SCREEN);
}
get settingIcon () {
return $(SELECTORS.SETTING_ICON);
}
get logoutButton () {
return $(SELECTORS.LOGOUT_BUTTON);
}
}
export default new HomeScreen();
And i am writing my test like this test.js:
import HomeScreen from '../screenobjects/home.screen';
import FormScreen from '../screenobjects/forms.screen';
import CommonPage from '../pageobjects/common.page';
describe('Sending item successfullt,', () => {
beforeEach(() => {
CommonPage.login()
});
afterEach(() => {
CommonPage.logout()
});
it('should be able to send the item to the mirror', () => {
driver.pause(3000)
HomeScreen.productsearchField.click();
driver.pause(3000)
HomeScreen.customersearchButon.click();
});
});
As you can see above, I have to add driver.pause otherwise my tests would fail because of button not clickable or typeable.

My suggestion is that you can get your elements attribute clickable and if its true keep doing your things
public boolean isClickable(String element) {
return androidDriver.findElementByAccessibilityId(element).getAttribute("clickable").equals("true");
}
You can use any method to find your element.

Best approach is to stop using implicit waits and do an explicit wait before each driver UI interaction.
You should do some reading on waitUntil / WebDriverWait (not sure if you have that in node.js implementation).
Then create functions for interacting with all types of elements in your app that perform an explicit wait before execution.
Pseudo code:
get clickButton (Selector element) {
waitUntil(clickable(element),...);
return $(driver.click(element));
}
Write generic methods for all type of elements in your app (button, textfield, dropdown...) and remove implicit waits from driver. You will see a big difference in your test stability.

Related

Elegant way to execute code on function exit in Dart

Suppose we need to execute some code when a function finishes, no matter how.
Example:
void myFunc() async {
await myLock.acquire();
if(...) {
myLock.release();
return;
}
...
myLock.release();
}
Many languages have features that allow to achieve this in a more elegant way than just manually calling myLock.release() before every return statement (For example defer in Go). Is something like that also possible in Dart?
Dart does not have RAII. You instead would need to use try-finally.
(Dart did recently (in 2.17) add Finalizers, but those would fire when objects are garbage collected, which might happen at some non-deterministic time, if ever.)
And just for the record, an example of using try/finally:
void myFunc() async {
await myLock.acquire();
try {
if(...) {
return;
}
...
} finally {
myLock.release();
}
}
You'd want to start the try after allocating the resource, so that you don't try to release if allocation throws.

Vaadin 14: sending data from a web component to server

How can i send data from client to server using html5 webcomponent
setting up data from server to client, is very easy, works like a charm
how ever cannot find solution to send data to server
Please assist, but Iam not going to use Lit or Polymer
#JavaScript
class SimpleComponent extends HtmlElement {
connectedCallback() {
this.innerHTML = '<input type="text" id="test"/>";
this._input = this.querySelector('#test');
this._input.onchange = function() {
***** i want to send the value to server ****
})
}
setInputValue(value) {
this._input.value = value;
}
}
customElements.define("simple-com",SimpleComponent);
Now Java at Server
#Tag("simple-com")
class SimpleComponent extends Component {
public SimpleComponent() {
}
public void setValue(String value) {
getElement().callJsFunction("setValue",value);
}
}
The main challenge compared to Polymer or LitElement is that an event handler defined using the pattern innerElement.onchange = function() {} will not be run with this referencing the custom element instance. This in turn means that trying to use this.$server won't work because this isn't pointing to the expected value even though $server is indeed present in the place where it's supposed to be.
The easiest way of fixing this is to change the code to use an arrow function (() => {}) instead of an explicit function. This works because arrow functions inherit this from the scope where the function is defined whereas explicit functions have this defined in different ways depending on how it is run. Another approach would be to store a reference to this in a separate variable (e.g. let root = this) and then reference that variable instead of this in the function (e.g root.$server.doSomething()).
Putting everything together, this is what the code looks like with my modifications to make everything work.
class SimpleComponent extends HTMLElement {
connectedCallback() {
this.innerHTML = '<input type="text" id="test"/>';
this._input = this.querySelector('#test');
this._input.onchange = () => {
this.$server.handleChange(this._input.value);
};
}
setValue(value) {
this._input.value = value;
}
}
customElements.define("simple-com", SimpleComponent);

Is this loginRequired(f)() the way to handle login required functions in dart?

I am new to Dart programming. I am trying to figure out what is the proper way (what everyone will do) to handle/guard those functions which are login required. The following is my first trial:
$ vim login_sample.dart:
var isLoggedIn;
class LoginRequiredException implements Exception {
String cause;
LoginRequiredException(this.cause);
}
Function loginRequired(Function f) {
if (!isLoggedIn) {
throw new LoginRequiredException("Login is reuiqred.");
}
return f;
}
void secretPrint() {
print("This is a secret");
}
void main(List<String> args) {
if (args.length != 1) return null;
isLoggedIn = (args[0] == '1') ? true : false;
try {
loginRequired(secretPrint)();
} on LoginRequiredException {
print("Login is required!");
}
}
then, run it with $ dart login_sample.dart 1 and $ dart login_sample.dart 2.
I am wondering if this is the recommended way to guard login required functions or not.
Thank you very much for your help.
Edited:
My question is more about general programming skills in Dart than how to use a plugin. In python, I just need to add #login_required decorator in the front of the function to protect it. I am wondering if this decorator function way is recommended in dart or not.
PS: All firebase/google/twitter/facebook etc... are blocked in my country.
I like the functional approach. I'd only avoid using globals, you can wrap it in a Context so you can mock then for tests and use Futures as Monads: https://dartpad.dartlang.org/ac24a5659b893e8614f3c29a8006a6cc
Passing the function is not buying much value. In a typical larger Dart project using a framework there will be some way to guard at a higher level than a function - such as an entire page or component/widget.
If you do want to guard at a per-function level you first need to decide with it should be the function or the call site that decides what needs to be guarded. In your example it is the call site making the decision. After that decision you can implement a throwIfNotAuthenticated and add a call at either the definition or call site.
void throwIfNotAuthenticated() {
if (!userIsAuthenticated) {
throw new LoginRequiredException();
}
}
// Function decides authentication is required:
void secretPrint() {
throwIfNotAuthenticated();
print('This is a secret');
}
// Call site decides authentication is required:
void main() {
// do stuff...
throwIfNotAuthenticated();
anotherSecreteMethod();
}

Send closure from Objective-C to JavaScript in iOS React-Native

Is it possible to construct a closure in objective-c and pass it to javascript where it can be invoked? The specific problem I am trying to solve is adding support for changing shipping methods and contacts in Apple Pay as part of the tipsi-stripe react-native module (something it doesn't do yet). This is basically what I have so far, but the callback in javascript gets 'null'.
- (void) paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didSelectShippingMethod: (PKShippingMethod *) shippingMethod
completion:(nonnull void (^)(PKPaymentAuthorizationStatus, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion {
id callback = (void (^)(NSArray* summaryItems)) {
completion(PKPaymentAuthorizationStatusSuccess, nil, summaryItems);
}
[self sendEventWithName: "#ShippingMethodChanged" body:#{#"selectedMethod": #"someMethodDetails", #"callback": callback}];
}
In javascript, I have something like this:
import { NativeEventEmitter, NativeModules } from 'react-native'
const { TPSStripeManager } = NativeModules;
const stripeEventEmitter = new NativeEventEmitter(TPSStripeManager);
componentWillMount() {
this.stripeOnShippingMethodChanged = stripeEventEmitter.addListener(
'ShippingMethodChanged',
(method, callback) => {
// async compute some value then
let summaryItems = await computeItemsWithMethod(method);
callback(summaryItems);
}
);
}
componentWillUnmount() {
this.stripeOnShippingMethodChanged.remove();
}
I'm assuming I have to somehow wrap the Objective-C closure so javascript knows how to invoke it but I can't find anything. Any help appreciated!
It is not possible to do what I was attempting to do here, the react-native bindings only support simple types that can be encoded as a string. The solution that I ended up with based on patterns I found elsewhere is to store the completion as a property on the object, trigger an event that can be seen in js-land and provide another exported method that can be called to trigger the completion. Code is here:
https://github.com/tipsi/tipsi-stripe/pull/244/files

How can I access Dart functions/variables from the Dartium DevTool Console?

In JavaScript you can access global variables and functions from the DevTool console (e.g. to call a function manually).
I tried to do this in Dartium, but I always get a reference error.
I tried following variations:
testFunc () {
return "test";
}
var testFunc2 = () {
return "test";
}
void main() {
var testFunc3 () {
return "test";
}
}
but none can be called via DevTool console of Dartium.
You need to select a Dart context.
When you open devtools > Console tab there is <top frame> selected by default.
You need to switch to a Dart context like dart:core.
As far as I remember it doesn't matter which Dart context is selected, just one of the Dart contexts.

Resources