Unable to Scroll Elements inside ListView with Appium Selenium Android - selenium

For a few days I try to find a simple solution for scroll inside a list view
Since that Appium Inspector not provide the all elements of the list (only by manualy swipe and refresh the inspector then the new elements with the new instance loads.
After research i find out the distance between list item is as follow:
Item Location= (15, 828)
Item Location= (15, 1209)
Item Location= (15, 1590)
So i guess that every click need to scroll 381 pixels down, after so many tries I cannot find solution for this part of code and will be happy if someone can help with that:
List<WebElement> list = driver.findElements(By.id("net.balink.diplomat.qa:id/btnAddToCart"));
System.out.println("List Size is= " + list.size());
for (int j = 0; j < list.size(); j++) {
WebElement listItem = list.get(j);
Point location = listItem.getLocation();
System.out.println("Location= " + location);
listItem.click();
//to do here: swipe 381 px down after any click, then re-initialize
//the listItem in order to get a new index - and the loop when
//theres no more list items
Thread.sleep(2000);
}

I am using the following method for scrolling screen:
public static MobileElement scrollElementByContentDesc(String scrollableList, String uiSelector, String textToSearchInList) {
return driver.findElement(MobileBy.AndroidUIAutomator(
"new UiScrollable(new UiSelector().resourceId(\"" + scrollableList + "\")).getChildByDescription("
+ "new UiSelector().className(\"" + uiSelector + "\"), \"" + textToSearchInList+ "\")"));
}
scrollableList is id of your scrollable List element,
uiSelector is the className of the item of list,
textToSearchInList can be any text that you need to search in the list. It can be any random text if your purpose is just to scroll till the end of the list.
Call this method from any method:
public void someMethod(){
//other code
try{
MobileElement element= scrollElementByContentDesc("your scrollableList id",
"uiSelector classname", "any text you need to find in the list);
}catch(Exception e){
//do nothing
}
}
If you want to swipe by co0rdinate, you can do like this.
import io.appium.java_client.TouchAction;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import java.util.concurrent.TimeUnit;
import static java.time.Duration.ofSeconds;
TouchAction action = new TouchAction(driver);
action.press(PointOption.point(115, 650)).waitAction(WaitOptions.waitOptions(ofSeconds(1)))
.moveTo(PointOption.point(115, 350)).release().perform();
Make sure to import correct library.

The more reliable approach is to use native UiAutomator way:
So first of all find parent view of your list elements with scrollable: true attribute in place. That definitely should be at least one.
Then use inspector to build & test your UiAutomator locator
MobileElement elementScrollTo = driver
.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()"
+ ".resourceId(\"android:id/list\")).scrollIntoView("
+ "new UiSelector().text(\"Some text\"));");
UiSelector has pretty rich API , check it and find what suits you best.
This approach is better than TouchActions as you are not dependent on device screen resolution/coordinates.

Related

Install4j: how to implement tooltips for a list component in a form

I've tried a few different ways to implement tooltips support for a list component in a form. Following is code that I think should be close but it does not work.
The code is placed in the initialization script for the list component in a simple form and the list is the only component in the form.
My workaround is to display what would be the contents of the tooltip in static text below the listbox and change the static text as the selection in the list changes. I have this working but it's not the best way to present the information.
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
ToolTipManager.sharedInstance().registerComponent(configurationObject);
configurationObject.addMouseMotionListener(new MouseMotionAdapter()
{
#Override
public void mouseMoved(MouseEvent e) {
JList<?> l = (JList<?>) e.getSource();
Integer i = l.locationToIndex(e.getPoint());
ListModel<?> m = (ListModel<?>) l.getModel();
if (i >= 0) {
String item = m.getElementAt(i).toString() + i.toString();
l.setToolTipText(item);
}
}
});
I believe I could do this by subclassing the list and overriding getToolTipText but I'm not sure how to do this in install4j.

How to get Position of button in selenium c#

One Video is there below that one button is there i need to automate that button wheather that button is present below that video or not any one please help me to resolve this
If the button is a part of the page DOM and it can be searched by Selenium you should be able to access it's Location property like:
System.Drawing.Point location = driver.FindElement(By.XPath("//your_element_locator")).Location;
Console.WriteLine("My element location: " + location);
If you want to conditionally execute this or that code block depending on presence/absence of the element you can go for FindElements() function like
if (driver.FindElements(By.XPath("//your_element_locator")).Count > 0)
{
// element is present
}
else
{
//element is absent
}
If the button is not present in the DOM and it's a part of video - you will have to go for image recognition frameworks like AForge.NET, Emgu CV or SeeTest

Unable to scroll on following screens due to overlay of elements?

JA
Unable to scroll on following screens due to overlay of elements?
Jatin · 2 days ago
Scenario- After filling all the details , user need to scroll from "for how many people" to bottom...
Line of code -
driver.findElementByXPath("//android.widget.TextView[#text='Send enquiry']").click();
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_dialog_send_button").click();
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_date_text").click();
driver.findElementById("com.letsdogether.dogether:id/cancel").click();
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_date_text").click();
// driver.findElementById("com.letsdogether.dogether:id/date_picker_year").click();
// driver.findElementByXPath("//android.widget.TextView[#content-desc=\"2020\"]").sendKeys("2020");
driver.findElement(By.xpath("//android.view.View[#index='24']")).sendKeys("25");
driver.findElementByXPath("//android.widget.Button[#text='OK']").click();
driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(\"Message (Optional)\").instance(0))");
-------- scrolling is not happening by this command or neither from below command
// driver.findElementsByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(text(\"Message (Optional)\"));");
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_decrease_seats_button").click();
WebElement buttonElement = driver.findElement(By.id("com.letsdogether.dogether:id/send_enquiry_increase_seats_button"));
int i;
for(i=0;i<=10;i++) {
buttonElement.click();
}
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_dialog_send_button").click();
// driver.findElementById("com.letsdogether.dogether:id/send_enquiry_increase_seats_button").click();
This blog post does a good job of covering some of the ways you can scroll in Appium, specifically on Android. A few ways you can scroll to the bottom of your screen are:
With UiScrollable, using scrollIntoView() and passing the identifier for the scrollable container. For example:
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().resourceId(\"" + *scrollable container ID* + "\")).scrollIntoView("+ "new UiSelector().resourceId(\"" + *ID of the element you want to scroll to* + "\"))"));
With UiScrollable, just execute a scrollForward(). For example,
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().resourceId(\"" + *scrollable container ID* + "\")).scrollForward()"));
Last resort, you can always use TouchActions. For example,
TouchAction actions = new TouchAction(driver);
actions.press(startX,startY).waitAction(Duration.ofSeconds(1)).moveTo(endX, endY).release().perform();
You can determine the coordinates to begin and end your TouchAction either as a proportion of your screen size, or as specific coordinates from one element to another.
Google is your friend. Let me know if this helps!

stale element exception : click on report link in page then back button and so on

AS shown in the image : i want to click on each link one by one , on clicking :window does not gets change but it refresh.
clicking in the report link navigate to the next page, where clicking on back link it navigates back to the same page.
once it take back to the same page , locator no longer identify the next report link & throws stale element exception
public void getreports(String reportname) throws Exception
List<WebElement> li=driver.findElements(By.xpath(".//tbody/tr/th/following::
tr/td//div/a"));
for(WebElement e: li) {
if(reportname.equalsIgnoreCase(e.getText())) {
utilities.wait_control(e);
e.click();
break;
}
else if(reportname.equalsIgnoreCase("all"))
{
utilities.wait_control(e);
e.click();
NetReports ld = PageFactory.initElements(driver, NetReports .class);
ld.Netsubcategoryreport_backbutton.click();
Thread.sleep(2000);
} }
I think you just need a small adjustment to your loop:
String selector = ".//tbody/tr/th/following::tr/td//div/a";
List<WebElement> li=driver.findElements(By.xpath(selector));
for (int i = 0; i < li.length; i++) {
li=driver.findElements(By.xpath(selector));
WebElement e = li.get(i);
//Rest of your logic goes here
}
StaleElementReferenceException -
As the name suggests this exception occurs when the element stale, which means the element reference on which you are trying to take a action upon is no longer available on the page or has changed. 
To avoid this exception, try to find the element as and when you need to
take an action upon it rather than getting the element at some point of code
and then reusing it at different places.

How to handle the click on the sticky header decor in a RecyclerView?

I have a RecyclerView with a StickyHeaderDecor (with Button, ImageView, and TextView inside).
How do I handle the clicks on these components within the StickyHeader?
The library used is UltimateRecyclerView.
This is the code where I setup my recyclerView:
StickyRecyclerHeadersDecoration headersDecoration =
new StickyRecyclerHeadersDecoration(adapter);
recyclerView.addItemDecoration(headersDecoration);
StickyRecyclerHeadersTouchListener headersTouchListener =
new StickyRecyclerHeadersTouchListener(recyclerView, headersDecoration);
headersTouchListener.setOnHeaderClickListener(new StickyRecyclerHeadersTouchListener.OnHeaderClickListener() {
#Override
public void onHeaderClick(View headerView, int position, long headerId) {
Log.d(TAG, "clicked view " + v.getId() + " position:" + position);
// my code here to handle click (*)
}
});
recyclerView.addOnItemTouchListener(headersTouchListener);
(*) I don't have the possibility to handle click on headerView.
Unfortunately it is not possible to easy handle click of part of item decor. Here is an explanation why.
For Sticky Headers is better use:
FlexibleAdapter
SuperSlim