selenium unable to find element button - c#

i am trying to get this button with selenium in c#
<a id="1|0AqnCSdkjQ0|none" href="" target="_self" rel="nofollow" class="download_link 1">Download</a>
i tried with id and class but it didn't work.
Here is the web page:
http://www.mp3juices.cc/ - > on the next page

Your code is failing with that "Compound class" error because you are, basically, asking for two class names.
The button has the class download_link.
If you do something like driver.findElements(By.className("download_link")) you'll get a List of all the buttons, and get whichever you wanted.
(The above snippet is Java, so you may have to adapt it to C#)

you can use this as a solution
driver.findElement(By.xpath("//a[#class='download_link 1'] and contains(text(),'Download')"));

Did you try
driver.FindElement(By.CssSelector("a.download_link.2")
When you tried to use "download_link 2" you were requesting two class names. You can specify two class names (or more) in a CSS Selector and put a period between them. The CSS selector above is read as find an A tag with class download_link and class 2.

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
try
{
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
try
{
return d.FindElement(By.ClassName("dl_link 1"));
}
catch
{
return null;
}
});
}
catch(Exception e)
{
}
ReadOnlyCollection<IWebElement> lists = driver.FindElements(By.ClassName("download_link"));
lists[0].Click();
*The code is not optimized, but it works great. (First part i am using to wait for the button to be loaded).

Related

Unable to click web element by xpath via selenium chrome driver

Hellow, i have pop-up window with 'select' element in chrome browser, i need to click this 'select' element in my ui-test scenario. It is on image: my web page
I am using c# and TechTalk.SpecFlow. I am trying to click it like this:
Browser.ClickWebElementNew("/html/body/div[1]/div/select", FoundBy.XPath);
here is realisation of Browser.ClickWebElementNew(), it from selenium chrome driver:
//
public void ClickWebElementNew(
string findElement, FoundBy f
)
{
if (f == FoundBy.XPath)
{
var element = _chromeDriver.FindElement(By.XPath(findElement));
element.Click();
}
else if (f == FoundBy.CssSelector)
{
var element = _chromeDriver.FindElement(By.CssSelector(findElement));
element.Click();
}
}
//
public IWebElement FindElement(By by) => !(by == (By) null) ? by.FindElement((ISearchContext) this) : throw new ArgumentNullException(nameof (by), "by cannot be null");
but i allways get this error:
OpenQA.Selenium.NoSuchElementException : no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[1]/div/select
xPath to 'select' is totally correct, i check it many times. i have a enought delay in test scenario before this pop-up window emerge so what i am doing wrong? what i must do to suссessfully click this 'select'?
A couple of suggestions. I would try suggestion 1 first. If that doesn't work, try suggestion 2 as well:
Don't Use Exact XPaths — I see this frequently. Use a combination of tag names, attributes and parent elements to make your locators more robust. In fact, the <select> tag has an Id. Use that. Id attributes must be unique in the HTML document (if they aren't, it is a bug that should be fixed):
Browser.ClickWebElementNew("//select[#id = 'state']", FoundBy.XPath);
This can help keep your tests passing when minor HTML changes are made in the future.
Use An Explicit Wait — You will likely need this as well. You will need to wait for the element to be clickable. If using Selenium 3 or if you have the DotNetSeleniumExtras NuGet package installed, use ExpectedConditions in the ClickWebElementNew method:
public void ClickWebElementNew(string findElement, FoundBy f)
{
var wait = new WebDriverWait(_chromeDriver, TimeSpan.FromSeconds(30));
By locator = null;
if (f == FoundBy.XPath)
{
locator = By.XPath(findElement)
}
else if (f == FoundBy.CssSelector)
{
locator = By.CssSelector(findElement);
}
else
{
throw new InvalidOperationException("Unsupported FoundBy");
}
var element = wait.Until(ExpectedConditions.ElementToBeClickable(locator));
element.Click();
}
If using Selenium 4 and you don't have the DotNetSeleniumExtras package installed, this should work:
var element = wait.Until(d => { d.FindElement(locator).Click(); return true; });
element.Click();
The main reason for "waiting for the element to be clickable" is because certain user interface animations prevent Selenium from interacting with elements. These can be subtle, but important. Any movement, or fade-in can cause issues with interacting with the page.
If ideas 1 and 2 do not work, look to see if the element is inside a frame or iframe. You need to switch to the frame before interacting with its elements. Also look for elements that overlap that same region of the page. This can cause problems too, especially if running in headless mode and you are not setting a window size.

C# Selenium not consistent on different machines [duplicate]

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 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();

How to scroll up using Protractor.NET?

My web page is little lengthy and the SAVE button is at the top right-hand corner. As I input the data through Protractor.NET, the webpage scrolls down which hides the SAVE button, thereby throwing a Element is not clickable at a point error. Now inorder to save the webpage, I need to scroll up and then find the SAVE button and click it.
I have an example in Protractor which uses window.scrollTo(0,0), but how do I implement the same in Protractor.NET
EDIT: Included code
public void Test()
{
var saveBtn = NgWebDriver
.FindElement(By.ClassName("btnSave"))
.FindElement(By.ClassName("Save"));
var btnSv = Scroller(saveBtn);
btnSv.Click();
}
public IWebElement Scroller(IWebElement element)
{
((IJavaScriptExecutor)NgWebDriver).ExecuteScript("arguments[0].scrollIntoView();", element);
return element;
}
So the exception occurs in Scroller method while casting the NgWebDriver to IJavaScriptExecutor type
How can I accomplish this?
Finally got the solution to scrolling up to the top in Protractor.NET
Had referred the link and was able to solve my problem.
The below code worked for me.
IWebDriver driver = MyWebDriver.WrappedDriver;
IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
jse.ExecuteScript("scroll(0, -250);");
Why do you want to make it complicated?
If you want to scroll to an element you can use this simple method:
public IWebElement ScrollToElement(IWebElement webElement)
{
((IJavaScriptExecutor)Driver).ExecuteScript("arguments[0].scrollIntoView();", webElement);
return webElement;
}
The below code helped me to achieve the same.
IJavaScriptExecutor jse = (IJavaScriptExecutor)NgDriver;
jse.ExecuteScript("arguments[0].scrollIntoView()", webElement);

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