Selenium Webdriver check if image is displayed using id - selenium

I have been trying to check if an image is displayed on my page using the image id. I have looked through similar posts but cannot find one that solves my problem.
I don't know why my error message says css selector, I am trying to find the element using its id.
Any ideas would be great, thanks?
Test:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
IWebElement BannerImageElement = driver.FindElement(By.Id("HomePageBanner"));
driver.Navigate().GoToUrl(HomeUrl);
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
Assert.True(BannerImageElement.Displayed);
}
Index.cshtml
#model HomeViewModel
#{
ViewData["Title"] = _loc[Model.PageTabTitle];
}
<div class="text-center">
#section header_image{
<div class="bg-img" id="HomePageBanner">
}
</div>
</div>
_Layout.cshtml
<body>
<header>
#RenderSection("header_image", required: false)
</header>
</body>
Error:
Message:
OpenQA.Selenium.NoSuchElementException : no such element: Unable to locate element: {"method":"css selector","selector":"#HomePageBanner"}
(Session info: chrome=83.0.4103.61)
Stack Trace:
RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
RemoteWebDriver.FindElement(String mechanism, String value)
RemoteWebDriver.FindElementById(String id)
<>c__DisplayClass16_0.<Id>b__0(ISearchContext context)
By.FindElement(ISearchContext context)
RemoteWebDriver.FindElement(By by)
TestHomepageComponentsArePresent.CheckBannerImage() line 21

A few words:
Ideally, you need to start finding the WebElement only after you invoke Navigate().GoToUrl(). So the sequence would be:
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = driver.FindElement(By.Id("HomePageBanner"));
Though you have declared an instance of WebDriverWait as wait you but haven't utilized it while looking out for the element.
Finally, as per the discussion in Official locator strategies for the webdriver other then xpath all the other locator strategies are converted in to css-selectors while execution.
Solution
To check if an image is displayed on the webpage you have to induce WebDriverWait for the ElementIsVisible and you can use either of the following solutions:
Using Id:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.Id("HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
}
Using CssSelector:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.CssSelector("#HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
}
Using XPath:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='HomePageBanner']")));
Assert.True(BannerImageElement.Displayed);
}
Update
Incase you are using nuget packages you need to use SeleniumExtras.WaitHelpers.ExpectedConditions as follows:
Using Id:
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Id("HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
Using CssSelector:
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.CssSelector("#HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
Using XPath:
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='HomePageBanner']")));
Assert.True(BannerImageElement.Displayed);
References
You can find a couple of relevent discussions in:
WebDriverWait is not waiting for the element I specify
ExpectedConditions.ElementIsVisible returns TimeoutException even when element is present

Related

How to handle the popup within the eCommerce website https://www.firstcry.com using Selenium and Java

`
WebDriver Driver = null;
WebDriverWait wait = null;
#BeforeTest
public void beforeTest() {
System.setProperty("webdriver.chrome.driver","src\\test\\resources\\drivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("excludeSwitches",Arrays.asList("disable-popup-blocking"));
options.addArguments("--disable-popup-blocking");
Driver = new ChromeDriver(options);
Driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
wait = new WebDriverWait(Driver, 25);
}
#Test(dataProvider = "dp")
public void Test( String s) {
String SearchWord = s;
String url = "https://www.firstcry.com/";
Driver.get(url);
wait.until(ExpectedConditions.alertIsPresent());
By popupdeny1 = By.xpath("//*[#id=\"deny\"]");
By searchbox = By.id("search_box");
By sortSelect = By.xpath("/html/body/div[5]/div[2]/div/div[2]/div[1]/div[2]/div[1]/div");
By descendingPrice = By.xpath("/html/body/div[5]/div[2]/div/div[2]/div[1]/div[2]/div[1]/ul/li[4]/a");
if(Driver.findElement(popupdeny1).isDisplayed())
Driver.findElement(popupdeny1).click();`
I am automating firstcry webpage for a study purpose. There are few popups in this url, which i need to handle before searching for a product and sort the items based on price
https://www.firstcry.com/
I even added Chromeoptions in browser setting, but still the popups are coming...here is the code part.
I tried to click the deny button in my code, but ended with error saying cant find the element.
Any help is appreciated
To click() the element with text as Allow within the url https://www.firstcry.com/, as the the desired element is within a <iframe> so you have to:
Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt.
Induce WebDriverWait for the desired elementToBeClickable.
You can use either of the following Locator Strategies:
Using cssSelector:
driver.get("https://www.firstcry.com/");
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe[title='webpush-onsite']")));
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button#allow"))).click();
Using xpath:
driver.get("https://www.firstcry.com/");
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[#title='webpush-onsite']")));
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#id='allow']"))).click();
Browser Snapshot:

How to click on the reCAPTCHA using Selenium and Java

Why am I getting errors when trying to get the driver to click on the reCAPTCHA button?
This is the site where I am trying to get it to work: https://rsps100.com/vote/760/
This is my current code so far:
WebElement iframeSwitch = driver.findElement(By.xpath("/html/body/div[1]/div/div[1]/div/div/div[2]/div/form/div/div/div/div/iframe"));
driver.switchTo().frame(iframeSwitch);
driver.findElement(By.cssSelector("div[class=recaptcha-checkbox-checkmark]")).click();
To invoke click() on the reCaptcha checkbox as the element is within an <iframe> you need to:
Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt.
Induce WebDriverWait for the desired elementToBeClickable.
You can use the following solution:
Code Block:
public class ReCaptcha_click {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.addArguments("disable-infobars");
options.addArguments("--disable-extensions");
WebDriver driver = new ChromeDriver(options);
driver.get("https://rsps100.com/vote/760");
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[starts-with(#name, 'a-') and starts-with(#src, 'https://www.google.com/recaptcha')]")));
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.recaptcha-checkbox-checkmark"))).click();
}
}
Browser Snapshot:
Use WebDriverWait to identify the element.See if this help.
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[starts-with(#name,'a-')]")));
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.recaptcha-checkbox-checkmark")));
element.click();
This worked for me. Please note that I am using Selenide. For regular selenium code look the same.
import static com.codeborne.selenide.Selenide.*;
void recaptchaTest() {
open("https://rsps100.com/vote/760");
switchTo().frame($x("//iframe[starts-with(#name, 'a-') and starts-with(#src, 'https://www.google.com/recaptcha')]"));
$("div.rc-anchor-content").click();
switchTo().defaultContent();
}
Here is the code that should work.
driver.switchTo().frame("a-9wt0e8vkopnm");
driver.findElement(By.xpath("//span[#id='recaptcha-anchor']")).click();
I solved this maybe on the stupid way. But hawe in mind that I am not in test environment and I practicing automatization of tests. So this is my solution:
Beside using
public void notABot( ) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds( 15 ));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[starts-with(#name,'a-') and starts-with (#src, 'https://www.google.com/recaptcha')]")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div [ #class = 'recaptcha-checkbox-border']"))).click( );
driver.switchTo().defaultContent();
}
this, I also added custom send keys method
public void inputEmail( ) {
inputEmail.click( );
String email = Strings.EMAIL_FOR_SIGNUP;
for (int i = 0; i < email.length(); i++) {
char c = email.charAt(i);
String s = new StringBuilder( ).append( c ).toString( );
inputEmail.sendKeys( s );
sleepSendKeys( );
}
}
Sleep is 300 millis. In 96 procent time I manage to cheat google reCaptcha that actually human is login to the page. Its work for me

Can someone please suggest me to create dynamic xpath for https://jpetstore.cfapps.io/catalog/categories/FISH

System.setProperty("webdriver.chrome.driver", "C:\\Users\\Testing\\Downloads\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://jpetstore.cfapps.io/login");
driver.manage().window().maximize();
driver.findElement(By.name("username")).sendKeys("Testing");
driver.findElement(By.name("password")).sendKeys("test#123");
driver.findElement(By.id("login")).click();
driver.findElement(By.xpath("//div[#id='SidebarContent']/a[contains(#href,'FISH')]/img")).click();
Here I was able to create dynamic xpath
driver.findElement(By.xpath("//div[#id='Catalog']//parent::td//preceding-sibling::td//a//following::td//a")).click();
driver.findElement(By.xpath("//div[#id='Catalog']//parent::a//following::a[contains(text(),'Add to Cart')]")).click();
driver.findElement(By.xpath("//div[#id='BackLink']//a[contains(text(),'Return to Main Menu')]")).click();
driver.findElement(By.xpath("//div[#id='SidebarContent']//a[#href='/catalog/categories/FISH']")).click();
If you want to click on that link then you need to take the xpath till a node, try the below xpath :
String xPath = "//div[#id='SidebarContent']/a[contains(#href,'FISH')]";
If you are still getting an exception then you need to give some delay before clicking on it :
Thread.sleep(3000);
driver.findElement(By.xpath("//div[#id='SidebarContent']/a[contains(#href,'FISH')]")).click();
You can use FluentWait to avoid some exceptions, try the below code if you want to use the FluentWait :
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(60, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
WebElement fish = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("//div[#id='SidebarContent']/a[contains(#href,'FISH')]"));
}
});
fish.click();
Update :
As per the discussion in the comments, here is the solution :
driver.get("https://jpetstore.cfapps.io/login");
driver.manage().window().maximize();
driver.findElement(By.name("username")).sendKeys("some username");
driver.findElement(By.name("password")).sendKeys("some password");
driver.findElement(By.id("login")).click();
driver.findElement(By.xpath("//div[#id='SidebarContent']/a[contains(#href,'FISH')]")).click();
// Replace Name('Angelfish') with any fish you want
driver.findElement(By.xpath("//td[text()='Angelfish']/preceding-sibling::td/a")).click();
// Replace Description('Small') with any size you want
driver.findElement(By.xpath("(//span[text()='Small']/parent::td/following::td//a[#class='Button'])[1]")).click();
I hope it helps...

NoSuchElementException: Unable to locate element uisng selenium web-driver

Here i am trying to click a button using css selector find method.But its unable to locate the element. So i tried giving the time also but still its unable to click the element
Code sample -->
WebDriverWait waitr = new WebDriverWait(driver, 10);
WebElement element = waitr.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#userTable > tbody > tr:nth-child(3) > td.sorting_1 > div > a")));
element.click();
My HTML body Looks as follows
<a data-toggle="dropdown" class="mainAnchor" aria-expanded="false">CA05
<span class="caret" style="margin-left:5px;"><span> </span></span></a>
If i use Thread.sleep(1000); instead of wait it works fine but i don't want to use Thread.sleep.Please help me to solve this issue
To click on the element with text as CA05 you can use the following line of code :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.mainAnchor[data-toggle=dropdown]"))).click();
Hi you can use a fluentwait like the following below.
static Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(elementWaitTime, SECONDS)
.pollingEvery(2,SECONDS)
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver aDriver) {
driver= aDriver;
element.click();
return aDriver.findElement(cssSelector("#userTab a.mainAnchor"));
}
});

Unable to click 2 value from the dropdown in webdriver

The Code is:
public void setRing(int index, String ringPattern) throws InterruptedException {
List<WebElement> webElementList = driver.findElements(By.xpath(an.getProperty("an_ringPattern")));
webElementList.get(index).click();
List<WebElement> options = webElementList.get(index).findElements(By.tagName("option"));
for (WebElement element : options) {
if (element.getText().equals(ringPattern)) {
element.click();
Thread.sleep(2000);
}
}
}
When I execute this code in debug mode, it is working fine. It selects whatever value I pass to the method.
But when I run this code it is not able to change the value in the drop down. It selects the value in the drop down, but it's not able to set the value.
Please let me know if I am missing something.
If the Exception .Error message display below at org.openqa.selenium.support.ui.WebDriverWait.timeoutExceptio‌​n(WebDriverWait.java‌​:80) is being thrown, means that somehow that element is not ready on the frame, the driver is not on that frame or the xpath is wrong.
You can try to switch to the frame where the element is located, like this: driver.switchToFrame("here goes the id of the frame"); You can inspect the ID of the frame or sometimes just passing the integer 0 works. Also, I would rather use wait1.until(ExpectedConditions.visibilityOfElementLocated(element)); instead of wait1.until(ExpectedConditions.presenceOfElementLocated(element));.
When you use presenceOfElementLocated, you cant assure that the element is visible for the driver.
You can use explicit wait in selenium - WebDriverWait
Use below modified code
public void setRing(int index, String ringPattern) throws InterruptedException {
List<WebElement> webElementList = driver.findElements(By.xpath(an.getProperty("an_ringPattern")));
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.presenceOfElementLocated(webElementList.get(index)));
webElementList.get(index).click();
List<WebElement> options = webElementList.get(index).findElements(By.tagName("option"));
for (WebElement element : options) {
WebDriverWait wait1 = new WebDriverWait(driver, 60);
wait1.until(ExpectedConditions.presenceOfElementLocated(element));
if (element.getText().equals(ringPattern)) {
element.click();
Thread.sleep(2000);
}
}
}