I have a element with data-qa-id = "journal-submit";
When I ran the test with small screen resolution Selenium says this element is not visible and cannot perform any action on it.
The same element is visible to selenium in regular chrome resolution. Can anyone explain me why it is so ? How to handle it ?
There's a few options for solutions here. I think scrolling to an element can be a bit hacky, because then it will remove other elements from the view of the browser, so you'll end up having to scroll all over the place to locate elements that may or may not be in view of the browser.
But, if you wish to use a scrolling solution, you can try something like this:
// declare JS executor
JavascriptExecutor executor = (JavascriptExecutor)driver;
// this is the element you want to find
WebElement element = driver.findElement(someLocatorHere);
// scroll to the element
executor.executeScript("arguments[0].scrollIntoView(true);", element);
I'm not a huge fan of this solution, for reasons I mentioned above. A "true" solution that will solve all problems of this type is to run your browser in headless and specify the screen size in the driver settings.
// declaring the webdriver
// headless options
ChromeOptions headlessOptions = new ChromeOptions();
headlessOptions.AddArgument("--headless");
headlessOptions.AddArguments("--disable-gpu");
headlessOptions.AddArguments("--window-size=1920,1200");
// start driver
driver = new ChromeDriver(headlessOptions);
I prefer the headless solution because it will solve most, if not all, of your issues regarding smaller screen resolution. I've gone back and forth with screen resolution issues for the majority of my career, and scrolling all over pages to locate individual elements was not a long-term or robust solution. I had much better success using headless, and driver is able to locate all of my elements.
I used JavascriptExecutor and it worked
JavascriptExecutor executor = (JavascriptExecutor)browser;
WebElement submit_btn = browser.findElement(By.name("submit-btn"));
executor.executeScript("arguments[0].click()",submit_btn);
If selenium not able to identify web element due to resolution then try to move to the element using action.
WebElement element = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.visibilityOfElementLocated(By.id("someid")));
Actions action=new Actions(driver);
action.moveToElement(element).perform();
Then perform required action on the webelement
Related
I am currently working in a selenium with java automation proyect.
The web page I am automating opens a side menu depending on the size of the screen. In my case, it does not open it. To solve this you can either clic on the menu button to open it or change the zoom.
I am trying to implement the second solution zooming (this is the solution I need):
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.body.style.zoom='70%'");
The zoom works but the side menu does not appear. Is there anything extra that I need to do?
I also use the next line as part of my configurations:
ChromeOptions options = new ChromeOptions();
options.addArguments("window-size=1980,1080");
I also tried different ways to zoom in but the results are the same:
driver.findElement(By.tagName("html")).sendKeys(Keys.CONTROL,Keys.SUBTRACT);
WebElement html = driver.findElement(By.tagName("html"));
new Actions(driver)
.sendKeys(html, Keys.CONTROL, Keys.SUBTRACT, Keys.NULL)
.perform();
Any suggestions? I would appreciate them because I am new to selenium and I am pretty stuck with this issue.
driver = new ChromeDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
driver.get("chrome://settings/");
jse.executeScript("chrome.settingsPrivate.setDefaultZoom(0.9);");
driver.get("...");
This is how I managed myself to do zoom correctly.
I am trying to find a web element in Chrome with help of Selenium WebDriver.
When the driver launches the URL, a list of projects is being displayed and the driver has to select a specific project from that list.
As long as that project is on top of the list, it's ok and can find the project, however if project is at the very bottom of the list (as per list has been ordered alphabetically and say record 57 from list is tried to be selected), test keeps failing and driver can't find the web element!!!
I finally got to this point that I need to scroll my list till that item shows up, but as per this scroll bar is in that menu not in the main window this command is not even executed!
Do I need to identify the project menu to driver at all? how can I scroll down that project menu in the window? I don't want to scroll the main Web window, I need to scroll in the project list only.
I tried all the possible solutions and was surfing all over the Stack Overflow forum as well as internet but couldn't fix this error.
It would be great if you guys have a look at this code bellow and give me some advice. Please let me know if I have to provide more information. Good to mention here that I am reading the "projectName" from spreadsheet.
// Initially I need to hover the mouse on Select Project menu.
Actions action = new Actions(driver);
WebElement list = driver.findElement(By.xpath("//*[#id=\"gridview-1032\"]"));
action.moveToElement(list);
JavascriptExecutor js = (JavascriptExecutor) driver;
// Now I need to scroll down till find my desire project in the list.
WebElement Project = driver.findElement(By.xpath("//*[text()= '"+ projectName +"']"));
js.executeScript("arguments[0].scrollIntoView(true);",Project);
Project.click();
Actual result:
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
no such element: Unable to locate element:
{"method":"xpath","selector":"//*[text()= 'projectName']"}
Expected result:
Find the element in the list and click on that item to launch the project!
Here below is the code that worked for me.This code works fine in your case
Actions action = new Actions(driver);
WebElement list = driver.findElement(By.xpath("//*[#id=\"gridview-1032\"]"));
action.moveToElement(list);
JavascriptExecutor js = (JavascriptExecutor) driver;
// Now I need to scroll down till find my desire project in the list.
WebElement Project = driver.findElement(By.xpath("//*[text()= '"+ projectName +"']"));
js.executeScript("arguments[0].click();",Project);
I found an alternative solution for this question which is simpler:
// Create instance of Javascript executor
JavascriptExecutor je = (JavascriptExecutor) driver;
//Identify the WebElement which will appear after scrolling down
WebElement Project = driver.findElement(By.className("x-grid-item-container"));
// now execute query which actually will scroll until that element is not appeared on page.
je.executeScript("arguments[0].scrollIntoView(true);",Project);
//Login to desired project
Project.click();
I thought this might be an issue for someone else, I am adding my solution as well, it might be helpful:
//it find the list and scroll 3000 pixel
EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(driver6);
eventFiringWebDriver.executeScript("document.querySelector('#gridview-1032').scrollTop=3000");
//find the project and login
WebElement Project = driver6.findElement(By.xpath("//*[text()= '"+ projectName +"']"));
Project.click();
I am using following xpath to click on element using JSExecutor in Selenium webdriver. This works fine in Firefox and chrome but does not work in IE.
Any idea to make this work? After lot of trial and error I have made this work in FF and chrome and have come up with the following XPath.
//*[contains(#class,'ui-select-choices-row') or contains(#id,'ui-select-choices-row')]//*[text()='TextofMyElementToBeclicked'
Additional info: This is a Jquery drop down on an angularJS application. When the user clicks on the drop down //ul is loaded and i am using the above xpath (which is part of //ul) to select the element based on text (using Javascript executor click). I used JS executor because, click() function in selenium simply could not click on the drop down element.
I am clicking element using below.
WebElement element = driver.findElement(By.xpath("YourNumbersXpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
enter code here
I successfully tested your XPath with IE11, so it's not an issue related to IE. It's most likely a timing issue. First click on the drop button, then wait for the targeted element to appear and finally click on it:
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.get("...");
// move the cursor to the menu Product
WebElement element = driver.findElement(By.xpath("drop down button")).click();
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("drop down item"))).click();
IE11 seems to struggle with contains(#class and possibly also the contains(#id. Try using alternative solutions like starts-with.
Some of WebElements are not recognized by WebDriver, WebDriver fails to find the element which is not visible in browser's visible area.
In order to make the WebElement viewable by WebDriver, We need to make that element to visible in browser's view to do scroll down on particular div!
How can I perform my action(scroll down and click) on particular area of my webpage. I tried lot, doesn't helped me.
Please help me resolve my issue.
First of all, most of the answers posted here are just off the topic. I have been working with selenium 2 and selenium 3 now, the webdriver can handle window scroll to make an element visible.
For everyone posting snippets like:
driver.execute_script('scrollBy(0, 250)')
you do not get the question at all!
Actually I still did not find a way to properly simulate the drag action of scroll handle but this answer seems promising -- but I did not try.
So so far personally there are two ways to do this for me:
Use Keys.ARROW_DOWN
Use Keys.PAGE_DOWN
Actually there is a third way, just give up selenium and contact the website if they provide any API.
The easiest way to do that is executing a Javascript to scroll the element up/down.
JavascriptExecutor jsExec = (JavascriptExecutor) driver;
jsExec.executeScript("document.getElementById('id').scrollDown += 100");
driver.get("http://www.***.com/");
driver.manage().window().maximize();
WebElement scroll = driver.findElement(By.id("someId"));
scroll.sendKeys(Keys.PAGE_DOWN);
Scroll Down:
import org.openqa.selenium.JavascriptExecutor;
WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(0, 250)"); //y value '250' can be altered
Scroll up:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(250, 0)"); //x value '250' can be altered
Scroll bottom of the Page:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));");
or
Actions actions = new Actions(driver);
actions.keyDown(Keys.CONTROL).sendKeys(Keys.END).perform();
Full scroll to bottom in slow motion:
for (int second = 0;; second++) {
if(second >=60){
break;
}
((JavascriptExecutor) driver).executeScript("window.scrollBy(0,400)", ""); //y value '400' can be altered
Thread.sleep(3000);
}
or
JavascriptExecutor jse = (JavascriptExecutor)driver;
for (int second = 0;; second++) {
if(second >=60){
break;
}
jse.executeScript("window.scrollBy(0,800)", ""); //y value '800' can be altered
Thread.sleep(3000);
}
Scroll automatically to your WebElement:
Point hoverItem =driver.findElement(By.xpath("Value")).getLocation();
((JavascriptExecutor)driver).executeScript("return window.title;");
Thread.sleep(6000);
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,"+(hoverItem.getY())+");");
// Adjust your page view by making changes right over here (hoverItem.getY()-400)
or
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", driver.findElement(By.xpath("Value')]")));
or
WebElement element = driver.findElement(By.xpath("Value"));
Coordinates coordinate = ((Locatable)element).getCoordinates();
coordinate.onPage();
coordinate.inViewPort();
First you should do scroll rather than find element so do like below :
document.getElementById("your div id").scrollTop(250);
After above you can find that specific div.
You can also try below :
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250,350)");
Another way of doing it using JavascriptExceutor's scrollIntoView() method:
WebElement DIVelement = driver.findElement(By.xpath("xpath to div"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView(true)", DIVelement);
Consider your HTML is like below:
<div id="someId" class="className" style="position: relative; top: 0px; left: opx;>
you can observe style attribute in div
check for the value of top which is 0px in above example
Now try to do something like:
$('.className').animate({top: "-60px"});
which will help you to scroll down.
Its a JavaScript executor so of course you need to implement it.
My 'WORKAROUND' is to scroll to the position by element's x and y co-ordinates. I also added an offset to y so that any header/footer or other element don't block the visibility of the element that I want to scroll to.
I have my answer posted under this question -
Selenium webdriver can't click on a link outside the page
None of the posted answers worked for me, however I have found a solution based on this post.
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollTop=arguments[1].offsetTop",
divWithScrollbarElement,
elementToScrollTo);
where divWithScrollbarElement is the div element which you are looking to scroll, and elementToScrollTo is the child element which you want to make viewable (which in my case was actually the parent of the element which I was initially trying to view). If elementToScrollTo is not actually in the DOM yet, you may need to use the script once to scroll down as far as possible, and then again once more elements have loaded.
As you found, webdriver won't find elements that aren't visible so you need to scroll to the element. However you can't scroll directly to the element because webdriver won't find it until it is visible. Catch-22.
However I do have a way that you can scroll within a DIV. First assign the DIV you want to scroll to an element variable, and then you can use javascript to scroll that element instead of scrolling the entire window.
Some VB.NET example code that should be easily adapted to other languages:
Dim div_to_scroll As IWebElement = driver.FindElement(By.XPath("[put your xpath here]"))
driver.ExecuteJavaScript("arguments[0].scrollBy(0,500)", div_to_scroll)
' Short pause to make sure the screen updates:
System.Threading.Thread.Sleep(500)
If you don't know how far you need to scroll then you will need a loop with a test to see if the desired element is visible yet. This isn't a particularly elegant or fast way of doing things but webdriver isn't a fast solution to begin with and I have found this method to be very robust.
Just in case for anyone looking for an alternative solution, here I put mine using python, which should be easy to transform to Java. First, I was using:
more = panel.find_elements(By.CSS_SELECTOR, "//li")
self.driver.execute_script("arguments[0].scrollIntoView();", more[-1])
if last == more[-1]:
break
else:
last = more_followers[-1]
#wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "//li")))
time.sleep(0.5)
in a loop for a ul inside a div. However, the more li elements appear, the slowest was selenium to perfom this action. At the end, because the div containing the ul had a unique class name I used the following in a loop:
while num_of_il<num_of_elements:
self.driver.execute_script("document.getElementsByClassName('myclass')[0].scrollTop += 100;");
time.sleep(0.5)
num_of_il = self.driver.execute_script("return document.getElementsByTagName('li').length")
print("Num of li "+str(num_of_il))
This way is not slow anymore, and with the 0.5 I give enough time to load my next entries. You can also have other getElementsBy as getElementById(), getElementsByName(), getElementsByTagName() and getElementsByTagNameNS(). Look methods at https://developer.mozilla.org/en-US/docs/Web/API/document/ You can check the number of elements loaded accessing the num_of_il variable. Consider introducing some code to break the loop in case num_of_il does not change (e.g. end of items reached).
I have searched all the forums but I didn't get a correct answer for my issue. My web page to test has a link hidden below, and I am trying to find it manually by searching for it with xpath or the ID attribute of the element, but I am not able to find it when I am running the web driver script. Even when it is not giving any error on that element, I am getting an error on next command/line.
I found below code from the forums, which is scrolling whole page. I don't want this, I want to scroll down vertically in a specific div area as in screen shot.
JavascriptExecutor jsx = (JavascriptExecutor)driver;
jsx.executeScript("ctl00_Menu1_scrollDiv.scrollBy(0,250)", "");
div id for this is "ctl00_Menu1_scrollDiv"
Element id: ctl00_Menu1_DlMenu_ctl09_LnkMenuname
Please help me on this issue. Thanks in advance.
Help will be appreciated.
This is umendra tomar , I have found very simple solution for this, please use the below code for scroll a specific div in html using selenium .
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.getElementById('scrollCustom').scrollTop= 450");
scrollCustom = this is the ID of your div which you want to scroll.
document.getElementById = this is use in javascript to locate a webelement.
Don't worry we can use this in java using javascriptExecutor
Check if this works for you.
var s = $('#ctl00_Menu1_scrollDiv').scrollTop();
This will give the current value of the scroll in the div.Use this only if you want to scroll inside a div to a certain point dynamically. Otherwise you can hardcode the scrollTop value inside animate()
Using the current value of your scroll you can parameterize the given below scrollTop parameter
$("#ctl00_Menu1_scrollDiv").animate({ scrollTop: "100px" }); // Here 100 px is just an example
I had used this to scroll a large div programmatically in my webdriver framework. Also, this will work if your AUT has jQuery loaded in the browser.
In Java:
JavascriptExecutor js;
js = (JavascriptExecutor) driver;
js.executeScript("$(\"#ctl00_Menu1_scrollDiv\").animate({ scrollTop: \"100px\" })");
First you should not just reference an element by the id. You should set scrollTop to scroll it to a position.
document.getElementById("ctl00_Menu1_scrollDiv").scrollTop(250);
Non-JQuery solution based on this post.
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollTop=arguments[1].offsetTop",
divWithScrollbarElement,
elementToScrollTo);
where divWithScrollbarElement is the div element which you are looking to scroll, and elementToScrollTo is the child element which you want to make viewable (which in my case was actually the parent of the element which I was initially trying to view). If elementToScrollTo is not actually in the DOM yet, you may need to use the script once to scroll down as far as possible, and then again once more elements have loaded.