I'm currently testing an email service, and upon opening a list of options to filter email, I want to be able to automate clicking on an option in the list. The code for the list is:
However, selenium cannot find this element, even though I can find it by searching the HTML using CTRL+F. The code I'm currently using to try and find and click this list element is:
wait.until(ExpectedConditions.visibilityOfElementLocated(org.myorg.automation.Objects.ManageEmails.Locators.FilterList));
Select dropdown = new Select(driver.findElement(org.myorg.automation.Objects.ManageEmails.Locators.FilterList));
dropdown.selectByVisibleText("Unread");
The xpath of the list is:
/html/body/div[7]/div/div/div/div/div/div/ul
Any help would really be appreciated!!
The problem is that you don't have a select in this case and the: Select dropdown = new Select(); wont work. You'll need a custom method to select a value from that list
public class Testing {
public WebDriver driver;
#Test
public void TestSomething() {
driver = new ChromeDriver();
driver.get("<the url where this list is present>");
// assuming that the ul list is unique on the page if not find another way to get it
WebElement ulListParent = driver.findElement(By.xpath("//ul[contains(#class,'ms-ContextualMenu-list is-open')]"));
SelectBasedOnValue(ulListParent, "Unread");
driver.close();
}
public void SelectBasedOnValue(WebElement parentElement, String optionValue) {
parentElement.findElement(By.xpath(String.format("//li[text()='%s']", optionValue))).click();
}
}
Related
I am trying to click on an option (array of images) from an unordered list using Selenium Java.
I have tried doing a click on the className of "attachment" but that doesn't seem to pick up the list item that I need to click on.
Is there anyway to pick up something like the data-id?
The code that I have tried:
public void click(By by) {
waitProvider.waitFor().waitUntilElementIsClickable(by);
WebElement clickableElement = locate(by);
Actions actions = new Actions(webDriverProvider.driver());
actions.moveToElement(clickableElement);
actions.click().perform();
}
and then we do:
public void selectFirstImage() {
click("attachment");
}
locate:
public WebElement locate(By by) {
waitProvider.waitFor().waitUntilVisibilityOfElementLocatedBy(by);
scrollIntoView(by);
return webDriverProvider.driver().findElement(by);
}
I think click method call is incorrect.
Since click expects By not String it should look like this:
click(new ByCssSelector(".attachment-preview"));
I need a little help. I'm trying to run an automated test on the website http://zara.com and i want to select the language from the language dropdown.
This is the HTML code from Zara. https://prntscr.com/g6hdiv
This is the code i've tried with Selenium 2.53 in IntelliJ
public class RegistrationTest {
WebDriver driver;
#Before
public void setUp(){
driver = new FirefoxDriver();
driver.get("http://zara.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#After
public void tearDown(){
driver.quit();
}
#Test
public void test(){
WebElement languageDropdown = driver.findElement(By.id("language"));
Select selectLanguage = new Select(languageDropdown);
selectLanguage.selectByValue("en");
}
}
I always receive the error below even if I've tried in different setups but it didn't work.
org.openqa.selenium.ElementNotVisibleException: The element is not currently visible and so may not be interacted with
Could you please tell me what am I doing wrong?
Appreciate the help.
The element is not currently visible and so may not be interacted with
You need to scroll the page, so that the element is in the current viewport. Something like this:
WebElement languageDropdown = driver.findElement(By.id("language"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", languageDropdown);
Select selectLanguage = new Select(languageDropdown);
selectLanguage.selectByValue("en");
I have been reading about stale elements and am still a bit confused. For instance, the following won't work, correct?
public void clickFoo(WebElement ele) {
try {
ele.click();
} catch (StaleElementReferenceException ex) {
ele.click();
}
}
because if ele is stale, it will remain stale. The best thing is to redo the driver.findElement(By), but as you can see in this example, there is no xpath. You can attempt to ele.getAttribute("id") and use that, but if the element has no id, this also will not work. All methods calling this would have to put the try/catch around it, which may not be feasible.
Is there some other way the element could be refound? Also, assuming there is an id, would the id remain the same after the element goes stale? What in the WebElement object ele is different once it goes stale?
(Java Eclipse)
I would recommend you NOT create a method like the above. There's no need to add another function layer on top of .click(). Just call .click() on the element itself.
driver.findElement(By.id("test-id")).click();
or
WebElement e = driver.findElement(By.id("test-id"));
e.click();
One way that I use regularly to avoid stale elements is find the element only when you need it and generally I do this by in a page object method. Here's a quick example.
The page object for a home page.
public class HomePage
{
private WebDriver driver;
public WebElement staleElement;
private By waitForLocator = By.id("sampleId");
// please put the variable declarations in alphabetical order
private By sampleElementLocator = By.id("sampleId");
public HomePage(WebDriver driver)
{
this.driver = driver;
// wait for page to finish loading
new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(waitForLocator));
// see if we're on the right page
if (!driver.getCurrentUrl().contains("samplePage.jsp"))
{
throw new IllegalStateException("This is not the XXXX Sample page. Current URL: " + driver.getCurrentUrl());
}
}
public void clickSampleElement()
{
// sample method code goes here
driver.findElement(sampleElementLocator).click();
}
}
To use it
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://www.example.com");
HomePage homePage = new HomePage(driver);
homePage.clickSampleElement();
// do stuff that changes the page and makes the element stale
homePage.clickSampleElement();
Now I no longer have to rely on an old reference. I just call the method again and it does all the work for me.
There are many references on the page object model. Here's one from the Selenium wiki. http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern
If you want to read more info on what a stale element is, the docs have a good explanation. http://docs.seleniumhq.org/exceptions/stale_element_reference.jsp
firstli i write my scenario:
go http://demo.opencart.com/
search ipod
click add to compare in every found items
here is my code (java webdriver pagefactory)
searchresultspage (my object page)
#FindBy(id = "compare-total")
WebElement numberOfProductToCompare;
public void compareAllItems() {
for (WebElement compareButtons: compareButton) {
compareButtons.click();
}
}
public void areAllItemsClickedCompare() {
String text = numberOfProductToCompare.getText();
System.out.println(text);
}
My main test class
#Test
public void addToCompare() {
searchresultspage.compareAllItems();
searchresultspage.areAllItemsClickedCompare();
}
i click all compare buttons and i want to get number from link Product Compare (4) but when i use searchresultspage.areAllItemsClickedCompare(); then System.out.println(text); print me Product Compare (0), even this method is after adding to compare (should be should be Product Compare (4)) Dont know what to do, some advice?
Think, the problem appears because the compare-total element is captured by Selenium on class instantiating, but when its content is updated on the page, it doesn't affect the captured value.
Try to capture the compare-total element only after all checkboxes were clicked:
public void areAllItemsClickedCompare() {
WebElement numberOfProductToCompare = driver.findElement(By.id("compare-total"));
String text = numberOfProductToCompare.getText();
System.out.println(text);
}
Where driver is your WebDriver instance.
I am trying to automate search box of Amazon.in and when i try to enter some string over there, it rather points towards the address bar of browser. My code for the same.
Note- I have already tried with different xpaths using firebug and also through tag traversing.
Also please let me know why we have to use always build and perform methods with actions?
public static void main(String args[])
{
WebDriver driver= new FirefoxDriver();
driver.get("http://amazon.in");
Actions action=new Actions(driver);
WebElement element= driver.findElement(By.xpath(".//*[#id='nav-link-yourAccount']/span[2]"));
action.moveToElement(element).build().perform();
WebElement search= driver.findElement(By.xpath(".//*[#id='twotabsearchtextbox']"));
action.keyDown(Keys.SHIFT).moveToElement(search).sendKeys("teststring").build().perform();
action.contextClick(search).build().perform();
}
public static void main(String args[]) {
WebDriver driver = new FirefoxDriver();
driver.get("http://amazon.in");
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
Actions action = new Actions(driver);
WebElement search = driver.findElement(By.xpath(".//*[#id='twotabsearchtextbox']"));
//Search using actions by combining entering search string and then hit enter
action.click(search).sendKeys("Test").sendKeys(Keys.RETURN).build().perform();
// This also works where it does the same without actions class
search.sendKeys("test");
search.sendKeys(Keys.RETURN);
}
In your code:
Below line enters teststring into the browser search instead of the amazon search bar because you are just moving to that element and not clicking on it. action.keyDown(Keys.SHIFT).moveToElement(search).sendKeys("teststring").build().perform();
This like right clicks / context click on the search bar
action.contextClick(search).build().perform();
From the API doc:
build() Generates a composite action containing all actions so far,
ready to be performed (and resets the internal builder state, so
subsequent calls to build() will contain fresh sequences).
perform() A convenience method for performing the actions without
calling build() first
Please read below links for a clear picture on them:
LinkOne
LinkTwo