Webdriver can't find the element - java

Selenium cant find this xpath I tried every way I need to click last button Deactivate but I cant
I tried xpath,cssSelectors,
#When("^I click deactivate button$")
public void iClickDeactivateButton(){
WebElement deactivateBatchButton = driver.findElement(By.xpath("//BUTTON[#_ngcontent-c14=''][text()='Deactivate'][text()='Deactivate']/self::BUTTONclass='deactivate']"));
deactivateBatchButton.click();
}
I want to click this button and carry one rest of the tests.

As the desired element is a Angular element and to locate it you have to induce WebDriverWait and you can use either of the following solutions:
cssSelector:
WebElement deactivateBatchButton = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.deactivate.xh-highlight")));
xpath:
WebElement deactivateBatchButton = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='deactivate xh-highlight' and text()='Deactivate']")));

You can carry on with the button name.
WebElement deactivateBatchButton = driver.findElement(By.xpath("//*[text()='Deactivate']"));
deactivateBatchButton.click();

Related

Selenium Webdriver with Eclipese IDE - Element should have been "select" but was "span"

My application have dropdown, and I have this problem:
org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "span"
enter code here
#Test
public void cadastrar_serviço_completo() throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://erpforme-hml.alterdata.com.br/");
Thread.sleep(1000);
driver.findElement(By.id("email-login")).sendKeys("*****");
driver.findElement(By.xpath("//form/div[2]/div/input")).sendKeys("*****");
driver.findElement(By.xpath("//button[#id='login-passaporte']")).click();
Thread.sleep(10000);
driver.findElement(By.xpath("//conpass[#id='conpass-tag']/div/div/div")).click();
driver.findElement(By.id("koopon-cabecalho-navbar-cadastro")).click();
driver.findElement(By.id("koopon-cabecalho-navbar-cadastro-estoque-servicos")).click();
Thread.sleep(1000);
driver.findElement(By.id("koopon-produto-servicos-btn-novo")).click();
Thread.sleep(1000);
driver.findElement(By.id("koopon-servico-input-valor-unitario")).sendKeys("10");
WebElement element = driver.findElement(By.id("select2-koopon-servico-select-lista-
codigos-servico-container"));
Select combo = new Select(element);
combo.selectByIndex(2);**
enter image description here
UnexpectedTagNameException this exception is displayed when passing the
reference of the WebElement which is not Select type underneath it
A check is made that the given element is, indeed, a SELECT tag. If it is not, then an UnexpectedTagNameException is thrown.
So instead of select2-koopon-servico-select-lista-codigos-servico-container taking this attribute which is of span if you just pass the select id which is koopon-servico-select-lista-codigos-servico so the exception will not get displayed
WebElement element = driver.findElement(By.id("koopon-servico-select- lista-codigos-servico"));
Select combo = new Select(element);
combo.selectByIndex(2);
I hope the above statements will help you
It is not a select it is a span, it should go through in a loop iterating through both spans capturing them with some common attribute, in this way select the one you need under some condition if you wish.
sorry my english.
Example:
el= driver.find_elements_by_xpath("//span[contains(#class,'select2-election')]")
for span in el :
if span.text == 'xxxxx':
span.click()

Unable to find locators(Xpath,Css) ,in the webpage

I am trying to automate application,tried first to find xpath or CSS locators unable to find looks no frame also inside the element.
I am able to handle using JavaScript but unable to enter full text in the search box,it's trimming some text,,please help me.
JavaScript which i tried.
((JavascriptExecutor)driver).executeScript("return document.querySelector('#app').shadowRoot.querySelector('#base > wego-search-form').shadowRoot.querySelector('div > wego-hotel-search-form').shadowRoot.querySelector('#loc').shadowRoot.querySelector('#item0 > div.disable-select.city-country-name').click();");
((JavascriptExecutor)driver).executeScript("return document.querySelector('#app').shadowRoot.querySelector('#base > wego-search-form').shadowRoot.querySelector('div > wego-hotel-search-form').shadowRoot.querySelector('#dates').shadowRoot.querySelector('#depart').shadowRoot.querySelector('#btn').click();");
My scenario i want to click search form and enter some destination details,If possible anyway i can handle this case using locators suggest me
Shadow DOM Elements are used in this website. Shadow DOM provides encapsulation for the JavaScript, CSS, and templating in a Web Component.
Shadow DOM allows hidden DOM trees to be attached to elements in the
regular DOM tree — this shadow DOM tree starts with a shadow root,
underneath which can be attached to any elements you want, in the same
way as the normal DOM.
Refer this To get details about it or for more details Google it.
Now handle Shadow element take reference from this blog. I've tried the below code to enter text as you expected and its working for me.
public static WebDriver driver;
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", "driver_path");
driver = new ChromeDriver();
driver.get("https://www.wego.com.my/hotels");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.manage().window().maximize();
WebElement root1 = driver.findElement(By.id("app"));
WebElement shadowRoot1 = expandRootElement(root1);
WebElement root2 = shadowRoot1.findElement(By.tagName("wego-search-form"));
WebElement shadowRoot2 = expandRootElement(root2);
WebElement root3 = shadowRoot2.findElement(By.tagName("wego-hotel-search-form"));
WebElement shadowRoot3 = expandRootElement(root3);
WebElement root4 = shadowRoot3.findElement(By.id("loc"));
WebElement shadowRoot4 = expandRootElement(root4);
shadowRoot4.findElement(By.cssSelector("div.root-container div.container")).click();
WebElement element = shadowRoot4.findElement(By.id("searchKeywordInput"));
Actions action = new Actions(driver);
action.click(element).sendKeys(Keys.chord(Keys.CONTROL, "a"));
element.sendKeys(Keys.DELETE);
element.sendKeys("narendra");
}
public static WebElement expandRootElement(WebElement element) {
WebElement newElement = (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", element);
return newElement;
}
Updated
As an alternative of sendKeys(), JavascriptExecutor can be used to set the value of text box. Use below code
WebElement element = shadowRoot4.findElement(By.id("searchKeywordInput"));
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
javascriptExecutor.executeScript("arguments[0].value='Your Text Goes Here';", element);
I've tested this so many time and this is working fine in each case.
Note: using JavascriptExecutor may not trigger the search result auto suggestion.

Explicit wait for two elements using OR operator in Selenium

I am trying to find either one of the 2 elements in selenium (java). If anyone is found then that should be clicked. following is not working;                                                            
WebDriverWait wait5 = new WebDriverWait(driver, 5);
wait5.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#data-period='R6M'] || //span[#title='FYTD']"))).click();
The xpath is invalid, or is a single |
wait5.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#data-period='R6M'] | //span[#title='FYTD']"))).click();
You can also use ExpectedConditions.or fo this
wait5.until(ExpectedConditions.or(
ExpectedConditions.elementToBeClickable(By.xpath("//a[#data-period='R6M']")),
ExpectedConditions.elementToBeClickable(By.xpath("//span[#title='FYTD']"))));
To get WebElement from one of two conditions you can build your own implementation
public ExpectedCondition<WebElement> customCondition(By... locators) {
#Override
public WebElement apply(WebDriver d) {
for (By locator in locators) {
return ExpectedConditions.elementToBeClickable(locator).apply(d);
}
}
}
WebElement element = wait4.until(customCondition(By.xpath("//a[#data-period='R6M']"), By.xpath("//span[#title='FYTD']")));
To induce WebDriverWait for either one of the 2 elements using Selenium java client you can use the following Locator Strategy:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.or(
ExpectedConditions.elementToBeClickable(By.xpath("//a[#data-period='R6M']")),
ExpectedConditions.elementToBeClickable(By.xpath("//span[#title='FYTD']"))
));
Reference
You can find a relevant discussion in:
How to wait for either of the two elements in the page using selenium xpath

Check if element is clickable in Selenium Java

I'm new to Selenium and need to check if element is clickable in Selenium Java, since element.click() passes both on link and label.
I tried using the following code, but it is not working:
WebDriverWait wait = new WebDriverWait(Scenario1Test.driver, 10);
if(wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//div[#id='brandSlider']/div[1]/div/div/div/img)[50]")))==null)
elementToBeClickable is used for checking an element is visible and enabled such that you can click it.
ExpectedConditions.elementToBeClickable returns WebElement if expected condition is true otherwise it will throw TimeoutException, It never returns null.
So if your using ExpectedConditions.elementToBeClickable to find an element which will always gives you the clickable element, so no need to check for null condition, you should try as below :-
WebDriverWait wait = new WebDriverWait(Scenario1Test.driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//div[#id='brandSlider']/div[1]/div/div/div/img)[50]")));
element.click();
As you are saying element.click() passes both on link and label that's doesn't mean element is not clickable, it means returned element clicked but may be there is no event performs on element by click action.
Note:- I'm suggesting you always try first to find elements by id, name, className and other locator. if you faced some difficulty to find then use cssSelector and always give last priority to xpath locator because it is slower than other locator to locate an element.
Hope it helps you..:)
There are instances when element.isDisplayed() && element.isEnabled() will return true but still element will not be clickable, because it is hidden/overlapped by some other element.
In such case, Exception caught is:
org.openqa.selenium.WebDriverException: unknown error: Element is not
clickable at point (781, 704). Other element would receive the click:
<div class="footer">...</div>
Use this code instead:
WebElement element=driver.findElement(By.xpath"");
JavascriptExecutor ex=(JavascriptExecutor)driver;
ex.executeScript("arguments[0].click()", element);
It will work.
wait.until(ExpectedConditions) won't return null, it will either meet the condition or throw TimeoutException.
You can check if the element is displayed and enabled
WebElement element = driver.findElement(By.xpath);
if (element.isDisplayed() && element.isEnabled()) {
element.click();
}
There are certain things you have to take care:
WebDriverWait inconjunction with ExpectedConditions as elementToBeClickable() returns the WebElement once it is located and clickable i.e. visible and enabled.
In this process, WebDriverWait will ignore instances of NotFoundException that are encountered by default in the until condition.
Once the duration of the wait expires on the desired element not being located and clickable, will throw a timeout exception.
The different approach to address this issue are:
To invoke click() as soon as the element is returned, you can use:
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("(//div[#id='brandSlider']/div[1]/div/div/div/img)[50]"))).click();
To simply validate if the element is located and clickable, wrap up the WebDriverWait in a try-catch{} block as follows:
try {
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("(//div[#id='brandSlider']/div[1]/div/div/div/img)[50]")));
System.out.println("Element is clickable");
}
catch(TimeoutException e) {
System.out.println("Element isn't clickable");
}
If WebDriverWait returns the located and clickable element but the element is still not clickable, you need to invoke executeScript() method as follows:
WebElement element = new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("(//div[#id='brandSlider']/div[1]/div/div/div/img)[50]")));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", element);
From the source code you will be able to view that, ExpectedConditions.elementToBeClickable(), it will judge the element visible and enabled, so you can use isEnabled() together with isDisplayed(). Following is the source code.
public static ExpectedCondition<WebElement> elementToBeClickable(final WebElement element) {
return new ExpectedCondition() {
public WebElement apply(WebDriver driver) {
WebElement visibleElement = (WebElement) ExpectedConditions.visibilityOf(element).apply(driver);
try {
return visibleElement != null && visibleElement.isEnabled() ? visibleElement : null;
} catch (StaleElementReferenceException arg3) {
return null;
}
}
public String toString() {
return "element to be clickable: " + element;
}
};
}
the class attribute contains disabled when the element is not clickable.
WebElement webElement = driver.findElement(By.id("elementId"));
if(!webElement.getAttribute("class").contains("disabled")){
webElement.click();
}
List<WebElement> wb=driver.findElements(By.xpath(newXpath));
for(WebElement we: wb){
if(we.isDisplayed() && we.isEnabled())
{
we.click();
break;
}
}
}

Identifying which web form element is selected after pressing tab key via selenium web-driver java?

I am using the sendKeys(key,Keys.TAB) method to navigate through a form.
Actions action = new Actions(driver);
CharSequence key = null;
for(int i=0;i<42;i++)
{
action.sendKeys(key,Keys.TAB).build().perform();
}
At the end of every action(a tab key press) I want to know which form element is selected
I want to reach to the 42nd element of the form and cross check whether its the desired element and for that i need to retrieve some of its information.
I am new to selenium and I am not able to figure out a way to achieve this.
You can use WebDriver's TargetLocator class for this purpose.
WebElement currentElement = driver.switchTo().activeElement();
This will return you with current element it focussed currently. If no element is focussed it will return you the body element, which is the case when u launch your browser.
Internally it will be returning u the element returned by document.activeElement. So to verify u can always run as:
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement currentElement = (WebElement) js.executeScript("return document.activeElement");

Categories