How to edit element in table with selenium? - selenium

I'm trying to edit value of element that placed it the table on
this page.
I'm using this code:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwCellTable");
WebElement firstName = driver.findElement(By.xpath("//*[#id=\"gwt-debug-contentPanel\"]/div[2]/div/div[2]/div/div[3]/div/div/div/table/tbody/tr[1]/td/table/tbody[1]/tr[1]/td[2]/div"));
firstName.click();
firstName.clear();
firstName.sendKeys("test");
It says:
"Element must be user-editable in order to clear it."
How i can edit this element?
Also i have troubles with "Category" field on this page. I'm trying to select each of them successively. Doing this with:
WebElement category = driver.findElement(By.xpath("//*[#id=\"gwt-debug-contentPanel\"]/div[2]/div/div[2]/div/div[3]/div/div/div/table/tbody/tr[1]/td/table/tbody[1]/tr[1]/td[4]/div/select"));
category.sendKeys("Businesses");
category.sendKeys("Friends");
category.sendKeys("Coworkers");
category.sendKeys("Businesses");
category.sendKeys("Family");
I tried to make category.sendKeys(""); once and it works well.
But throws this: "stale element reference: element is not attached to the page document" when i get a lot. How i can change this elements one by one?

This is kinda a strange one. The DOM keeps changing which makes it harder to see what's going on so that you can do the right thing to make it work. You have to click one element which changes the DOM and inserts an INPUT which is what you need to .sendKeys() to. I have tested the code below and it works.
I like to create functions for things like this so that they are reusable. This function changes the first name. rowIndex is the row of the table you want to change and firstName is the desired first name. You have to wait for the table to finish loading because it loads dynamically after the page is loaded.
public static void setFirstName(int rowIndex, String firstName)
{
WebElement firstNameElement = new WebDriverWait(driver, 10)
.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("tr[__gwt_row='" + rowIndex + "'] > td > div")))
.get(1);
firstNameElement.click();
firstNameElement.findElement(By.tagName("input")).sendKeys(firstName + "\n");
}
To change the first name of the first row to "FirstName" you would call it like,
setFirstName(0, "FirstName");

Related

selenium element.click() not working (doesn't click)

String selector = ".rmcAlertDialog .buttons :first-child";
RemoteWebElement selection = (RemoteWebElement) driver.findElement(By.cssSelector(selector));
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(selection));
if (element == selection) selection.click();
But the element in question (a button) is not responding to the click.
If I click the button manually it works so its not the web page at fault, but the automation.
I have verified the button is there by comparing it's text content.
updated for clarification
This code works (or worked) for most buttons. The code is from a script interpreter which is parsing:-
select ".rmcAlertDialog .buttons :first-child" click
This code was working prior to more recent versions of chrome/selenium/chromedriver.
The code now doesn't work for some buttons.
selection.click() IS being called (verified in a debugger), as element will always equal selection, it just is not working.
.buttons is the class name of the container div for the button(s)
The selector is not directing to the element with button class. You have a space between .button and :first-child in the selector. Remove the space. The given selector is searching for a child element of the tag with button class. But I'm assuming you are trying to click on the first element with button class not the child node of the button class element.
Use this:
String selector = ".rmcAlertDialog .buttons:first-child";
I think the main reason it's failing is because your if statement will never be true. I've never done any comparisons like this but you can simplify your code significantly and still get the desired effect.
A few suggestions:
Don't define locators as Strings, define them as Bys. The By class is defined for just such a task and makes using and passing them around MUCH easier.
String selector = ".rmcAlertDialog .buttons:first-child";
would turn into
By locator = By.cssSelector(".rmcAlertDialog .buttons:first-child");
Note the correction that S Ahmed pointed out in his answer.
You don't need to find the element to wait for it to be clickable. There is an overload that takes a By locator, use that instead.
RemoteWebElement selection = (RemoteWebElement) driver.findElement(By.cssSelector(selector));
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(selection));
becomes
WebElement element = new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(locator));
Skip the RemoteWebElement and WebElement comparison. I don't think this will work and there's no need for it anyway. Your locator will locate the same element consistently.
So your final code should look something like
By locator = By.cssSelector(".rmcAlertDialog .buttons:first-child");
new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(locator)).click();

Cant insert text - a msg that the element is not visible is displayed

I run automation on a site that after I click on a button and a screen of PayPal is opened for inserting details. The PayPal is opened in another tab. I added a syntax that move the testing to the relevant tab and then I insert a syntax that checks that the "email input" field exists (to check that it is really goes to the correct tab) - and the result of this test :- field exists.
Then - I add a syntax for the same field to insert the email and the test is failed - the text is not inserted and there is a msg that the field is not visible.
No need to do scroll because the filed is in the top of the screen.
What can I do in this case?
This is the relevant code:
String oldTab = driver.getWindowHandle();
comOps.clickOrChose(PLS.buyButton);
Thread.sleep(4000);
ArrayList<String> newTab = new ArrayList<String> (driver.getWindowHandles());
newTab.remove(oldTab);
driver.switchTo().window(newTab.get(0));
comOps.verifyElementExist(PLP.payPalEmail);
comOps.insertText(PLP.payPalEmail, "paypal-buyer#makeitleo.com");
The reason you get this error message is that the element apparently exists but is not visible when you try to enter text to it. There are a lot of possible reasons why the element is not visible.
Given that a new tab is opended a probable reason is that the page (and its elements) is still loading. If this is the case, you need to wait for the visiblity of the element, e.g. using this piece of code (before inserting text):
WebDriverWait wait = new WebDriverWait(driver, 300); //waiting up to 5 minutes
ExpectedCondition<WebElement> condition =
ExpectedConditions.visibilityOf(PLP.payPalEmail);
wait.until(condition);
Note: that this solution assumes that PLP.payPalEmail is of type org.openqa.selenium.WebElement. If it is of type org.openqa.selenium.By use visibilityOfElementLocated(By locator).
Telling from your code snippet, I assume that comOps is an object of a class wrapping all Selenium actions. So, it is a good idea to place the above code in some method inside that class which could look like this:
public void verifyElementVisible(WebElement element) {
WebDriverWait wait = new WebDriverWait(driver, 300); //ToDo: use configurable timeout
ExpectedCondition<WebElement> condition =
ExpectedConditions.visibilityOf(element);
wait.until(condition);
}
and call it like this
comOps.verifyElementVisible(PLP.payPalEmail);

How to select the checkbox in the list of checkboxes ONE-BY-ONE in selenium?

I need to select all the checkboxes from here one-by-one after every 3 second. I tried couple of xpaths with list,none of them have worked
Tried xpaths:
//div/div[#class='filters-list sdCheckbox ']
Using input and type. But none of them worked. Can you please help me out?
Reference website: https://www.snapdeal.com/products/storage-devices?sort=plrty
->Capacity at the left hand corner
By.xpath("//a[#class='filter-name']") this one listed out all the filters of page.
The xPath "//div[#data-name='Capacity_s']/div[#class='filters-list sdCheckbox ']/input" will fetch you the list of all input elements that you need to check.
There is a container DIV that holds all the filters of a certain type, e.g. Brand, Capacity, etc. The one for Brand is shown below.
<div class="filter-inner " data-name="Brand">
Under that container, all the LABEL tags are what you need to click to check the boxes. So, we can craft a CSS selector using the grouping as a filter to reach only the checkboxes we want.
"div[data-name='Brand'] label"
Since this is something I assume you will reuse, I would write this as a function.
public static void CheckFilters(String filterGroup)
{
WebDriverWait wait = new WebDriverWait(driver, 10);
List<WebElement> filters = driver.findElements(By.cssSelector("div[data-name='" + filterGroup + "'] label"));
// System.out.println(filters.size()); // for debugging
for (int i = 0; i < filters.size(); i++)
{
filters.get(i).click();
// wait for the two overlays to disappear
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div.searcharea-overlay")));
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.filterLoader.hidden")));
// reload the element list after the refresh so you don't get StaleElementExceptions
filters = driver.findElements(By.cssSelector("div[data-name='" + filterGroup + "'] label"));
}
}
and you would call it like
driver.get("https://www.snapdeal.com/products/storage-devices?sort=plrty");
CheckFilters("Brand");

how can I validate whether values entered in a new form is reflected correctly in edit form

I am trying to automate a website which is mainly dealing with Forms. I have entered values in new form and I need to validate whether it is reflected back correctly in edit form.
In New form I have tried like :
WebElement FN = driver.findElement(By.id("ctl00_ctl41_g_1fc852c8_32cb_4220_80ee_2af21b671f9e_ff21_ctl00_ctl00_TextField"));
FN.click();
FN.sendKeys("abc");
In the edit form code:
if(FN.getAttribute("value").equals("abc"))
System.out.println("First Name is matching with new form");
else
System.out.println("First Name is not matching with new form");
and I am getting error like
Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document(Session info: chrome=57.0.2987.110)
Thanks in advance .
You need to reinitialize the FN Webelement once you are at edit form, as the previous FN Webelement will become stale as soon as you move away from new form. Hence, try following:
FN = driver.findElement(By.id("ctl00_ctl41_g_1fc852c8_32cb_4220_80ee_2af21b671f9e_ff21_ctl00_ctl00_TextField"));
if(FN.getAttribute("value").equals("abc"))
System.out.println("First Name is matching with new form");
else
System.out.println("First Name is not matching with new form");
Let me know, if you have any further queries.
Possibly, you are having exception at FN.sendKeys("abc");. When you click on the element before going to edit mode, the element is also changing. That's why you are having that exception.
I suggest, after clicking on the FN element have locator for textfield afresh and use sendkeys() method on it.
To know about this type of exception this might help you:
http://darrellgrainger.blogspot.com/2012/06/staleelementexception.html

How to select option from dynamic dropdown

I got a problem with choosing an option from a dynamic dropdown.
I've already tried several options:
- by choosing from the select list (in the 'target' i tried (label, index, value))
- by choosing from the div id="id_language_chzn (in the 'target' i tried (label, index, value))
Nothing supposed to work !
Code is here: http://pastebin.com/v3Q7NDGs
Regards if could help me on this,
Szymon
Use a little delay after the page load, very likely the JS did not initialize completely.
http://release.seleniumhq.org/selenium-core/1.0/reference.html#pause
Also for this Chosen problem, click on the dynamically created element itself, do not use the html form element.
I would do it like this:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
By ddLocator = By.xpath(".//select[1]");
By items = By.xpath(".//option");
ByChained comboBox1 = new ByChained( ".//select[1]", ".//option" );
List<WebElement> allOptions = driver.getElements( comboBox1 );
for ( WebElement we : allOptions ) {
// do something here
}
Ok, it occurred that selenium IDE had some problems with taking out the selected option. I have used webdriver and it helped.
Here is the code:
driver.findElement(By.cssSelector("a.class > span")).click();
driver.findElement(By.id("id_name[1]")).click();