Selenium clicks on Browser's url rather than search box of website - java

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

Related

Selenium cannot find ul Element that is visible on Page

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();
}
}

Selenium hover code works in Chrome not Edge

public void Hover()
{
Actions action = new Actions(BrowserWindow.Instance.Driver);
action.MoveToElement(WebElement).Perform();
}
This is working in Chrome. Not Edge. I have confirmed with the developer that I am "hovering" over the correct element.
WebElement elem = yourWebDriverInstance.findElement(By.xpath("//*[#class='goog-menu goog-menu-vertical uploadmenu density-tiny']/input"));
String js = "arguments[0].style.height='auto'; arguments[0].style.visibility='visible';";
((JavascriptExecutor) yourWebDriverInstance).executeScript(js, elem);
Which also failed to work. Anyone have any idea what I am doing wrong?
More info.
This is also failing on Firefox. I saw an article about out of date selenium drivers. I have JUST installed both geckodriver and set the Edge driver to auto update according to the documentation. I do not believe I have out of date drivers.
More info take 2
Calling code is
public static void DoCloseActiveTabEntire()
{
Element tab = new Element(byTab);
tab.Hover();
// CLose button is not clickable. Cannot use standard BUTTON for find
Button close = new Button(byClosePanelButton);
close.Click();
}
If I set a break point at button close... after the hover attempt, I notice that moving my mouse over the "tab" also does not cause the button to be visible.
This is weird. But replace
action.MoveToElement(WebElement).Perform();
with
action.MoveToElement(WebElement).Build().Perform();
And it works. I read that the Build is built into Perform. But I was kinda just smacking at it hoping something fell out. And it worked.
perform()
perform() is the convenience method for performing the actions without calling build() first.
build()
build() generates a composite action containing all actions so far, ready to be performed and additionally also resets the internal builder state, so subsequent calls to build() will contain fresh sequences.
This usecase
In your usecase, you have invovoked perform() just after moveToElement(WebElement) without generating the composite action to be performed using build().
Solution
A straight forward solution would be to invoke build() before perform() as follows:
public void Hover()
{
Actions action = new Actions(BrowserWindow.Instance.Driver);
action.moveToElement(WebElement).build().perform();
}
So, I don't know why I thought the build().perform() did the job. I know it worked ONCE. What I wound up doing is keeping the hover code the same.
public void Hover()
{
Actions action = new Actions(BrowserWindow.Instance.Driver);
action.MoveToElement(WebElement).Build().Perform();
Thread.Sleep(1000);
}
I changed the calling code which attempts to close the panel/page whatever I want to call it to this:
public static void DoCloseActiveTabEntire()
{
// So there is a defect in EDGE whereby the behavior of the code containted in the hover on the tab executes without
// error but the action underneath does not occur. So in Edge, callng the hover method of the TAB as seen in the else condition
// below does nto display the CLOSE button which needs to be clicked.
// So for Edge, javascript is used to display the button directly.
IWebElement close;
if (BrowserWindow.Instance.Browser == BrowserWindow.Browsers.Edge)
{
close = BrowserWindow.Instance.Driver.FindElement(byClosePanelButton);
string js = "arguments[0].style.height='auto'; arguments[0].style.visibility='visible'; arguments[0].style.display='inline';";
IWebDriver driver = BrowserWindow.Instance.Driver;
IWebElement element = close;
((IJavaScriptExecutor)driver).ExecuteScript(js, element);
}
else
{
Element tab = new Element(byTab);
tab.Hover();
close = new Button(byClosePanelButton).WebElement;
}
close.Click();
}
For me, I am happy that the thing can be closed. I don't care that much whether the hover achieves it.

Need to click on sub option of dropdown menu in OWA

My test script are developed using Java with Selenium webdriver api. There is 1 particular scenario where I need to click on a sub option loaded from a dropdown menu but I am not able to do that. Following are the test steps and the screenshot for the particular problem.
-Launch Microsoft Outlook Web App (OWA) and login
-On main screen I need to enter some text in Search Field
-Click the drop down next to it
-Select "This Folder" from the options loaded
(Screenshot)
I dont see any frameid so not using any. Dropdown works fine but failing to click on suboption.
Adding the code which I am using for click this
public static final By searchDropDown_locator= By.xpath(".//*[#id='divSScp']");
public static final By thisFolderText_locator= By.xpath("(.//*[#id='spnT' and text()='This Folder'])[2]");
public void clickSearchDropDown()
{
WebElement searchIcon= websitedriver.findElement(searchDropDown_locator);
searchIcon.click();
}
public void clickThisFolder()
{
WebElement searchIcon= websitedriver.findElement(thisFolderText_locator);
searchIcon.click();
}
I am calling both these functions in my script file.
What could be the solution here.
Try to use JavascriptExecutor for click as below
public void clickSearchDropDown()
{
WebElement searchIcon= websitedriver.findElement(searchDropDown_locator);
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", searchIcon);
}
public void clickThisFolder()
{
WebElement searchIcon= websitedriver.findElement(thisFolderText_locator);
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", searchIcon);
}
Hope it will help you :)

How do I extract the recognition strategy of a Selenium Web Element during run time?

The problem I have is that my Page Object class finds all of the objects on the screen and then sends it to a more generic method to do the actual data entry. During this data entry process, some objects become stale and I get the "StaleElementException".
My plan is to catch that exception and attempt to re-find the element again.
Is there a way of extract the selection strategy from the runtime WebElement object other than doing a "object.toString()" and then parsing it?
I use page objects by defining the locators at the top of the class, then the constructor that verifies that we're on the right page (etc), and then methods for each action available on the page. Here's a simple example for the Google search page.
GoogleSearchPage.java
public class GoogleSearchPage
{
private WebDriver driver;
private By waitForLocator = By.id("lst-ib"); // optional
private By searchBoxLocator = By.id("lst-ib");
private By searchButtonLocator = By.cssSelector("button[name='btnG']");
private By feelingLuckyButtonLocator = By.id("gbqfbb");
public GoogleSearchPage(WebDriver webDriver)
{
driver = webDriver;
// 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("https://www.google.com"))
{
throw new IllegalStateException("This is not the Google search page. Current URL: " + driver.getCurrentUrl());
}
}
public void doSearch(String searchString)
{
driver.findElement(searchBoxLocator).sendKeys(searchString);
driver.findElement(searchButtonLocator).click();
}
}
GoogleSearchTest.java
public class GoogleSearchTest
{
public static void main(String[] args)
{
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
GoogleSearchPage googleSearchPage = new GoogleSearchPage(driver);
googleSearchPage.doSearch("selenium");
System.out.println(driver.getCurrentUrl().contains("#q=selenium"));
}
}
This is obviously a super simple example but it shows one good way to create page objects that should significantly reduce the frequency of StaleElementExceptions and, in some cases, speed up your script execution because you only scrape what you need and move on.
Reduce the urge to provide a getX() and clickX() method for each and every element on the page. Instead favor task based methods. Ask yourself what tasks a user is going to want to accomplish on the page and provide methods to do those tasks. It will keep your page object API much cleaner and more clear in what it provides to the consumer (you and other script writers).

Unable to click on a radio button in Selenium Webdriver

I am learning Selenium Webdriver using Java.
As a learning example, I tried to open MakeMyTrip, access International Flights page and click on One Way radio button in Google Chrome.
I tried different ways to locate this radio button but it's still not working.
Please find below my code sample.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class TryRadioClass {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "Chrome exe path");
WebDriver driver=new ChromeDriver();
driver.get("http://www.makemytrip.com/international-flights");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
boolean displayFlag = driver.findElement(By.linkText("ONE WAY")).isDisplayed();
System.out.println("Display Flag :- "+displayFlag);
boolean enableFlag = driver.findElement(By.linkText("ONE WAY")).isEnabled();
System.out.println("Enable Flag :- "+enableFlag);
if(displayFlag==true && enableFlag==true)
{
WebElement element=driver.findElement(By.linkText("ONE WAY"));
element.click();
System.out.println("Tried to click One Way");
}
}
}
Can anyone please help me to resolve this issue?
Use below code :-
if(displayFlag==true && enableFlag==true)
{
try{
Thread.sleep(5000);
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
WebElement element=driver.findElement(By.xpath("//span[#class='radio_state']"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
System.out.println("Tried to click One Way");
}
enjoy .. get back to me if still getting any issue :)
Clicking on link sometimes might skip checking the radio button. Try clicking on the radio button (or input html tag) directly rather than clicking on the anchor tag. Here's an example -
WebElement ele=driver.findElement(By.xpath("//input[#value='one_way']"));
ele.click();
Hope this helps.
Try to never use Thread.sleep(time)
Never use general Exception catching.
Instead of it try this, what is more safe:
public Boolean isDisplayed() {
try {
wait.withTimeout(20).until(new ExpectedCondition<Boolean>() {
#Nullable #Override public Boolean apply(WebDriver input) {
return videoComponent.isDisplayed();
}
});
} catch (TimeoutException e) {
return false;
}
return true;
}
This code will check markup within 20 seconds until it return true.If not, after 20 sec it will return false.
Always specify Exception type, which you want to catch. In other cases it is useless.
Try below xpath.
//*[#id="one_way_button1"]/span/input
It should work.
driver.findElement(By.xpath(//*[#id=\"one_way_button1\"]/span/input)).click();
As per my check, the specific radio button has following structure:
<a id="one_way_button1" href="javascript:void(0);" onclick="change_trip_type('one_way_button', 'trip_type', 'o');" class="one_way_button trip_type row first seg_text" tabindex="1">
<span class="radio_state">
<input type="radio" name="way_fields" value="one_way">
</span> ONE WAY
</a>
So what you are gonna to click is not the tag a which contains 'ONE WAY' but the span inside. You may have a try to locate the span by using xpath
"//a[text()='ONE WAY']/span[#class='radio_state']"
We have found in the past that with a radio and a click that the above happens (Sometimes it clicks it sometimes it does not) and as we try and steer clear of wait for tasks/Thread.Sleep (Due to then timing issues it then can cause on different environments). This alone can become a giant headache quick in using thread.sleeps :p
We have personally found that sometimes the best solution is to send a click then a (Sendkeys.Enter or a Sendkeys.Space) or just send the (Sendkeys.Enter or a Sendkeys.Space) only and don't use the click with a radio.
Especially on pages that use Telerik controls. This then tends to work on multiple machines/environments without the need to add a Thread.Sleep and make every test which uses that step take way longer than it needs to (Trust me when you have 1000's of tests that 5s thread.sleep soon adds up if a lot of tests use the same method)
Just throwing in another possible solution into the mix...
This is the more proper way to do this and I just tested it and it works fine. The best practice is to wait for the element to be clickable. You do that using WebDriverWait with ExpectedConditions. What this will do is wait up to 20s for the element to appear, when it does execution continues. This is a big advantage over Thread.sleep().
driver.get("http://www.makemytrip.com/international-flights");
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement oneWayRadioButton = wait.until(ExpectedConditions.elementToBeClickable(By.id("one_way_button1")));
oneWayRadioButton.click();
System.out.println("Clicked One Way");
I tried many different ways to force selenium to wait for the radio button to be visible but it kept timing out. I eventually had to settle for clicking the label for:
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = driver.findElement(selector);
wait.until(ExpectedConditions.elementToBeClickable(element));
element.click();
Where selected is defined by:
By selector = By.cssSelector(cssSelector);
With HTML looking like this:
...
<div class="multi-choice">
<input id="wibble" type="radio" name="wobble" value="TEXT">
<label for="wibble">Wobble</label>
</div>
...
And an example string cssSelector of:
String cssSelector = "label[for='wibble']"

Categories