I am automating Webmap operations for which I have to pass a Latitude-Longitude to the Chrome browser so that particular area is clicked.
I understand Selenium 4 has features to use Chrome DevTools to do this operation. But I have to implment this automation only with Selenium 3.12 or 3.14 due to project restrictions.
This is my following code which I tried:
#Test
public void testLocationClick() {
int zoomActionCounter = 1;
while (findElement(By.className("leaflet-control-zoom-in")).isEnabled()) {
if (zoomActionCounter == 12) {
break;
}
findElement(By.className("leaflet-control-zoom-in")).click();
zoomActionCounter++;
}
((LocationContext)getDriver()).setLocation(new Location(37.774929, -122.419416, 0));
getDriver().get(SITE_URL);
WebElement map = getDriver().findElement(By.className("leaflet-interactive"));
waitForFewSeconds(1000);
map.click();
map.getLocation().getX();
map.getLocation().getY();
JavascriptExecutor js = (JavascriptExecutor) getDriver();
js.executeScript("window.navigator.geolocation.getCurrentPosition=function(success){"+
"var position = {\"coords\" : {\"latitude\": \"555\",\"longitude\": \"999\"}};"+
"success(position);}");
}
In this code I am not able to achieve the result. Any leads will be helpful.
I have to pass a latitude and longitude coordinates to the test method so that the click event happens in that coorinate location.
Related
How can I click on Text link inside in textview in appium
for ex. i have a string and Don't Have an Account? Register
Only Register has a link other text are disable, when i click on Register it navigate to Register screen.
But I can't click on Register.
Refer a image
WebElement element = driver.findElement(By.id("element id here"));
Point point = element.getLocation();
//you can change follwing point based on your link location
int x = point.x +1;
int y = point.y + element.getSize().getHeight() - 1;
new TouchAction(driver).tap(x, y).perform();
I find this solution here in appium discussion
I usually try to avoid XPATH in my tests, hence to search for Elements by Text I am doing something like this, which will return a By element to be used in the webdriver interaction.
public static By byText(final String text)
{
switch (Configuration.getInstance().getPlatform())
{
case ANDROID:
// This requires a UiAutomator2 test driver:
return MobileBy.AndroidUIAutomator("new UiSelector().text(\"" + text + "\")");
case IOS:
default:
throw new RuntimeException("not implemented");
}
}
Unfortunately I don't know the equivalent to iOS just now, but it should also be possible somehow ;)
Use this simple code
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
I'm playing around with selenium and just lately started to take a look at drop-downs and selecting elements.
For learning Selenium I'm using following site:
http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category
There is a drop-down Grid on which I'm trying to locate an element.
Since the drop-down is dynamic and has a scroll bar then I need to scroll down and locate an element.
Can anyone give me hints how I can locate and select an element on such drop-down?
Let's say I would like to select:
Item: contains "Envelopes"
Unit: "EA"
Unit Cost: gather then 0.2
Here is my code:
By itemPicker = ByScLocator.xpath("/html/body/div[2]/div/div/div/div/div[1]/div[2]/div/div/div[4]/div[1]/div/div/div/div[1]/div/div/div/form/table/tbody[2]/tr[2]/td[2]/table/tbody/tr/td[1]");
driver.findElement(itemPicker).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(itemPicker));
driver.findElement(itemPicker).sendKeys();
boolean find = false;
while (!find) {
By menuItems = ByScLocator.xpath("//tr[contains(#id, \"isc_PickListMenu_\")]");
List<WebElement> all = driver.findElements(menuItems);
try {
//Verify if all elements still exists in DOM
for (WebElement element : all) {
element.findElements(By.tagName("td"));
}
} catch (StaleElementReferenceException e) {
all = driver.findElements(menuItems);
}
for (WebElement element : all) {
List<WebElement> columns = element.findElements(By.tagName("td"));
String currenlyProcessedItem = columns.get(0).getText();
if (currenlyProcessedItem.matches(".*Envelopes.*")) {
if (columns.get(1).getText().equals("Ea")) {
if (Double.parseDouble(columns.get(2).getText()) > 0.2) {
find = true;
element.click();
break;
}
}
}
}
if (find) { //load another set of list items
driver.findElement(By.id("isc_3N")).sendKeys(Keys.PAGE_DOWN);
}
}
The problem is that I'm unable to scroll down the list and identify item I want to select.
Also I don't know if my aproach is optimal.
You can select only one item on this select list.
I think the problem is, that the item you trying to find isn't on the list.
The scroll bar doesn't mater as long as the select list is open.
If you trying just to select an item then this works for the item "Glue UHU Clear Gum 250ml"
public class selectItem {
#Test
public void selectItem(){
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category");
// Open select list
driver.findElement(By.id("isc_1Y")).click();
// Select row based on a string present
driver.findElement(By.xpath("//div[contains(text(), 'Glue UHU Clear Gum 250ml')]")).click();
driver.quit();
}
}
Using the solution below I was able to get elements in the dropdown to resolve. There are obvious dependencies on timing in the implementation to account for StaleElementExceptions when scrolling the content, but I'm hopeful those can be filtered out with a little more effort.
If the test doesn't pass for you right away try increasing the
'pollingEvery' time to 1/second. I'm pretty sure that's going to be
based on the machine it's being run on, and that will probably need
addressing.
/** Desired text to find in the dropdown.*/
String text = "Envelopes Kraft 305 x 255mm (12 x 10) (84GSM)";
//String text = "Pens Stabiliner 808 Ballpoint Fine Black";
/**
* Test to try to find a reference inside a scrollable gwt dropdown container.
* <p/>
* Behavior is heavily timing dependent and will take progressively longer as the content in the dropdown increases.
* <p/>
* I'm sure this can be optimized, but as a proof it does the job.
*/
#Test
public void gwtDropdownWithScrollContent() {
WebDriver driver = new FirefoxDriver();
try {
driver.get(
"http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category");
WebDriverWait wait = new WebDriverWait(driver, 240);
By dropdownTwiddle = By.xpath(".//*[#id='isc_1Y']");
//Find the combo and hit the twiddle button to expand the options.
WebElement we = wait.until(ExpectedConditions.elementToBeClickable(dropdownTwiddle)); // Find the drop down
we.click();
/*
* Create a function to use with the webdriver wait. Each iteration it will resolve the table object, find
* all of the rows, and try to find the desired text in the first <td> field of each row.
*
* If the element is not found, the scroll bar is resovled and the Actions class is used to get a hold of
* the scroll bar and move it down. Then the wait loops and tries again.
*/
Function<WebDriver, WebElement> scrollFinder = new Function<WebDriver, WebElement>() {
By optionTable = By.xpath(".//*[#id='isc_3A']");
By scrollElement = By.xpath(".//*[#id='isc_3N']/table/tbody/tr/td/img");
public WebElement apply(WebDriver arg0) {
WebElement table = arg0.findElement(optionTable);
List<WebElement> visibleEntries = table.findElements(By.xpath(".//tr"));
WebElement reference = null;
for (WebElement element : visibleEntries) {
if (ExpectedConditions.stalenessOf(element).apply(arg0)) {
//This happens if the scroll down happens and we loop back too quickly and grab the contents of the table before it refreshes.
//Seems to be tied directly to the poll configuration for the web driver wait.
continue;
}
WebElement firstColumn = element.findElement(By.xpath(".//td"));
String colVal = firstColumn.getText();
if (!Strings.isNullOrEmpty(colVal)) {
if (text.equalsIgnoreCase(firstColumn.getText())) {
reference = element;
break;
}
}
}
if (reference == null) {
//If the element wasn't found then scroll down and retry the effort.
WebElement scrollBar = arg0.findElement(scrollElement);
Actions actions = new Actions(arg0);
//The offset below may be increased to make a larger scroll effort between iterations.
actions.moveToElement(scrollBar).clickAndHold().moveByOffset(0, 5).release().build().perform();
}
return reference;
}
};
//XXX: THIS is the time to increase if the test doesn't seem to "work".
wait.pollingEvery(500, TimeUnit.MILLISECONDS); // Setting too low can cause StaleElementException inside the
// loop. When scrolling down the Object can be refreshed and
// disconnected from the DOM.
Assert.assertNotNull(wait.until(scrollFinder));
} finally {
driver.close();
}
}
Best of Luck.
I am trying to scroll a page completely using this code:
JavascriptExecutor js = (JavascriptExecutor) Browser;
js.executeScript("javascript:window.onload=toBottom();"+
"function toBottom(){" +"window.scrollTo(0,Math.max(document.documentElement.scrollHeight," +"document.body.scrollHeight,document.documentElement.clientHeight));" +"}");
js.executeScript("window.status = 'fail';");
//Attach the Ajax call back method
js.executeScript( "$(document).ajaxComplete(function() {" + "status = 'success';});");
js.executeScript("window.status = 'fail';");
//Attach the Ajax call back method
js.executeScript( "$(document).ajaxComplete(function() {" +"status = 'success';});");
This code works fine and scroll the page for the first attempt but when page is scrolled down, new data appears at the page and this code failed to scroll it again.
So what I need is that someone will help me to scroll the page till end until scrolling is completed.
Do I use any loop for this?
Help/Suggestions/Response will be appreciated!
I had a page with similar functionality and another question I answered previously. I am not familiar with any generic way to know if page does not have any other elements on load. In my case the page is designed to load 40/80(forgot the exact count) element in each scroll. Since, most of the cases I know an estimated number of scroll(since I am using a test company and I know how many element present for that in db) I can estimate the number of scroll and did the following to handle that page.
public void ScrollPage(int counter)
{
const string script =
#"window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));";
int count = 0;
while (count != counter)
{
IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
js.ExecuteScript(script);
Thread.Sleep(500);
count++;
}
}
See my other answer here
Java equivalency code
public void ScrollPage(int counter) throws InterruptedException {
String script = "window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));";
int count = 0;
while (count != counter)
{
((JavascriptExecutor)driver).executeScript(script);
Thread.sleep(500);
count++;
}
}
Use
ScrollPage(10);
in wherever the scroll is necessary
So, I would do something like that:
bool pageEnded = false;
while (!pageEnded) {
JavascriptExecutor js = (JavascriptExecutor) Browser;
js.executeScript("window.scrollTo(0, document.body.offsetHeight);");
pageEnded = (String)js.executeScript("return document.readyState;") ? true;
}
The best Way to do this is the following (implemented in Python):
import time
def loadFullPage(Timeout):
reachedbottom = None
while not reachedbottom:
#scroll one pane down
driver.execute_script("window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));");
time.sleep(Timeout)
#check if the bottom is reached
a = driver.execute_script("return document.documentElement.scrollTop;")
b = driver.execute_script("return document.documentElement.scrollHeight - document.documentElement.clientHeight;")
relativeHeight = a / b
if(relativeHeight==1):
reachedbottom = True
You have to find a efficient Timeout for your internet connection. A timeout of 3 seconds worked well for me.
An element not coming into view as the pane remains constant. I believe if I scroll down the pane maybe it will solve that issue?
So basically I want to scroll down a div to an element so as to get into visibility.
What piece of code would I need to add to my webdriver java?
I tried with the following without success:
WebDriver driver = null;
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("$('#fed-panel').data('jsp').scrollToBottom()");
I use the following in my code to deal with some Ajax objects that appear only when one scrolls down. You can replace the 'this.objectExists' function below (which is something I implemented) with ObjectVisible.
public void scrollDown(String identifier, String m){
Boolean readyStateComplete = false;
int i=0;
while (!readyStateComplete) {
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight," +
"document.body.scrollHeight,document.documentElement.clientHeight));");
covlog.logIssue(CovLogger.DEBUG, "scrollDown","Scrolling for the " + ++i + " times");
String tmp = js.executeScript("return document.readyState").toString();
readyStateComplete = tmp.contentEquals("complete");
//In case the object doesn't exists, break out of the loop
//the object might represent a spinner that shows that more
// records are downloaded.
if ((i%24)==0){ //24 is page size
if (!this.objectExists(identifier, m)){
readyStateComplete = true;
}
}
}
}
I have a problem using Selenium Webdriver (version 2.32.0) and Firefox (21.0), trying to change the values on a slider.
I wrote a Java code like this:
private void selectGiftCardPrice() throws TestingException {
try {
WebElement slider = getDriver().findElement(
By.cssSelector("div.sliderHandle"));
Actions move = new Actions(getDriver());
move.dragAndDropBy(slider, 90, 0);
move.build().perform();
sleep(4000);
} catch (Exception e) {
log.info(e);
throw new TestingException("e");
}
I tried out every code I found on the Web, every change, and it still does not work. It does not show any problem, just finds the element, and does nothing. Any idea what it is, or what can I do?
EDIT from comment:
I finally made it working with jQuery slider demo
driver.get("http://jqueryui.com/resources/demos/slider/multiple-vertical.html");
WebElement slider = driver.findElement(By.xpath("//div[1]/a[contains(#class,'ui-slider-handle')]"));
But it is still not working for me with jQuery UI Slider demo page using Xpath //div[#id='slider']/a. What is the problem?
This code works absolutely fine for me.
program handles slider of website : Homeshope18.com
Check it out:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.homeshop18.com/fashion-jewellery/category:15143/filter_Theme:%28%22Traditional+Wear%22+%22Cuff+%26+Kada%22+%22Daily+Wear%22+%22Maang+Tikka%22+%22Openable+Round%22+%22Round%22+%22Openable+Oval%22%29/sort:Popularity/inStock:true/?it_category=HP&it_action=JW-HPSP01&it_label=HP-HPSP01-131021235900-PD-JW-ZC-VK-SC_DiwaliFestWeddingJewellery&it_value=0");
WebElement slider = driver.findElement(By.xpath("//*[#id='slider-range']/a[1]"));
Thread.sleep(3000);
Actions moveSlider = new Actions(driver);
Action action = moveSlider.dragAndDropBy(slider, 30, 0).build();
action.perform();
Using Actions class, firs use clickAndHold("WebElemnt");
Then to move horizontally we need to move in the Y direction of the screen so we can use movebyoffset, i.e X-axis: 0 & Y axis: 40px
To move vertically we need to move in the X direction of the screen so we can use movebyoffset, i.e X-axis: 40px & Y axis: 0
The sample code would be :
Actions slider=new Actions(driver);
slider.clickAndHold("WebElemnt");
slider.movebyoffset(0,40).build.perform();