Unable to locate element using ID or Name - selenium-webdriver

HTML:
<input name="txtAnswer" type="text" maxlength="20" id="txtAnswer" class="box1">
Code trials:
driver.findElement(By.xpath("//table[#id='tblSecurityAnswer']//tbody//tr[2]//td[2]//input[#id='txtAnswer']")).sendKeys("green");
and also:
driver.findElement(By.cssSelector("//tr:nth-child(1) > td > table > tbody >
// tr:nth-child(2) > td:nth-child(2)"));
public static void main(String[] args) throws InterruptedException {
WebDriver driver;
// IE webdriver
// System.setProperty("webdriver.ie.driver", "C:\\IEDriverServer.exe");
// driver = new InternetExplorerDriver();
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
driver = new ChromeDriver();
// Maximize the browser window
driver.manage().window().maximize();
// navigate to specified url
driver.get("http://dxbqcapp01/molforms/login.aspx");
driver.findElement(By.id("txtUserName")).sendKeys("MS200963915");
driver.findElement(By.id("txtPassword")).sendKeys("test#123");
driver.findElement(By.xpath("//input[#type='submit' and #value='Submit']")).sendKeys(Keys.ENTER);
driver.findElement(By.id("txtAnswer")).sendKeys("green");

The error stack trace would have helped us to debug your issue in a better way. However to send a character sequence to the desired element you have to induce WebDriverWait for the element to be clickable and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input.box1#txtAnswer"))).sendKeys("green");
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#class='box1' and #id='txtAnswer']"))).sendKeys("green");

Related

Why can't Selenium Web Driver find the elements in this case?

Selenium newbie here. The examples I tried so far worked well but now I stumbled upon a case that seemingly doesn't work:
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class GeckoDriverTest
{
public static void main(String[] args) throws Throwable
{
System.setProperty("webdriver.gecko.driver", "D://XXX/seleniumdrivers/geckodriver.exe");
FirefoxDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.aerzen.com/de/karriere/stellenangebote.html");
System.out.println("URL = "+driver.getCurrentUrl());
Thread.sleep(3000);
driver.findElement(By.cssSelector("a.consent-banner--accept.button.submit")).click();
Thread.sleep(3000);
System.out.println("URL = "+driver.getCurrentUrl());
List<WebElement> elements = driver.findElements(By.cssSelector("tr > td > a"));
System.out.println("Elements: "+elements.size());
for(WebElement element : elements)
{
String url = element.getAttribute("href");
System.out.println(url);
}
}
}
The first part does work but the "tr > td > a" selector doesn't find any elements although I'm pretty sure they exist (I can see them in the browser window).
Any idea what's going wrong there? Thanks a lot.
The table is inside an iframe. In order to access these elements you will need to switch to that iframe.
Also instead of tr > td > a cssSelector try using table td.real_table_col1 a cssSelector.
This should work better:
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//iframe")));
driver.switchTo().frame(driver.findElement(By.xpath("//iframe")));
List<WebElement> elements = driver.findElements(By.cssSelector("table td.real_table_col1 a"));
System.out.println("Elements: "+elements.size());
for(WebElement element : elements)
{
String url = element.getAttribute("href");
System.out.println(url);
}
Also instead of hardcoded pauses like
Thread.sleep(3000);
You should use ExpectedConditions something like
WebdriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a.consent-banner--accept.button.submit")));

ElementClickInterceptedException on cucumber parallel AbstractTestNGCucumberTests

I have parallel test setup in cucumber 6.9.1 using AbstractTestNGCucumberTests and then directing the test to a grid using RemoteWebDriver
#Override
#DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
}
and creating RemoteWebDriver like below
String hubURL = "http://192.168.1.7:65299/wd/hub";
System.setProperty("webdriver.gecko.driver", "/Users/../../geckodriver");
FirefoxProfile profile = new FirefoxProfile();
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
capabilities.setPlatform(Platform.ANY);
FirefoxOptions options = new FirefoxOptions();
options.merge(capabilities);
return driver = new RemoteWebDriver(new URL(hubURL),options);
It opens two instances of firefox , and they overlap each other and I keep getting
org.openqa.selenium.ElementClickInterceptedException: Element <button class="btn btn-link pull-right" on one or the other instance of firefox .
I have tried several solutions mentioned in many questions but none of them seems to help in my scenario
I tried below solutions
global.wait.until(ExpectedConditions.visibilityOf(PageObjects.AddUser));
global.jsExecutor.executeScript("arguments[0].click();", PageObjects.AddUser);
PageObjects.AddUser.sendKeys(Keys.ENTER);
Actions builder = new Actions(global.driver);
Action clickElement = (Action) builder.click(PageObjects.AddUser);
clickElement.perform();
global.wait.until(ExpectedConditions.invisibilityOfElementLocated((By) PageObjects.allDom));
I am running test on FF 77.0 and Mac OS (catalina)
How do I resolve this?
EDIT. To include ThreadLocal change
public class FirefoxManager extends DriverManager{
private final ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
#Override
protected RemoteWebDriver createDriver() throws MalformedURLException , IOException {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.out.println("hubport from sys prop var.."+System.getProperty("hub.port"));
String hubURL = "http://192.168.1.7:65299/wd/hub";
System.setProperty("webdriver.gecko.driver", "/Users/amit/Desktop/amit/projects/misc/geckodriver");
FirefoxProfile profile = new FirefoxProfile();
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
capabilities.setPlatform(Platform.ANY);
FirefoxOptions options = new FirefoxOptions();
options.merge(capabilities);
driver.set(new RemoteWebDriver(new URL(hubURL),options));
return driver.get();
}
You will need to use ThreadLocal since WebDriver is not ThreadSafe.
copied code, but idea is same
protected ThreadLocal<WebDriver> wbdriver = new ThreadLocal<WebDriver>();
String url = "https://google.com";
wbdriver.set(new ChromeDriver(options));
wbdriver.get().manage().window().maximize();
wbdriver.get().get(url);
I achieved cucumber parallelism using courgette-jvm . It worked out of the box and run parallel test at scenario level
Simply inlclude similar runner class in cucumber. My tests are further using RemoteWebdriver to open multiple instances on selenium grid. Make sure grid is up and running and node is registered to the grid.
import courgette.api.CourgetteOptions;
import courgette.api.CourgetteRunLevel;
import courgette.api.CucumberOptions;
import courgette.api.testng.TestNGCourgette;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
#Test
#CourgetteOptions(
threads = 10,
runLevel = CourgetteRunLevel.SCENARIO,
rerunFailedScenarios = true,
rerunAttempts = 1,
showTestOutput = true,
reportTitle = "Courgette-JVM Example",
reportTargetDir = "build",
environmentInfo = "browser=chrome; git_branch=master",
cucumberOptions = #CucumberOptions(
features = "src/test/resources/com/test/",
glue = "com.test.stepdefs",
publish = true,
plugin = {
"pretty",
"json:target/cucumber-report/cucumber.json",
"html:target/cucumber-report/cucumber.html"}
))
class AcceptanceIT extends TestNGCourgette {
}
RemoteWebdriver config is
protected RemoteWebDriver createDriver() throws MalformedURLException , IOException {
Properties properties = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String hubURL = "http://192.168.1.7:65299/wd/hub";
System.setProperty("webdriver.gecko.driver", "/Users/amit/Desktop/amit/projects/misc/geckodriver");
FirefoxProfile profile = new FirefoxProfile();
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
capabilities.setPlatform(Platform.ANY);
FirefoxOptions options = new FirefoxOptions();
options.merge(capabilities);
driver.set(new RemoteWebDriver(new URL(hubURL),options));
return driver.get();
}

Unable to click on a button (Angular JS application)

I'm unable to click on a button (Application built on Angular Js). My automation framework is existing one built on Java/Selenium WebDriver. I have tried with Xpath, CSS, etc still not working.
<button type="button" id="Button2" class="btn btn-primary btn-xs" data-ng-click="StartWizard()" data-ng-keyup="$event.keyCode == 13 ? StartWizard() : null">Import New File</button>
Script:
WebElement clickNextButton = driver.findElement(By.xpath("//button[contains(text(),'Import New File')]"));
clickNextButton.click();
Error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//button[contains(text(),'Import New File')]"}
Could you please help me to resolve this. Please let me know if this can be resolved using ngWebDriver?
You can execute the ng-click function defined in the element:
String waitForAngularJs = "angular.element(\"#Button2\").scope().StartWizard();";
try {
ExpectedCondition<Boolean> waitForAngular = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeAsyncScript(waitForAngularJs).equals(true);
}
};
WebDriverWait wait = new WebDriverWait(myWebDriver, 60);
wait.until(waitForAngular);
}catch(Exception e) {
e.printStackTrace();
}
Enjoy the code!

Not able to Click a Link in Gmail using Selenium Webdriver

I am a learner.
I am trying to automate the logout functionality of Gmail using Selenium Webdriver but unable to do so ..
There are two Phases in logout, first click the Right Link at the top, if that box appears then click logout. iam unable to do so.
<span id="gbi4t" style="max-width: 76px; text-align: left;">Mahmood Ali</span>
<a id="gb_71" class="gbqfbb" href="?logout&hl=en&hlor" onclick="gbar.logger.il(9,{l:'o'})" role="button" target="_top">Sign out</a>
here is my xpath
//*[#id="gbi4t"] -> Clicking that top to get the logout pop up
//*[#id="gb_71"] -> To logout the gmail application
i have tried such as
driver.findElement(By.id("gbi4t")).click(); OR
driver.findElement(By.xpath("//*[#id='gbi4t']")).click();
driver.findElement(By.id("gb_71")).click(); OR
driver.findElement(By.xpath("//*[#id='gb_71']")).click();
Some ideas out there ?
Actually the <span> isn't recognized as an element.
You need to use the <a id="gbg4" ...> to click() on it, wait the pop up and click on the <a id="gb_71" class="gbqfbb" ...> to logout.
I let you code, since you need to pracctice :P
tell me what's up.
Suggestions :
What i can suggest to you is to use the cssSelector().
why ? Because it's faster than the xpath and when page like google or others use dynamic value used for id/name it's better to use the class attribute and cssSelector() is way better than others.
But sometimes you'll use xpath to find an element that has "cancel" as inner text (exemple : <a>cancel</a> )
cssSelector() reference
You can also try following:
driver.find_element(:id, "gbgs4dn").click
driver.find_element(:id, "gb_71").click
This worked for me.
This code certainly works for me:
// (after logging to google.com)
WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("gbi4t")));
//open overlay
driver.findElement(By.id("gbi4t")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("gb_71")));
//press logout
driver.findElement(By.id("gb_71")).click();
Heres a solved example ::
package testme;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class testexample {
public static WebDriver driver;
public static WebElement element;
public static void main(String args[]) throws InterruptedException {
//setting the chrome driver
System.setProperty("webdriver.chrome.driver", "C:/Users/workspace/Downloads/chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://www.gmail.com");
element =driver.findElement(By.linkText("Sign in"));
element.click();
Thread.sleep(1000);
element = driver.findElement(By.id("Email"));
element.sendKeys("yourusername#gmail.com");
element = driver.findElement(By.id("Passwd"));
element.sendKeys("yourpassword");
element.submit();
Thread.sleep(1000);
//click on the logout link step 1
element = driver.findElement(By.xpath("//*[#id='gb']/div[1]/div[1]/div/div[3]/div[1]/a"));
element.click();
// click on actual logout button step 2
element = driver.findElement(By.id("gb_71"));
element.click();
//closing the webdriver window after successful completion of the test
driver.close();
}
}

Unable to find a link while running Selenium Test case

I am using Selenium webdriver. I can log in to the application, but while logging out it gets stuck, reason it cannot find logout link. I tried to find it byLink and byId. I have also tried using thread.sleep() but nothing seems to be working.
Logout link is present in all the pages.
HTML code:
<li>#{loginView.loggedInUser}>
<ul><li><h:link value="Administration" outcome="Administration.xhtml" /></li>
<li><h:commandLink value="Logout" actionListener="#{loginView.logout}">
<f:param id="userName" value="#{loginView.username}" />
</h:commandLink></li>
</ul></li>
SELENIUM code:
Thread.sleep(5000);
WebElement logOut = findElementByLinkText("Logout");
logOut.click();
assertEquals("Please sign in: ", findElementBySelector("h3.loginTitle.centerAlign").getText());
Use this code check how many links are present on page if it contains your logout link then you can click on it by using locator "linktext".
public void Link(){
driver.get(baseUrl);
HtmlTagFinder links = LinkFinder.links();
List<WebElement> allLinks = (List<WebElement>) links.findFrom(driver);
System.out.println(allLinks.size());
int i = 1;
for(WebElement link : allLinks){
System.out.println(i);
System.out.println(link.getText());
i++;
}
driver.close();
driver.quit();
}
driver.findElement(By.xpath("#value='Logout'")).click();

Resources