Selenium C# - scrolling to a web element - c#

Selenium C# - scrolling to a web element
I tried both the below options:
1.
IWebElement button = this.WebDriver.FindElement(By.ClassName("btn-default"));
// locate the button, can be done with any other selector
Actions action = new Actions(this.WebDriver);
action.MoveToElement(button).Perform(); // move to the button
button.Click();
2.
IJavaScriptExecutor js = (IJavaScriptExecutor)this.WebDriver;
js.ExecuteScript("arguments[0].scrollIntoView(true);", button);
Here is the HTML for the button:
button class="btn btn-default" data-bind="click: $root.addParameter, enable: $root.selectedParameter() == null" type="button"Add parameter/button
Any suggestions?

Try use this method, it will adjust the vertical exibition to an element:
public void AdjustElementExibition(IWebElement elemento)
{
ExecuteJavascript("window.scrollTo(0, 0)");
if (elemento.Location.Y < 400) return;
var actions = new Actions(this.WebDriver);
actions.MoveToElement(elemento);
actions.Perform();
ExecuteJavascript("window.scrollBy(0,250)");
Thread.Sleep(100); //sometimes js take some miliseconds to execute;
}
private object ExecutarComandoJavascript(string script)
{
return ((IJavaScriptExecutor)this.WebDriver).ExecuteScript(script);
}

I would recommend scrolling with javascript, like this:
public void ScrollElementIntoView(IWebElement element) {
((IJavaScriptExecutor)WebDriver.Instance.Driver()).ExecuteScript("window.scroll(" + element.Location.X + "," + (element.Location.Y - 200) + ");");
}
Where WebDriver.Instance.Driver() is your WebDriver instance. The Y-offset is for compensating for a 200px top menu.

You can try below code:
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
List<WebElement> displayedOptions = driver.FindElements(//span[#class='Button']);
for (WebElement option : displayedOptions)
{
try
{
js.ExecuteScript("arguments[0].scrollIntoView(true);", option);
System.Threading.Thread.Sleep(2000);
// Click on Button
driver.FindElement(By.XPath("//span[#class='Button']")).Click();
}
catch (WebException E)
{}
}

Scrolling to particular element can be handle through Actions class or IJavaScriptExecutor.
IWebDriver driver = new ChromeDriver();
var elementAtDown= driver.FindElemet(by.Id("DemoElement"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
//This will scroll the page till the element is found
js.ExecuteScript("arguments[0].scrollIntoView();", elementAtDown);
//This will scroll the web page till end.
js.executeScript("window.scrollTo(0, document.body.scrollHeight)");
Or
Actions actions = new Actions(driver);
actions.MoveToElement(elementAtDown);
actions.Perform();

Related

Selenium C# ElementNotVisibleException: element not interactable but the element is actually visible

I'm using Selenium.WebDriver for C# to ask a question on Quora just typing my question in notepad.
Everything worked fine since I had to post it.
To post it I need to click on a link inside a span like this:
<span id="__w2_wEA6apRq1_submit_question">
<a class="submit_button modal_action" href="#" id="__w2_wEA6apRq1_submit">Add Question</a>
</span>
In order to click it I've tried this method, that I've used for all my previous button clicks:
Selecting the element and clicking it:
var element = driver.FindElement(By.CssSelector(".submit_button.modal_action"));
element.Click();
Doing so I can get the element, but unfortunately it throws "ElementNotVisibleException". Debugging my application I could see that Displayed property was set to False, while it wasn't, because in my ChromeDriver I could clearly see the button.
To avoid clicking the element, I tried IJavaScriptExecutor and Driver.ExecuteJavaScript(); to click the link through a script:
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].click()", element);
Same logic has been used for Driver.ExecuteJavaScript(); but I get the same result, but when I write the same script into DevTools's Console tab it works perfectly.
How can I solve this issue?
You might have a case where the button become displayed(visible) after your check is executed, so you might try following delay in order to ensure that the button is displayed at the time of check:
public static void WaitForElementToBecomeVisibleWithinTimeout(IWebDriver driver,
IWebElement element, int timeout)
{
new WebDriverWait(driver,
TimeSpan.FromSeconds(timeout)).Until(ElementIsVisible(element));
}
private static Func<IWebDriver, bool> ElementIsVisible(IWebElement element)
{
return driver =>
{
try
{
return element.Displayed;
}
catch (Exception)
{
// If element is null, stale or if it cannot be located
return false;
}
};
}
If the button is not visible in the viewport(i.e. need scrolling to become visible) then you may scroll it with
public static void ScrollElementToBecomeVisible(IWebDriver driver, IWebElement element)
{
IJavaScriptExecutor jsExec = (IJavaScriptExecutor)driver;
jsExec.ExecuteScript("arguments[0].scrollIntoView(true);", element);
}
As per the HTML you have shared to click on the element with text as Add Question as the element is within a Modal Dialog you need to induce WebDriverWait for the desired ElementToBeClickable and you can use either of the following Locator Strategies as solutions:
LinkText:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.LinkText("Add Question"))).Click();
CssSelector:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("span[id$='_submit_question']>a.submit_button.modal_action"))).Click();
XPath:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//span[contains(#id,'_submit_question')]/a[#class='submit_button modal_action' and contains(.,'Add Question')]"))).Click();

Selenium Webdriver C#, Chrome, the icon hides the element and it is not clickable [duplicate]

This question already has answers here:
Selenium Web Driver & Java. Element is not clickable at point (x, y). Other element would receive the click
(9 answers)
Closed 4 years ago.
Update: The main problem was that element icon hid a button and it was not clickable. Solution was, using js.Executor, to hide this icon.
I am trying to use Selenium WebDriver for tests, it is new for me, and I have a problem with one element, it is no clickable, I tried find it by linktext, classname, cssselector, it does not work.
I have already read a lot of about this issue "Element is not clickable" , but have not found solution for my test. Hope, you will give me good advice.
Chrome version 67.0.3396.99, 64 bit
Visual C# 2017
Webdriver version 3.13.1.0
Here is my script:
namespace MK_edit
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new ChromeDriver(#"C:\Users\alina\ProjectLibre");
driver.Url = "http://test.test.com"; //not real url, I cannot show it
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);
driver.Manage().Window.Maximize();
//close popup
driver.FindElement(By.CssSelector("div.whatsnew-content"));
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
driver.FindElement(By.CssSelector("button.btn.btn-success")).Click();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);
//edit part
var lab = driver.FindElement(By.CssSelector("span.glyphicon.glyphicon-edit"));
lab.Click();
}
}
}
Element info:
<li class="allwaysVisible"><span class="glyphicon glyphicon-edit"></span></li>
Error message:
Element <span class=\"glyphicon glyphicon-edit\">
</span> is not clickable at point (312, 24).
Other element would receive the click: <div class=\"modal-backdrop fade\">
</div>\n
Thank you!
As per error message you have shared, <div class=\"modal-backdrop fade\"> would recieve the click and not <span class=\"glyphicon glyphicon-edit\">. You cannot interract with your element until div element hovers your element. It means div, if it is a popup or dialogue, should be closed. Or if it is a element which automatically dissapears, you have to wait until this element will be not more visible. Then you can click on your element.
I cannot provide the code sample to solve your issue, since I don't have a link to website. Hope this helps.
Wait until the spinner/loader disappears, try passing the spinner element ".modal-backdrop" inside a method like this...
public static void WaitForNotVisible(IWebElement element, IWebDriver driver)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(drv =>
{
try
{
if (element.Displayed)
{
return false;
}
return true;
}
catch
{
return true;
}
});
}
Like this...
var spinnerElement = driver.FindElement(By.CssSelector(".modal-backdrop"));
WaitForNotVisible(spinnerElement, driver);
labosana.Click();
Please add some wait before finding the labosana element
Code:
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
wait.Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("span.glyphicon.glyphicon-edit")));
var labosana = driver.FindElement(By.CssSelector("span.glyphicon.glyphicon-edit"));
labosana.Click();
You may replace click event with action class,
Actions builder = new Actions(driver);
builder.MoveToElement("Your target element").Click().Perform();
My element became visible and clickable after such additions, tnx for advices
//open edit
var lab = driver.FindElement(By.CssSelector("a[title=\"---\"]"));
var icon = driver.FindElement(By.CssSelector("span.glyphicon.glyphicon-edit"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].style='display: none;'", icon);
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
wait.Until(ExpectedConditions.ElementToBeClickable(lab));
lab.Click();

How can i use click event in Selenium and C#

How can I use click event in Selenium and C#
For example:
Go to Google Homepage.
Search the result Test
Click on the Search button, page change.
How can I get the new page?
Code Screenshot link: https://www.dropbox.com/s/23ih019wuczp3uv/Screenshot%202018-05-07%2011.08.38.png?dl=0
public void opengoogle()
{
ChromeOptions option = new ChromeOptions();
option.AddArgument("--headless");
ChromeDriver wd = new ChromeDriver(option);
try
{
wd.Navigate().GoToUrl("https://www.google.co.in/");
Thread.Sleep(2000);
wd.FindElement(By.CssSelector("#lst-ib")).Click();
Thread.Sleep(2000);
wd.FindElement(By.CssSelector("#lst-ib")).Click();
wd.FindElement(By.CssSelector("#lst-ib")).Clear();
wd.FindElement(By.CssSelector("#lst-ib")).SendKeys("Test");
}
finally { }
If you observe the HTML the desired element identified through By.CssSelector("#lst-ib"), it is within a <form> tag. So once you have sent the search text within the search field you can invoke Submit() method as follows :
wd.FindElement(By.CssSelector("#lst-ib")).Click();
wd.FindElement(By.CssSelector("#lst-ib")).Clear();
wd.FindElement(By.CssSelector("#lst-ib")).SendKeys("Test");
wd.FindElement(By.CssSelector("#lst-ib")).Submit();

Selenium C# Scrolling and clicking - web element

What should the program do? Click on every Button on the site.
By bybut = By.XPath("//span[#class='Button']");
var element = driver.FindElement(bybut);
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
for (int i = 0; i < 99; i++)
{
// Scroll element into view (orange rectangle on my picture)
js.ExecuteScript("arguments[0].scrollIntoView(true);", element);
// Time for scrolling
System.Threading.Thread.Sleep(2000);
// Click on Button
driver.FindElement(By.XPath("//span[#class='Button']")).Click();
}
On the internet site, if you click on the button, it will be removed.
My Problem:
If the For-Loop repeated, it comes to an error, because the next button is already in my view frame. How can I check, if a button is already into view?
Do you have any other solutions? Thanks in advance!
YOu can try below code :_
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
List<WebElement> displayedOptions = driver.FindElements(//span[#class='Button']);
for (WebElement option : displayedOptions)
{
try{
js.ExecuteScript("arguments[0].scrollIntoView(true);", option );
System.Threading.Thread.Sleep(2000);
// Click on Button
driver.FindElement(By.XPath("//span[#class='Button']")).Click();
}catch(WebException E){
}

How to scroll to element with Selenium WebDriver

How do I get Selenium WebDriver to scroll to a particular element to get it on the screen. I have tried a lot of different options but have had no luck.
Does this not work in the C# bindings?
I can make it jump to a particular location ex
((IJavaScriptExecutor)Driver).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 150)");
But I want to be able to send it to different elements without giving the exact location each time.
public IWebElement Example { get { return Driver.FindElement(By.Id("123456")); } }
Ex 1)
((IJavaScriptExecutor)Driver).ExecuteScript("arguments[0].scrollIntoView(true);", Example);
Ex 2)
((IJavaScriptExecutor)Driver).ExecuteScript("window.scrollBy(Example.Location.X", "Example.Location.Y - 100)");
When I watch it, it does not jump down the page to the element, and the exception matches the element being off screen.
I added an bool ex = Example.Exists(); after it and checked the results.
It does Exist (its true).
Its not Displayed (as its still offscreen as it has not moved to the element)
Its not Selected ??????
Someone is seeing success By.ClassName.
Does anyone know if there is a problem with doing this By.Id in the C# bindings?
Its little older question, but I believe that there is better solution than suggested above.
Here is original answer: https://stackoverflow.com/a/26461431/1221512
You should use Actions class to perform scrolling to element.
var element = driver.FindElement(By.id("element-id"));
Actions actions = new Actions(driver);
actions.MoveToElement(element);
actions.Perform();
This works for me in Chrome, IE8 & IE11:
public void ScrollTo(int xPosition = 0, int yPosition = 0)
{
var js = String.Format("window.scrollTo({0}, {1})", xPosition, yPosition);
JavaScriptExecutor.ExecuteScript(js);
}
public IWebElement ScrollToView(By selector)
{
var element = WebDriver.FindElement(selector);
ScrollToView(element);
return element;
}
public void ScrollToView(IWebElement element)
{
if (element.Location.Y > 200)
{
ScrollTo(0, element.Location.Y - 100); // Make sure element is in the view but below the top navigation pane
}
}
This works for me:
var elem = driver.FindElement(By.ClassName("something"));
driver.ExecuteScript("arguments[0].scrollIntoView(true);", elem);
This works for me in C# automation:
public Page scrollUp()
{
IWebElement s = driver.FindElement(By.Id("your_locator")); ;
IJavaScriptExecutor je = (IJavaScriptExecutor)driver;
je.ExecuteScript("arguments[0].scrollIntoView(false);", s);
return this;
}
I created a extension for IWebDriver:
public static IWebElement GetElementAndScrollTo(this IWebDriver driver, By by)
{
var js = (IJavaScriptExecutor)driver;
try
{
var element = driver.FindElement(by);
if (element.Location.Y > 200)
{
js.ExecuteScript($"window.scrollTo({0}, {element.Location.Y - 200 })");
}
return element;
}
catch (Exception ex)
{
return null;
}
}
For scroll down inside the page here I have small code and solution
My Scenario was until I scroll down the page. Accept and Don't accept button was not getting enabled. I was having 15 terms and conditions from which I needed to select 15th term and condition by inspecting webpage and taking the Id of last terms and condition paragraph.
driver.FindElement(By.Id("para15")).Click();
<div id="para15">One way Non-Disclosure Agreement</div>
I had somehow same problem. I was working on a web page and need to click on a button on a child window which by default, was located below screen.
This is the code I used and it worked.
Actually I just simulated a mouse drag and drop and moved the window 250 points upwards so that the button was in the screen.
Actions action = new Actions(driver);
action.DragAndDropToOffset(driver.FindElement(By.XPath("put an element path which **is in the screen now**, such as a label")), 0, -250);
action.Build().Perform();
If the reason we put time is for a long time to load the page, we put it. Just it.
ChromeOptions options = new ChromeOptions();
var driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.w3schools.com/");
Thread.Sleep(5000);
driver.ExecuteScript("scroll(0,400)");
HtmlDocument countriesDocument = new HtmlDocument();
countriesDocument.LoadHtml(driver.PageSource);
I am providing solution to scroll within a specific element, like a scrollable table.
// Driver is the Selenium IWebDriver
IJavaScriptExecutor exec = (IJavaScriptExecutor) Driver;
int horizontalScroll= direction == Direction.Right ? X : 0;
int verticalScroll = direction == Direction.Down ? Y : 0;
exec.ExecuteScript(
"arguments[0].scrollBy(arguments[1], arguments[2])"
, Self
, horizontalScroll
, verticalScroll);
Actions actions = new Actions(driver);
actions.SendKeys(Keys.PageDown).Build().Perform();
You do it through for, it works like clockwork, simple, but not always convenient
var js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'})", PutYourElementIDHere);
var e = driver.FindElement(By.XPath("//*[text()='Timesheet']"));
// JavaScript Executor to scroll to element
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", e);

Categories

Resources