appium : webview : selenium : How to automate touchend event on a div? - java

I want to automate a hybrid app using appium.
My app uses touchend events instead of click events for div
How do I automate this touchend events in appium?
For simple click I can find an element and then perform click by simply doing WebElement.click();
How to fire an event for touchend?

I have spend the last few days looking into this same issue. Eventually what I have found is that the Appium touch actions only work on the NATIVE context. However when you are testing/automating a web application you are in WEBVIEW context. So you have to switch to NATIVE, perform the touch actions, then switch back.
Ok, so that doesn't sound to bad. But they can't let it be that simple. So you can not use your Selenium WebElement as an argument in the Touch Actions. You will either have to re-find it using the NATIVE context, or use the elements location and dimensions to calculate a touch position and use that. However, the X and Y coordinates in the NATIVE context are different than those in the WEBVIEW context. So if you need them to be exact, then you have to translate them.
Well, at least that is where I am now. Perhaps someone else can provide some more or better details.
Here is some sample code for a tap which ignores the pixel translation issue. I have only tested this with iOS, but it should work with Android as well.
private void tapElement(AppiumDriver appiumDriver, WebElement element) {
// Locate center of element
Point location = element.getLocation();
Dimension size = element.getSize();
int tapX = location.getX() + (size.getWidth() / 2);
int tapY = location.getY() + (size.getHeight() / 2);
// Execute tap
String originalContext = appiumDriver.getContext();
appiumDriver.context("NATIVE_APP");
TouchAction action = new TouchAction(appiumDriver);
action.tap(tapX, tapY).perform();
appiumDriver.context(originalContext);
}

Have you looked through documentation?
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/touch-actions.md

Related

Accessibility service dispatchGesture swiping the screen not tapping

I have been trying to make the accessibility service dispatchGesture with a click and not a swipe.
This code is just swiping down on the screen, and not actually clicking on the x,y cords.
What I have tried.
Path clickPath = new Path();
clickPath.moveTo(Float.intBitsToFloat(x), Float.intBitsToFloat(y));
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(clickPath, 0, 1));
dispatchGesture(gestureBuilder.build(), null, null);
I have also tried replaced the clickPath.moveTo to add clickPath.addCircle, and clickPath.addRect, But both of those just crash the application.
I know this question was a few months ago, but from what I've seen, your duration is too short. I wasn't able to get touch events to register with a duration of less than 50ms. I also passed a custom handler:
val handler = Handler(Looper.myLooper()!!)
It's possible that one or both of these could be the source of the reason it wasn't working for you. In general, you seem to be doing the same thing that I am, and I'm having some success with it.

Acessing Navigate Bar in Android With Appium

I need to automate a test that consists of simulating the touches on the navigate bar, it cannot be just the command.
I tried to simulate the touch with this:
TouchAction action = new TouchAction(driver);
action.tap(PointOption.point(530, 2400)).perform();
But appears the error that the Coordinate [x=530.0, y=2400.0] is outside of element rectangle.
And it needs to be simulating the touch on the screen.
A friend of mine have achieved the result you are looking for by reading the id for the page you want to tap on, in this case the id it's home
public AppiumWebElement HomeTab => AppiumDriver.FindElementById("com.package.appname/home");
and then using the following HomeTab.Click();

Java HTMLUnit Testing Navigation Buttons

I'm quite new to Selenium HTMLUnit so I'm looking for some help in creating a basic test for a navigation button in my Spring Boot app.
I'm trying to put together some basic tests to make sure that the navigation buttons in my webapp work as expected. My approach to this is to find the required navigation button by Id, click it, then check that the current URL is the new page I was expecting to be on.
...
private HtmlUnitDriver driver = new HtmlUnitDriver(true);
...
#Test
public void navigationTest() {
driver.get(BASE_URL);
WebElement button = driver.findElement(By.id("navigation_button_id"));
button.click();
String currentUrl = driver.getCurrentUrl();
Assert.assertThat(currentUrl, is(BASE_URL + "some_other_page"));
driver.close();
}
I've attempted to use the .click() method (shown above), I've also attempted to use an Actions object instead of the simpler .click() method (see below) to perform the navigation but this still did not work.
Actions actions = new Actions(driver);
actions.click(button).build().perform();
The behaviour at the moment is that the URL is not changing from the BASE_URL (e.g. http://localhost:8080), I have verified that it works manually (clicking around in person) but I can't get the test to click the button and tell me that the URL has changed (showing that the user has been taken to the new page e.g. http://localhost:8080/some_other_page).
Can anyone offer some advice to get this working? I just need the simplest means of testing basic navigation is working in HTMLUnit.
I would suggest you to use below code for Navigation purpose :
To go forward :
driver.naviagte().forward();
To go backward :
driver.navigate().back();
For solving your issue , when you are going forward/backward : Wait for some element by using this code :
WebDriver wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated("some element locator"));
Then get the currentUrl by using driver.getCurrentUrl(); code.
Hope this will help you to resolve your issue.
Please let me know if you have any concerns related to this.
The way I remember doing it is to wait/ assert for the new page to load. If you can't do that, add a wait of few seconds before getCurrentUrl()

Unable to Automate Drag and Drop for IE11 : Selenium WebDriver

I am trying to automate drag and drop functionality in IE11 using Selenium Web Driver in Java. I am somehow able to achieve it on Chrome, but it's not happening in IE.
Before further explanation here is how I'm dragging and dropping:
Actions builder = new Actions(driver);
builder.clickAndHold(sourceElement)
.moveToElement(targetElement)
.release(targetElement)
.build().perform();
In IE: Instead of dragging and dropping it selects all the text from source to destination element. I thought this might be because it's pickup up the wrong element and tried the operation with some relevant parent and child elements but didn't work.
In Chrome: Works damn smooth.
In Firefox: Just performs click on holds and while dragging throws, element no longer attached to DOM exception. This might be because, I am dragging a row from a grid (kendo grid) and since dragging a row from a grid is not possible our devs have implemented it in such a way that when you drag a row a new dynamic element is created which moves along.
Just to add on more details:
I have already tried dragAndDrop() and other Javacript options.
I'm using the latest version of selenium and updated IE.
Our grid uses HTML5 components and I've discovered that there are few issues already there (not sure about what all issues though), but still since my scenario was working in one browser I hope this is not one of those issues.
I have made it possible somehow using Robot class but it is too unreliable and behaves weird, I would prefer giving up than using it.
Any help will be appreciated!
One solution if it's an HTML5 drag and drop is to simulate it with some javascript.
Here is a working example that drops an item to a bin:
final String JS_DnD =
"var src=arguments[0],tgt=arguments[1];var dataTransfer={dropEffe" +
"ct:'',effectAllowed:'all',files:[],items:{},types:[],setData:fun" +
"ction(format,data){this.items[format]=data;this.types.append(for" +
"mat);},getData:function(format){return this.items[format];},clea" +
"rData:function(format){}};var emit=function(event,target){var ev" +
"t=document.createEvent('Event');evt.initEvent(event,true,false);" +
"evt.dataTransfer=dataTransfer;target.dispatchEvent(evt);};emit('" +
"dragstart',src);emit('dragenter',tgt);emit('dragover',tgt);emit(" +
"'drop',tgt);emit('dragend',src);";
WebDriver driver = new InternetExplorerDriver();
driver.get("http://html5demos.com/drag");
WebElement ele_source = driver.findElement(By.id("two"));
WebElement ele_target = driver.findElement(By.id("bin"));
// drag and drop item two into the bin
((JavascriptExecutor)driver).executeScript(JS_DnD, ele_source, ele_target);

Sencha Disabled Button and Selenium Webdriver

I have a button on a website built with sencha/extjs. Currently the button id is savebutton-1550-btnEl, but this changes everytime the page is loaded. I know that the button is disabled, but for testing purposes, I'd like to set this button as enabled, and then click it.
How would I go about finding this element each time, and then disabling it and clicking it with Java Selenium?
I'm guessing I'll have to execute some javascript, but I'm having a hard time finding the target for the javascript.
To locate the element you will have to use part of the DOM surrounding the element as a unique locator. It is impossible to give a more specific answer without seeing the DOM you are working on, but you may try something like:
WebElement saveButton = driver.findElement(By.xpath("//button[text()='Save']");
For changing the element to enabled, take a look at this answer: Selenium Webdriver - click on hidden elements
Also a longer term solution might be to work with development to see if they can build in a unique locator especially since this probably wont be the only object that you have problems with. At my company we use the "class" field to uniquely identify objects in extjs.
I override the the class "AbstractComponent":
Ext.define('Foo.overrides.AbstractComponent', {
override: 'Ext.AbstractComponent',
onBoxReady: function () {
var me = this;
var el = me.getEl();
if (el && el.dom && me.itemId) {
el.dom.setAttribute('data-test', me.itemId);
}
me.callOverridden(arguments);
}
});
If you set in configuation of the button the "itemId", you
can be accessed the button via seleniumas follows:
IWebElement element = webDriver.FindElement(By.XPath($"//*[#data-test='{itemId}']"));

Categories