Tried sendomg keys , right relative xpath or ID used but still not working properly
Tried using absolute xpath , relative xpath also ID. Tried using selassist and chropath still not working. Could there be something preventing it?
public void LoginWebSystem() {
driver = new ChromeDriver();
driver.get("http://localhost:82");
WebElement email = driver.findElement(By.id("login_username"));
email.sendKeys("superadmin");
System.out.println("Username Set");
WebElement password = driver.findElement(By.id("login_password"));
password.sendKeys("nelsoft121586");
System.out.println("Password Set");
WebElement login = driver.findElement(By.id("login_submit"));
login.click();
System.out.println("Login Button Clicked");
String newUrl = driver.getCurrentUrl();
if(newUrl.equalsIgnoreCase("http://localhost:82/controlpanel.php")){
System.out.println("Login Success");
}
else {
System.out.println("Login Failed");
}
driver.findElement(By.partialLinkText("Product")).click();
System.out.println("Successful in proceeding to Product Page");
driver.findElement(By.id("createlink")).click();
System.out.println("Successful in proceeding to Create Product by Detailed");
driver.switchTo().alert().accept();
System.out.println("Successful in clicking alert button");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
#Test (priority=1)
public void ProductDetails() {
WebElement product = driver.findElement(By.xpath(" //*[#id="text-product"]"));
product.sendKeys("superadmin");
}
}
Expected output should input superadmin to product textbox
You have a typo in your XPath expression:
WebElement product = driver.findElement(By.xpath(" //*[#id="text-product"]"));
^ remove this space break
It's better to use By.Id locator strategy where possible as this is the fastest and the most robust way of identifying elements in DOM
Consider using Explicit Wait to ensure that the element is present and can be interacted with as it might be the case the element becomes available after document.readyState becomes complete. Check out How to use Selenium to test web applications using AJAX technology article for more detailed explanation.
new WebDriverWait(driver, 10)
.until(ExpectedConditions.elementToBeClickable(By.id("text-product")))
.click();
Make sure that your selector matches an <input> because if the id belongs to other element type like <div> it doesn't make a lot of sense to send keys there.
Related
Sources: Selenium WebDriver, Chrome 73V, ChromeDriver, Java , testNG, CRM application , Eclipse
I am working on web application which is kind of CRM, loaded with tons of UI elements. One test case works today and fail tomorrow. FYI, I used fluent wait for my test cases.
I checked all the xpaths and they are good. On top of this I executed with Debug mode and tests are passing on debug mode.
They are randomly flaky and un-stable , I am not sure what to do to make them stable? I don't want to use thread.sleep , off course.
Below code (just for the idea) I used to click few elements of the page , sometime Action class works sometime doesn't and sometime Click function works sometime doesn't, not sure how to handle such weird scenario?
driver.findElement(By.name("submit")).sendKeys(Keys.ENTER);
OR
driver.findElement(By.name("submit")).sendKeys(Keys.RETURN);
OR
driver.findElement(By.name("submit")).click();
OR
WebElement webElement = driver.findElement(By.id("Your ID Here"));
Actions builder = new Actions(driver);
builder.moveToElement(webElement).click(webElement);
builder.perform();
OR
WebElement webElement = driver.findElement(By.id("Your ID here"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", webElement);
Thanks for your comments, Please see below, this is my fluent wait:
public static boolean waitForElementToBeVisibleOrClickable (WebDriver driver, WebElement element) {
boolean webElement = false;
try {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 30)
.ignoring(NoSuchElementException.class,
StaleElementReferenceException.class)
.pollingEvery(200);
wait.until(ExpectedConditions.visibilityOf(element));
**OR**
wait.until(ExpectedConditions.elementToBeClickable(element));
Log.info("Element is visible");
webElement = true;
} catch (Exception e) {
Log.error("Element is not visible");
webElement = false;
} finally {
driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
}
return webElement;
}
You defined method to wait, but you don't actually use it. You are locating the element using driver and immediately click it. You should also modify the wait to use it while locating the element, not afterwards
public WebElement waitForElement(By by) {
return wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}
waitForElement(By.name("submit")).click();
You need to take care of the couple of things:
To invoke click() on an element you should always induce WebDriverWait for the elementToBeClickable().
You can find a relevant discussion in How to click a hyperlink without any link text
If the element is within a <form> tag, as an alternative you can use the submit() method.
You can find a detailed discussion in Selenium: submit() works fine, but click() does not
As per the documentation, Do not mix implicit and explicit waits! Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.
You can find a detailed discussion in How to properly configure Implicit / Explicit Waits and pageLoadTimeout through Selenium?
Solution
Instead of using fluent wait you can induce WebDriverWait in conjunction with ExpectedConditions and an optimized code block will be:
public static boolean waitForElementToBeVisibleOrClickable (WebDriver driver, WebElement element) {
try {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
new WebDriverWait(driver, 30).until(ExpectedConditions.elementToBeClickable(element));
System.out.println("Element is clickable now");
} catch (TimeoutException e) {
System.out.println("Element isn't clickable");
} finally {
driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
}
return element;
}
I have written a piece of code to login into an application which is working fine. Now I have to click an add button, and I have tried it by Id, XPath, ClassName but it just gives me the exception of element not found. I thought I should apply an explicit wait, but it also did not work. Please check my code below:
public static void Login()
{
Browser.Url = "http://example.com";
_username = Browser.FindElement(By.Id("UserName"));
var password = Browser.FindElement(By.Id("Password"));
var loginbtn = Browser.FindElement(By.ClassName("btn-primary"));
_username.SendKeys("admin");
password.SendKeys("123");
loginbtn.Click();
var supplierTab = Browser.FindElement(By.Id("mainSupplier"));
supplierTab.Click();
WebDriverWait wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(20));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
try
{
return d.FindElement(By.Id("btnAddSupplier_SupplierForm"));
}
catch
{
return null;
}
});
var addbtn = Browser.FindElement(By.Id("btnAddSupplier_SupplierForm"));
addbtn.Click();
}
This always gives an exception on the second last line of code that element not found.
Here is the HTML:
Try the following
public static void Login()
{
Browser.Url = "http://example.com";
_username = Browser.FindElement(By.Id("UserName"));
var password = Browser.FindElement(By.Id("Password"));
var loginbtn = Browser.FindElement(By.ClassName("btn-primary"));
_username.SendKeys("admin");
password.SendKeys("123");
loginbtn.Click();
//I think you have mentioned the iframe exist and assuming the element is inside the iframe do the following. If not skip the SwitchTo() part
//you can use name, css to identify the iframe
Browser.SwitchTo().Frame(Browser.FindElement(By.XPath("xpath for the iframe")));
var supplierTab = Browser.FindElement(By.Id("mainSupplier"));
supplierTab.Click();
WebDriverWait wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(20));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id("btnAddSupplier_SupplierForm"));
});
//if you think the id is not unique try using xpath or css
//even though you added an explicit wait you never used it
myDynamicElement.Click();
}
Sometimes the element will be existing in the source code but will not be visible for selenium to perform a click operation. Try the below code which will wait until the element is visible:
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(20));
IWebElement element = wait.Until(
ExpectedConditions.ElementIsVisible(By.Id("btnAddSupplier_SupplierForm")));
element.Click();
Not sure if this would help, but try calling this function before you click on Add button:
void waitForPageLoad(WebDriver driver)
{
ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
wait.until(pageLoadCondition);
}
A NoSuchElementException is thrown when the locating mechanism used is not available in the dom.
A TimeoutException is thrown when your expected condition fails to be true within the time limit. An expected condition can be anything, (exists,visibility,attribute value etc...).
First you want to figure out if the element's locating mechanism you are using is indeed not found in the dom. Here is a good way to manually find out.
Open chrome and navigate to the page.
Open chrome dev tools and click on the console tab.
In the text box type $x("//*[#id='btnAddSupplier_SupplierForm']") and hit enter. This will run an xpath query, basically you are looking for any element that has an id attribute with value "btnAddSupplier_SupplierForm".
If an element appears in the console and is the correct element then it's likely that you are trying to find an element in the dom before the dom is finished loading. If no element appears in the console then you have a bad locator.
Please report your findings.
There is a html page with button, and my selenium test is testing, that there is an action executed, when the button is clicked.
The problem is, that it looks like the click happens before the javascript is executed - before the handler is bound to the page. The consequence is, that the selenium test will click on the button, but no action happens.
I can solve this problem by repeatedly trying to click and then observe, if the desired action happened (some element is present on page, typically). I'd like to hear that there are some more elegant solutions...
There is no clear way to say "wait until element X has such-and-such handler"; this is a limitation of JavaScript and the DOM (see for example Get event listeners attached to node using addEventListener and jQuery find events handlers registered with an object), and for that matter a selenium Expected Condition can't be created, at least not trivially.
I've resorted to time.sleep(0.5).
You can write some logic to handle this.
I have write a method that will return the WebElement and this method will be called three times or you can increase the time and add a null check for WebElement
Here is an example
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://www.crowdanalytix.com/#home");
WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
int i = 1;
while (webElement == null && i < 4) {
webElement = getWebElement(driver, "homessssssssssss");
System.out.println("calling");
i++;
}
System.out.println(webElement.getTagName());
System.out.println("End");
driver.close();
}
public static WebElement getWebElement(WebDriver driver, String id) {
WebElement myDynamicElement = null;
try {
myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By
.id(id)));
return myDynamicElement;
} catch (TimeoutException ex) {
return null;
}
}
I am new to selenium. I am practicing to write a test case on http://www.countdown.tfl.gov.uk. Below are the steps I followed:
a) I opened the browser to selenium Web Driver
b) Found the search text Box and enter H32 and clicked on search button to selenium.
Till this part it works fine.
Now on the page I am actually getting two records on the left side of the page under the search. I am actually trying to click on the first one i.e. "Towards Southall,Townhall" link. Nothing is happening.
Below is my code:
public class CountdownTest {
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver)
}
//open the countdowntfl page
private WebDriver openWebDriver(){
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.get("http://www.countdown.tfl.gov.uk");
return driver;
}
private void searchforBus(WebDriver driver,String search){
WebElement searchBox = driver.findElement(By.xpath("//input[#id='initialSearchField']"));
searchBox.sendKeys(search);
WebElement searchButton = driver.findElement(By.xpath("//button[#id='ext-gen35']"));
searchButton.click();
}
private void selectrouteDirection(WebDriver driver){
WebElement towardssouthallLink= driver.findElement(By.xpath("//span[#id='ext-gen165']']"));
((WebElement) towardssouthallLink).click();
}
}
Please help me.
Thanks.
Since you are getting NoSuchElement Exception now, you may try the following code with the usage of WebDriver explicit wait.
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement towardssouthallLink = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("(//*[#id='route-search']//li/span)[1]")));
towardssouthallLink.click();
Or WebDriver implicit wait
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("http://www.countdown.tfl.gov.uk");
Tips:
The search results need some time to be retrieved, so please use Explicit wait or Implicit wait.
Don't use locators like span[#id='ext-gen165'], they are ExtJs auto generated.
In this case, css selector can also be used: #route-search li:nth-of-type(1) > span
You aren't calling selectrouteDirection.
You probably want:
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver);
}
You also don't need to cast here:
((WebElement) towardssouthallLink).click();
It's already a WebElement anyway.
I found that id for those links are dynamically generated. ids are of the form 'ext-genXXX' where XXX is number which is dynamically generated hence varies each time.
Actually, you should try with linkText:
For 'Towards Southall, Town Hall'
driver.findElement(By.linkText("Towards Southall, Town Hall")).click
For 'Towards Hounslow, Bus Station'
driver.findElement(By.linkText("Towards Hounslow, Bus Station")).click
Here is a logic:
Get all elements which have id starts with 'ext-gen' & iterate over it & click on link with matching text. Following is Ruby code(sorry, I don't know Java well):
links = driver.find_elements(:xpath, "//span[starts-with(#id, 'ext-gen')]")
links.each do |link|
if link.text == "Towards Southall, Town Hall"
link.click
break
end
end
I am trying to search Google for Selenium, then run down the list of links by clicking each one, printing the page title, then navigating back.
List<WebElement> linkElements = driver.findElements( **<insert code here>** );
for(WebElement elem: linkElements)
{
String text = elem.getText();
driver.findElement(By.linkText(text)).click();
System.out.println("Title of link\t:\t" + driver.getTitle());
driver.navigate().back();
}
To find the elements, I have tried By.tagName("a") which doesn't work because it gets ALL the links, not just the search ones. Using Firebug, I see that each search link has a class of r used on the header h3, and the a tag nested inside it.
See the following:
<h3 class="r">
<a href="/url sa=t&rct=j&q=selenium&source=web&cd=1&cad=rja&ved=0CC8QFjAA&url=http%3A%2F%2Fseleniumhq.org%2F&ei=y4eNUYiIGuS7iwL-r4DADA&usg=AFQjCNHCelhj_BWssRX2H0HZCcPqhgBrRg&sig2=WBhmm65gCH7RQxIv9vgrug&bvm=bv.46340616,d.cGE" onmousedown="return rwt(this,'','','','1','AFQjCNHCelhj_BWssRX2H0HZCcPqhgBrRg','WBhmm65gCH7RQxIv9vgrug','0CC8QFjAA','','',event)"><em>Selenium</em> - Web Browser Automation
</a></h3>
What code can I insert to make this work?
You have a lot of solution for doing it. There's mine. You keep your way like
// You get all links in a list
List<WebElement> linkElements = driver.findElements(By.xpath("//h3/a"));
// for each element(link) you click() on it
for(WebElement elem: linkElements)
{
elem.click();
// i suggest to put a wait right there
System.out.println("Title of link\t:\t" + driver.getTitle());
driver.navigate().back();
}
i don't know why you were trying to complicate with getText() etc.
Try below New Code
WebDriver driver;
driver = new FirefoxDriver();
driver.get("http://www.google.com");
driver.findElement(By.id("gbqfq")).sendKeys("Selenium");
Thread.sleep(1500L);
driver.findElement(By.id("gbqfb")).click();
Thread.sleep(1500L);
List<WebElement> linkElements = driver.findElements(By.xpath("//h3[#class='r']/a"));
for(int i=0;i<=linkElements.size();i++)
{
String text = linkElements.get(i).getText();
driver.findElement(By.linkText(text)).click();
Thread.sleep(2000L);
System.out.println("Title of link\t:\t" + driver.getTitle());
Thread.sleep(2000L);
driver.navigate().back();
linkElements = driver.findElements(By.xpath("//h3[#class='r']/a"));
}
try searching for this selector:
'.g:nth-child('+clickPosition+') h3.r a'
where "clickPosition" is the SERP result array key. Careful though, google now implements an "onmousedown" event that will change the href attribute to their redirect.